From 5b1ab32d161570cf9d3ef865977d765beb0d84c7 Mon Sep 17 00:00:00 2001 From: uazo <29201891+uazo@users.noreply.github.com> Date: Thu, 29 Aug 2024 02:49:51 +0000 Subject: [PATCH] [AUTO][FILECONTROL] - version 128.0.6613.114 --- tools/under-control/src/RELEASE | 2 +- .../browser/aw_content_browser_client.cc | 1419 + .../browser/aw_field_trials.cc | 273 + .../chrome/android/java/AndroidManifest.xml | 1363 + .../chrome_browsing_data_remover_delegate.cc | 1752 ++ .../chrome_browser_interface_binders.cc | 1956 ++ .../browser/chrome_content_browser_client.cc | 8661 +++++ .../src/chrome/browser/prefs/browser_prefs.cc | 2722 ++ .../src/chrome/browser/ui/tab_helpers.cc | 840 + ...hrome_content_browser_client_webui_part.cc | 120 + .../api/accessibility_service_private.idl | 30 + .../common/extensions/api/appview_tag.idl | 49 + .../extensions/api/autofill_private.idl | 426 + .../extensions/api/autotest_private.idl | 1678 + .../api/braille_display_private.idl | 93 + .../extensions/api/certificate_provider.idl | 305 + .../api/certificate_provider_internal.idl | 34 + .../extensions/api/chrome_url_overrides.idl | 25 + .../extensions/api/crash_report_private.idl | 54 + .../extensions/api/developer_private.idl | 893 + .../common/extensions/api/document_scan.idl | 654 + .../common/extensions/api/downloads.idl | 630 + .../extensions/api/downloads_internal.idl | 14 + .../api/enterprise_device_attributes.idl | 61 + .../api/enterprise_hardware_platform.idl | 24 + .../extensions/api/enterprise_kiosk_input.idl | 36 + .../api/enterprise_networking_attributes.idl | 34 + .../api/enterprise_platform_keys.idl | 230 + .../api/enterprise_platform_keys_internal.idl | 60 + .../api/enterprise_reporting_private.idl | 407 + .../extensions/api/file_manager_private.idl | 2127 ++ .../api/file_manager_private_internal.idl | 180 + .../extensions/api/file_system_provider.idl | 833 + .../api/file_system_provider_internal.idl | 82 + .../chrome/common/extensions/api/identity.idl | 243 + .../chrome/common/extensions/api/idltest.idl | 33 + .../extensions/api/image_loader_private.idl | 45 + .../extensions/api/image_writer_private.idl | 145 + .../api/language_settings_private.idl | 183 + .../chrome/common/extensions/api/login.idl | 180 + .../extensions/api/login_screen_storage.idl | 51 + .../common/extensions/api/login_screen_ui.idl | 33 + .../common/extensions/api/login_state.idl | 55 + .../src/chrome/common/extensions/api/mdns.idl | 53 + .../common/extensions/api/notifications.idl | 218 + .../extensions/api/odfs_config_private.idl | 66 + .../extensions/api/passwords_private.idl | 622 + .../extensions/api/pdf_viewer_private.idl | 72 + .../common/extensions/api/platform_keys.idl | 185 + .../extensions/api/platform_keys_internal.idl | 76 + .../chrome/common/extensions/api/printing.idl | 203 + .../extensions/api/printing_metrics.idl | 157 + .../common/extensions/api/processes.idl | 183 + .../extensions/api/quick_unlock_private.idl | 153 + .../common/extensions/api/reading_list.idl | 117 + .../extensions/api/resources_private.idl | 24 + .../extensions/api/safe_browsing_private.idl | 173 + .../common/extensions/api/scripting.idl | 268 + .../chrome/common/extensions/api/search.idl | 42 + .../extensions/api/settings_private.idl | 126 + .../extensions/api/shared_storage_private.idl | 30 + .../common/extensions/api/side_panel.idl | 109 + .../api/smart_card_provider_private.idl | 268 + .../api/speech_recognition_private.idl | 88 + .../extensions/api/system_indicator.idl | 38 + .../common/extensions/api/system_log.idl | 26 + .../common/extensions/api/tab_capture.idl | 130 + .../common/extensions/api/users_private.idl | 77 + .../common/extensions/api/vpn_provider.idl | 201 + .../api/web_authentication_proxy.idl | 196 + .../extensions/api/webrtc_audio_private.idl | 64 + .../api/webrtc_desktop_capture_private.idl | 34 + .../extensions/api/webrtc_logging_private.idl | 186 + .../extensions/api/wm_desks_private.idl | 145 + .../chrome_content_renderer_client.cc | 1881 ++ .../browser/web_contents/web_contents_impl.cc | 11146 +++++++ .../src/content/child/runtime_features.cc | 791 + .../public/browser/content_browser_client.cc | 1769 ++ .../src/extensions/common/api/alarms.idl | 104 + .../api/app_current_window_internal.idl | 66 + .../src/extensions/common/api/app_runtime.idl | 165 + .../src/extensions/common/api/app_window.idl | 502 + .../src/extensions/common/api/audio.idl | 167 + .../src/extensions/common/api/automation.idl | 1577 + .../common/api/automation_internal.idl | 167 + .../src/extensions/common/api/bluetooth.idl | 187 + .../common/api/bluetooth_low_energy.idl | 603 + .../common/api/bluetooth_private.idl | 197 + .../common/api/bluetooth_socket.idl | 326 + .../src/extensions/common/api/cec_private.idl | 65 + .../src/extensions/common/api/clipboard.idl | 55 + .../extensions/common/api/content_scripts.idl | 66 + .../common/api/cross_origin_isolation.idl | 16 + .../common/api/declarative_net_request.idl | 850 + .../src/extensions/common/api/diagnostics.idl | 38 + .../src/extensions/common/api/dns.idl | 28 + .../common/api/extension_options_internal.idl | 24 + .../common/api/feedback_private.idl | 288 + .../extensions/common/api/file_handlers.idl | 55 + .../src/extensions/common/api/file_system.idl | 186 + .../src/extensions/common/api/hid.idl | 159 + .../extensions/common/api/icon_variants.idl | 23 + .../common/api/lock_screen_data.idl | 97 + .../common/api/media_perception_private.idl | 609 + .../common/api/mime_handler_private.idl | 71 + .../extensions/common/api/mojo_private.idl | 13 + .../extensions/common/api/networking_onc.idl | 1039 + .../common/api/networking_private.idl | 1114 + .../src/extensions/common/api/oauth2.idl | 22 + .../src/extensions/common/api/offscreen.idl | 88 + .../src/extensions/common/api/power.idl | 35 + .../common/api/printer_provider.idl | 114 + .../common/api/printer_provider_internal.idl | 58 + .../common/api/scripts_internal.idl | 72 + .../src/extensions/common/api/serial.idl | 371 + .../extensions/common/api/shared_module.idl | 32 + .../src/extensions/common/api/socket.idl | 397 + .../src/extensions/common/api/sockets_tcp.idl | 295 + .../common/api/sockets_tcp_server.idl | 197 + .../src/extensions/common/api/sockets_udp.idl | 342 + .../src/extensions/common/api/system_cpu.idl | 61 + .../extensions/common/api/system_display.idl | 457 + .../extensions/common/api/system_memory.idl | 21 + .../extensions/common/api/system_network.idl | 31 + .../extensions/common/api/system_storage.idl | 86 + .../src/extensions/common/api/usb.idl | 423 + .../extensions/common/api/user_scripts.idl | 180 + .../common/api/virtual_keyboard.idl | 39 + .../common/api/web_accessible_resources.idl | 35 + .../api/web_accessible_resources_mv2.idl | 12 + .../extensions/common/api/webcam_private.idl | 101 + tools/under-control/src/gin/v8_initializer.cc | 667 + .../src/media/base/video_codecs.h | 152 + .../src/services/network/network_context.cc | 3261 ++ .../variations/fieldtrial_testing_config.json | 26061 ++++++++++++++++ .../use_counter/metrics/web_feature.mojom | 4419 +++ .../webpreferences/web_preferences.mojom | 494 + .../aria_notification_options.idl | 8 + .../renderer/core/animation/animatable.idl | 42 + .../renderer/core/animation/animation.idl | 67 + .../core/animation/animation_effect.idl | 38 + .../core/animation/animation_timeline.idl | 14 + .../renderer/core/animation/base_keyframe.idl | 14 + .../base_property_indexed_keyframe.idl | 11 + .../core/animation/computed_effect_timing.idl | 13 + .../core/animation/css/css_animation.idl | 10 + .../core/animation/css/css_transition.idl | 10 + .../core/animation/document_animation.idl | 11 + .../core/animation/document_timeline.idl | 11 + .../animation/document_timeline_options.idl | 9 + .../renderer/core/animation/effect_timing.idl | 19 + .../core/animation/get_animations_options.idl | 9 + .../animation/keyframe_animation_options.idl | 29 + .../core/animation/keyframe_effect.idl | 45 + .../animation/keyframe_effect_options.idl | 11 + .../core/animation/optional_effect_timing.idl | 19 + .../core/animation/scroll_timeline.idl | 15 + .../animation/scroll_timeline_options.idl | 10 + .../renderer/core/animation/view_timeline.idl | 16 + .../core/animation/view_timeline_options.idl | 13 + .../renderer/core/aom/accessible_node.idl | 74 + .../core/aom/accessible_node_list.idl | 18 + .../core/aom/computed_accessible_node.idl | 54 + .../renderer/core/clipboard/data_transfer.idl | 48 + .../core/clipboard/data_transfer_item.idl | 40 + .../clipboard/data_transfer_item_list.idl | 42 + .../blink/renderer/core/css/css.idl | 39 + .../renderer/core/css/css_condition_rule.idl | 12 + .../renderer/core/css/css_container_rule.idl | 11 + .../core/css/css_counter_style_rule.idl | 19 + .../renderer/core/css/css_font_face_rule.idl | 27 + .../core/css/css_font_feature_values_rule.idl | 22 + .../core/css/css_font_palette_values_rule.idl | 13 + .../renderer/core/css/css_grouping_rule.idl | 13 + .../renderer/core/css/css_import_rule.idl | 33 + .../renderer/core/css/css_keyframe_rule.idl | 36 + .../renderer/core/css/css_keyframes_rule.idl | 42 + .../core/css/css_layer_block_rule.idl | 10 + .../core/css/css_layer_statement_rule.idl | 10 + .../renderer/core/css/css_margin_rule.idl | 13 + .../renderer/core/css/css_media_rule.idl | 27 + .../renderer/core/css/css_namespace_rule.idl | 13 + .../blink/renderer/core/css/css_page_rule.idl | 28 + .../core/css/css_position_try_descriptors.idl | 79 + .../core/css/css_position_try_rule.idl | 11 + .../renderer/core/css/css_property_rule.idl | 12 + .../blink/renderer/core/css/css_rule.idl | 55 + .../blink/renderer/core/css/css_rule_list.idl | 33 + .../renderer/core/css/css_scope_rule.idl | 10 + .../core/css/css_starting_style_rule.idl | 8 + .../core/css/css_style_declaration.idl | 46 + .../renderer/core/css/css_style_rule.idl | 34 + .../renderer/core/css/css_style_sheet.idl | 39 + .../core/css/css_style_sheet_init.idl | 10 + .../renderer/core/css/css_supports_rule.idl | 34 + .../core/css/css_view_transition_rule.idl | 11 + .../core/css/cssom/caret_position.idl | 13 + .../core/css/cssom/css_color_value.idl | 17 + .../blink/renderer/core/css/cssom/css_hsl.idl | 16 + .../blink/renderer/core/css/cssom/css_hwb.idl | 18 + .../core/css/cssom/css_image_value.idl | 12 + .../core/css/cssom/css_keyword_value.idl | 15 + .../core/css/cssom/css_math_clamp.idl | 14 + .../core/css/cssom/css_math_invert.idl | 12 + .../renderer/core/css/cssom/css_math_max.idl | 12 + .../renderer/core/css/cssom/css_math_min.idl | 12 + .../core/css/cssom/css_math_negate.idl | 12 + .../core/css/cssom/css_math_product.idl | 12 + .../renderer/core/css/cssom/css_math_sum.idl | 12 + .../core/css/cssom/css_math_value.idl | 20 + .../core/css/cssom/css_matrix_component.idl | 14 + .../cssom/css_matrix_component_options.idl | 10 + .../core/css/cssom/css_numeric_array.idl | 13 + .../core/css/cssom/css_numeric_type.idl | 26 + .../core/css/cssom/css_numeric_value.idl | 28 + .../core/css/cssom/css_perspective.idl | 15 + .../core/css/cssom/css_position_value.idl | 14 + .../blink/renderer/core/css/cssom/css_rgb.idl | 16 + .../renderer/core/css/cssom/css_rotate.idl | 17 + .../renderer/core/css/cssom/css_scale.idl | 15 + .../renderer/core/css/cssom/css_skew.idl | 14 + .../renderer/core/css/cssom/css_skew_x.idl | 13 + .../renderer/core/css/cssom/css_skew_y.idl | 13 + .../core/css/cssom/css_style_value.idl | 16 + .../css/cssom/css_transform_component.idl | 15 + .../core/css/cssom/css_transform_value.idl | 16 + .../renderer/core/css/cssom/css_translate.idl | 16 + .../core/css/cssom/css_unit_value.idl | 14 + .../core/css/cssom/css_unit_values.idl | 91 + .../core/css/cssom/css_unparsed_value.idl | 19 + .../cssom/css_variable_reference_value.idl | 14 + .../css/cssom/element_computed_style_map.idl | 11 + .../core/css/cssom/style_property_map.idl | 15 + .../cssom/style_property_map_read_only.idl | 17 + .../blink/renderer/core/css/cssom_string.idl | 9 + .../blink/renderer/core/css/font_face.idl | 64 + .../core/css/font_face_descriptors.idl | 19 + .../blink/renderer/core/css/font_face_set.idl | 61 + .../core/css/font_face_set_load_event.idl | 39 + .../css/font_face_set_load_event_init.idl | 9 + .../renderer/core/css/font_face_source.idl | 8 + .../blink/renderer/core/css/media_list.idl | 36 + .../renderer/core/css/media_query_list.idl | 35 + .../core/css/media_query_list_event.idl | 13 + .../core/css/media_query_list_event_init.idl | 10 + .../core/css/parser/media_query_parser.cc | 634 + .../renderer/core/css/property_definition.idl | 10 + .../core/css/property_registration.idl | 11 + .../blink/renderer/core/css/style_media.idl | 39 + .../blink/renderer/core/css/style_sheet.idl | 34 + .../renderer/core/css/style_sheet_list.idl | 31 + ...ent_visibility_auto_state_change_event.idl | 10 + ...isibility_auto_state_change_event_init.idl | 8 + .../renderer/core/dom/abort_controller.idl | 14 + .../blink/renderer/core/dom/abort_signal.idl | 31 + .../renderer/core/dom/abstract_range.idl | 15 + .../renderer/core/dom/accessibility_role.idl | 12 + .../renderer/core/dom/aria_attributes.idl | 56 + .../core/dom/aria_relationship_attributes.idl | 21 + .../blink/renderer/core/dom/attr.idl | 34 + .../renderer/core/dom/attribute_part.idl | 13 + .../dom/caret_position_from_point_options.idl | 7 + .../blink/renderer/core/dom/cdata_section.idl | 25 + .../renderer/core/dom/character_data.idl | 34 + .../blink/renderer/core/dom/child_node.idl | 29 + .../renderer/core/dom/child_node_part.idl | 15 + .../blink/renderer/core/dom/comment.idl | 26 + .../renderer/core/dom/common_definitions.idl | 18 + .../blink/renderer/core/dom/document.idl | 234 + .../document_and_element_event_handlers.idl | 10 + .../renderer/core/dom/document_fragment.idl | 32 + .../core/dom/document_or_shadow_root.idl | 29 + .../renderer/core/dom/document_part_root.idl | 10 + .../blink/renderer/core/dom/document_type.idl | 30 + .../blink/renderer/core/dom/dom_exception.idl | 80 + .../renderer/core/dom/dom_implementation.idl | 33 + .../renderer/core/dom/dom_string_list.idl | 33 + .../renderer/core/dom/dom_string_map.idl | 35 + .../renderer/core/dom/dom_token_list.idl | 42 + .../blink/renderer/core/dom/element.idl | 175 + .../core/dom/element_creation_options.idl | 9 + .../core/dom/element_css_inline_style.idl | 12 + .../core/dom/element_definition_options.idl | 7 + .../core/dom/element_registration_options.idl | 10 + .../dom/events/add_event_listener_options.idl | 11 + .../renderer/core/dom/events/custom_event.idl | 35 + .../core/dom/events/custom_event_init.idl | 9 + .../blink/renderer/core/dom/events/event.idl | 57 + .../renderer/core/dom/events/event_init.idl | 11 + .../core/dom/events/event_listener.idl | 25 + .../dom/events/event_listener_options.idl | 9 + .../core/dom/events/event_modifier_init.idl | 19 + .../renderer/core/dom/events/event_target.idl | 36 + .../core/dom/frame_request_callback.idl | 34 + .../core/dom/function_string_callback.idl | 33 + .../renderer/core/dom/get_html_options.idl | 8 + .../core/dom/get_inner_html_options.idl | 12 + .../core/dom/get_root_node_options.idl | 9 + .../core/dom/global_event_handlers.idl | 154 + .../core/dom/interest_invoker_element.idl | 9 + .../renderer/core/dom/invoker_element.idl | 9 + .../renderer/core/dom/mutation_observer.idl | 46 + .../core/dom/mutation_observer_init.idl | 15 + .../renderer/core/dom/mutation_record.idl | 45 + .../renderer/core/dom/named_node_map.idl | 35 + .../blink/renderer/core/dom/node.idl | 82 + .../blink/renderer/core/dom/node_filter.idl | 47 + .../blink/renderer/core/dom/node_iterator.idl | 36 + .../blink/renderer/core/dom/node_list.idl | 29 + .../blink/renderer/core/dom/node_part.idl | 12 + .../core/dom/non_document_type_child_node.idl | 9 + .../core/dom/non_element_parent_node.idl | 8 + .../blink/renderer/core/dom/observable.idl | 76 + .../blink/renderer/core/dom/parent_node.idl | 44 + .../blink/renderer/core/dom/part.idl | 19 + .../blink/renderer/core/dom/part_root.idl | 36 + .../core/dom/pointer_lock_options.idl | 4 + .../core/dom/popover_invoker_element.idl | 11 + .../core/dom/processing_instruction.idl | 31 + .../blink/renderer/core/dom/range.idl | 71 + .../blink/renderer/core/dom/shadow_root.idl | 88 + .../renderer/core/dom/shadow_root_init.idl | 19 + .../blink/renderer/core/dom/static_range.idl | 10 + .../renderer/core/dom/static_range_init.idl | 12 + .../blink/renderer/core/dom/subscriber.idl | 17 + .../dom/testing/internals_storage_access.idl | 9 + .../blink/renderer/core/dom/text.idl | 32 + .../blink/renderer/core/dom/tree_walker.idl | 38 + .../blink/renderer/core/dom/void_function.idl | 7 + .../blink/renderer/core/dom/xml_document.idl | 31 + .../ime/character_bounds_update_event.idl | 18 + .../character_bounds_update_event_init.idl | 13 + .../core/editing/ime/edit_context.idl | 36 + .../core/editing/ime/edit_context_init.idl | 14 + .../renderer/core/editing/ime/text_format.idl | 22 + .../core/editing/ime/text_format_init.idl | 15 + .../editing/ime/text_format_update_event.idl | 18 + .../ime/text_format_update_event_init.idl | 12 + .../core/editing/ime/text_update_event.idl | 23 + .../editing/ime/text_update_event_init.idl | 16 + .../blink/renderer/core/editing/selection.idl | 75 + .../renderer/core/events/animation_event.idl | 35 + .../core/events/animation_event_init.idl | 11 + .../core/events/animation_playback_event.idl | 13 + .../events/animation_playback_event_init.idl | 10 + .../events/before_create_policy_event.idl | 10 + .../core/events/before_unload_event.idl | 36 + .../renderer/core/events/clipboard_event.idl | 12 + .../core/events/clipboard_event_init.idl | 9 + .../renderer/core/events/command_event.idl | 17 + .../core/events/composition_event.idl | 40 + .../core/events/composition_event_init.idl | 9 + .../blink/renderer/core/events/drag_event.idl | 12 + .../renderer/core/events/drag_event_init.idl | 9 + .../renderer/core/events/error_event.idl | 42 + .../renderer/core/events/error_event_init.idl | 13 + .../core/events/event_type_names.json5 | 381 + .../renderer/core/events/focus_event.idl | 33 + .../renderer/core/events/focus_event_init.idl | 9 + .../core/events/hash_change_event.idl | 29 + .../core/events/hash_change_event_init.idl | 10 + .../renderer/core/events/input_event.idl | 20 + .../renderer/core/events/input_event_init.idl | 17 + .../renderer/core/events/interest_event.idl | 17 + .../renderer/core/events/keyboard_event.idl | 58 + .../core/events/keyboard_event_init.idl | 17 + .../renderer/core/events/message_event.idl | 52 + .../core/events/message_event_init.idl | 15 + .../renderer/core/events/mouse_event.idl | 73 + .../renderer/core/events/mouse_event_init.idl | 24 + .../renderer/core/events/mutation_event.idl | 45 + .../renderer/core/events/navigator_events.idl | 37 + .../renderer/core/events/overscroll_event.idl | 14 + .../core/events/overscroll_event_init.idl | 10 + .../core/events/page_transition_event.idl | 34 + .../events/page_transition_event_init.idl | 9 + .../renderer/core/events/pointer_event.idl | 28 + .../core/events/pointer_event_init.idl | 25 + .../renderer/core/events/pop_state_event.idl | 36 + .../core/events/pop_state_event_init.idl | 10 + .../renderer/core/events/progress_event.idl | 35 + .../core/events/progress_event_init.idl | 11 + .../core/events/promise_rejection_event.idl | 13 + .../events/promise_rejection_event_init.idl | 10 + .../core/events/resource_progress_event.idl | 37 + .../security_policy_violation_event.idl | 51 + .../security_policy_violation_event_init.idl | 27 + .../blink/renderer/core/events/text_event.idl | 46 + .../renderer/core/events/toggle_event.idl | 11 + .../core/events/toggle_event_init.idl | 8 + .../renderer/core/events/touch_event.idl | 39 + .../renderer/core/events/touch_event_init.idl | 11 + .../renderer/core/events/transition_event.idl | 36 + .../core/events/transition_event_init.idl | 11 + .../blink/renderer/core/events/ui_event.idl | 38 + .../renderer/core/events/ui_event_init.idl | 11 + .../renderer/core/events/wheel_event.idl | 41 + .../renderer/core/events/wheel_event_init.idl | 16 + .../renderer/core/exported/web_view_impl.cc | 4166 +++ .../core/fetch/attribution_reporting.idl | 8 + .../blink/renderer/core/fetch/body.idl | 20 + .../core/fetch/deferred_request_init.idl | 9 + .../blink/renderer/core/fetch/fetch_later.idl | 32 + .../blink/renderer/core/fetch/headers.idl | 22 + .../renderer/core/fetch/private_token.idl | 31 + .../blink/renderer/core/fetch/request.idl | 71 + .../renderer/core/fetch/request_init.idl | 38 + .../blink/renderer/core/fetch/response.idl | 31 + .../renderer/core/fetch/response_init.idl | 11 + .../core/fetch/testing/internals_fetch.idl | 9 + .../fetch/testing/worker_internals_fetch.idl | 12 + .../renderer/core/fetch/window_fetch.idl | 11 + .../renderer/core/fetch/worker_fetch.idl | 11 + .../blink/renderer/core/fileapi/blob.idl | 47 + .../core/fileapi/blob_property_bag.idl | 12 + .../blink/renderer/core/fileapi/file.idl | 39 + .../blink/renderer/core/fileapi/file_list.idl | 34 + .../core/fileapi/file_property_bag.idl | 9 + .../renderer/core/fileapi/file_reader.idl | 66 + .../core/fileapi/file_reader_sync.idl | 41 + .../renderer/core/fileapi/url_file_api.idl | 11 + .../fragment_directive/fragment_directive.idl | 12 + .../fragment_directive/text_directive.idl | 16 + .../text_directive_options.idl | 12 + .../blink/renderer/core/frame/bar_prop.idl | 35 + .../coop_access_violation_report_body.idl | 19 + .../frame/csp/csp_violation_report_body.idl | 22 + .../deprecation/deprecation_report_body.idl | 17 + .../blink/renderer/core/frame/directive.idl | 14 + .../document_policy_violation_report_body.idl | 17 + .../blink/renderer/core/frame/external.idl | 9 + .../blink/renderer/core/frame/history.idl | 41 + .../core/frame/intervention_report_body.idl | 16 + .../core/frame/is_input_pending_options.idl | 8 + .../blink/renderer/core/frame/location.idl | 60 + .../blink/renderer/core/frame/navigator.idl | 44 + .../navigator_automation_information.idl | 9 + .../frame/navigator_concurrent_hardware.idl | 9 + .../renderer/core/frame/navigator_cookies.idl | 10 + .../core/frame/navigator_device_memory.idl | 10 + .../renderer/core/frame/navigator_id.idl | 42 + .../core/frame/navigator_language.idl | 10 + .../renderer/core/frame/navigator_on_line.idl | 35 + .../core/frame/navigator_scheduling.idl | 10 + .../renderer/core/frame/navigator_ua.idl | 9 + .../core/frame/navigator_ua_brand_version.idl | 10 + .../renderer/core/frame/navigator_ua_data.idl | 13 + .../core/frame/navigator_user_activation.idl | 11 + ...rmissions_policy_violation_report_body.idl | 17 + .../blink/renderer/core/frame/report.idl | 14 + .../blink/renderer/core/frame/report_body.idl | 11 + .../core/frame/reporting_observer.idl | 19 + .../core/frame/reporting_observer_options.idl | 10 + .../blink/renderer/core/frame/scheduling.idl | 10 + .../blink/renderer/core/frame/screen.idl | 53 + .../core/frame/scroll_into_view_options.idl | 6 + .../renderer/core/frame/scroll_options.idl | 11 + .../renderer/core/frame/scroll_to_options.idl | 10 + .../core/frame/selector_directive.idl | 11 + .../blink/renderer/core/frame/settings.json5 | 1258 + .../renderer/core/frame/test_report_body.idl | 12 + .../renderer/core/frame/ua_data_values.idl | 19 + .../renderer/core/frame/user_activation.idl | 11 + .../renderer/core/frame/visual_viewport.idl | 55 + .../blink/renderer/core/frame/window.idl | 227 + .../core/frame/window_event_handlers.idl | 51 + .../frame/window_or_worker_global_scope.idl | 42 + .../frame/window_post_message_options.idl | 10 + .../renderer/core/frame/window_properties.idl | 13 + .../core/fullscreen/document_fullscreen.idl | 47 + .../core/fullscreen/element_fullscreen.idl | 23 + .../core/fullscreen/fullscreen_options.idl | 19 + .../renderer/core/geometry/dom_matrix.idl | 72 + .../core/geometry/dom_matrix_2d_init.idl | 20 + .../core/geometry/dom_matrix_init.idl | 19 + .../core/geometry/dom_matrix_read_only.idl | 81 + .../renderer/core/geometry/dom_point.idl | 18 + .../renderer/core/geometry/dom_point_init.idl | 12 + .../core/geometry/dom_point_read_only.idl | 23 + .../blink/renderer/core/geometry/dom_quad.idl | 22 + .../renderer/core/geometry/dom_quad_init.idl | 12 + .../blink/renderer/core/geometry/dom_rect.idl | 21 + .../renderer/core/geometry/dom_rect_init.idl | 12 + .../renderer/core/geometry/dom_rect_list.idl | 16 + .../core/geometry/dom_rect_read_only.idl | 25 + .../core/highlight/css_highlight_registry.idl | 10 + .../renderer/core/highlight/highlight.idl | 22 + .../highlight/highlight_pointer_event.idl | 14 + .../core/highlight/highlight_registry.idl | 9 + .../core/html/assigned_nodes_options.idl | 9 + .../renderer/core/html/canvas/baselines.idl | 9 + .../canvas/high_dynamic_range_options.idl | 28 + .../core/html/canvas/html_canvas_element.idl | 47 + .../renderer/core/html/canvas/image_data.idl | 48 + .../core/html/canvas/image_data_settings.idl | 23 + .../core/html/canvas/image_encode_options.idl | 21 + .../core/html/canvas/text_metrics.idl | 53 + .../core/html/closewatcher/close_watcher.idl | 18 + .../closewatcher/close_watcher_options.idl | 3 + .../html/custom/custom_element_registry.idl | 25 + .../core/html/custom/custom_state_set.idl | 12 + .../core/html/custom/element_internals.idl | 36 + .../core/html/custom/validity_state_flags.idl | 18 + .../renderer/core/html/event_handler.idl | 22 + .../renderer/core/html/fenced_frame/fence.idl | 16 + .../core/html/fenced_frame/fence_event.idl | 39 + .../html/fenced_frame/fenced_frame_config.idl | 20 + .../html_fenced_frame_element.idl | 16 + .../renderer/core/html/focus_options.idl | 3 + .../renderer/core/html/forms/form_data.idl | 48 + .../core/html/forms/form_data_event.idl | 12 + .../core/html/forms/form_data_event_init.idl | 9 + .../core/html/forms/html_button_element.idl | 50 + .../html/forms/html_data_list_element.idl | 37 + .../html/forms/html_field_set_element.idl | 39 + .../forms/html_form_controls_collection.idl | 30 + .../core/html/forms/html_form_element.idl | 51 + .../core/html/forms/html_input_element.idl | 117 + .../core/html/forms/html_label_element.idl | 29 + .../core/html/forms/html_legend_element.idl | 31 + .../html/forms/html_opt_group_element.idl | 27 + .../core/html/forms/html_option_element.idl | 43 + .../html/forms/html_options_collection.idl | 37 + .../core/html/forms/html_output_element.idl | 47 + .../core/html/forms/html_select_element.idl | 63 + .../html/forms/html_select_list_element.idl | 29 + .../html/forms/html_text_area_element.idl | 68 + .../core/html/forms/radio_node_list.idl | 37 + .../renderer/core/html/forms/submit_event.idl | 12 + .../core/html/forms/submit_event_init.idl | 9 + .../core/html/forms/validity_state.idl | 38 + .../core/html/html_all_collection.idl | 37 + .../core/html/html_anchor_element.idl | 49 + .../renderer/core/html/html_area_element.idl | 42 + .../html_attributionsrc_element_utils.idl | 8 + .../renderer/core/html/html_base_element.idl | 27 + .../renderer/core/html/html_body_element.idl | 50 + .../renderer/core/html/html_br_element.idl | 28 + .../renderer/core/html/html_collection.idl | 31 + .../renderer/core/html/html_data_element.idl | 12 + .../core/html/html_details_element.idl | 27 + .../core/html/html_dialog_element.idl | 36 + .../core/html/html_directory_element.idl | 26 + .../renderer/core/html/html_div_element.idl | 28 + .../renderer/core/html/html_dlist_element.idl | 28 + .../renderer/core/html/html_document.idl | 27 + .../blink/renderer/core/html/html_element.idl | 87 + .../renderer/core/html/html_embed_element.idl | 44 + .../renderer/core/html/html_font_element.idl | 28 + .../renderer/core/html/html_frame_element.idl | 38 + .../core/html/html_frame_set_element.idl | 46 + .../renderer/core/html/html_head_element.idl | 25 + .../core/html/html_heading_element.idl | 28 + .../renderer/core/html/html_hr_element.idl | 32 + .../renderer/core/html/html_html_element.idl | 28 + .../html/html_hyperlink_element_utils.idl | 21 + .../core/html/html_iframe_element.idl | 81 + .../renderer/core/html/html_image_element.idl | 69 + .../renderer/core/html/html_li_element.idl | 30 + .../renderer/core/html/html_link_element.idl | 60 + .../renderer/core/html/html_map_element.idl | 28 + .../core/html/html_marquee_element.idl | 45 + .../renderer/core/html/html_menu_element.idl | 28 + .../renderer/core/html/html_meta_element.idl | 33 + .../renderer/core/html/html_meter_element.idl | 32 + .../renderer/core/html/html_mod_element.idl | 28 + .../core/html/html_object_element.idl | 66 + .../renderer/core/html/html_olist_element.idl | 32 + .../core/html/html_or_foreign_element.idl | 20 + .../core/html/html_paragraph_element.idl | 28 + .../renderer/core/html/html_param_element.idl | 32 + .../core/html/html_permission_element.idl | 16 + .../core/html/html_picture_element.idl | 10 + .../renderer/core/html/html_pre_element.idl | 29 + .../core/html/html_progress_element.idl | 29 + .../renderer/core/html/html_quote_element.idl | 27 + .../core/html/html_script_element.idl | 55 + ..._shared_storage_writable_element_utils.idl | 9 + .../renderer/core/html/html_slot_element.idl | 36 + .../core/html/html_source_element.idl | 40 + .../renderer/core/html/html_span_element.idl | 31 + .../renderer/core/html/html_style_element.idl | 36 + .../core/html/html_table_caption_element.idl | 29 + .../core/html/html_table_cell_element.idl | 53 + .../core/html/html_table_col_element.idl | 36 + .../renderer/core/html/html_table_element.idl | 55 + .../core/html/html_table_row_element.idl | 40 + .../core/html/html_table_section_element.idl | 38 + .../core/html/html_template_element.idl | 51 + .../renderer/core/html/html_time_element.idl | 12 + .../renderer/core/html/html_title_element.idl | 26 + .../renderer/core/html/html_ulist_element.idl | 29 + .../core/html/html_unknown_element.idl | 35 + .../core/html/media/html_audio_element.idl | 34 + .../core/html/media/html_media_element.idl | 99 + .../core/html/media/html_video_element.idl | 59 + .../renderer/core/html/media/media_error.idl | 36 + .../blink/renderer/core/html/time_ranges.idl | 33 + .../renderer/core/html/track/audio_track.idl | 16 + .../core/html/track/audio_track_list.idl | 18 + .../core/html/track/html_track_element.idl | 45 + .../renderer/core/html/track/text_track.idl | 49 + .../core/html/track/text_track_cue.idl | 39 + .../core/html/track/text_track_cue_list.idl | 33 + .../core/html/track/text_track_list.idl | 37 + .../renderer/core/html/track/track_event.idl | 33 + .../core/html/track/track_event_init.idl | 9 + .../renderer/core/html/track/video_track.idl | 16 + .../core/html/track/video_track_list.idl | 19 + .../renderer/core/html/track/vtt/vtt_cue.idl | 53 + .../core/html/track/vtt/vtt_region.idl | 43 + .../renderer/core/html/void_callback.idl | 32 + .../core/imagebitmap/image_bitmap.idl | 15 + .../core/imagebitmap/image_bitmap_options.idl | 18 + .../core/input/input_device_capabilities.idl | 23 + .../input/input_device_capabilities_init.idl | 9 + .../blink/renderer/core/input/touch.idl | 44 + .../blink/renderer/core/input/touch_init.idl | 24 + .../blink/renderer/core/input/touch_list.idl | 33 + .../core/inspector/dev_tools_host.idl | 51 + .../core/inspector/inspector_overlay_host.idl | 35 + .../intersection_observer.idl | 26 + .../intersection_observer_entry.idl | 19 + .../intersection_observer_init.idl | 14 + .../core/layout/custom/css_layout_worklet.idl | 14 + .../custom_layout_constraints_options.idl | 21 + .../layout/custom/fragment_result_options.idl | 12 + .../core/layout/custom/intrinsic_sizes.idl | 15 + .../custom/intrinsic_sizes_result_options.idl | 10 + .../core/layout/custom/layout_child.idl | 18 + .../core/layout/custom/layout_constraints.idl | 23 + .../core/layout/custom/layout_edges.idl | 21 + .../core/layout/custom/layout_fragment.idl | 22 + .../custom/layout_worklet_global_scope.idl | 21 + .../renderer/core/mathml/mathml_element.idl | 12 + .../core/messaging/message_channel.idl | 35 + .../renderer/core/messaging/message_port.idl | 44 + .../core/messaging/post_message_options.idl | 15 + .../structured_serialize_options.idl | 7 + .../blink/renderer/core/mojo/mojo.idl | 53 + .../mojo/mojo_create_data_pipe_options.idl | 8 + .../mojo/mojo_create_data_pipe_result.idl | 9 + .../mojo/mojo_create_message_pipe_result.idl | 10 + .../mojo/mojo_create_shared_buffer_result.idl | 8 + .../core/mojo/mojo_discard_data_options.idl | 7 + .../mojo_duplicate_buffer_handle_options.idl | 7 + .../blink/renderer/core/mojo/mojo_handle.idl | 31 + .../core/mojo/mojo_handle_signals.idl | 9 + .../core/mojo/mojo_map_buffer_result.idl | 13 + .../core/mojo/mojo_read_data_options.idl | 8 + .../core/mojo/mojo_read_data_result.idl | 8 + .../core/mojo/mojo_read_message_flags.idl | 7 + .../core/mojo/mojo_read_message_result.idl | 14 + .../blink/renderer/core/mojo/mojo_watcher.idl | 12 + .../core/mojo/mojo_write_data_options.idl | 7 + .../core/mojo/mojo_write_data_result.idl | 8 + .../mojo/test/mojo_interface_interceptor.idl | 31 + .../test/mojo_interface_request_event.idl | 11 + .../mojo_interface_request_event_init.idl | 7 + .../core/navigation_api/navigate_event.idl | 27 + .../navigation_api/navigate_event_init.idl | 26 + .../core/navigation_api/navigation.idl | 30 + .../navigation_api/navigation_activation.idl | 13 + .../navigation_current_entry_change_event.idl | 12 + ...gation_current_entry_change_event_init.idl | 9 + .../navigation_api/navigation_destination.idl | 15 + .../navigation_history_entry.idl | 21 + .../navigation_intercept_options.idl | 28 + .../navigation_navigate_options.idl | 15 + .../navigation_api/navigation_options.idl | 8 + .../navigation_reload_options.idl | 8 + .../core/navigation_api/navigation_result.idl | 9 + .../navigation_api/navigation_transition.idl | 8 + ...avigation_update_current_entry_options.idl | 8 + .../core/offscreencanvas/offscreen_canvas.idl | 20 + .../origin_trials/origin_trial_context.cc | 751 + .../core/page/color_page_popup_controller.idl | 13 + .../core/page/page_popup_controller.idl | 50 + .../permissions_policy/feature_policy.idl | 14 + .../preferences/navigator_preferences.idl | 12 + .../core/preferences/preference_manager.idl | 17 + .../core/preferences/preference_object.idl | 20 + .../core/resize_observer/resize_observer.idl | 20 + .../resize_observer/resize_observer_entry.idl | 14 + .../resize_observer_options.idl | 15 + .../resize_observer/resize_observer_size.idl | 12 + .../renderer/core/scheduler/idle_deadline.idl | 12 + .../core/scheduler/idle_request_callback.idl | 7 + .../core/scheduler/idle_request_options.idl | 9 + .../renderer/core/scheduler/scheduler.idl | 24 + .../scheduler_post_task_callback.idl | 6 + .../scheduler/scheduler_post_task_options.idl | 17 + .../scheduler/scheduler_yield_options.idl | 20 + .../scheduler/script_wrappable_task_state.idl | 8 + .../core/scheduler/task_controller.idl | 13 + .../core/scheduler/task_controller_init.idl | 8 + .../scheduler/task_priority_change_event.idl | 12 + .../task_priority_change_event_init.idl | 8 + .../renderer/core/scheduler/task_signal.idl | 17 + .../core/scheduler/task_signal_any_init.idl | 7 + .../core/scheduler/window_idle_tasks.idl | 12 + .../window_or_worker_global_scope_timers.idl | 41 + .../scheduler/window_or_worker_scheduler.idl | 11 + .../blink/renderer/core/scroll/snap_event.idl | 11 + .../shadow_realm_global_scope.idl | 9 + .../streams/byte_length_queuing_strategy.idl | 15 + .../core/streams/count_queuing_strategy.idl | 15 + .../core/streams/queuing_strategy_init.idl | 9 + .../readable_byte_stream_controller.idl | 15 + .../renderer/core/streams/readable_stream.idl | 28 + .../streams/readable_stream_byob_reader.idl | 15 + .../streams/readable_stream_byob_request.idl | 13 + .../readable_stream_default_controller.idl | 15 + .../readable_stream_default_reader.idl | 15 + .../readable_stream_generic_reader.idl | 11 + .../readable_stream_get_reader_options.idl | 9 + .../readable_stream_iterator_options.idl | 9 + .../streams/readable_stream_read_result.idl | 10 + .../core/streams/readable_writable_pair.idl | 10 + .../core/streams/stream_pipe_options.idl | 12 + .../core/streams/transform_stream.idl | 14 + .../transform_stream_default_controller.idl | 14 + .../core/streams/underlying_sink_base.idl | 20 + .../core/streams/underlying_source.idl | 13 + .../underlying_source_cancel_callback.idl | 7 + .../underlying_source_pull_callback.idl | 7 + .../underlying_source_start_callback.idl | 7 + .../renderer/core/streams/writable_stream.idl | 15 + .../writable_stream_default_controller.idl | 12 + .../writable_stream_default_writer.idl | 25 + .../blink/renderer/core/svg/svg_a_element.idl | 34 + .../blink/renderer/core/svg/svg_angle.idl | 43 + .../renderer/core/svg/svg_animate_element.idl | 31 + .../core/svg/svg_animate_motion_element.idl | 31 + .../svg/svg_animate_transform_element.idl | 31 + .../renderer/core/svg/svg_animated_angle.idl | 32 + .../core/svg/svg_animated_boolean.idl | 32 + .../core/svg/svg_animated_enumeration.idl | 34 + .../core/svg/svg_animated_integer.idl | 32 + .../renderer/core/svg/svg_animated_length.idl | 32 + .../core/svg/svg_animated_length_list.idl | 32 + .../renderer/core/svg/svg_animated_number.idl | 33 + .../core/svg/svg_animated_number_list.idl | 32 + .../svg_animated_preserve_aspect_ratio.idl | 32 + .../renderer/core/svg/svg_animated_rect.idl | 33 + .../renderer/core/svg/svg_animated_string.idl | 32 + .../core/svg/svg_animated_transform_list.idl | 32 + .../core/svg/svg_animation_element.idl | 48 + .../renderer/core/svg/svg_circle_element.idl | 34 + .../core/svg/svg_clip_path_element.idl | 34 + ...vg_component_transfer_function_element.idl | 46 + .../renderer/core/svg/svg_defs_element.idl | 30 + .../renderer/core/svg/svg_desc_element.idl | 30 + .../blink/renderer/core/svg/svg_document.idl | 28 + .../blink/renderer/core/svg/svg_element.idl | 36 + .../renderer/core/svg/svg_ellipse_element.idl | 34 + .../core/svg/svg_fe_blend_element.idl | 56 + .../core/svg/svg_fe_color_matrix_element.idl | 43 + .../svg/svg_fe_component_transfer_element.idl | 34 + .../core/svg/svg_fe_composite_element.idl | 49 + .../svg/svg_fe_convolve_matrix_element.idl | 51 + .../svg/svg_fe_diffuse_lighting_element.idl | 38 + .../svg/svg_fe_displacement_map_element.idl | 45 + .../core/svg/svg_fe_distant_light_element.idl | 33 + .../core/svg/svg_fe_drop_shadow_element.idl | 34 + .../core/svg/svg_fe_flood_element.idl | 33 + .../core/svg/svg_fe_func_a_element.idl | 31 + .../core/svg/svg_fe_func_b_element.idl | 31 + .../core/svg/svg_fe_func_g_element.idl | 31 + .../core/svg/svg_fe_func_r_element.idl | 31 + .../core/svg/svg_fe_gaussian_blur_element.idl | 38 + .../core/svg/svg_fe_image_element.idl | 35 + .../core/svg/svg_fe_merge_element.idl | 33 + .../core/svg/svg_fe_merge_node_element.idl | 32 + .../core/svg/svg_fe_morphology_element.idl | 42 + .../core/svg/svg_fe_offset_element.idl | 36 + .../core/svg/svg_fe_point_light_element.idl | 34 + .../svg/svg_fe_specular_lighting_element.idl | 39 + .../core/svg/svg_fe_spot_light_element.idl | 39 + .../renderer/core/svg/svg_fe_tile_element.idl | 34 + .../core/svg/svg_fe_turbulence_element.idl | 49 + .../renderer/core/svg/svg_filter_element.idl | 41 + ...g_filter_primitive_standard_attributes.idl | 35 + .../renderer/core/svg/svg_fit_to_view_box.idl | 32 + .../core/svg/svg_foreign_object_element.idl | 34 + .../blink/renderer/core/svg/svg_g_element.idl | 30 + .../core/svg/svg_geometry_element.idl | 42 + .../core/svg/svg_gradient_element.idl | 43 + .../core/svg/svg_graphics_element.idl | 48 + .../renderer/core/svg/svg_image_element.idl | 44 + .../blink/renderer/core/svg/svg_length.idl | 49 + .../renderer/core/svg/svg_length_list.idl | 44 + .../renderer/core/svg/svg_line_element.idl | 34 + .../core/svg/svg_linear_gradient_element.idl | 34 + .../renderer/core/svg/svg_marker_element.idl | 54 + .../renderer/core/svg/svg_mask_element.idl | 42 + .../blink/renderer/core/svg/svg_matrix.idl | 51 + .../core/svg/svg_metadata_element.idl | 26 + .../renderer/core/svg/svg_mpath_element.idl | 33 + .../blink/renderer/core/svg/svg_number.idl | 30 + .../renderer/core/svg/svg_number_list.idl | 44 + .../renderer/core/svg/svg_path_element.idl | 31 + .../renderer/core/svg/svg_pattern_element.idl | 45 + .../blink/renderer/core/svg/svg_point.idl | 35 + .../renderer/core/svg/svg_point_list.idl | 44 + .../renderer/core/svg/svg_polygon_element.idl | 35 + .../core/svg/svg_polyline_element.idl | 35 + .../core/svg/svg_preserve_aspect_ratio.idl | 52 + .../core/svg/svg_radial_gradient_element.idl | 36 + .../blink/renderer/core/svg/svg_rect.idl | 35 + .../renderer/core/svg/svg_rect_element.idl | 37 + .../renderer/core/svg/svg_script_element.idl | 33 + .../renderer/core/svg/svg_set_element.idl | 31 + .../renderer/core/svg/svg_stop_element.idl | 31 + .../renderer/core/svg/svg_string_list.idl | 43 + .../renderer/core/svg/svg_style_element.idl | 43 + .../renderer/core/svg/svg_svg_element.idl | 71 + .../renderer/core/svg/svg_switch_element.idl | 30 + .../renderer/core/svg/svg_symbol_element.idl | 32 + .../blink/renderer/core/svg/svg_tests.idl | 32 + .../core/svg/svg_text_content_element.idl | 48 + .../renderer/core/svg/svg_text_element.idl | 30 + .../core/svg/svg_text_path_element.idl | 46 + .../core/svg/svg_text_positioning_element.idl | 35 + .../renderer/core/svg/svg_title_element.idl | 30 + .../blink/renderer/core/svg/svg_transform.idl | 49 + .../renderer/core/svg/svg_transform_list.idl | 47 + .../renderer/core/svg/svg_tspan_element.idl | 30 + .../renderer/core/svg/svg_unit_types.idl | 34 + .../renderer/core/svg/svg_uri_reference.idl | 31 + .../renderer/core/svg/svg_use_element.idl | 36 + .../renderer/core/svg/svg_view_element.idl | 33 + .../renderer/core/svg/svg_zoom_and_pan.idl | 37 + .../core/testing/callback_function_test.idl | 18 + .../testing/death_aware_script_wrappable.idl | 6 + .../renderer/core/testing/dictionary_test.idl | 14 + .../garbage_collected_script_wrappable.idl | 7 + .../renderer/core/testing/gc_observation.idl | 36 + .../core/testing/hit_test_layer_rect.idl | 37 + .../core/testing/hit_test_layer_rect_list.idl | 34 + .../core/testing/internal_dictionary.idl | 37 + .../testing/internal_dictionary_derived.idl | 9 + .../internal_dictionary_derived_derived.idl | 7 + .../core/testing/internal_settings.idl | 54 + .../blink/renderer/core/testing/internals.idl | 467 + .../core/testing/internals_cookie.idl | 17 + .../testing/internals_delete_all_cookies.idl | 9 + .../testing/internals_get_all_cookies.idl | 11 + .../testing/internals_get_named_cookie.idl | 11 + .../core/testing/internals_ukm_recorder.idl | 11 + .../core/testing/origin_trials_test.idl | 64 + .../testing/origin_trials_test_dictionary.idl | 8 + .../testing/origin_trials_test_partial.idl | 19 + .../testing/origin_trials_test_window.idl | 10 + .../renderer/core/testing/record_test.idl | 29 + .../renderer/core/testing/sequence_test.idl | 24 + .../core/testing/static_selection.idl | 11 + .../core/testing/type_conversions.idl | 58 + .../core/testing/union_types_test.idl | 22 + .../core/testing/worker_internals.idl | 14 + .../timing/back_forward_cache_restoration.idl | 11 + .../core/timing/dom_high_res_time_stamp.idl | 7 + .../renderer/core/timing/epoch_time_stamp.idl | 7 + .../renderer/core/timing/event_counts.idl | 10 + .../core/timing/internals_profiler.idl | 11 + .../core/timing/largest_contentful_paint.idl | 17 + .../renderer/core/timing/layout_shift.idl | 14 + .../core/timing/layout_shift_attribution.idl | 13 + .../measure_memory/memory_attribution.idl | 12 + .../memory_attribution_container.idl | 11 + .../measure_memory/memory_breakdown_entry.idl | 12 + .../measure_memory/memory_measurement.idl | 11 + .../renderer/core/timing/memory_info.idl | 40 + .../core/timing/not_restored_reasons.idl | 25 + .../renderer/core/timing/performance.idl | 82 + .../timing/performance_element_timing.idl | 19 + .../core/timing/performance_entry.idl | 42 + .../performance_entry_filter_options.idl | 9 + .../core/timing/performance_entry_list.idl | 7 + .../core/timing/performance_event_timing.idl | 15 + ...erformance_long_animation_frame_timing.idl | 15 + .../timing/performance_long_task_timing.idl | 11 + .../renderer/core/timing/performance_mark.idl | 33 + .../core/timing/performance_mark_options.idl | 9 + .../core/timing/performance_measure.idl | 31 + .../timing/performance_measure_options.idl | 11 + .../core/timing/performance_navigation.idl | 45 + .../timing/performance_navigation_timing.idl | 37 + ...nce_navigation_timing_activation_start.idl | 10 + .../core/timing/performance_observer.idl | 18 + .../performance_observer_callback_options.idl | 9 + .../performance_observer_entry_list.idl | 14 + .../core/timing/performance_observer_init.idl | 13 + .../core/timing/performance_paint_timing.idl | 9 + .../timing/performance_resource_timing.idl | 83 + .../core/timing/performance_script_timing.idl | 33 + .../core/timing/performance_server_timing.idl | 14 + .../core/timing/performance_timing.idl | 60 + .../blink/renderer/core/timing/profiler.idl | 13 + .../renderer/core/timing/profiler_frame.idl | 12 + .../core/timing/profiler_init_options.idl | 9 + .../renderer/core/timing/profiler_sample.idl | 13 + .../renderer/core/timing/profiler_stack.idl | 10 + .../renderer/core/timing/profiler_trace.idl | 12 + .../core/timing/soft_navigation_entry.idl | 8 + .../core/timing/task_attribution_timing.idl | 14 + .../core/timing/visibility_state_entry.idl | 7 + .../core/timing/window_performance.idl | 13 + .../worker_global_scope_performance.idl | 39 + .../core/trustedtypes/trusted_html.idl | 17 + .../core/trustedtypes/trusted_script.idl | 17 + .../core/trustedtypes/trusted_script_url.idl | 15 + .../core/trustedtypes/trusted_type_policy.idl | 16 + .../trusted_type_policy_factory.idl | 31 + .../trusted_type_policy_options.idl | 15 + .../blink/renderer/core/url/url.idl | 53 + .../renderer/core/url/url_search_params.idl | 23 + .../renderer/core/url_pattern/url_pattern.idl | 41 + .../url_pattern_component_result.idl | 12 + .../core/url_pattern/url_pattern_init.idl | 16 + .../core/url_pattern/url_pattern_options.idl | 8 + .../core/url_pattern/url_pattern_result.idl | 17 + .../view_transition/page_reveal_event.idl | 12 + .../page_reveal_event_init.idl | 9 + .../core/view_transition/page_swap_event.idl | 13 + .../view_transition/page_swap_event_init.idl | 10 + .../core/view_transition/view_transition.idl | 36 + .../view_transition_callback.idl | 9 + .../view_transition_options.idl | 7 + .../view_transition_supplement.idl | 11 + .../view_transition_type_set.idl | 8 + .../renderer/core/workers/abstract_worker.idl | 38 + .../workers/dedicated_worker_global_scope.idl | 51 + .../renderer/core/workers/shared_worker.idl | 52 + .../workers/shared_worker_global_scope.idl | 42 + .../blink/renderer/core/workers/worker.idl | 43 + .../core/workers/worker_global_scope.idl | 73 + .../renderer/core/workers/worker_location.idl | 44 + .../core/workers/worker_navigator.idl | 41 + .../renderer/core/workers/worker_options.idl | 12 + .../blink/renderer/core/workers/worklet.idl | 12 + .../core/workers/worklet_global_scope.idl | 11 + .../renderer/core/workers/worklet_options.idl | 8 + .../core/xml/document_xpath_evaluator.idl | 30 + .../blink/renderer/core/xml/dom_parser.idl | 38 + .../core/xml/parse_from_string_options.idl | 10 + .../renderer/core/xml/xml_serializer.idl | 28 + .../renderer/core/xml/xpath_evaluator.idl | 33 + .../renderer/core/xml/xpath_expression.idl | 27 + .../renderer/core/xml/xpath_ns_resolver.idl | 25 + .../blink/renderer/core/xml/xpath_result.idl | 51 + .../renderer/core/xml/xslt_processor.idl | 51 + .../core/xmlhttprequest/xml_http_request.idl | 83 + .../xml_http_request_event_target.idl | 40 + .../xml_http_request_upload.idl | 34 + .../renderer/extensions/chromeos/chromeos.idl | 13 + .../chromeos/diagnostics/cros_cpu_info.idl | 17 + .../chromeos/diagnostics/cros_diagnostics.idl | 23 + .../diagnostics/cros_logical_cpu_info.idl | 25 + .../diagnostics/cros_network_interface.idl | 16 + .../extensions/chromeos/kiosk/cros_kiosk.idl | 9 + .../renderer/extensions/webview/android.idl | 9 + .../media_integrity/media_integrity_error.idl | 26 + .../media_integrity_token_provider.idl | 20 + .../renderer/extensions/webview/web_view.idl | 33 + .../testing/internals_accessibility.idl | 17 + .../ad_auction/ad_auction_data_config.idl | 23 + .../modules/ad_auction/ad_request_config.idl | 34 + .../blink/renderer/modules/ad_auction/ads.idl | 8 + .../modules/ad_auction/auction_ad.idl | 19 + .../modules/ad_auction/auction_ad_config.idl | 113 + .../ad_auction/auction_ad_interest_group.idl | 79 + .../modules/ad_auction/navigator_auction.idl | 62 + .../modules/ad_auction/protected_audience.idl | 11 + .../blink/renderer/modules/ai/ai.idl | 40 + .../renderer/modules/ai/ai_text_session.idl | 32 + .../modules/ai/ai_text_session_options.idl | 10 + .../ai/window_or_worker_global_scope_ai.idl | 16 + .../animation_worklet_global_scope.idl | 21 + .../css_animation_worklet.idl | 11 + .../animationworklet/worklet_animation.idl | 29 + .../worklet_animation_effect.idl | 14 + .../animationworklet/worklet_group_effect.idl | 9 + .../app_banner/app_banner_prompt_result.idl | 10 + .../before_install_prompt_event.idl | 13 + .../before_install_prompt_event_init.idl | 7 + .../app_banner/window_installation.idl | 12 + ...html_media_element_audio_output_device.idl | 13 + .../awc/additional_windowing_controls.idl | 29 + .../background_fetch_event.idl | 13 + .../background_fetch_event_init.idl | 9 + .../background_fetch_manager.idl | 18 + .../background_fetch_options.idl | 9 + .../background_fetch_record.idl | 13 + .../background_fetch_registration.idl | 44 + .../background_fetch_ui_options.idl | 10 + .../background_fetch_update_ui_event.idl | 13 + ...e_worker_global_scope_background_fetch.idl | 15 + ...e_worker_registration_background_fetch.idl | 13 + .../background_sync_options.idl | 10 + .../background_sync/periodic_sync_event.idl | 13 + .../periodic_sync_event_init.idl | 9 + .../background_sync/periodic_sync_manager.idl | 15 + .../service_worker_global_scope_sync.idl | 10 + .../service_worker_registration_sync.idl | 11 + .../modules/background_sync/sync_event.idl | 13 + .../background_sync/sync_event_init.idl | 10 + .../modules/background_sync/sync_manager.idl | 12 + .../modules/badging/navigator_badge.idl | 15 + .../badging/worker_navigator_badge.idl | 15 + .../modules/battery/battery_manager.idl | 20 + .../modules/battery/navigator_battery.idl | 9 + .../modules/beacon/navigator_beacon.idl | 13 + .../renderer/modules/bluetooth/bluetooth.idl | 21 + .../bluetooth/bluetooth_advertising_event.idl | 21 + .../bluetooth_advertising_event_init.idl | 16 + .../bluetooth_characteristic_properties.idl | 21 + .../bluetooth/bluetooth_data_filter_init.idl | 10 + .../modules/bluetooth/bluetooth_device.idl | 36 + .../modules/bluetooth/bluetooth_le_scan.idl | 17 + .../bluetooth_le_scan_filter_init.idl | 13 + .../bluetooth/bluetooth_le_scan_options.idl | 11 + ...luetooth_manufacturer_data_filter_init.idl | 9 + .../bluetooth_manufacturer_data_map.idl | 13 + .../bluetooth_remote_gatt_characteristic.idl | 29 + .../bluetooth_remote_gatt_descriptor.idl | 19 + .../bluetooth_remote_gatt_server.idl | 21 + .../bluetooth_remote_gatt_service.idl | 17 + .../bluetooth/bluetooth_service_data_map.idl | 13 + .../modules/bluetooth/bluetooth_uuid.idl | 24 + .../modules/bluetooth/navigator_bluetooth.idl | 13 + .../bluetooth/request_device_options.idl | 13 + .../watch_advertisements_options.idl | 9 + .../media_stream_track_generator.idl | 18 + .../media_stream_track_generator_init.idl | 11 + .../media_stream_track_processor.idl | 18 + .../media_stream_track_processor_init.idl | 10 + .../breakout_box/video_track_generator.idl | 25 + .../broadcastchannel/broadcast_channel.idl | 20 + .../browsing_topics/browsing_topic.idl | 13 + .../browsing_topics_document_supplement.idl | 19 + .../browsing_topics_options.idl | 3 + .../buckets/navigator_storage_buckets.idl | 13 + .../modules/buckets/storage_bucket.idl | 31 + .../buckets/storage_bucket_manager.idl | 16 + .../buckets/storage_bucket_options.idl | 17 + .../worker_navigator_storage_buckets.idl | 13 + .../renderer/modules/cache_storage/cache.idl | 38 + .../cache_storage/cache_query_options.idl | 10 + .../modules/cache_storage/cache_storage.idl | 25 + .../multi_cache_query_options.idl | 8 + .../cache_storage/window_cache_storage.idl | 10 + .../cache_storage/worker_cache_storage.idl | 10 + .../canvas2d/canvas_2d_gpu_transfer.idl | 14 + .../canvas_2d_gpu_transfer_option.idl | 19 + .../modules/canvas/canvas2d/canvas_filter.idl | 12 + .../canvas2d/canvas_filter_dictionary.idl | 11 + .../canvas/canvas2d/canvas_gradient.idl | 35 + .../modules/canvas/canvas2d/canvas_path.idl | 21 + .../canvas/canvas2d/canvas_pattern.idl | 34 + .../canvas2d/canvas_rendering_context_2d.idl | 189 + .../canvas_rendering_context_2d_settings.idl | 13 + .../canvas/canvas2d/mesh_2d_index_buffer.idl | 8 + .../canvas/canvas2d/mesh_2d_uv_buffer.idl | 8 + .../canvas/canvas2d/mesh_2d_vertex_buffer.idl | 8 + .../modules/canvas/canvas2d/path_2d.idl | 38 + ...vas_context_creation_attributes_module.idl | 65 + .../htmlcanvas/html_canvas_element_module.idl | 21 + .../image_bitmap_rendering_context.idl | 15 + .../window_create_image_bitmap.idl | 24 + .../worker_create_image_bitmap.idl | 13 + .../offscreen_canvas_module.idl | 18 + .../offscreen_canvas_rendering_context_2d.idl | 126 + .../renderer/modules/clipboard/clipboard.idl | 40 + .../modules/clipboard/clipboard_item.idl | 20 + .../modules/clipboard/navigator_clipboard.idl | 11 + .../compression/compression_stream.idl | 7 + .../compression/decompression_stream.idl | 7 + .../compute_pressure/pressure_observer.idl | 41 + .../pressure_observer_options.idl | 8 + .../compute_pressure/pressure_record.idl | 23 + .../pressure_update_callback.idl | 9 + .../contacts_picker/contact_address.idl | 11 + .../modules/contacts_picker/contact_info.idl | 13 + .../contacts_picker/contacts_manager.idl | 14 + .../contacts_select_options.idl | 11 + .../contacts_picker/navigator_contacts.idl | 12 + .../content_index/content_description.idl | 22 + .../content_index/content_icon_definition.idl | 12 + .../modules/content_index/content_index.idl | 14 + .../content_index/content_index_event.idl | 13 + .../content_index_event_init.idl | 9 + ...vice_worker_global_scope_content_index.idl | 12 + ...vice_worker_registration_content_index.idl | 13 + .../cookie_deprecation_label.idl | 11 + .../navigator_cookie_deprecation_label.idl | 10 + .../cookie_store/cookie_change_event.idl | 22 + .../cookie_store/cookie_change_event_init.idl | 10 + .../modules/cookie_store/cookie_init.idl | 21 + .../modules/cookie_store/cookie_list_item.idl | 18 + .../modules/cookie_store/cookie_store.idl | 33 + .../cookie_store_delete_options.idl | 12 + .../cookie_store/cookie_store_get_options.idl | 10 + .../cookie_store/cookie_store_manager.idl | 19 + .../extendable_cookie_change_event.idl | 20 + .../extendable_cookie_change_event_init.idl | 10 + ...rvice_worker_global_scope_cookie_store.idl | 12 + .../service_worker_registration_cookies.idl | 10 + .../cookie_store/window_cookie_store.idl | 12 + ...uthentication_extensions_client_inputs.idl | 52 + ...tication_extensions_client_inputs_json.idl | 38 + ...thentication_extensions_client_outputs.idl | 33 + ...ication_extensions_client_outputs_json.idl | 28 + ...ntication_extensions_large_blob_inputs.idl | 10 + ...tication_extensions_large_blob_outputs.idl | 10 + ...thentication_extensions_payment_inputs.idl | 10 + .../authentication_extensions_prf_inputs.idl | 15 + .../authentication_extensions_prf_outputs.idl | 10 + ...xtensions_supplemental_pub_keys_inputs.idl | 10 + ...tensions_supplemental_pub_keys_outputs.idl | 8 + .../authentication_response_json.idl | 14 + .../authenticator_assertion_response.idl | 15 + .../authenticator_assertion_response_json.idl | 12 + .../authenticator_attestation_response.idl | 18 + ...uthenticator_attestation_response_json.idl | 14 + .../authenticator_response.idl | 13 + .../authenticator_selection_criteria.idl | 14 + .../cable_authentication_data.idl | 10 + .../collected_client_data.idl | 13 + .../credentialmanagement/credential.idl | 11 + .../credential_creation_options.idl | 16 + .../credentialmanagement/credential_data.idl | 9 + .../credential_properties_output.idl | 8 + .../credential_report_options.idl | 7 + .../credential_request_options.idl | 28 + .../credential_user_data.idl | 10 + .../credentials_container.idl | 14 + .../digital_credential.idl | 17 + .../digital_credential_request_options.idl | 14 + .../federated_credential.idl | 17 + .../federated_credential_init.idl | 12 + .../federated_credential_request_options.idl | 9 + .../identity_claim_requirement.idl | 21 + .../identity_credential.idl | 29 + .../identity_credential_error.idl | 24 + ...dentity_credential_logout_r_ps_request.idl | 10 + .../identity_credential_request_options.idl | 26 + .../identity_provider.idl | 38 + .../identity_provider_config.idl | 26 + .../identity_standard_claims.idl | 37 + .../navigator_credentials.idl | 9 + .../navigator_identity.idl | 11 + .../credentialmanagement/navigator_login.idl | 28 + .../credentialmanagement/otp_credential.idl | 12 + .../otp_credential_request_options.idl | 13 + .../password_credential.idl | 14 + .../password_credential_data.idl | 11 + .../payment_credential_instrument.idl | 11 + .../public_key_credential.idl | 21 + ...public_key_credential_creation_options.idl | 18 + ...c_key_credential_creation_options_json.idl | 24 + .../public_key_credential_descriptor.idl | 11 + .../public_key_credential_descriptor_json.idl | 11 + .../public_key_credential_entity.idl | 8 + .../public_key_credential_json.idl | 10 + .../public_key_credential_parameters.idl | 20 + .../public_key_credential_report_options.idl | 8 + .../public_key_credential_request_options.idl | 16 + ...ic_key_credential_request_options_json.idl | 15 + .../public_key_credential_rp_entity.idl | 9 + .../public_key_credential_user_entity.idl | 10 + .../registration_response_json.idl | 14 + .../remote_desktop_client_override.idl | 12 + .../testing/internals_fed_cm.idl | 20 + .../blink/renderer/modules/crypto/crypto.idl | 39 + .../renderer/modules/crypto/crypto_key.idl | 41 + .../renderer/modules/crypto/json_web_key.idl | 28 + .../modules/crypto/rsa_other_primes_info.idl | 11 + .../renderer/modules/crypto/subtle_crypto.idl | 56 + .../renderer/modules/crypto/window_crypto.idl | 37 + .../crypto/worker_global_scope_crypto.idl | 37 + .../modules/csspaint/css_paint_worklet.idl | 12 + .../csspaint/paint_rendering_context_2d.idl | 96 + .../paint_rendering_context_2d_settings.idl | 7 + .../renderer/modules/csspaint/paint_size.idl | 12 + .../csspaint/paint_worklet_global_scope.idl | 17 + .../delegated_ink_trail_presenter.idl | 14 + .../renderer/modules/delegated_ink/ink.idl | 11 + .../delegated_ink/ink_presenter_param.idl | 9 + .../modules/delegated_ink/ink_trail_style.idl | 10 + .../modules/delegated_ink/navigator_ink.idl | 12 + .../device_motion_event.idl | 38 + .../device_motion_event_acceleration.idl | 33 + .../device_motion_event_acceleration_init.idl | 11 + .../device_motion_event_init.idl | 12 + .../device_motion_event_rotation_rate.idl | 33 + ...device_motion_event_rotation_rate_init.idl | 11 + .../device_orientation_event.idl | 43 + .../device_orientation_event_init.idl | 12 + .../window_device_motion.idl | 9 + .../window_device_orientation.idl | 10 + .../modules/device_posture/device_posture.idl | 14 + .../navigator_device_posture.idl | 13 + .../testing/internals_device_posture.idl | 10 + .../direct_sockets/socket_connection.idl | 21 + .../modules/direct_sockets/socket_options.idl | 41 + .../direct_sockets/tcp_server_socket.idl | 21 + .../modules/direct_sockets/tcp_socket.idl | 24 + .../modules/direct_sockets/udp_message.idl | 12 + .../modules/direct_sockets/udp_socket.idl | 24 + .../document_picture_in_picture.idl | 16 + .../document_picture_in_picture_event.idl | 14 + ...document_picture_in_picture_event_init.idl | 9 + .../document_picture_in_picture_options.idl | 12 + .../window_document_picture_in_picture.idl | 15 + .../donottrack/navigator_do_not_track.idl | 35 + .../modules/encoding/text_decode_options.idl | 9 + .../modules/encoding/text_decoder.idl | 42 + .../modules/encoding/text_decoder_options.idl | 10 + .../modules/encoding/text_decoder_stream.idl | 15 + .../modules/encoding/text_encoder.idl | 38 + .../text_encoder_encode_into_result.idl | 10 + .../modules/encoding/text_encoder_stream.idl | 13 + .../html_media_element_encrypted_media.idl | 13 + .../encryptedmedia/media_encrypted_event.idl | 34 + .../media_encrypted_event_init.idl | 10 + .../media_key_message_event.idl | 42 + .../media_key_message_event_init.idl | 10 + .../encryptedmedia/media_key_session.idl | 57 + .../encryptedmedia/media_key_status_map.idl | 25 + .../media_key_system_access.idl | 14 + .../media_key_system_configuration.idl | 21 + .../media_key_system_media_capability.idl | 11 + .../modules/encryptedmedia/media_keys.idl | 41 + .../media_keys_get_status_for_policy.idl | 12 + .../encryptedmedia/media_keys_policy.idl | 9 + ...igator_request_media_key_system_access.idl | 11 + .../modules/eventsource/event_source.idl | 53 + .../modules/eventsource/event_source_init.idl | 9 + .../eyedropper/color_selection_options.idl | 9 + .../eyedropper/color_selection_result.idl | 9 + .../modules/eyedropper/eye_dropper.idl | 16 + .../data_transfer_item_file_system_access.idl | 15 + .../directory_picker_options.idl | 10 + .../file_picker_accept_type.idl | 9 + .../file_picker_options.idl | 20 + .../file_system_change_record.idl | 37 + .../file_system_cloud_identifier.idl | 14 + ...stem_create_sync_access_handle_options.idl | 17 + .../file_system_create_writable_options.idl | 17 + .../file_system_directory_handle.idl | 37 + .../file_system_file_handle.idl | 59 + .../file_system_get_directory_options.idl | 8 + .../file_system_get_file_options.idl | 8 + .../file_system_access/file_system_handle.idl | 77 + ...le_system_handle_permission_descriptor.idl | 14 + .../file_system_observer.idl | 29 + .../file_system_observer_callback.idl | 10 + .../file_system_observer_observe_options.idl | 9 + .../file_system_read_write_options.idl | 8 + .../file_system_remove_options.idl | 8 + .../file_system_sync_access_handle.idl | 30 + .../file_system_writable_file_stream.idl | 27 + .../open_file_picker_options.idl | 8 + .../save_file_picker_options.idl | 8 + .../storage_manager_file_system_access.idl | 13 + .../window_file_system_access.idl | 20 + .../file_system_access/write_params.idl | 18 + .../data_transfer_item_file_system.idl | 37 + ...icated_worker_global_scope_file_system.idl | 40 + .../filesystem/dev_tools_host_file_system.idl | 11 + .../modules/filesystem/directory_entry.idl | 55 + .../filesystem/directory_entry_sync.idl | 39 + .../modules/filesystem/directory_reader.idl | 39 + .../filesystem/directory_reader_sync.idl | 36 + .../modules/filesystem/dom_file_system.idl | 39 + .../filesystem/dom_file_system_sync.idl | 37 + .../modules/filesystem/entries_callback.idl | 34 + .../renderer/modules/filesystem/entry.idl | 55 + .../modules/filesystem/entry_callback.idl | 34 + .../modules/filesystem/entry_sync.idl | 47 + .../modules/filesystem/error_callback.idl | 34 + .../modules/filesystem/file_callback.idl | 8 + .../modules/filesystem/file_entry.idl | 43 + .../modules/filesystem/file_entry_sync.idl | 37 + .../filesystem/file_system_callback.idl | 34 + .../modules/filesystem/file_system_flags.idl | 14 + .../modules/filesystem/file_writer.idl | 64 + .../filesystem/file_writer_callback.idl | 34 + .../modules/filesystem/file_writer_sync.idl | 42 + .../html_input_element_file_system.idl | 38 + .../renderer/modules/filesystem/metadata.idl | 37 + .../modules/filesystem/metadata_callback.idl | 34 + ...shared_worker_global_scope_file_system.idl | 40 + .../modules/filesystem/window_file_system.idl | 40 + .../modules/font_access/font_data.idl | 18 + .../modules/font_access/query_options.idl | 8 + .../font_access/window_font_access.idl | 14 + .../modules/formatted_text/formatted_text.idl | 20 + .../modules/fuzzing/internals_fuzzing.idl | 13 + .../renderer/modules/gamepad/gamepad.idl | 55 + .../modules/gamepad/gamepad_axis_event.idl | 15 + .../gamepad/gamepad_axis_event_init.idl | 11 + .../modules/gamepad/gamepad_button.idl | 11 + .../modules/gamepad/gamepad_button_event.idl | 15 + .../gamepad/gamepad_button_event_init.idl | 11 + .../gamepad/gamepad_effect_parameters.idl | 16 + .../modules/gamepad/gamepad_event.idl | 12 + .../modules/gamepad/gamepad_event_init.idl | 12 + .../gamepad/gamepad_haptic_actuator.idl | 34 + .../modules/gamepad/gamepad_touch.idl | 13 + .../modules/gamepad/navigator_gamepad.idl | 26 + .../modules/geolocation/geolocation.idl | 55 + .../geolocation/geolocation_coordinates.idl | 37 + .../geolocation/geolocation_position.idl | 35 + .../geolocation_position_error.idl | 35 + .../geolocation/navigator_geolocation.idl | 24 + .../modules/geolocation/position_options.idl | 9 + .../handwriting/handwriting_drawing.idl | 18 + .../handwriting_drawing_segment.idl | 12 + .../modules/handwriting/handwriting_hints.idl | 12 + .../handwriting_model_constraint.idl | 9 + .../modules/handwriting/handwriting_point.idl | 12 + .../handwriting/handwriting_prediction.idl | 10 + .../handwriting/handwriting_recognizer.idl | 16 + .../handwriting_recognizer_query_result.idl | 26 + .../handwriting/handwriting_segment.idl | 12 + .../handwriting/handwriting_stroke.idl | 22 + ...igator_handwriting_recognition_service.idl | 19 + .../blink/renderer/modules/hid/hid.idl | 32 + .../modules/hid/hid_collection_info.idl | 28 + .../modules/hid/hid_connection_event.idl | 16 + .../modules/hid/hid_connection_event_init.idl | 11 + .../blink/renderer/modules/hid/hid_device.idl | 77 + .../modules/hid/hid_device_filter.idl | 13 + .../hid/hid_device_request_options.idl | 11 + .../modules/hid/hid_input_report_event.idl | 16 + .../renderer/modules/hid/hid_report_info.idl | 17 + .../renderer/modules/hid/hid_report_item.idl | 127 + .../renderer/modules/hid/navigator_hid.idl | 15 + .../modules/hid/worker_navigator_hid.idl | 14 + .../renderer/modules/idle/idle_detector.idl | 28 + .../renderer/modules/idle/idle_options.idl | 10 + .../constrain_point_2d_parameters.idl | 10 + .../modules/imagecapture/image_capture.idl | 16 + .../imagecapture/media_settings_range.idl | 11 + .../imagecapture/photo_capabilities.idl | 31 + .../modules/imagecapture/photo_settings.idl | 12 + .../modules/imagecapture/point_2d.idl | 10 + .../renderer/modules/indexeddb/idb_cursor.idl | 65 + .../indexeddb/idb_cursor_with_value.idl | 32 + .../modules/indexeddb/idb_database.idl | 53 + .../modules/indexeddb/idb_database_info.idl | 10 + .../modules/indexeddb/idb_factory.idl | 51 + .../renderer/modules/indexeddb/idb_index.idl | 49 + .../indexeddb/idb_index_parameters.idl | 10 + .../modules/indexeddb/idb_key_range.idl | 45 + .../modules/indexeddb/idb_object_store.idl | 88 + .../indexeddb/idb_object_store_parameters.idl | 10 + .../modules/indexeddb/idb_open_db_request.idl | 33 + .../modules/indexeddb/idb_request.idl | 52 + .../modules/indexeddb/idb_transaction.idl | 58 + .../indexeddb/idb_transaction_options.idl | 13 + .../indexeddb/idb_version_change_event.idl | 41 + .../idb_version_change_event_init.idl | 11 + .../indexeddb/window_indexed_database.idl | 31 + .../worker_global_scope_indexed_database.idl | 31 + .../installedapp/navigator_installed_app.idl | 13 + .../installedapp/related_application.idl | 13 + .../renderer/modules/keyboard/keyboard.idl | 25 + .../modules/keyboard/keyboard_layout_map.idl | 12 + .../modules/keyboard/navigator_keyboard.idl | 9 + .../launch/dom_window_launch_queue.idl | 13 + .../renderer/modules/launch/launch_params.idl | 14 + .../renderer/modules/launch/launch_queue.idl | 15 + .../lock_screen/dom_window_lock_screen.idl | 13 + .../modules/lock_screen/lock_screen_data.idl | 23 + .../modules/locked_mode/locked_mode.idl | 13 + .../locked_mode/navigator_locked_mode.idl | 15 + .../blink/renderer/modules/locks/lock.idl | 12 + .../renderer/modules/locks/lock_info.idl | 10 + .../renderer/modules/locks/lock_manager.idl | 22 + .../modules/locks/lock_manager_snapshot.idl | 9 + .../renderer/modules/locks/lock_options.idl | 14 + .../modules/locks/navigator_locks.idl | 12 + .../modules/locks/worker_navigator_locks.idl | 12 + .../managed_device/navigator_managed.idl | 11 + .../managed_device/navigator_managed_data.idl | 27 + .../modules/manifest/image_resource.idl | 14 + .../audio_configuration.idl | 14 + .../key_system_track_configuration.idl | 9 + .../media_capabilities/media_capabilities.idl | 13 + .../media_capabilities_decoding_info.idl | 9 + .../media_capabilities_info.idl | 11 + ..._capabilities_key_system_configuration.idl | 15 + .../media_configuration.idl | 10 + .../media_decoding_configuration.idl | 18 + .../media_encoding_configuration.idl | 14 + .../navigator_media_capabilities.idl | 12 + .../video_configuration.idl | 22 + .../worker_navigator_media_capabilities.idl | 12 + .../canvas_capture_media_stream_track.idl | 11 + .../html_canvas_element_capture.idl | 10 + .../html_media_element_capture.idl | 11 + .../modules/mediarecorder/blob_event.idl | 13 + .../modules/mediarecorder/blob_event_init.idl | 10 + .../modules/mediarecorder/media_recorder.idl | 35 + .../mediarecorder/media_recorder_options.idl | 19 + .../mediasession/chapter_information.idl | 14 + .../mediasession/chapter_information_init.idl | 11 + .../modules/mediasession/media_image.idl | 11 + .../modules/mediasession/media_metadata.idl | 17 + .../mediasession/media_metadata_init.idl | 13 + .../mediasession/media_position_state.idl | 11 + .../modules/mediasession/media_session.idl | 53 + .../media_session_action_details.idl | 9 + .../media_session_seek_to_action_details.idl | 10 + .../mediasession/navigator_media_session.idl | 13 + .../mediasource/audio_track_source_buffer.idl | 11 + .../html_video_element_media_source.idl | 35 + .../modules/mediasource/media_source.idl | 95 + .../mediasource/media_source_handle.idl | 16 + .../modules/mediasource/source_buffer.idl | 106 + .../mediasource/source_buffer_config.idl | 18 + .../mediasource/source_buffer_list.idl | 38 + .../modules/mediasource/track_default.idl | 25 + .../mediasource/track_default_list.idl | 15 + .../modules/mediasource/url_media_source.idl | 37 + .../mediasource/video_playback_quality.idl | 37 + .../mediasource/video_track_source_buffer.idl | 11 + .../browser_capture_media_stream_track.idl | 19 + .../mediastream/capture_controller.idl | 66 + .../modules/mediastream/capture_handle.idl | 9 + .../mediastream/capture_handle_config.idl | 10 + .../mediastream/captured_mouse_event.idl | 15 + .../mediastream/captured_mouse_event_init.idl | 10 + .../mediastream/captured_wheel_action.idl | 12 + .../constrain_boolean_parameters.idl | 10 + .../constrain_dom_string_parameters.idl | 10 + .../mediastream/constrain_double_range.idl | 10 + .../mediastream/constrain_long_range.idl | 10 + .../modules/mediastream/crop_target.idl | 16 + .../modules/mediastream/double_range.idl | 10 + .../modules/mediastream/input_device_info.idl | 10 + .../modules/mediastream/long_range.idl | 10 + .../modules/mediastream/media_device_info.idl | 43 + .../modules/mediastream/media_devices.idl | 45 + .../modules/mediastream/media_stream.idl | 53 + .../mediastream/media_stream_constraints.idl | 60 + .../mediastream/media_stream_event.idl | 34 + .../mediastream/media_stream_event_init.idl | 10 + .../mediastream/media_stream_track.idl | 63 + .../media_stream_track_audio_stats.idl | 18 + .../media_stream_track_content_hint.idl | 10 + .../mediastream/media_stream_track_event.idl | 33 + .../media_stream_track_event_init.idl | 9 + .../media_stream_track_video_stats.idl | 12 + .../mediastream/media_track_capabilities.idl | 49 + .../media_track_constraint_set.idl | 66 + .../mediastream/media_track_constraints.idl | 9 + .../mediastream/media_track_settings.idl | 58 + .../media_track_supported_constraints.idl | 59 + .../mediastream/navigator_media_stream.idl | 53 + .../mediastream/navigator_user_media.idl | 11 + .../mediastream/overconstrained_error.idl | 11 + .../mediastream/restriction_target.idl | 16 + .../screen_capture_media_stream_track.idl | 15 + .../testing/internals_media_stream.idl | 14 + .../blink/renderer/modules/ml/ml.idl | 16 + .../blink/renderer/modules/ml/ml_context.idl | 132 + .../modules/ml/ml_context_options.idl | 60 + .../renderer/modules/ml/navigator_ml.idl | 14 + .../modules/ml/webnn/ml_activation.idl | 10 + .../renderer/modules/ml/webnn/ml_buffer.idl | 15 + .../modules/ml/webnn/ml_buffer_descriptor.idl | 11 + .../renderer/modules/ml/webnn/ml_graph.idl | 11 + .../modules/ml/webnn/ml_graph_builder.idl | 372 + .../renderer/modules/ml/webnn/ml_operand.idl | 13 + .../ml/webnn/ml_operand_descriptor.idl | 21 + .../modules/ml/worker_navigator_ml.idl | 14 + .../modules/mojo/mojo_file_system_access.idl | 14 + .../navigator_content_utils.idl | 28 + .../netinfo/navigator_network_information.idl | 9 + .../modules/netinfo/network_information.idl | 40 + .../netinfo/testing/internals_net_info.idl | 12 + .../worker_navigator_network_information.idl | 10 + .../nfc/ndef_make_read_only_options.idl | 8 + .../renderer/modules/nfc/ndef_message.idl | 14 + .../modules/nfc/ndef_message_init.idl | 9 + .../renderer/modules/nfc/ndef_reader.idl | 29 + .../modules/nfc/ndef_reading_event.idl | 16 + .../modules/nfc/ndef_reading_event_init.idl | 11 + .../renderer/modules/nfc/ndef_record.idl | 20 + .../renderer/modules/nfc/ndef_record_init.idl | 15 + .../modules/nfc/ndef_scan_options.idl | 8 + .../modules/nfc/ndef_write_options.idl | 10 + .../get_notification_options.idl | 10 + .../modules/notifications/notification.idl | 82 + .../notifications/notification_action.idl | 18 + .../notifications/notification_event.idl | 15 + .../notifications/notification_event_init.idl | 11 + .../notifications/notification_options.idl | 36 + ...vice_worker_global_scope_notifications.idl | 13 + ...vice_worker_registration_notifications.idl | 14 + .../notifications/timestamp_trigger.idl | 13 + .../language_translator.idl | 16 + .../on_device_translation/translation.idl | 34 + .../translation_language_options.idl | 8 + ...dow_or_worker_global_scope_translation.idl | 11 + .../modules/payments/abort_payment_event.idl | 13 + .../modules/payments/address_errors.idl | 18 + .../modules/payments/address_init.idl | 18 + .../payments/android_pay_method_data.idl | 12 + .../payments/can_make_payment_event.idl | 14 + .../payments/can_make_payment_event_init.idl | 12 + .../payments/goods/digital_goods_service.idl | 21 + .../goods/dom_window_digital_goods.idl | 13 + .../modules/payments/goods/item_details.idl | 28 + .../payments/goods/purchase_details.idl | 9 + .../google_play_billing_method_data.idl | 7 + .../payments/html_iframe_element_payments.idl | 12 + .../modules/payments/image_object.idl | 13 + .../modules/payments/payer_errors.idl | 11 + .../modules/payments/payment_address.idl | 23 + ...ayment_app_service_worker_global_scope.idl | 14 + ...ayment_app_service_worker_registration.idl | 12 + .../payments/payment_currency_amount.idl | 10 + .../modules/payments/payment_details_base.idl | 11 + .../modules/payments/payment_details_init.idl | 10 + .../payments/payment_details_modifier.idl | 12 + .../payments/payment_details_update.idl | 12 + .../payments/payment_handler_response.idl | 15 + .../modules/payments/payment_instrument.idl | 12 + .../modules/payments/payment_instruments.idl | 17 + .../modules/payments/payment_item.idl | 11 + .../modules/payments/payment_manager.idl | 22 + .../payments/payment_method_change_event.idl | 15 + .../payment_method_change_event_init.idl | 10 + .../modules/payments/payment_method_data.idl | 10 + .../modules/payments/payment_options.idl | 19 + .../modules/payments/payment_request.idl | 28 + .../payment_request_details_update.idl | 14 + .../payments/payment_request_event.idl | 27 + .../payments/payment_request_event_init.idl | 17 + .../payments/payment_request_update_event.idl | 14 + .../payment_request_update_event_init.idl | 8 + .../modules/payments/payment_response.idl | 36 + .../payments/payment_shipping_option.idl | 12 + .../payments/payment_validation_errors.idl | 11 + .../secure_payment_confirmation_request.idl | 33 + .../peerconnection/rtc_answer_options.idl | 8 + .../peerconnection/rtc_certificate.idl | 37 + .../peerconnection/rtc_codec_specifics.idl | 17 + .../peerconnection/rtc_configuration.idl | 46 + .../peerconnection/rtc_data_channel.idl | 66 + .../peerconnection/rtc_data_channel_event.idl | 33 + .../rtc_data_channel_event_init.idl | 9 + .../peerconnection/rtc_data_channel_init.idl | 14 + .../peerconnection/rtc_dtls_fingerprint.idl | 9 + .../peerconnection/rtc_dtls_transport.idl | 23 + .../peerconnection/rtc_dtmf_sender.idl | 34 + .../rtc_dtmf_tone_change_event.idl | 33 + .../rtc_dtmf_tone_change_event_init.idl | 9 + .../rtc_encoded_audio_frame.idl | 19 + .../rtc_encoded_audio_frame_metadata.idl | 16 + .../rtc_encoded_audio_frame_options.idl | 9 + .../rtc_encoded_video_frame.idl | 26 + .../rtc_encoded_video_frame_metadata.idl | 40 + .../rtc_encoded_video_frame_options.idl | 9 + .../peerconnection/rtc_encoding_options.idl | 9 + .../modules/peerconnection/rtc_error.idl | 35 + .../peerconnection/rtc_error_event.idl | 11 + .../peerconnection/rtc_error_event_init.idl | 8 + .../modules/peerconnection/rtc_error_init.idl | 13 + .../peerconnection/rtc_ice_candidate.idl | 81 + .../peerconnection/rtc_ice_candidate_init.idl | 12 + .../peerconnection/rtc_ice_candidate_pair.idl | 9 + .../peerconnection/rtc_ice_parameters.idl | 9 + .../modules/peerconnection/rtc_ice_server.idl | 15 + .../peerconnection/rtc_ice_transport.idl | 47 + .../peerconnection/rtc_insertable_streams.idl | 10 + .../rtc_offer_answer_options.idl | 9 + .../peerconnection/rtc_offer_options.idl | 14 + .../peerconnection/rtc_peer_connection.idl | 157 + .../rtc_peer_connection_ice_error_event.idl | 17 + ...c_peer_connection_ice_error_event_init.idl | 14 + .../rtc_peer_connection_ice_event.idl | 33 + .../rtc_peer_connection_ice_event_init.idl | 11 + .../peerconnection/rtc_rtcp_parameters.idl | 9 + .../modules/peerconnection/rtc_rtp_ack.idl | 8 + .../modules/peerconnection/rtc_rtp_acks.idl | 23 + .../peerconnection/rtc_rtp_capabilities.idl | 9 + .../modules/peerconnection/rtc_rtp_codec.idl | 11 + .../rtc_rtp_codec_capability.idl | 7 + .../rtc_rtp_codec_parameters.idl | 8 + .../rtc_rtp_coding_parameters.idl | 8 + .../rtc_rtp_contributing_source.idl | 15 + .../rtc_rtp_decoding_parameters.idl | 7 + .../rtc_rtp_encoding_parameters.idl | 30 + .../rtc_rtp_header_extension_capability.idl | 10 + .../rtc_rtp_header_extension_init.idl | 8 + .../rtc_rtp_header_extension_parameters.idl | 10 + .../peerconnection/rtc_rtp_packet_init.idl | 13 + .../peerconnection/rtc_rtp_parameters.idl | 10 + .../rtc_rtp_receive_parameters.idl | 8 + .../peerconnection/rtc_rtp_receiver.idl | 23 + .../rtc_rtp_send_parameters.idl | 17 + .../peerconnection/rtc_rtp_send_result.idl | 9 + .../peerconnection/rtc_rtp_send_stream.idl | 18 + .../modules/peerconnection/rtc_rtp_sender.idl | 25 + .../modules/peerconnection/rtc_rtp_sent.idl | 12 + .../rtc_rtp_synchronization_source.idl | 8 + .../peerconnection/rtc_rtp_transceiver.idl | 30 + .../rtc_rtp_transceiver_init.idl | 11 + .../peerconnection/rtc_rtp_transport.idl | 16 + .../peerconnection/rtc_sctp_transport.idl | 22 + .../rtc_session_description.idl | 49 + .../rtc_session_description_init.idl | 11 + .../rtc_set_parameter_options.idl | 8 + .../peerconnection/rtc_stats_report.idl | 364 + .../peerconnection/rtc_track_event.idl | 15 + .../peerconnection/rtc_track_event_init.idl | 11 + .../testing/internals_rtc_certificate.idl | 9 + .../testing/internals_rtc_peer_connection.idl | 12 + .../camera_device_permission_descriptor.idl | 9 + .../clipboard_permission_descriptor.idl | 10 + .../fullscreen_permission_descriptor.idl | 7 + .../midi_permission_descriptor.idl | 7 + .../permissions/navigator_permissions.idl | 14 + .../permissions/permission_descriptor.idl | 53 + .../modules/permissions/permission_status.idl | 22 + .../modules/permissions/permissions.idl | 18 + .../push_permission_descriptor.idl | 8 + .../testing/internals_permission.idl | 9 + ...l_storage_access_permission_descriptor.idl | 8 + .../worker_navigator_permissions.idl | 14 + .../document_picture_in_picture.idl | 14 + .../html_video_element_picture_in_picture.idl | 16 + .../picture_in_picture_event.idl | 12 + .../picture_in_picture_event_init.idl | 8 + .../picture_in_picture_window.idl | 15 + .../renderer/modules/plugins/mime_type.idl | 31 + .../modules/plugins/mime_type_array.idl | 31 + .../modules/plugins/navigator_plugins.idl | 13 + .../blink/renderer/modules/plugins/plugin.idl | 34 + .../renderer/modules/plugins/plugin_array.idl | 32 + .../presentation/navigator_presentation.idl | 12 + .../modules/presentation/presentation.idl | 16 + .../presentation_availability.idl | 15 + .../presentation/presentation_connection.idl | 34 + ...resentation_connection_available_event.idl | 14 + ...tation_connection_available_event_init.idl | 9 + .../presentation_connection_close_event.idl | 17 + ...esentation_connection_close_event_init.idl | 8 + .../presentation_connection_list.idl | 14 + .../presentation/presentation_receiver.idl | 13 + .../presentation/presentation_request.idl | 20 + .../presentation/presentation_source.idl | 46 + .../modules/printing/navigator_printing.idl | 14 + .../modules/printing/web_print_job.idl | 39 + .../renderer/modules/printing/web_printer.idl | 23 + .../printing/web_printer_attributes.idl | 90 + .../modules/printing/web_printing_enums.idl | 86 + .../modules/printing/web_printing_manager.idl | 14 + .../private_attribution.idl | 57 + .../window_private_attribution.idl | 14 + .../modules/push_messaging/push_event.idl | 13 + .../push_messaging/push_event_init.idl | 12 + .../modules/push_messaging/push_manager.idl | 17 + .../push_messaging/push_message_data.idl | 14 + .../push_messaging/push_subscription.idl | 25 + .../push_subscription_change_event.idl | 14 + .../push_subscription_change_event_init.idl | 10 + .../push_subscription_options.idl | 13 + .../push_subscription_options_init.idl | 10 + .../service_worker_global_scope_push.idl | 11 + .../service_worker_registration_push.idl | 13 + .../quota/deprecated_storage_callbacks.idl | 12 + .../quota/deprecated_storage_quota.idl | 34 + .../renderer/modules/quota/dom_error.idl | 38 + .../modules/quota/navigator_storage_quota.idl | 33 + .../modules/quota/storage_estimate.idl | 11 + .../modules/quota/storage_manager.idl | 16 + .../modules/quota/storage_usage_details.idl | 12 + .../quota/worker_navigator_storage_quota.idl | 25 + .../html_media_element_remote_playback.idl | 12 + .../remoteplayback/remote_playback.idl | 28 + .../sanitizer_api/element_sanitizer.idl | 19 + .../modules/sanitizer_api/sanitizer.idl | 23 + .../sanitizer_api/sanitizer_config.idl | 16 + .../screen_details/screen_detailed.idl | 51 + .../modules/screen_details/screen_details.idl | 24 + .../screen_details/window_screen_details.idl | 12 + .../screen_orientation/screen_orientation.idl | 34 + .../screen_screen_orientation.idl | 9 + .../sensor/absolute_orientation_sensor.idl | 12 + .../renderer/modules/sensor/accelerometer.idl | 15 + .../modules/sensor/ambient_light_sensor.idl | 14 + .../modules/sensor/gravity_sensor.idl | 12 + .../renderer/modules/sensor/gyroscope.idl | 16 + .../sensor/linear_acceleration_sensor.idl | 12 + .../renderer/modules/sensor/magnetometer.idl | 16 + .../modules/sensor/orientation_sensor.idl | 16 + .../sensor/relative_orientation_sensor.idl | 12 + .../blink/renderer/modules/sensor/sensor.idl | 23 + .../modules/sensor/sensor_error_event.idl | 14 + .../sensor/sensor_error_event_init.idl | 10 + .../modules/sensor/sensor_options.idl | 10 + .../modules/sensor/spatial_sensor_options.idl | 12 + .../testing/create_virtual_sensor_options.idl | 11 + .../sensor/testing/internals_sensor.idl | 26 + .../testing/virtual_sensor_information.idl | 9 + .../sensor/testing/virtual_sensor_reading.idl | 21 + .../modules/serial/navigator_serial.idl | 13 + .../blink/renderer/modules/serial/serial.idl | 19 + .../modules/serial/serial_input_signals.idl | 16 + .../modules/serial/serial_options.idl | 25 + .../modules/serial/serial_output_signals.idl | 14 + .../renderer/modules/serial/serial_port.idl | 32 + .../modules/serial/serial_port_filter.idl | 11 + .../modules/serial/serial_port_info.idl | 11 + .../serial/serial_port_request_options.idl | 10 + .../serial/worker_navigator_serial.idl | 14 + .../modules/service_worker/client.idl | 26 + .../service_worker/client_query_options.idl | 24 + .../modules/service_worker/clients.idl | 14 + .../service_worker/extendable_event.idl | 37 + .../service_worker/extendable_event_init.idl | 9 + .../extendable_message_event.idl | 16 + .../extendable_message_event_init.idl | 13 + .../modules/service_worker/fetch_event.idl | 19 + .../service_worker/fetch_event_init.idl | 12 + .../modules/service_worker/install_event.idl | 13 + .../navigation_preload_manager.idl | 14 + .../navigation_preload_state.idl | 9 + .../navigator_service_worker.idl | 10 + .../service_worker/registration_options.idl | 10 + .../service_worker/router_condition.idl | 32 + .../modules/service_worker/router_rule.idl | 15 + .../modules/service_worker/router_source.idl | 10 + .../modules/service_worker/service_worker.idl | 59 + .../service_worker_container.idl | 48 + .../service_worker_global_scope.idl | 49 + .../service_worker_registration.idl | 30 + .../testing/internals_service_worker.idl | 9 + .../modules/service_worker/window_client.idl | 22 + .../shapedetection/barcode_detector.idl | 15 + .../barcode_detector_options.idl | 26 + .../shapedetection/detected_barcode.idl | 14 + .../modules/shapedetection/detected_face.idl | 11 + .../modules/shapedetection/detected_text.idl | 13 + .../modules/shapedetection/face_detector.idl | 14 + .../shapedetection/face_detector_options.idl | 10 + .../modules/shapedetection/landmark.idl | 12 + .../modules/shapedetection/text_detector.idl | 14 + .../shared_storage/private_aggregation.idl | 18 + ...private_aggregation_debug_mode_options.idl | 7 + ...ate_aggregation_histogram_contribution.idl | 9 + .../modules/shared_storage/shared_storage.idl | 88 + ...red_storage_private_aggregation_config.idl | 6 + ...d_storage_run_operation_method_options.idl | 6 + .../shared_storage_set_method_options.idl | 3 + .../shared_storage_url_with_metadata.idl | 4 + .../shared_storage/shared_storage_worklet.idl | 34 + .../shared_storage_worklet_global_scope.idl | 36 + .../shared_storage_worklet_options.idl | 12 + .../shared_storage/window_shared_storage.idl | 10 + .../smart_card/navigator_smart_card.idl | 15 + .../smart_card/smart_card_connection.idl | 54 + .../smart_card_connection_status.idl | 22 + .../modules/smart_card/smart_card_context.idl | 94 + .../modules/smart_card/smart_card_error.idl | 39 + .../smart_card_resource_manager.idl | 16 + .../modules/speech/speech_grammar.idl | 37 + .../modules/speech/speech_grammar_list.idl | 39 + .../modules/speech/speech_recognition.idl | 63 + .../speech/speech_recognition_alternative.idl | 33 + .../speech/speech_recognition_error_event.idl | 37 + .../speech_recognition_error_event_init.idl | 10 + .../speech/speech_recognition_event.idl | 37 + .../speech/speech_recognition_event_init.idl | 10 + .../speech/speech_recognition_result.idl | 34 + .../speech/speech_recognition_result_list.idl | 33 + .../modules/speech/speech_synthesis.idl | 43 + .../speech/speech_synthesis_error_event.idl | 28 + .../speech_synthesis_error_event_init.idl | 8 + .../modules/speech/speech_synthesis_event.idl | 37 + .../speech/speech_synthesis_event_init.idl | 12 + .../speech/speech_synthesis_utterance.idl | 47 + .../modules/speech/speech_synthesis_voice.idl | 37 + .../testing/internals_speech_synthesis.idl | 35 + .../speech/window_speech_synthesis.idl | 31 + .../html_media_element_src_object.idl | 18 + .../renderer/modules/storage/storage.idl | 38 + .../modules/storage/storage_event.idl | 46 + .../modules/storage/storage_event_init.idl | 13 + .../modules/storage/window_storage.idl | 12 + .../document_storage_access.idl | 32 + .../storage_access/storage_access_handle.idl | 17 + .../storage_access/storage_access_types.idl | 19 + .../modules/subapps/navigator_sub_apps.idl | 12 + .../renderer/modules/subapps/sub_apps.idl | 22 + .../modules/subapps/sub_apps_add_params.idl | 7 + .../modules/subapps/sub_apps_list_result.idl | 7 + .../modules/vibration/navigator_vibration.idl | 30 + .../vibration/testing/internals_vibration.idl | 36 + ...o_element_request_video_frame_callback.idl | 11 + .../video_rvfc/video_frame_metadata.idl | 52 + .../video_frame_request_callback.idl | 7 + .../navigator_virtual_keyboard.idl | 13 + .../virtualkeyboard/virtual_keyboard.idl | 22 + ...virtual_keyboard_geometry_change_event.idl | 14 + .../modules/wake_lock/navigator_wake_lock.idl | 12 + .../renderer/modules/wake_lock/wake_lock.idl | 17 + .../modules/wake_lock/wake_lock_sentinel.idl | 18 + .../wake_lock/worker_navigator_wake_lock.idl | 16 + .../modules/webaudio/analyser_node.idl | 49 + .../modules/webaudio/analyser_options.idl | 11 + .../modules/webaudio/audio_buffer.idl | 50 + .../modules/webaudio/audio_buffer_options.idl | 10 + .../webaudio/audio_buffer_source_node.idl | 44 + .../webaudio/audio_buffer_source_options.idl | 13 + .../modules/webaudio/audio_context.idl | 65 + .../webaudio/audio_context_options.idl | 13 + .../webaudio/audio_destination_node.idl | 30 + .../modules/webaudio/audio_listener.idl | 49 + .../renderer/modules/webaudio/audio_node.idl | 56 + .../modules/webaudio/audio_node_options.idl | 10 + .../renderer/modules/webaudio/audio_param.idl | 63 + .../webaudio/audio_param_descriptor.idl | 12 + .../modules/webaudio/audio_param_map.idl | 10 + .../modules/webaudio/audio_playout_stats.idl | 15 + .../webaudio/audio_processing_event.idl | 34 + .../webaudio/audio_processing_event_init.idl | 10 + .../webaudio/audio_scheduled_source_node.idl | 14 + .../modules/webaudio/audio_sink_info.idl | 11 + .../modules/webaudio/audio_timestamp.idl | 9 + .../modules/webaudio/audio_worklet.idl | 11 + .../webaudio/audio_worklet_global_scope.idl | 25 + .../modules/webaudio/audio_worklet_node.idl | 15 + .../webaudio/audio_worklet_node_options.idl | 12 + .../webaudio/audio_worklet_processor.idl | 12 + .../modules/webaudio/base_audio_context.idl | 68 + .../modules/webaudio/biquad_filter_node.idl | 52 + .../webaudio/biquad_filter_options.idl | 12 + .../modules/webaudio/channel_merger_node.idl | 34 + .../webaudio/channel_merger_options.idl | 8 + .../webaudio/channel_splitter_node.idl | 31 + .../webaudio/channel_splitter_options.idl | 8 + .../modules/webaudio/constant_source_node.idl | 12 + .../webaudio/constant_source_options.idl | 8 + .../modules/webaudio/convolver_node.idl | 34 + .../modules/webaudio/convolver_options.idl | 9 + .../renderer/modules/webaudio/delay_node.idl | 32 + .../modules/webaudio/delay_options.idl | 9 + .../webaudio/dynamics_compressor_node.idl | 37 + .../webaudio/dynamics_compressor_options.idl | 12 + .../renderer/modules/webaudio/gain_node.idl | 33 + .../modules/webaudio/gain_options.idl | 8 + .../modules/webaudio/iir_filter_node.idl | 13 + .../modules/webaudio/iir_filter_options.idl | 9 + .../media_element_audio_source_node.idl | 33 + .../media_element_audio_source_options.idl | 8 + .../media_stream_audio_destination_node.idl | 32 + .../media_stream_audio_source_node.idl | 33 + .../media_stream_audio_source_options.idl | 8 + .../offline_audio_completion_event.idl | 32 + .../offline_audio_completion_event_init.idl | 8 + .../webaudio/offline_audio_context.idl | 38 + .../offline_audio_context_options.idl | 10 + .../modules/webaudio/oscillator_node.idl | 49 + .../modules/webaudio/oscillator_options.idl | 11 + .../renderer/modules/webaudio/panner_node.idl | 69 + .../modules/webaudio/panner_options.idl | 23 + .../modules/webaudio/periodic_wave.idl | 32 + .../webaudio/periodic_wave_constraints.idl | 8 + .../webaudio/periodic_wave_options.idl | 9 + .../webaudio/script_processor_node.idl | 36 + .../modules/webaudio/stereo_panner_node.idl | 13 + .../webaudio/stereo_panner_options.idl | 8 + .../webaudio/testing/internals_web_audio.idl | 11 + .../modules/webaudio/wave_shaper_node.idl | 39 + .../modules/webaudio/wave_shaper_options.idl | 9 + .../modules/webcodecs/aac_encoder_config.idl | 16 + .../renderer/modules/webcodecs/audio_data.idl | 28 + .../webcodecs/audio_data_copy_to_options.idl | 12 + .../modules/webcodecs/audio_data_init.idl | 16 + .../webcodecs/audio_data_output_callback.idl | 7 + .../modules/webcodecs/audio_decoder.idl | 64 + .../webcodecs/audio_decoder_config.idl | 24 + .../modules/webcodecs/audio_decoder_init.idl | 10 + .../webcodecs/audio_decoder_support.idl | 10 + .../modules/webcodecs/audio_encoder.idl | 56 + .../webcodecs/audio_encoder_config.idl | 25 + .../modules/webcodecs/audio_encoder_init.idl | 10 + .../webcodecs/audio_encoder_support.idl | 10 + .../modules/webcodecs/audio_sample_format.idl | 16 + .../modules/webcodecs/avc_encoder_config.idl | 14 + .../modules/webcodecs/codec_state.idl | 11 + .../modules/webcodecs/decrypt_config.idl | 11 + .../modules/webcodecs/encoded_audio_chunk.idl | 21 + .../webcodecs/encoded_audio_chunk_init.idl | 16 + .../encoded_audio_chunk_metadata.idl | 9 + .../encoded_audio_chunk_output_callback.idl | 8 + .../modules/webcodecs/encoded_video_chunk.idl | 23 + .../webcodecs/encoded_video_chunk_init.idl | 16 + .../encoded_video_chunk_metadata.idl | 10 + .../encoded_video_chunk_output_callback.idl | 9 + .../modules/webcodecs/encryption_pattern.idl | 8 + .../modules/webcodecs/hardware_preference.idl | 11 + .../modules/webcodecs/hevc_encoder_config.idl | 14 + .../webcodecs/image_decode_options.idl | 15 + .../modules/webcodecs/image_decode_result.idl | 13 + .../modules/webcodecs/image_decoder.idl | 52 + .../modules/webcodecs/image_decoder_init.idl | 30 + .../modules/webcodecs/image_track.idl | 31 + .../modules/webcodecs/image_track_list.idl | 23 + .../modules/webcodecs/latency_mode.idl | 10 + .../modules/webcodecs/opus_encoder_config.idl | 35 + .../modules/webcodecs/plane_layout.idl | 14 + .../modules/webcodecs/subsample_entry.idl | 8 + .../modules/webcodecs/svc_output_metadata.idl | 9 + .../webcodecs/video_color_primaries.idl | 13 + .../modules/webcodecs/video_color_space.idl | 19 + .../webcodecs/video_color_space_init.idl | 12 + .../modules/webcodecs/video_decoder.idl | 82 + .../webcodecs/video_decoder_config.idl | 37 + .../modules/webcodecs/video_decoder_init.idl | 10 + .../webcodecs/video_decoder_support.idl | 10 + .../modules/webcodecs/video_encoder.idl | 63 + .../webcodecs/video_encoder_buffer.idl | 11 + .../webcodecs/video_encoder_config.idl | 38 + .../video_encoder_encode_options.idl | 19 + .../video_encoder_encode_options_for_av1.idl | 9 + .../video_encoder_encode_options_for_avc.idl | 9 + .../video_encoder_encode_options_for_vp9.idl | 9 + .../modules/webcodecs/video_encoder_init.idl | 13 + .../webcodecs/video_encoder_support.idl | 10 + .../modules/webcodecs/video_frame.idl | 60 + .../webcodecs/video_frame_buffer_init.idl | 27 + .../webcodecs/video_frame_copy_to_options.idl | 24 + .../modules/webcodecs/video_frame_init.idl | 15 + .../webcodecs/video_frame_output_callback.idl | 7 + .../webcodecs/video_matrix_coefficients.idl | 13 + .../modules/webcodecs/video_pixel_format.idl | 49 + .../video_transfer_characteristics.idl | 14 + .../webcodecs/webcodecs_error_callback.idl | 7 + .../renderer/modules/webdatabase/database.idl | 43 + .../modules/webdatabase/sql_error.idl | 45 + .../modules/webdatabase/sql_result_set.idl | 37 + .../webdatabase/sql_result_set_row_list.idl | 35 + .../webdatabase/sql_statement_callback.idl | 32 + .../sql_statement_error_callback.idl | 32 + .../modules/webdatabase/sql_transaction.idl | 44 + .../webdatabase/sql_transaction_callback.idl | 32 + .../sql_transaction_error_callback.idl | 32 + .../webdatabase/window_web_database.idl | 37 + .../modules/webgl/angle_instanced_arrays.idl | 41 + .../modules/webgl/ext_blend_min_max.idl | 12 + .../modules/webgl/ext_clip_control.idl | 20 + .../modules/webgl/ext_color_buffer_float.idl | 10 + .../webgl/ext_color_buffer_half_float.idl | 35 + .../modules/webgl/ext_conservative_depth.idl | 10 + .../modules/webgl/ext_depth_clamp.idl | 11 + .../webgl/ext_disjoint_timer_query.idl | 28 + .../webgl/ext_disjoint_timer_query_webgl2.idl | 15 + .../modules/webgl/ext_float_blend.idl | 10 + .../renderer/modules/webgl/ext_frag_depth.idl | 31 + .../webgl/ext_polygon_offset_clamp.idl | 13 + .../modules/webgl/ext_render_snorm.idl | 10 + .../modules/webgl/ext_shader_texture_lod.idl | 10 + .../blink/renderer/modules/webgl/ext_srgb.idl | 14 + .../webgl/ext_texture_compression_bptc.idl | 14 + .../webgl/ext_texture_compression_rgtc.idl | 14 + .../webgl/ext_texture_filter_anisotropic.idl | 33 + .../ext_texture_mirror_clamp_to_edge.idl | 11 + .../modules/webgl/ext_texture_norm_16.idl | 18 + .../webgl/khr_parallel_shader_compile.idl | 32 + .../nv_shader_noperspective_interpolation.idl | 10 + .../webgl/oes_draw_buffers_indexed.idl | 28 + .../modules/webgl/oes_element_index_uint.idl | 31 + .../modules/webgl/oes_fbo_render_mipmap.idl | 10 + .../modules/webgl/oes_sample_variables.idl | 10 + .../oes_shader_multisample_interpolation.idl | 13 + .../webgl/oes_standard_derivatives.idl | 32 + .../modules/webgl/oes_texture_float.idl | 31 + .../webgl/oes_texture_float_linear.idl | 31 + .../modules/webgl/oes_texture_half_float.idl | 32 + .../webgl/oes_texture_half_float_linear.idl | 31 + .../modules/webgl/oes_vertex_array_object.idl | 37 + .../modules/webgl/ovr_multiview_2.idl | 20 + .../webgl/webgl2_rendering_context.idl | 12 + .../webgl/webgl2_rendering_context_base.idl | 590 + .../modules/webgl/webgl_active_info.idl | 34 + .../webgl/webgl_blend_func_extended.idl | 16 + .../renderer/modules/webgl/webgl_buffer.idl | 31 + .../webgl/webgl_clip_cull_distance.idl | 21 + .../webgl/webgl_color_buffer_float.idl | 34 + .../webgl/webgl_compressed_texture_astc.idl | 41 + .../webgl/webgl_compressed_texture_etc.idl | 21 + .../webgl/webgl_compressed_texture_etc1.idl | 12 + .../webgl/webgl_compressed_texture_pvrtc.idl | 36 + .../webgl/webgl_compressed_texture_s3tc.idl | 36 + .../webgl_compressed_texture_s3tc_srgb.idl | 15 + .../webgl/webgl_context_attributes.idl | 46 + .../modules/webgl/webgl_context_event.idl | 33 + .../webgl/webgl_context_event_init.idl | 9 + .../webgl/webgl_debug_renderer_info.idl | 33 + .../modules/webgl/webgl_debug_shaders.idl | 32 + .../modules/webgl/webgl_depth_texture.idl | 32 + .../modules/webgl/webgl_draw_buffers.idl | 69 + ...aw_instanced_base_vertex_base_instance.idl | 24 + .../modules/webgl/webgl_framebuffer.idl | 31 + .../modules/webgl/webgl_lose_context.idl | 33 + .../modules/webgl/webgl_multi_draw.idl | 42 + ...aw_instanced_base_vertex_base_instance.idl | 35 + .../renderer/modules/webgl/webgl_object.idl | 10 + .../modules/webgl/webgl_polygon_mode.idl | 18 + .../renderer/modules/webgl/webgl_program.idl | 31 + .../modules/webgl/webgl_provoking_vertex.idl | 15 + .../renderer/modules/webgl/webgl_query.idl | 10 + .../webgl/webgl_render_shared_exponent.idl | 10 + .../modules/webgl/webgl_renderbuffer.idl | 31 + .../modules/webgl/webgl_rendering_context.idl | 36 + .../webgl/webgl_rendering_context_base.idl | 739 + .../renderer/modules/webgl/webgl_sampler.idl | 10 + .../renderer/modules/webgl/webgl_shader.idl | 31 + .../webgl_shader_pixel_local_storage.idl | 60 + .../webgl/webgl_shader_precision_format.idl | 35 + .../modules/webgl/webgl_stencil_texturing.idl | 12 + .../renderer/modules/webgl/webgl_sync.idl | 10 + .../renderer/modules/webgl/webgl_texture.idl | 31 + .../modules/webgl/webgl_timer_query_ext.idl | 10 + .../webgl/webgl_transform_feedback.idl | 10 + .../modules/webgl/webgl_uniform_location.idl | 32 + .../webgl/webgl_vertex_array_object.idl | 10 + .../webgl/webgl_vertex_array_object_oes.idl | 31 + .../blink/renderer/modules/webgpu/gpu.idl | 34 + .../renderer/modules/webgpu/gpu_adapter.idl | 20 + .../modules/webgpu/gpu_adapter_info.idl | 21 + .../modules/webgpu/gpu_bind_group.idl | 12 + .../webgpu/gpu_bind_group_descriptor.idl | 10 + .../modules/webgpu/gpu_bind_group_entry.idl | 12 + .../modules/webgpu/gpu_bind_group_layout.idl | 12 + .../gpu_bind_group_layout_descriptor.idl | 9 + .../webgpu/gpu_bind_group_layout_entry.idl | 23 + .../modules/webgpu/gpu_blend_component.idl | 41 + .../modules/webgpu/gpu_blend_state.idl | 10 + .../renderer/modules/webgpu/gpu_buffer.idl | 33 + .../modules/webgpu/gpu_buffer_binding.idl | 12 + .../webgpu/gpu_buffer_binding_layout.idl | 17 + .../modules/webgpu/gpu_buffer_descriptor.idl | 11 + .../modules/webgpu/gpu_buffer_usage.idl | 22 + .../webgpu/gpu_canvas_configuration.idl | 32 + .../modules/webgpu/gpu_canvas_context.idl | 17 + .../modules/webgpu/gpu_color_dict.idl | 12 + .../webgpu/gpu_color_state_descriptor.idl | 12 + .../modules/webgpu/gpu_color_target_state.idl | 11 + .../modules/webgpu/gpu_color_write.idl | 17 + .../modules/webgpu/gpu_command_buffer.idl | 12 + .../webgpu/gpu_command_buffer_descriptor.idl | 8 + .../modules/webgpu/gpu_command_encoder.idl | 57 + .../webgpu/gpu_command_encoder_descriptor.idl | 8 + .../modules/webgpu/gpu_compilation_info.idl | 12 + .../webgpu/gpu_compilation_message.idl | 23 + .../webgpu/gpu_compute_pass_descriptor.idl | 9 + .../webgpu/gpu_compute_pass_encoder.idl | 22 + .../gpu_compute_pass_timestamp_writes.idl | 11 + .../modules/webgpu/gpu_compute_pipeline.idl | 13 + .../gpu_compute_pipeline_descriptor.idl | 10 + .../webgpu/gpu_depth_stencil_state.idl | 22 + .../renderer/modules/webgpu/gpu_device.idl | 54 + .../modules/webgpu/gpu_device_descriptor.idl | 14 + .../modules/webgpu/gpu_device_lost_info.idl | 19 + .../renderer/modules/webgpu/gpu_error.idl | 12 + .../modules/webgpu/gpu_extent_3d_dict.idl | 15 + .../modules/webgpu/gpu_external_texture.idl | 13 + .../gpu_external_texture_binding_layout.idl | 8 + .../gpu_external_texture_descriptor.idl | 10 + .../modules/webgpu/gpu_fence_descriptor.idl | 9 + .../modules/webgpu/gpu_fragment_state.idl | 9 + .../modules/webgpu/gpu_heap_property.idl | 16 + .../modules/webgpu/gpu_image_copy_buffer.idl | 9 + .../webgpu/gpu_image_copy_external_image.idl | 20 + .../webgpu/gpu_image_copy_image_bitmap.idl | 12 + .../modules/webgpu/gpu_image_copy_texture.idl | 12 + .../webgpu/gpu_image_copy_texture_tagged.idl | 10 + .../modules/webgpu/gpu_image_data_layout.idl | 11 + .../modules/webgpu/gpu_internal_error.idl | 12 + .../renderer/modules/webgpu/gpu_map_mode.idl | 14 + .../modules/webgpu/gpu_memory_heap_info.idl | 12 + .../modules/webgpu/gpu_multisample_state.idl | 11 + .../modules/webgpu/gpu_object_base.idl | 9 + .../webgpu/gpu_object_descriptor_base.idl | 9 + .../modules/webgpu/gpu_origin_2d_dict.idl | 11 + .../modules/webgpu/gpu_origin_3d_dict.idl | 11 + .../webgpu/gpu_out_of_memory_error.idl | 12 + .../modules/webgpu/gpu_pipeline_base.idl | 9 + .../webgpu/gpu_pipeline_descriptor_base.idl | 13 + .../modules/webgpu/gpu_pipeline_error.idl | 24 + .../modules/webgpu/gpu_pipeline_layout.idl | 12 + .../webgpu/gpu_pipeline_layout_descriptor.idl | 9 + .../modules/webgpu/gpu_primitive_state.idl | 18 + .../webgpu/gpu_programmable_pass_encoder.idl | 20 + .../modules/webgpu/gpu_programmable_stage.idl | 16 + .../renderer/modules/webgpu/gpu_query_set.idl | 16 + .../webgpu/gpu_query_set_descriptor.idl | 15 + .../renderer/modules/webgpu/gpu_queue.idl | 44 + .../modules/webgpu/gpu_queue_descriptor.idl | 8 + .../gpu_rasterization_state_descriptor.idl | 25 + .../modules/webgpu/gpu_render_bundle.idl | 12 + .../webgpu/gpu_render_bundle_descriptor.idl | 8 + .../webgpu/gpu_render_bundle_encoder.idl | 15 + .../gpu_render_bundle_encoder_descriptor.idl | 10 + .../webgpu/gpu_render_encoder_base.idl | 34 + .../gpu_render_pass_color_attachment.idl | 15 + ...u_render_pass_depth_stencil_attachment.idl | 19 + .../webgpu/gpu_render_pass_descriptor.idl | 23 + .../webgpu/gpu_render_pass_encoder.idl | 32 + .../modules/webgpu/gpu_render_pass_layout.idl | 11 + .../gpu_render_pass_timestamp_writes.idl | 11 + .../modules/webgpu/gpu_render_pipeline.idl | 13 + .../webgpu/gpu_render_pipeline_descriptor.idl | 21 + .../webgpu/gpu_request_adapter_options.idl | 16 + .../renderer/modules/webgpu/gpu_sampler.idl | 12 + .../webgpu/gpu_sampler_binding_layout.idl | 15 + .../modules/webgpu/gpu_sampler_descriptor.idl | 45 + .../modules/webgpu/gpu_shader_module.idl | 13 + .../gpu_shader_module_compilation_hint.idl | 9 + .../webgpu/gpu_shader_module_descriptor.idl | 11 + .../modules/webgpu/gpu_shader_stage.idl | 15 + .../modules/webgpu/gpu_stencil_face_state.idl | 24 + .../gpu_storage_texture_binding_layout.idl | 17 + .../modules/webgpu/gpu_supported_features.idl | 35 + .../modules/webgpu/gpu_supported_limits.idl | 46 + .../renderer/modules/webgpu/gpu_texture.idl | 23 + .../webgpu/gpu_texture_binding_layout.idl | 19 + .../modules/webgpu/gpu_texture_descriptor.idl | 130 + .../modules/webgpu/gpu_texture_usage.idl | 17 + .../modules/webgpu/gpu_texture_view.idl | 12 + .../webgpu/gpu_texture_view_descriptor.idl | 30 + .../webgpu/gpu_uncaptured_error_event.idl | 13 + .../gpu_uncaptured_error_event_init.idl | 9 + .../modules/webgpu/gpu_validation_error.idl | 12 + .../modules/webgpu/gpu_vertex_attribute.idl | 45 + .../webgpu/gpu_vertex_buffer_layout.idl | 16 + .../modules/webgpu/gpu_vertex_state.idl | 9 + .../renderer/modules/webgpu/navigator_gpu.idl | 12 + .../modules/webgpu/wgsl_language_features.idl | 26 + .../modules/webgpu/worker_navigator_gpu.idl | 12 + .../renderer/modules/webmidi/midi_access.idl | 44 + .../modules/webmidi/midi_connection_event.idl | 39 + .../webmidi/midi_connection_event_init.idl | 12 + .../renderer/modules/webmidi/midi_input.idl | 38 + .../modules/webmidi/midi_input_map.idl | 12 + .../modules/webmidi/midi_message_event.idl | 39 + .../webmidi/midi_message_event_init.idl | 12 + .../renderer/modules/webmidi/midi_options.idl | 10 + .../renderer/modules/webmidi/midi_output.idl | 40 + .../modules/webmidi/midi_output_map.idl | 12 + .../renderer/modules/webmidi/midi_port.idl | 72 + .../modules/webmidi/navigator_web_midi.idl | 38 + .../modules/webshare/navigator_share.idl | 16 + .../renderer/modules/webshare/share_data.idl | 12 + .../modules/websockets/close_event.idl | 40 + .../modules/websockets/close_event_init.idl | 11 + .../renderer/modules/websockets/websocket.idl | 67 + .../websockets/websocket_close_info.idl | 10 + .../modules/websockets/websocket_error.idl | 15 + .../websockets/websocket_open_info.idl | 13 + .../modules/websockets/websocket_stream.idl | 18 + .../websockets/websocket_stream_options.idl | 10 + .../modules/webtransport/web_transport.idl | 28 + .../web_transport_bidirectional_stream.idl | 13 + .../webtransport/web_transport_close_info.idl | 10 + .../web_transport_connection_stats.idl | 12 + .../web_transport_datagram_duplex_stream.idl | 19 + .../web_transport_datagram_stats.idl | 10 + .../webtransport/web_transport_error.idl | 22 + .../webtransport/web_transport_error_init.idl | 10 + .../webtransport/web_transport_hash.idl | 9 + .../webtransport/web_transport_options.idl | 9 + .../renderer/modules/webusb/navigator_usb.idl | 13 + .../blink/renderer/modules/webusb/usb.idl | 17 + .../webusb/usb_alternate_interface.idl | 20 + .../modules/webusb/usb_configuration.idl | 17 + .../modules/webusb/usb_connection_event.idl | 15 + .../webusb/usb_connection_event_init.idl | 9 + .../usb_control_transfer_parameters.idl | 24 + .../renderer/modules/webusb/usb_device.idl | 54 + .../modules/webusb/usb_device_filter.idl | 14 + .../webusb/usb_device_request_options.idl | 10 + .../renderer/modules/webusb/usb_endpoint.idl | 29 + .../modules/webusb/usb_in_transfer_result.idl | 16 + .../renderer/modules/webusb/usb_interface.idl | 18 + .../usb_isochronous_in_transfer_packet.idl | 16 + .../usb_isochronous_in_transfer_result.idl | 16 + .../usb_isochronous_out_transfer_packet.idl | 16 + .../usb_isochronous_out_transfer_result.idl | 15 + .../webusb/usb_out_transfer_result.idl | 14 + .../modules/webusb/worker_navigator_usb.idl | 14 + .../navigator_window_controls_overlay.idl | 11 + .../window_controls_overlay.idl | 13 + ...controls_overlay_geometry_change_event.idl | 14 + ...ols_overlay_geometry_change_event_init.idl | 8 + .../blink/renderer/modules/xr/document_xr.idl | 12 + .../renderer/modules/xr/html_element_xr.idl | 12 + .../renderer/modules/xr/mathml_element_xr.idl | 12 + .../renderer/modules/xr/navigator_xr.idl | 11 + .../renderer/modules/xr/svg_element_xr.idl | 12 + .../blink/renderer/modules/xr/window_xr.idl | 12 + .../blink/renderer/modules/xr/xr_anchor.idl | 16 + .../renderer/modules/xr/xr_anchor_set.idl | 12 + .../modules/xr/xr_bounded_reference_space.idl | 13 + .../blink/renderer/modules/xr/xr_camera.idl | 12 + .../modules/xr/xr_composition_layer.idl | 31 + .../modules/xr/xr_cpu_depth_information.idl | 19 + .../modules/xr/xr_depth_information.idl | 16 + .../modules/xr/xr_depth_state_init.idl | 19 + .../modules/xr/xr_dom_overlay_init.idl | 8 + .../modules/xr/xr_dom_overlay_state.idl | 17 + .../blink/renderer/modules/xr/xr_frame.idl | 46 + .../modules/xr/xr_frame_request_callback.idl | 6 + .../blink/renderer/modules/xr/xr_hand.idl | 44 + .../modules/xr/xr_hit_test_options_init.idl | 14 + .../modules/xr/xr_hit_test_result.idl | 12 + .../modules/xr/xr_hit_test_source.idl | 9 + .../modules/xr/xr_image_tracking_result.idl | 25 + .../renderer/modules/xr/xr_input_source.idl | 29 + .../modules/xr/xr_input_source_array.idl | 13 + .../modules/xr/xr_input_source_event.idl | 13 + .../modules/xr/xr_input_source_event_init.idl | 8 + .../xr/xr_input_sources_change_event.idl | 14 + .../xr/xr_input_sources_change_event_init.idl | 9 + .../renderer/modules/xr/xr_joint_pose.idl | 11 + .../renderer/modules/xr/xr_joint_space.idl | 10 + .../blink/renderer/modules/xr/xr_layer.idl | 7 + .../renderer/modules/xr/xr_light_estimate.idl | 13 + .../renderer/modules/xr/xr_light_probe.idl | 12 + .../modules/xr/xr_light_probe_init.idl | 8 + .../blink/renderer/modules/xr/xr_plane.idl | 23 + .../renderer/modules/xr/xr_plane_set.idl | 14 + .../blink/renderer/modules/xr/xr_pose.idl | 15 + .../modules/xr/xr_projection_layer.idl | 18 + .../blink/renderer/modules/xr/xr_ray.idl | 16 + .../modules/xr/xr_ray_direction_init.idl | 10 + .../modules/xr/xr_reference_space.idl | 22 + .../modules/xr/xr_reference_space_event.idl | 14 + .../xr/xr_reference_space_event_init.idl | 9 + .../renderer/modules/xr/xr_render_state.idl | 16 + .../modules/xr/xr_render_state_init.idl | 12 + .../modules/xr/xr_rigid_transform.idl | 17 + .../blink/renderer/modules/xr/xr_session.idl | 94 + .../renderer/modules/xr/xr_session_event.idl | 13 + .../modules/xr/xr_session_event_init.idl | 8 + .../renderer/modules/xr/xr_session_init.idl | 12 + .../blink/renderer/modules/xr/xr_space.idl | 10 + .../renderer/modules/xr/xr_sub_image.idl | 12 + .../blink/renderer/modules/xr/xr_system.idl | 18 + .../modules/xr/xr_tracked_image_init.idl | 13 + ..._transient_input_hit_test_options_init.idl | 9 + .../xr/xr_transient_input_hit_test_result.idl | 9 + .../xr/xr_transient_input_hit_test_source.idl | 9 + .../blink/renderer/modules/xr/xr_view.idl | 30 + .../renderer/modules/xr/xr_viewer_pose.idl | 12 + .../blink/renderer/modules/xr/xr_viewport.idl | 15 + .../renderer/modules/xr/xr_webgl_binding.idl | 45 + .../renderer/modules/xr/xr_webgl_context.idl | 6 + .../modules/xr/xr_webgl_depth_information.idl | 12 + .../renderer/modules/xr/xr_webgl_layer.idl | 22 + .../modules/xr/xr_webgl_layer_init.idl | 14 + .../modules/xr/xr_webgl_sub_image.idl | 22 + .../platform/runtime_enabled_features.json5 | 4807 +++ .../global-interface-listing-expected.txt | 12081 +++++++ 2274 files changed, 172326 insertions(+), 1 deletion(-) create mode 100755 tools/under-control/src/android_webview/browser/aw_content_browser_client.cc create mode 100755 tools/under-control/src/android_webview/browser/aw_field_trials.cc create mode 100755 tools/under-control/src/chrome/android/java/AndroidManifest.xml create mode 100755 tools/under-control/src/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc create mode 100755 tools/under-control/src/chrome/browser/chrome_browser_interface_binders.cc create mode 100755 tools/under-control/src/chrome/browser/chrome_content_browser_client.cc create mode 100755 tools/under-control/src/chrome/browser/prefs/browser_prefs.cc create mode 100755 tools/under-control/src/chrome/browser/ui/tab_helpers.cc create mode 100755 tools/under-control/src/chrome/browser/ui/webui/chrome_content_browser_client_webui_part.cc create mode 100755 tools/under-control/src/chrome/common/extensions/api/accessibility_service_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/appview_tag.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/autofill_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/autotest_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/braille_display_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/certificate_provider.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/certificate_provider_internal.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/chrome_url_overrides.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/crash_report_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/developer_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/document_scan.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/downloads.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/downloads_internal.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/enterprise_device_attributes.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/enterprise_hardware_platform.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/enterprise_kiosk_input.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/enterprise_networking_attributes.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/enterprise_platform_keys.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/enterprise_platform_keys_internal.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/enterprise_reporting_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/file_manager_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/file_manager_private_internal.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/file_system_provider.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/file_system_provider_internal.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/identity.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/idltest.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/image_loader_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/image_writer_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/language_settings_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/login.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/login_screen_storage.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/login_screen_ui.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/login_state.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/mdns.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/notifications.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/odfs_config_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/passwords_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/pdf_viewer_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/platform_keys.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/platform_keys_internal.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/printing.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/printing_metrics.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/processes.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/quick_unlock_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/reading_list.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/resources_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/safe_browsing_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/scripting.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/search.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/settings_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/shared_storage_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/side_panel.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/smart_card_provider_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/speech_recognition_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/system_indicator.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/system_log.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/tab_capture.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/users_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/vpn_provider.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/web_authentication_proxy.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/webrtc_audio_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/webrtc_desktop_capture_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/webrtc_logging_private.idl create mode 100755 tools/under-control/src/chrome/common/extensions/api/wm_desks_private.idl create mode 100755 tools/under-control/src/chrome/renderer/chrome_content_renderer_client.cc create mode 100755 tools/under-control/src/content/browser/web_contents/web_contents_impl.cc create mode 100755 tools/under-control/src/content/child/runtime_features.cc create mode 100755 tools/under-control/src/content/public/browser/content_browser_client.cc create mode 100755 tools/under-control/src/extensions/common/api/alarms.idl create mode 100755 tools/under-control/src/extensions/common/api/app_current_window_internal.idl create mode 100755 tools/under-control/src/extensions/common/api/app_runtime.idl create mode 100755 tools/under-control/src/extensions/common/api/app_window.idl create mode 100755 tools/under-control/src/extensions/common/api/audio.idl create mode 100755 tools/under-control/src/extensions/common/api/automation.idl create mode 100755 tools/under-control/src/extensions/common/api/automation_internal.idl create mode 100755 tools/under-control/src/extensions/common/api/bluetooth.idl create mode 100755 tools/under-control/src/extensions/common/api/bluetooth_low_energy.idl create mode 100755 tools/under-control/src/extensions/common/api/bluetooth_private.idl create mode 100755 tools/under-control/src/extensions/common/api/bluetooth_socket.idl create mode 100755 tools/under-control/src/extensions/common/api/cec_private.idl create mode 100755 tools/under-control/src/extensions/common/api/clipboard.idl create mode 100755 tools/under-control/src/extensions/common/api/content_scripts.idl create mode 100755 tools/under-control/src/extensions/common/api/cross_origin_isolation.idl create mode 100755 tools/under-control/src/extensions/common/api/declarative_net_request.idl create mode 100755 tools/under-control/src/extensions/common/api/diagnostics.idl create mode 100755 tools/under-control/src/extensions/common/api/dns.idl create mode 100755 tools/under-control/src/extensions/common/api/extension_options_internal.idl create mode 100755 tools/under-control/src/extensions/common/api/feedback_private.idl create mode 100755 tools/under-control/src/extensions/common/api/file_handlers.idl create mode 100755 tools/under-control/src/extensions/common/api/file_system.idl create mode 100755 tools/under-control/src/extensions/common/api/hid.idl create mode 100755 tools/under-control/src/extensions/common/api/icon_variants.idl create mode 100755 tools/under-control/src/extensions/common/api/lock_screen_data.idl create mode 100755 tools/under-control/src/extensions/common/api/media_perception_private.idl create mode 100755 tools/under-control/src/extensions/common/api/mime_handler_private.idl create mode 100755 tools/under-control/src/extensions/common/api/mojo_private.idl create mode 100755 tools/under-control/src/extensions/common/api/networking_onc.idl create mode 100755 tools/under-control/src/extensions/common/api/networking_private.idl create mode 100755 tools/under-control/src/extensions/common/api/oauth2.idl create mode 100755 tools/under-control/src/extensions/common/api/offscreen.idl create mode 100755 tools/under-control/src/extensions/common/api/power.idl create mode 100755 tools/under-control/src/extensions/common/api/printer_provider.idl create mode 100755 tools/under-control/src/extensions/common/api/printer_provider_internal.idl create mode 100755 tools/under-control/src/extensions/common/api/scripts_internal.idl create mode 100755 tools/under-control/src/extensions/common/api/serial.idl create mode 100755 tools/under-control/src/extensions/common/api/shared_module.idl create mode 100755 tools/under-control/src/extensions/common/api/socket.idl create mode 100755 tools/under-control/src/extensions/common/api/sockets_tcp.idl create mode 100755 tools/under-control/src/extensions/common/api/sockets_tcp_server.idl create mode 100755 tools/under-control/src/extensions/common/api/sockets_udp.idl create mode 100755 tools/under-control/src/extensions/common/api/system_cpu.idl create mode 100755 tools/under-control/src/extensions/common/api/system_display.idl create mode 100755 tools/under-control/src/extensions/common/api/system_memory.idl create mode 100755 tools/under-control/src/extensions/common/api/system_network.idl create mode 100755 tools/under-control/src/extensions/common/api/system_storage.idl create mode 100755 tools/under-control/src/extensions/common/api/usb.idl create mode 100755 tools/under-control/src/extensions/common/api/user_scripts.idl create mode 100755 tools/under-control/src/extensions/common/api/virtual_keyboard.idl create mode 100755 tools/under-control/src/extensions/common/api/web_accessible_resources.idl create mode 100755 tools/under-control/src/extensions/common/api/web_accessible_resources_mv2.idl create mode 100755 tools/under-control/src/extensions/common/api/webcam_private.idl create mode 100755 tools/under-control/src/gin/v8_initializer.cc create mode 100755 tools/under-control/src/media/base/video_codecs.h create mode 100755 tools/under-control/src/services/network/network_context.cc create mode 100755 tools/under-control/src/testing/variations/fieldtrial_testing_config.json create mode 100755 tools/under-control/src/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom create mode 100755 tools/under-control/src/third_party/blink/public/mojom/webpreferences/web_preferences.mojom create mode 100755 tools/under-control/src/third_party/blink/renderer/core/accessibility/aria_notification_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/animatable.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/animation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/animation_effect.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/animation_timeline.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/base_keyframe.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/computed_effect_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/css/css_animation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/css/css_transition.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/document_animation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/document_timeline.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/document_timeline_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/effect_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/get_animations_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_animation_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_effect.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_effect_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/optional_effect_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/scroll_timeline.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/scroll_timeline_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/view_timeline.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/animation/view_timeline_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/aom/accessible_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/aom/accessible_node_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/aom/computed_accessible_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer_item.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer_item_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_condition_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_container_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_counter_style_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_font_face_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_font_feature_values_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_font_palette_values_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_grouping_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_import_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_keyframe_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_keyframes_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_layer_block_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_layer_statement_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_margin_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_media_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_namespace_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_page_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_position_try_descriptors.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_position_try_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_property_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_rule_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_scope_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_starting_style_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_style_declaration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_style_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_style_sheet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_style_sheet_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_supports_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/css_view_transition_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/caret_position.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_color_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_hsl.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_hwb.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_image_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_clamp.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_invert.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_max.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_min.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_negate.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_product.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_sum.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_matrix_component.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_matrix_component_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_array.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_type.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_perspective.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_position_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_rgb.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_rotate.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_scale.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew_x.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew_y.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_style_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_transform_component.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_transform_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_translate.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_unit_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_unit_values.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_unparsed_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_variable_reference_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/element_computed_style_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/style_property_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom/style_property_map_read_only.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/cssom_string.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/font_face.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/font_face_descriptors.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/font_face_set.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/font_face_set_load_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/font_face_set_load_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/font_face_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/media_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/media_query_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/media_query_list_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/media_query_list_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/parser/media_query_parser.cc create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/property_definition.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/property_registration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/style_media.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/style_sheet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/css/style_sheet_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/display_lock/content_visibility_auto_state_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/display_lock/content_visibility_auto_state_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/abort_controller.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/abort_signal.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/abstract_range.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/accessibility_role.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/aria_attributes.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/aria_relationship_attributes.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/attr.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/attribute_part.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/caret_position_from_point_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/cdata_section.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/character_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/child_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/child_node_part.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/comment.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/common_definitions.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/document.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/document_and_element_event_handlers.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/document_fragment.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/document_or_shadow_root.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/document_part_root.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/document_type.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/dom_exception.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/dom_implementation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/dom_string_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/dom_string_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/dom_token_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/element_creation_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/element_css_inline_style.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/element_definition_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/element_registration_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/events/add_event_listener_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/events/custom_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/events/custom_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/events/event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/events/event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/events/event_listener.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/events/event_listener_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/events/event_modifier_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/events/event_target.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/frame_request_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/function_string_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/get_html_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/get_inner_html_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/get_root_node_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/global_event_handlers.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/interest_invoker_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/invoker_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/mutation_observer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/mutation_observer_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/mutation_record.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/named_node_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/node_filter.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/node_iterator.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/node_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/node_part.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/non_document_type_child_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/non_element_parent_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/observable.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/parent_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/part.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/part_root.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/pointer_lock_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/popover_invoker_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/processing_instruction.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/range.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/shadow_root.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/shadow_root_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/static_range.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/static_range_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/subscriber.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/testing/internals_storage_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/text.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/tree_walker.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/void_function.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/dom/xml_document.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/character_bounds_update_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/character_bounds_update_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/edit_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/edit_context_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/text_format.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/text_format_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/text_format_update_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/text_format_update_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/text_update_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/ime/text_update_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/editing/selection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/animation_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/animation_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/animation_playback_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/animation_playback_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/before_create_policy_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/before_unload_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/clipboard_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/clipboard_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/command_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/composition_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/composition_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/drag_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/drag_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/error_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/error_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/event_type_names.json5 create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/focus_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/focus_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/hash_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/hash_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/input_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/input_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/interest_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/keyboard_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/keyboard_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/message_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/message_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/mouse_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/mouse_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/mutation_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/navigator_events.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/overscroll_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/overscroll_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/page_transition_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/page_transition_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/pointer_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/pointer_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/pop_state_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/pop_state_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/progress_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/progress_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/promise_rejection_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/promise_rejection_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/resource_progress_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/security_policy_violation_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/security_policy_violation_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/text_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/toggle_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/toggle_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/touch_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/touch_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/transition_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/transition_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/ui_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/ui_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/wheel_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/events/wheel_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/exported/web_view_impl.cc create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/attribution_reporting.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/body.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/deferred_request_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/fetch_later.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/headers.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/private_token.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/request.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/request_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/response.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/response_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/testing/internals_fetch.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/testing/worker_internals_fetch.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/window_fetch.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fetch/worker_fetch.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fileapi/blob.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fileapi/blob_property_bag.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fileapi/file.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fileapi/file_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fileapi/file_property_bag.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fileapi/file_reader.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fileapi/file_reader_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fileapi/url_file_api.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fragment_directive/fragment_directive.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fragment_directive/text_directive.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fragment_directive/text_directive_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/bar_prop.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/coop_access_violation_report_body.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/csp/csp_violation_report_body.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/deprecation/deprecation_report_body.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/directive.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/document_policy_violation_report_body.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/external.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/history.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/intervention_report_body.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/is_input_pending_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/location.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_automation_information.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_concurrent_hardware.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_cookies.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_device_memory.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_id.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_language.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_on_line.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_scheduling.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_ua.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_ua_brand_version.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_ua_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/navigator_user_activation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/permissions_policy_violation_report_body.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/report.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/report_body.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/reporting_observer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/reporting_observer_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/scheduling.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/screen.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/scroll_into_view_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/scroll_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/scroll_to_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/selector_directive.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/settings.json5 create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/test_report_body.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/ua_data_values.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/user_activation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/visual_viewport.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/window.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/window_event_handlers.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/window_or_worker_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/window_post_message_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/frame/window_properties.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fullscreen/element_fullscreen.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/fullscreen/fullscreen_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_matrix.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_matrix_2d_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_matrix_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_matrix_read_only.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_point.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_point_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_point_read_only.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_quad.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_quad_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_rect.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_rect_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_rect_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/geometry/dom_rect_read_only.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/highlight/css_highlight_registry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/highlight/highlight.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/highlight/highlight_pointer_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/highlight/highlight_registry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/assigned_nodes_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/canvas/baselines.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/canvas/high_dynamic_range_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/canvas/html_canvas_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/canvas/image_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/canvas/image_data_settings.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/canvas/image_encode_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/canvas/text_metrics.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/closewatcher/close_watcher.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/closewatcher/close_watcher_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/custom/custom_element_registry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/custom/custom_state_set.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/custom/element_internals.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/custom/validity_state_flags.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/event_handler.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/fenced_frame/fence.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/fenced_frame/fence_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/fenced_frame/fenced_frame_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/fenced_frame/html_fenced_frame_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/focus_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/form_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/form_data_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/form_data_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_button_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_data_list_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_field_set_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_form_controls_collection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_form_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_input_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_label_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_legend_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_opt_group_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_option_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_options_collection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_output_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_select_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_select_list_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/html_text_area_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/radio_node_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/submit_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/submit_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/forms/validity_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_all_collection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_anchor_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_area_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_attributionsrc_element_utils.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_base_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_body_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_br_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_collection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_data_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_details_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_dialog_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_directory_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_div_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_dlist_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_document.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_embed_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_font_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_frame_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_frame_set_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_head_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_heading_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_hr_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_html_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_hyperlink_element_utils.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_iframe_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_image_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_li_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_link_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_map_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_marquee_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_menu_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_meta_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_meter_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_mod_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_object_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_olist_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_or_foreign_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_paragraph_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_param_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_permission_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_picture_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_pre_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_progress_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_quote_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_script_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_shared_storage_writable_element_utils.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_slot_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_source_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_span_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_style_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_table_caption_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_table_cell_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_table_col_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_table_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_table_row_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_table_section_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_template_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_time_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_title_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_ulist_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/html_unknown_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/media/html_audio_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/media/html_media_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/media/html_video_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/media/media_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/time_ranges.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/audio_track.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/audio_track_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/html_track_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/text_track.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/text_track_cue.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/text_track_cue_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/text_track_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/track_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/track_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/video_track.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/video_track_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/vtt/vtt_cue.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/track/vtt/vtt_region.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/html/void_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/imagebitmap/image_bitmap.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/imagebitmap/image_bitmap_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/input/input_device_capabilities.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/input/input_device_capabilities_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/input/touch.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/input/touch_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/input/touch_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/inspector/dev_tools_host.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/inspector/inspector_overlay_host.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/intersection_observer/intersection_observer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/intersection_observer/intersection_observer_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/intersection_observer/intersection_observer_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/css_layout_worklet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/custom_layout_constraints_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/fragment_result_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/intrinsic_sizes.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/intrinsic_sizes_result_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/layout_child.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/layout_constraints.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/layout_edges.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/layout_fragment.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/layout/custom/layout_worklet_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mathml/mathml_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/messaging/message_channel.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/messaging/message_port.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/messaging/post_message_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/messaging/structured_serialize_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_create_data_pipe_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_create_data_pipe_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_create_message_pipe_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_create_shared_buffer_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_discard_data_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_duplicate_buffer_handle_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_handle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_handle_signals.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_map_buffer_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_read_data_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_read_data_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_read_message_flags.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_read_message_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_watcher.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_write_data_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/mojo_write_data_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/test/mojo_interface_interceptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/mojo/test/mojo_interface_request_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigate_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigate_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_activation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_current_entry_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_current_entry_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_destination.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_history_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_intercept_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_navigate_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_reload_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_transition.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/navigation_api/navigation_update_current_entry_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc create mode 100755 tools/under-control/src/third_party/blink/renderer/core/page/color_page_popup_controller.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/page/page_popup_controller.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/permissions_policy/feature_policy.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/preferences/navigator_preferences.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/preferences/preference_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/preferences/preference_object.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/resize_observer/resize_observer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/resize_observer/resize_observer_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/resize_observer/resize_observer_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/resize_observer/resize_observer_size.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/idle_deadline.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/idle_request_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/idle_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/scheduler.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/scheduler_post_task_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/scheduler_post_task_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/scheduler_yield_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/script_wrappable_task_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/task_controller.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/task_controller_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/task_priority_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/task_priority_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/task_signal.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/task_signal_any_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/window_idle_tasks.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/window_or_worker_global_scope_timers.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scheduler/window_or_worker_scheduler.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/scroll/snap_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/shadow_realm/shadow_realm_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/byte_length_queuing_strategy.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/count_queuing_strategy.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/queuing_strategy_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_byte_stream_controller.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_stream_byob_reader.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_stream_byob_request.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_stream_default_controller.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_stream_default_reader.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_stream_generic_reader.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_stream_get_reader_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_stream_iterator_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_stream_read_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/readable_writable_pair.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/stream_pipe_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/transform_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/transform_stream_default_controller.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/underlying_sink_base.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/underlying_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/underlying_source_cancel_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/underlying_source_pull_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/underlying_source_start_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/writable_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/writable_stream_default_controller.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/streams/writable_stream_default_writer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_a_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_angle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animate_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animate_motion_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animate_transform_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_angle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_boolean.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_enumeration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_integer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_length.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_length_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_number.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_number_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_rect.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_string.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animated_transform_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_animation_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_circle_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_clip_path_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_component_transfer_function_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_defs_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_desc_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_document.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_ellipse_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_blend_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_color_matrix_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_component_transfer_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_composite_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_convolve_matrix_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_diffuse_lighting_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_displacement_map_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_distant_light_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_drop_shadow_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_flood_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_func_a_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_func_b_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_func_g_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_func_r_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_gaussian_blur_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_image_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_merge_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_merge_node_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_morphology_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_offset_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_point_light_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_specular_lighting_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_spot_light_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_tile_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fe_turbulence_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_filter_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_fit_to_view_box.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_foreign_object_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_g_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_geometry_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_gradient_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_graphics_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_image_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_length.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_length_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_line_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_linear_gradient_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_marker_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_mask_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_matrix.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_metadata_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_mpath_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_number.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_number_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_path_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_pattern_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_point.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_point_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_polygon_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_polyline_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_radial_gradient_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_rect.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_rect_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_script_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_set_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_stop_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_string_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_style_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_svg_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_switch_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_symbol_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_tests.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_text_content_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_text_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_text_path_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_text_positioning_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_title_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_transform.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_transform_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_tspan_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_unit_types.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_uri_reference.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_use_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_view_element.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/svg/svg_zoom_and_pan.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/callback_function_test.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/death_aware_script_wrappable.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/dictionary_test.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/garbage_collected_script_wrappable.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/gc_observation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/hit_test_layer_rect.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/hit_test_layer_rect_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internal_dictionary.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internal_dictionary_derived.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internal_dictionary_derived_derived.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internal_settings.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internals.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internals_cookie.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internals_delete_all_cookies.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internals_get_all_cookies.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internals_get_named_cookie.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/internals_ukm_recorder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/origin_trials_test.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/origin_trials_test_dictionary.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/origin_trials_test_partial.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/origin_trials_test_window.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/record_test.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/sequence_test.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/static_selection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/type_conversions.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/union_types_test.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/testing/worker_internals.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/back_forward_cache_restoration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/dom_high_res_time_stamp.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/epoch_time_stamp.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/event_counts.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/internals_profiler.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/largest_contentful_paint.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/layout_shift.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/layout_shift_attribution.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/measure_memory/memory_attribution.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/measure_memory/memory_attribution_container.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/measure_memory/memory_breakdown_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/measure_memory/memory_measurement.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/memory_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/not_restored_reasons.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_element_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_entry_filter_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_entry_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_event_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_long_animation_frame_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_long_task_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_mark.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_mark_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_measure.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_measure_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_navigation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_navigation_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_navigation_timing_activation_start.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_observer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_observer_callback_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_observer_entry_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_observer_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_paint_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_resource_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_script_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_server_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/performance_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/profiler.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/profiler_frame.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/profiler_init_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/profiler_sample.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/profiler_stack.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/profiler_trace.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/soft_navigation_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/task_attribution_timing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/visibility_state_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/window_performance.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/timing/worker_global_scope_performance.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/trustedtypes/trusted_html.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/trustedtypes/trusted_script.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/trustedtypes/trusted_script_url.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/trustedtypes/trusted_type_policy.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_factory.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/trustedtypes/trusted_type_policy_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/url/url.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/url/url_search_params.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/url_pattern/url_pattern.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/url_pattern/url_pattern_component_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/url_pattern/url_pattern_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/url_pattern/url_pattern_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/url_pattern/url_pattern_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/view_transition/page_reveal_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/view_transition/page_reveal_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/view_transition/page_swap_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/view_transition/page_swap_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/view_transition/view_transition.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/view_transition/view_transition_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/view_transition/view_transition_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/view_transition/view_transition_supplement.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/view_transition/view_transition_type_set.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/abstract_worker.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/dedicated_worker_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/shared_worker.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/shared_worker_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/worker.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/worker_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/worker_location.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/worker_navigator.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/worker_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/worklet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/worklet_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/workers/worklet_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xml/document_xpath_evaluator.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xml/dom_parser.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xml/parse_from_string_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xml/xml_serializer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xml/xpath_evaluator.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xml/xpath_expression.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xml/xpath_ns_resolver.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xml/xpath_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xml/xslt_processor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xmlhttprequest/xml_http_request.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_event_target.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/core/xmlhttprequest/xml_http_request_upload.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/chromeos/chromeos.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/chromeos/diagnostics/cros_cpu_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/chromeos/diagnostics/cros_diagnostics.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/chromeos/diagnostics/cros_logical_cpu_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/chromeos/diagnostics/cros_network_interface.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/chromeos/kiosk/cros_kiosk.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/webview/android.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/webview/media_integrity/media_integrity_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/webview/media_integrity/media_integrity_token_provider.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/extensions/webview/web_view.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/accessibility/testing/internals_accessibility.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ad_auction/ad_auction_data_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ad_auction/ad_request_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ad_auction/ads.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ad_auction/auction_ad.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ad_auction/auction_ad_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ad_auction/auction_ad_interest_group.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ad_auction/navigator_auction.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ad_auction/protected_audience.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ai/ai.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ai/ai_text_session.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ai/ai_text_session_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ai/window_or_worker_global_scope_ai.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/animationworklet/animation_worklet_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/animationworklet/css_animation_worklet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/animationworklet/worklet_animation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/animationworklet/worklet_group_effect.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/app_banner/app_banner_prompt_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/app_banner/before_install_prompt_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/app_banner/before_install_prompt_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/app_banner/window_installation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/audio_output_devices/html_media_element_audio_output_device.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/awc/additional_windowing_controls.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/background_fetch_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/background_fetch_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/background_fetch_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/background_fetch_record.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/background_fetch_registration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/background_fetch_ui_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/background_fetch_update_ui_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/service_worker_global_scope_background_fetch.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_fetch/service_worker_registration_background_fetch.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_sync/background_sync_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_sync/periodic_sync_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_sync/periodic_sync_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_sync/periodic_sync_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_sync/service_worker_global_scope_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_sync/service_worker_registration_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_sync/sync_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_sync/sync_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/background_sync/sync_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/badging/navigator_badge.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/badging/worker_navigator_badge.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/battery/battery_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/battery/navigator_battery.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/beacon/navigator_beacon.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_advertising_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_characteristic_properties.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_data_filter_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_device.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_filter_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_le_scan_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_filter_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_manufacturer_data_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_characteristic.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_server.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_remote_gatt_service.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_service_data_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/request_device_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/breakout_box/media_stream_track_generator_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/breakout_box/media_stream_track_processor_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/breakout_box/video_track_generator.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/browsing_topics/browsing_topic.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/browsing_topics/browsing_topics_document_supplement.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/browsing_topics/browsing_topics_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/buckets/navigator_storage_buckets.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/buckets/storage_bucket.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/buckets/storage_bucket_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/buckets/storage_bucket_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/buckets/worker_navigator_storage_buckets.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cache_storage/cache.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cache_storage/cache_query_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cache_storage/cache_storage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cache_storage/multi_cache_query_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cache_storage/window_cache_storage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cache_storage/worker_cache_storage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/canvas_2d_gpu_transfer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/canvas_2d_gpu_transfer_option.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/canvas_filter_dictionary.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/canvas_gradient.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/canvas_path.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/canvas_pattern.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_settings.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/mesh_2d_index_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/mesh_2d_uv_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/mesh_2d_vertex_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/canvas2d/path_2d.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/htmlcanvas/canvas_context_creation_attributes_module.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/imagebitmap/window_create_image_bitmap.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/imagebitmap/worker_create_image_bitmap.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/offscreencanvas/offscreen_canvas_module.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/clipboard/clipboard.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/clipboard/clipboard_item.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/clipboard/navigator_clipboard.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/compression/compression_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/compression/decompression_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/compute_pressure/pressure_observer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/compute_pressure/pressure_observer_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/compute_pressure/pressure_record.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/compute_pressure/pressure_update_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/contacts_picker/contact_address.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/contacts_picker/contact_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/contacts_picker/contacts_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/contacts_picker/contacts_select_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/contacts_picker/navigator_contacts.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/content_index/content_description.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/content_index/content_icon_definition.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/content_index/content_index.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/content_index/content_index_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/content_index/content_index_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/content_index/service_worker_global_scope_content_index.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_deprecation_label/cookie_deprecation_label.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_deprecation_label/navigator_cookie_deprecation_label.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/cookie_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/cookie_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/cookie_store.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/cookie_store_delete_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/cookie_store_get_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/service_worker_registration_cookies.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/cookie_store/window_cookie_store.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_inputs_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_outputs.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_client_outputs_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_large_blob_inputs.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_large_blob_outputs.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_payment_inputs.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_prf_inputs.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_prf_outputs.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_supplemental_pub_keys_inputs.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_extensions_supplemental_pub_keys_outputs.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authentication_response_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authenticator_assertion_response.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authenticator_assertion_response_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authenticator_attestation_response.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authenticator_attestation_response_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authenticator_response.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/authenticator_selection_criteria.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/cable_authentication_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/collected_client_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/credential.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/credential_creation_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/credential_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/credential_properties_output.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/credential_report_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/credential_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/credential_user_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/credentials_container.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/digital_credential.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/digital_credential_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/federated_credential.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/federated_credential_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/federated_credential_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/identity_claim_requirement.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/identity_credential.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/identity_credential_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/identity_credential_logout_r_ps_request.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/identity_credential_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/identity_provider.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/identity_provider_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/identity_standard_claims.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/navigator_credentials.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/navigator_identity.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/navigator_login.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/otp_credential.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/otp_credential_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/password_credential.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/password_credential_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/payment_credential_instrument.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_creation_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_creation_options_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_descriptor_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_entity.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_report_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_request_options_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_rp_entity.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/public_key_credential_user_entity.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/registration_response_json.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/remote_desktop_client_override.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/credentialmanagement/testing/internals_fed_cm.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/crypto/crypto.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/crypto/crypto_key.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/crypto/json_web_key.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/crypto/rsa_other_primes_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/crypto/subtle_crypto.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/crypto/window_crypto.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/crypto/worker_global_scope_crypto.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/csspaint/css_paint_worklet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d_settings.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/csspaint/paint_size.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/delegated_ink/delegated_ink_trail_presenter.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/delegated_ink/ink.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/delegated_ink/ink_presenter_param.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/delegated_ink/ink_trail_style.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/delegated_ink/navigator_ink.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/device_motion_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/device_motion_event_acceleration_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/device_motion_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/device_motion_event_rotation_rate_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/device_orientation_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/device_orientation_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/window_device_motion.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_orientation/window_device_orientation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_posture/device_posture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_posture/navigator_device_posture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/device_posture/testing/internals_device_posture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/direct_sockets/socket_connection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/direct_sockets/socket_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/direct_sockets/tcp_server_socket.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/direct_sockets/tcp_socket.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/direct_sockets/udp_message.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/direct_sockets/udp_socket.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/document_picture_in_picture/document_picture_in_picture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/document_picture_in_picture/document_picture_in_picture_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/document_picture_in_picture/document_picture_in_picture_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/document_picture_in_picture/document_picture_in_picture_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/document_picture_in_picture/window_document_picture_in_picture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/donottrack/navigator_do_not_track.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encoding/text_decode_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encoding/text_decoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encoding/text_decoder_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encoding/text_decoder_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encoding/text_encoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encoding/text_encoder_encode_into_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encoding/text_encoder_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/html_media_element_encrypted_media.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_encrypted_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_key_message_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_key_session.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_key_status_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_key_system_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_key_system_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_key_system_media_capability.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_keys.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_keys_get_status_for_policy.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/media_keys_policy.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/encryptedmedia/navigator_request_media_key_system_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/eventsource/event_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/eventsource/event_source_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/eyedropper/color_selection_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/eyedropper/color_selection_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/eyedropper/eye_dropper.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/data_transfer_item_file_system_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/directory_picker_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_picker_accept_type.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_picker_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_change_record.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_cloud_identifier.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_create_sync_access_handle_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_create_writable_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_directory_handle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_file_handle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_get_directory_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_get_file_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_handle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_handle_permission_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_observer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_observer_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_observer_observe_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_read_write_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_remove_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_sync_access_handle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/file_system_writable_file_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/open_file_picker_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/save_file_picker_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/storage_manager_file_system_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/window_file_system_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/file_system_access/write_params.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/data_transfer_item_file_system.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/dedicated_worker_global_scope_file_system.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/directory_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/directory_entry_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/directory_reader.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/directory_reader_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/dom_file_system.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/entries_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/entry_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/entry_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/error_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/file_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/file_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/file_entry_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/file_system_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/file_system_flags.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/file_writer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/file_writer_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/file_writer_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/html_input_element_file_system.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/metadata.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/metadata_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/shared_worker_global_scope_file_system.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/filesystem/window_file_system.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/font_access/font_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/font_access/query_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/font_access/window_font_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/formatted_text/formatted_text.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/fuzzing/internals_fuzzing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_axis_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_axis_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_button.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_button_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_button_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_effect_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/gamepad_touch.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/gamepad/navigator_gamepad.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/geolocation/geolocation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/geolocation/geolocation_coordinates.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/geolocation/geolocation_position.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/geolocation/geolocation_position_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/geolocation/navigator_geolocation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/geolocation/position_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_drawing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_drawing_segment.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_hints.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_model_constraint.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_point.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_prediction.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_recognizer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_recognizer_query_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_segment.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/handwriting_stroke.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/handwriting/navigator_handwriting_recognition_service.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid_collection_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid_connection_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid_connection_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid_device.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid_device_filter.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid_device_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid_input_report_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid_report_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/hid_report_item.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/navigator_hid.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/hid/worker_navigator_hid.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/idle/idle_detector.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/idle/idle_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/imagecapture/constrain_point_2d_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/imagecapture/image_capture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/imagecapture/media_settings_range.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/imagecapture/photo_capabilities.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/imagecapture/photo_settings.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/imagecapture/point_2d.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_cursor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_database.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_database_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_factory.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_index.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_index_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_key_range.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_object_store.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_object_store_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_open_db_request.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_request.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_transaction.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_transaction_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_version_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/idb_version_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/window_indexed_database.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/indexeddb/worker_global_scope_indexed_database.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/installedapp/navigator_installed_app.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/installedapp/related_application.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/keyboard/keyboard.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/keyboard/keyboard_layout_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/keyboard/navigator_keyboard.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/launch/dom_window_launch_queue.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/launch/launch_params.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/launch/launch_queue.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/lock_screen/dom_window_lock_screen.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/lock_screen/lock_screen_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/locked_mode/locked_mode.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/locked_mode/navigator_locked_mode.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/locks/lock.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/locks/lock_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/locks/lock_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/locks/lock_manager_snapshot.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/locks/lock_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/locks/navigator_locks.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/locks/worker_navigator_locks.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/managed_device/navigator_managed.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/managed_device/navigator_managed_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/manifest/image_resource.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/audio_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/key_system_track_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/media_capabilities.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/media_capabilities_decoding_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/media_capabilities_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/media_capabilities_key_system_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/media_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/media_decoding_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/media_encoding_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/navigator_media_capabilities.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/video_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/media_capabilities/worker_navigator_media_capabilities.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediacapturefromelement/canvas_capture_media_stream_track.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediacapturefromelement/html_canvas_element_capture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediacapturefromelement/html_media_element_capture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediarecorder/blob_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediarecorder/blob_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediarecorder/media_recorder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediarecorder/media_recorder_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/chapter_information.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/chapter_information_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/media_image.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/media_metadata.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/media_metadata_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/media_position_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/media_session.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/media_session_action_details.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/media_session_seek_to_action_details.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasession/navigator_media_session.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/audio_track_source_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/html_video_element_media_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/media_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/media_source_handle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/source_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/source_buffer_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/source_buffer_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/track_default.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/track_default_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/url_media_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/video_playback_quality.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediasource/video_track_source_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/browser_capture_media_stream_track.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/capture_controller.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/capture_handle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/capture_handle_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/captured_mouse_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/captured_mouse_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/captured_wheel_action.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/constrain_boolean_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/constrain_dom_string_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/constrain_double_range.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/constrain_long_range.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/crop_target.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/double_range.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/input_device_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/long_range.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_device_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_devices.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream_constraints.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream_track.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream_track_audio_stats.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream_track_content_hint.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream_track_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream_track_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_stream_track_video_stats.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_track_constraints.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_track_settings.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/navigator_media_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/navigator_user_media.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/overconstrained_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/restriction_target.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/screen_capture_media_stream_track.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mediastream/testing/internals_media_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/ml.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/ml_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/ml_context_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/navigator_ml.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/webnn/ml_activation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/webnn/ml_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/webnn/ml_buffer_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/webnn/ml_graph.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/webnn/ml_operand.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/webnn/ml_operand_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/ml/worker_navigator_ml.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/mojo/mojo_file_system_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/navigatorcontentutils/navigator_content_utils.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/netinfo/navigator_network_information.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/netinfo/network_information.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/netinfo/testing/internals_net_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/netinfo/worker_navigator_network_information.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_make_read_only_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_message.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_message_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_reader.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_reading_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_reading_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_record.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_record_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_scan_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/nfc/ndef_write_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/notifications/get_notification_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/notifications/notification.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/notifications/notification_action.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/notifications/notification_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/notifications/notification_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/notifications/notification_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/notifications/service_worker_global_scope_notifications.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/notifications/service_worker_registration_notifications.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/notifications/timestamp_trigger.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/on_device_translation/language_translator.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/on_device_translation/translation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/on_device_translation/translation_language_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/on_device_translation/window_or_worker_global_scope_translation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/abort_payment_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/address_errors.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/address_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/android_pay_method_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/can_make_payment_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/goods/item_details.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/goods/purchase_details.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/google_play_billing_method_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/html_iframe_element_payments.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/image_object.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payer_errors.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_address.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_app_service_worker_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_app_service_worker_registration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_currency_amount.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_details_base.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_details_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_details_modifier.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_details_update.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_handler_response.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_instrument.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_instruments.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_item.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_method_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_method_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_method_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_request.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_request_details_update.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_request_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_request_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_request_update_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_request_update_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_response.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_shipping_option.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/payment_validation_errors.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/payments/secure_payment_confirmation_request.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_answer_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_certificate.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_codec_specifics.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_data_channel.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_data_channel_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_dtls_fingerprint.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_metadata.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_encoding_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_error_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_error_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_ice_candidate_pair.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_ice_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_ice_server.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_insertable_streams.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_offer_answer_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_offer_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtcp_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_ack.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_acks.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_capabilities.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_capability.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_codec_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_coding_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_contributing_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_decoding_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_encoding_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_capability.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_header_extension_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_packet_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receive_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_send_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sent.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_synchronization_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_rtp_transport.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_session_description.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_session_description_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_set_parameter_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_track_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/rtc_track_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_certificate.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/peerconnection/testing/internals_rtc_peer_connection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/camera_device_permission_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/clipboard_permission_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/fullscreen_permission_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/midi_permission_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/navigator_permissions.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/permission_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/permission_status.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/permissions.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/push_permission_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/testing/internals_permission.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/top_level_storage_access_permission_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/permissions/worker_navigator_permissions.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_window.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/plugins/mime_type.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/plugins/mime_type_array.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/plugins/navigator_plugins.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/plugins/plugin.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/plugins/plugin_array.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/navigator_presentation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_availability.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_connection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_connection_available_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_connection_close_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_connection_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_receiver.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_request.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/presentation/presentation_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/printing/navigator_printing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/printing/web_print_job.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/printing/web_printer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/printing/web_printer_attributes.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/printing/web_printing_enums.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/printing/web_printing_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/private_attribution/private_attribution.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/private_attribution/window_private_attribution.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/push_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/push_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/push_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/push_message_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/push_subscription.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/push_subscription_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/push_subscription_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/push_subscription_options_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/service_worker_global_scope_push.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/push_messaging/service_worker_registration_push.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/quota/deprecated_storage_callbacks.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/quota/deprecated_storage_quota.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/quota/dom_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/quota/navigator_storage_quota.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/quota/storage_estimate.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/quota/storage_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/quota/storage_usage_details.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/quota/worker_navigator_storage_quota.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/remoteplayback/html_media_element_remote_playback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/remoteplayback/remote_playback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sanitizer_api/element_sanitizer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sanitizer_api/sanitizer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sanitizer_api/sanitizer_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/screen_details/screen_detailed.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/screen_details/screen_details.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/screen_details/window_screen_details.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/screen_orientation/screen_orientation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/screen_orientation/screen_screen_orientation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/absolute_orientation_sensor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/accelerometer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/ambient_light_sensor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/gravity_sensor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/gyroscope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/linear_acceleration_sensor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/magnetometer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/orientation_sensor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/relative_orientation_sensor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/sensor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/sensor_error_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/sensor_error_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/sensor_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/spatial_sensor_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/testing/create_virtual_sensor_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/testing/internals_sensor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/testing/virtual_sensor_information.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/sensor/testing/virtual_sensor_reading.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/navigator_serial.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/serial.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/serial_input_signals.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/serial_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/serial_output_signals.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/serial_port.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/serial_port_filter.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/serial_port_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/serial_port_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/serial/worker_navigator_serial.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/client.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/client_query_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/clients.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/extendable_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/extendable_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/extendable_message_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/extendable_message_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/fetch_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/fetch_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/install_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/navigation_preload_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/navigator_service_worker.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/registration_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/router_condition.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/router_rule.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/router_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/service_worker.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/service_worker_container.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/service_worker_registration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/testing/internals_service_worker.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/service_worker/window_client.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shapedetection/barcode_detector.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shapedetection/barcode_detector_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shapedetection/detected_barcode.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shapedetection/detected_face.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shapedetection/detected_text.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shapedetection/face_detector.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shapedetection/face_detector_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shapedetection/landmark.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shapedetection/text_detector.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/private_aggregation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/private_aggregation_debug_mode_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/private_aggregation_histogram_contribution.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/shared_storage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/shared_storage_private_aggregation_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/shared_storage_run_operation_method_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/shared_storage_set_method_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/shared_storage_url_with_metadata.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/shared_storage/window_shared_storage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/smart_card/navigator_smart_card.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/smart_card/smart_card_connection.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/smart_card/smart_card_connection_status.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/smart_card/smart_card_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/smart_card/smart_card_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/smart_card/smart_card_resource_manager.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_grammar.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_grammar_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_recognition.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_recognition_alternative.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_recognition_error_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_recognition_error_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_recognition_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_recognition_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_recognition_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_recognition_result_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_synthesis.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_synthesis_error_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_synthesis_error_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_synthesis_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_synthesis_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_synthesis_utterance.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/speech_synthesis_voice.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/testing/internals_speech_synthesis.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/speech/window_speech_synthesis.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/srcobject/html_media_element_src_object.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/storage/storage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/storage/storage_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/storage/storage_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/storage/window_storage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/storage_access/document_storage_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/storage_access/storage_access_handle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/storage_access/storage_access_types.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/subapps/navigator_sub_apps.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/subapps/sub_apps.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/subapps/sub_apps_add_params.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/subapps/sub_apps_list_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/vibration/navigator_vibration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/vibration/testing/internals_vibration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/video_rvfc/html_video_element_request_video_frame_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/video_rvfc/video_frame_metadata.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/wake_lock/wake_lock.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/wake_lock/worker_navigator_wake_lock.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/analyser_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/analyser_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_buffer_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_buffer_source_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_buffer_source_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_context_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_destination_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_listener.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_node_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_param.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_param_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_param_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_playout_stats.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_processing_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_processing_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_scheduled_source_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_sink_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_timestamp.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_worklet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_worklet_global_scope.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_worklet_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_worklet_node_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/base_audio_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/biquad_filter_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/biquad_filter_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/channel_merger_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/channel_merger_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/channel_splitter_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/channel_splitter_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/constant_source_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/constant_source_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/convolver_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/convolver_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/delay_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/delay_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/dynamics_compressor_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/dynamics_compressor_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/gain_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/gain_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/iir_filter_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/iir_filter_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/media_element_audio_source_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/media_element_audio_source_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/media_stream_audio_destination_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/media_stream_audio_source_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/offline_audio_completion_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/offline_audio_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/offline_audio_context_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/oscillator_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/oscillator_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/panner_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/panner_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/periodic_wave.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/periodic_wave_constraints.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/periodic_wave_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/script_processor_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/stereo_panner_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/stereo_panner_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/testing/internals_web_audio.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/wave_shaper_node.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webaudio/wave_shaper_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/aac_encoder_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_data_copy_to_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_data_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_data_output_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_decoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_decoder_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_decoder_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_decoder_support.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_encoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_encoder_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_encoder_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_encoder_support.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/audio_sample_format.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/avc_encoder_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/codec_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/decrypt_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk_metadata.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/encoded_audio_chunk_output_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_metadata.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/encoded_video_chunk_output_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/encryption_pattern.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/hardware_preference.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/hevc_encoder_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/image_decode_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/image_decode_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/image_decoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/image_decoder_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/image_track.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/image_track_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/latency_mode.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/opus_encoder_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/plane_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/subsample_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/svc_output_metadata.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_color_primaries.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_color_space.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_color_space_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_decoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_decoder_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_decoder_support.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_encoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_encoder_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_encoder_encode_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_encoder_encode_options_for_av1.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_encoder_encode_options_for_avc.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_encoder_encode_options_for_vp9.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_encoder_support.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_frame.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_frame_buffer_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_frame_copy_to_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_frame_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_matrix_coefficients.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_pixel_format.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/video_transfer_characteristics.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webcodecs/webcodecs_error_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/database.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/sql_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/sql_result_set.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/sql_result_set_row_list.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/sql_statement_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/sql_statement_error_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/sql_transaction.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/sql_transaction_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/sql_transaction_error_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webdatabase/window_web_database.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/angle_instanced_arrays.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_blend_min_max.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_clip_control.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_color_buffer_float.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_color_buffer_half_float.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_conservative_depth.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_depth_clamp.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_disjoint_timer_query_webgl2.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_float_blend.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_frag_depth.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_polygon_offset_clamp.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_render_snorm.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_shader_texture_lod.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_srgb.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_texture_compression_bptc.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_texture_compression_rgtc.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_texture_mirror_clamp_to_edge.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ext_texture_norm_16.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/nv_shader_noperspective_interpolation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_element_index_uint.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_sample_variables.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_shader_multisample_interpolation.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_standard_derivatives.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_texture_float.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_texture_float_linear.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_texture_half_float.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_texture_half_float_linear.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/oes_vertex_array_object.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/ovr_multiview_2.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_active_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_blend_func_extended.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_clip_cull_distance.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_color_buffer_float.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_pvrtc.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_compressed_texture_s3tc_srgb.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_context_attributes.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_context_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_context_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_debug_renderer_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_debug_shaders.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_depth_texture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_draw_buffers.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_draw_instanced_base_vertex_base_instance.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_framebuffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_lose_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_multi_draw.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced_base_vertex_base_instance.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_object.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_polygon_mode.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_program.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_provoking_vertex.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_query.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_render_shared_exponent.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_renderbuffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_rendering_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_sampler.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_shader.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_shader_pixel_local_storage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_shader_precision_format.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_stencil_texturing.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_sync.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_texture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_timer_query_ext.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_transform_feedback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_uniform_location.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgl/webgl_vertex_array_object_oes.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_adapter.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_adapter_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_bind_group.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_bind_group_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_bind_group_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_bind_group_layout_entry.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_blend_component.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_blend_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_buffer_binding.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_buffer_binding_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_buffer_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_buffer_usage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_canvas_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_color_dict.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_color_state_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_color_target_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_color_write.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_command_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_command_buffer_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_command_encoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_command_encoder_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_compilation_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_compilation_message.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_encoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_compute_pass_timestamp_writes.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_compute_pipeline_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_depth_stencil_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_device.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_device_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_device_lost_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_extent_3d_dict.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_external_texture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_external_texture_binding_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_external_texture_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_fence_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_fragment_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_heap_property.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_image_copy_buffer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_image_copy_external_image.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_image_copy_image_bitmap.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_image_copy_texture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_image_copy_texture_tagged.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_image_data_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_internal_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_map_mode.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_memory_heap_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_multisample_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_object_base.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_object_descriptor_base.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_origin_2d_dict.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_origin_3d_dict.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_out_of_memory_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_pipeline_base.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_pipeline_descriptor_base.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_pipeline_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_pipeline_layout_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_primitive_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_programmable_pass_encoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_programmable_stage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_query_set.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_query_set_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_queue.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_queue_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_rasterization_state_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_bundle.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_encoder_base.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_pass_color_attachment.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_pass_depth_stencil_attachment.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_pass_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_pass_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_pass_timestamp_writes.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_render_pipeline_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_request_adapter_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_sampler.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_sampler_binding_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_sampler_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_shader_module.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_shader_module_compilation_hint.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_shader_module_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_shader_stage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_stencil_face_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_storage_texture_binding_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_supported_features.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_supported_limits.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_texture.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_texture_binding_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_texture_usage.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_texture_view.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_texture_view_descriptor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_uncaptured_error_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_validation_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_vertex_attribute.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_vertex_buffer_layout.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/gpu_vertex_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/navigator_gpu.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/wgsl_language_features.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webgpu/worker_navigator_gpu.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_access.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_connection_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_connection_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_input.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_input_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_message_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_message_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_output.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_output_map.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/midi_port.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webmidi/navigator_web_midi.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webshare/navigator_share.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webshare/share_data.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/websockets/close_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/websockets/close_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/websockets/websocket.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/websockets/websocket_close_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/websockets/websocket_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/websockets/websocket_open_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/websockets/websocket_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/websockets/websocket_stream_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport_bidirectional_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport_close_info.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport_connection_stats.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport_datagram_duplex_stream.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport_datagram_stats.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport_error.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport_error_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport_hash.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webtransport/web_transport_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/navigator_usb.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_alternate_interface.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_configuration.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_connection_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_connection_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_control_transfer_parameters.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_device.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_device_filter.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_device_request_options.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_endpoint.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_in_transfer_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_interface.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_packet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_isochronous_in_transfer_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_packet.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_isochronous_out_transfer_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/usb_out_transfer_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/webusb/worker_navigator_usb.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/window_controls_overlay/navigator_window_controls_overlay.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/window_controls_overlay/window_controls_overlay.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/window_controls_overlay/window_controls_overlay_geometry_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/window_controls_overlay/window_controls_overlay_geometry_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/document_xr.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/html_element_xr.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/mathml_element_xr.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/navigator_xr.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/svg_element_xr.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/window_xr.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_anchor.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_anchor_set.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_camera.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_composition_layer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_cpu_depth_information.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_depth_information.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_depth_state_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_dom_overlay_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_dom_overlay_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_frame.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_frame_request_callback.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_hand.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_hit_test_options_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_hit_test_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_hit_test_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_image_tracking_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_input_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_input_source_array.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_input_source_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_input_source_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_input_sources_change_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_input_sources_change_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_joint_pose.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_joint_space.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_layer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_light_estimate.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_light_probe.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_light_probe_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_plane.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_plane_set.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_pose.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_projection_layer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_ray.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_ray_direction_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_reference_space.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_reference_space_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_reference_space_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_render_state.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_render_state_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_rigid_transform.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_session.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_session_event.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_session_event_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_session_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_space.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_sub_image.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_system.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_tracked_image_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_options_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_result.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_transient_input_hit_test_source.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_view.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_viewport.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_webgl_binding.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_webgl_context.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_webgl_depth_information.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_webgl_layer.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_webgl_layer_init.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/modules/xr/xr_webgl_sub_image.idl create mode 100755 tools/under-control/src/third_party/blink/renderer/platform/runtime_enabled_features.json5 create mode 100755 tools/under-control/src/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt diff --git a/tools/under-control/src/RELEASE b/tools/under-control/src/RELEASE index 40b6384ca..edec82baa 100644 --- a/tools/under-control/src/RELEASE +++ b/tools/under-control/src/RELEASE @@ -1 +1 @@ -128.0.6613.88 +128.0.6613.114 diff --git a/tools/under-control/src/android_webview/browser/aw_content_browser_client.cc b/tools/under-control/src/android_webview/browser/aw_content_browser_client.cc new file mode 100755 index 000000000..ac8518aef --- /dev/null +++ b/tools/under-control/src/android_webview/browser/aw_content_browser_client.cc @@ -0,0 +1,1419 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "android_webview/browser/aw_content_browser_client.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "android_webview/browser/aw_browser_context.h" +#include "android_webview/browser/aw_browser_context_store.h" +#include "android_webview/browser/aw_browser_main_parts.h" +#include "android_webview/browser/aw_browser_process.h" +#include "android_webview/browser/aw_client_hints_controller_delegate.h" +#include "android_webview/browser/aw_contents.h" +#include "android_webview/browser/aw_contents_client_bridge.h" +#include "android_webview/browser/aw_contents_io_thread_client.h" +#include "android_webview/browser/aw_cookie_access_policy.h" +#include "android_webview/browser/aw_devtools_manager_delegate.h" +#include "android_webview/browser/aw_feature_list_creator.h" +#include "android_webview/browser/aw_http_auth_handler.h" +#include "android_webview/browser/aw_settings.h" +#include "android_webview/browser/aw_speech_recognition_manager_delegate.h" +#include "android_webview/browser/aw_web_contents_view_delegate.h" +#include "android_webview/browser/cookie_manager.h" +#include "android_webview/browser/network_service/aw_browser_context_io_thread_handle.h" +#include "android_webview/browser/network_service/aw_proxy_config_monitor.h" +#include "android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h" +#include "android_webview/browser/network_service/aw_proxying_url_loader_factory.h" +#include "android_webview/browser/network_service/aw_url_loader_throttle.h" +#include "android_webview/browser/safe_browsing/aw_safe_browsing_navigation_throttle.h" +#include "android_webview/browser/safe_browsing/aw_url_checker_delegate_impl.h" +#include "android_webview/browser/supervised_user/aw_supervised_user_throttle.h" +#include "android_webview/browser/supervised_user/aw_supervised_user_url_classifier.h" +#include "android_webview/browser/tracing/aw_tracing_delegate.h" +#include "android_webview/common/aw_content_client.h" +#include "android_webview/common/aw_descriptors.h" +#include "android_webview/common/aw_features.h" +#include "android_webview/common/aw_paths.h" +#include "android_webview/common/aw_switches.h" +#include "android_webview/common/url_constants.h" +#include "base/android/build_info.h" +#include "base/android/locale_utils.h" +#include "base/base_paths_android.h" +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/containers/contains.h" +#include "base/feature_list.h" +#include "base/files/scoped_file.h" +#include "base/functional/bind.h" +#include "base/functional/callback.h" +#include "base/functional/callback_helpers.h" +#include "base/memory/ptr_util.h" +#include "base/memory/scoped_refptr.h" +#include "base/metrics/histogram_macros.h" +#include "base/notreached.h" +#include "base/path_service.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task/sequenced_task_runner.h" +#include "base/task/thread_pool/thread_pool_instance.h" +#include "base/trace_event/base_tracing.h" +#include "build/build_config.h" +#include "components/crash/content/browser/crash_handler_host_linux.h" +#include "components/embedder_support/origin_trials/origin_trials_settings_storage.h" +#include "components/embedder_support/switches.h" +#include "components/embedder_support/user_agent_utils.h" +#include "components/navigation_interception/intercept_navigation_delegate.h" +#include "components/page_load_metrics/browser/metrics_navigation_throttle.h" +#include "components/page_load_metrics/browser/metrics_web_contents_observer.h" +#include "components/policy/content/policy_blocklist_navigation_throttle.h" +#include "components/policy/core/browser/browser_policy_connector_base.h" +#include "components/prefs/pref_service.h" +#include "components/safe_browsing/content/browser/async_check_tracker.h" +#include "components/safe_browsing/content/browser/browser_url_loader_throttle.h" +#include "components/safe_browsing/content/browser/mojo_safe_browsing_impl.h" +#include "components/safe_browsing/core/common/features.h" +#include "components/safe_browsing/core/common/hashprefix_realtime/hash_realtime_utils.h" +#include "components/url_matcher/url_matcher.h" +#include "components/url_matcher/url_util.h" +#include "components/version_info/version_info.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/client_certificate_delegate.h" +#include "content/public/browser/file_url_loader.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/navigation_throttle.h" +#include "content/public/browser/network_service_instance.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/shared_cors_origin_access_list.h" +#include "content/public/browser/site_isolation_policy.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_descriptors.h" +#include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/url_constants.h" +#include "content/public/common/user_agent.h" +#include "mojo/public/cpp/bindings/pending_associated_receiver.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "net/android/network_library.h" +#include "net/cookies/site_for_cookies.h" +#include "net/http/http_util.h" +#include "net/net_buildflags.h" +#include "net/ssl/ssl_cert_request_info.h" +#include "net/ssl/ssl_info.h" +#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" +#include "services/metrics/public/cpp/ukm_source_id.h" +#include "services/network/network_service.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/url_loader_factory_builder.h" +#include "services/network/public/mojom/cookie_manager.mojom-forward.h" +#include "services/network/public/mojom/fetch_api.mojom.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/service_manager/public/cpp/binder_registry.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" +#include "third_party/blink/public/common/loader/url_loader_throttle.h" +#include "third_party/blink/public/common/web_preferences/web_preferences.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/resource/resource_bundle_android.h" +#include "ui/display/util/display_util.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/resources/grit/ui_resources.h" + +using content::BrowserThread; +using content::WebContents; +using safe_browsing::AsyncCheckTracker; +using safe_browsing::hash_realtime_utils::HashRealTimeSelection; +using AttributionReportingOsRegistrar = + content::ContentBrowserClient::AttributionReportingOsRegistrar; + +namespace android_webview { +namespace { +#if DCHECK_IS_ON() +// A boolean value to determine if the NetworkContext has been created yet. This +// exists only to check correctness: g_check_cleartext_permitted may only be set +// before the NetworkContext has been created (otherwise, +// g_check_cleartext_permitted won't have any effect). +bool g_created_network_context_params = false; +#endif + +// On apps targeting API level O or later, check cleartext is enforced. +bool g_check_cleartext_permitted = false; + +BASE_FEATURE(kWebViewOptimizeXrwNavigationFlow, + "WebViewOptimizeXrwNavigationFlow", + base::FEATURE_DISABLED_BY_DEFAULT); + +// A throttle which checks if the XRW origin trial is enabled for this +// navigation, and forwards it to the proxying loader factory. +class XrwNavigationThrottle : public content::NavigationThrottle { + public: + explicit XrwNavigationThrottle(content::NavigationHandle* handle) + : NavigationThrottle(handle) {} + ~XrwNavigationThrottle() override { + AwProxyingURLLoaderFactory::ClearXrwResultForNavigation( + navigation_handle()->GetNavigationId()); + } + + ThrottleCheckResult WillStartRequest() override { + auto* handle = navigation_handle(); + AwProxyingURLLoaderFactory::SetXrwResultForNavigation( + handle->GetURL(), + handle->IsInOutermostMainFrame() + ? blink::mojom::ResourceType::kMainFrame + : blink::mojom::ResourceType::kSubFrame, + handle->GetFrameTreeNodeId(), handle->GetNavigationId()); + return content::NavigationThrottle::PROCEED; + } + + const char* GetNameForLogging() override { return "XrwNavigationThrottle"; } +}; + +// Get async check tracker to make Safe Browsing v5 check asynchronous +base::WeakPtr GetAsyncCheckTracker( + const base::RepeatingCallback& wc_getter, + int frame_tree_node_id) { + if (!base::FeatureList::IsEnabled( + safe_browsing::kSafeBrowsingAsyncRealTimeCheck)) { + return nullptr; + } + content::WebContents* web_contents = wc_getter.Run(); + // Check whether current frame is a pre-rendered frame. WebView does not + // support NoStatePrefetch, so we do not check for that. + if (web_contents == nullptr || + web_contents->IsPrerenderedFrame(frame_tree_node_id)) { + return nullptr; + } + + return AsyncCheckTracker::GetOrCreateForWebContents( + web_contents, + AwBrowserProcess::GetInstance()->GetSafeBrowsingUIManager()) + ->GetWeakPtr(); +} + +} // anonymous namespace + +std::string GetProduct() { + return embedder_support::GetProductAndVersion(); +} + +std::string GetUserAgent() { + // "Version/4.0" had been hardcoded in the legacy WebView. + std::string product = "Version/4.0 " + GetProduct(); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kUseMobileUserAgent)) { + product += " Mobile"; + } + + if (base::FeatureList::IsEnabled( + features::kWebViewReduceUAAndroidVersionDeviceModel)) { + return content::BuildUnifiedPlatformUAFromProductAndExtraOs(product, + "; wv"); + } + + return content::BuildUserAgentFromProductAndExtraOSInfo( + product, "; wv", content::IncludeAndroidBuildNumber::Include); +} + +// TODO(yirui): can use similar logic as in PrependToAcceptLanguagesIfNecessary +// in chrome/browser/android/preferences/pref_service_bridge.cc +// static +std::string AwContentBrowserClient::GetAcceptLangsImpl() { + // Start with the current locale(s) in BCP47 format. + std::string locales_string = AwContents::GetLocaleList(); + + // If accept languages do not contain en-US, add in en-US which will be + // used with a lower q-value. + if (!base::Contains(locales_string, "en-US")) { + locales_string += ",en-US"; + } + return locales_string; +} + +// static +void AwContentBrowserClient::set_check_cleartext_permitted(bool permitted) { +#if DCHECK_IS_ON() + DCHECK(!g_created_network_context_params); +#endif + g_check_cleartext_permitted = permitted; +} + +// static +bool AwContentBrowserClient::get_check_cleartext_permitted() { + return g_check_cleartext_permitted; +} + +AwContentBrowserClient::AwContentBrowserClient( + AwFeatureListCreator* aw_feature_list_creator) + : sniff_file_urls_(AwSettings::GetAllowSniffingFileUrls()), + aw_feature_list_creator_(aw_feature_list_creator) { + // |aw_feature_list_creator| should not be null. The AwBrowserContext will + // take the PrefService owned by the creator as the Local State instead + // of loading the JSON file from disk. + DCHECK(aw_feature_list_creator_); +} + +AwContentBrowserClient::~AwContentBrowserClient() {} + +void AwContentBrowserClient::OnNetworkServiceCreated( + network::mojom::NetworkService* network_service) { + // TODO(crbug.com/40693524): If CertVerifierServiceFactory is moved to + // a separate process, this will likely need to be set somewhere else instead + // of here. + content::GetCertVerifierServiceFactory()->SetUseChromeRootStore( + false, base::DoNothing()); + + content::GetNetworkService()->SetUpHttpAuth( + network::mojom::HttpAuthStaticParams::New()); + content::GetNetworkService()->ConfigureHttpAuthPrefs( + AwBrowserProcess::GetInstance()->CreateHttpAuthDynamicParams()); + if (base::FeatureList::IsEnabled(features::kWebViewAsyncDns)) { + content::GetNetworkService()->ConfigureStubHostResolver( + /*insecure_dns_client_enabled=*/true, net::SecureDnsMode::kAutomatic, + net::DnsOverHttpsConfig(), + /*additional_dns_types_enabled=*/true); + } +} + +void AwContentBrowserClient::ConfigureNetworkContextParams( + content::BrowserContext* context, + bool in_memory, + const base::FilePath& relative_partition_path, + network::mojom::NetworkContextParams* network_context_params, + cert_verifier::mojom::CertVerifierCreationParams* + cert_verifier_creation_params) { + DCHECK(context); + + content::GetNetworkService()->ConfigureHttpAuthPrefs( + AwBrowserProcess::GetInstance()->CreateHttpAuthDynamicParams()); + + AwBrowserContext* aw_context = static_cast(context); + aw_context->ConfigureNetworkContextParams(in_memory, relative_partition_path, + network_context_params, + cert_verifier_creation_params); + + mojo::PendingRemote cookie_manager_remote; + network_context_params->cookie_manager = + cookie_manager_remote.InitWithNewPipeAndPassReceiver(); + +#if DCHECK_IS_ON() + g_created_network_context_params = true; +#endif + + // Pass the mojo::PendingRemote to + // android_webview::CookieManager, so it can implement its APIs with this mojo + // CookieManager. + aw_context->GetCookieManager()->SetMojoCookieManager( + std::move(cookie_manager_remote)); +} + +AwBrowserContext* AwContentBrowserClient::InitBrowserContext() { + return AwBrowserContextStore::GetOrCreateInstance()->GetDefault(); +} + +std::unique_ptr +AwContentBrowserClient::CreateBrowserMainParts(bool /* is_integration_test */) { + return std::make_unique(this); +} + +std::unique_ptr +AwContentBrowserClient::GetWebContentsViewDelegate( + content::WebContents* web_contents) { + return std::make_unique(web_contents); +} + +void AwContentBrowserClient::RenderProcessWillLaunch( + content::RenderProcessHost* host) { + // Grant content: scheme access to the whole renderer process, since we impose + // per-view access checks, and access is granted by default (see + // AwSettings.mAllowContentUrlAccess). + content::ChildProcessSecurityPolicy::GetInstance()->GrantRequestScheme( + host->GetID(), url::kContentScheme); +} + +bool AwContentBrowserClient::IsExplicitNavigation( + ui::PageTransition transition) { + return ui::PageTransitionCoreTypeIs(transition, ui::PAGE_TRANSITION_TYPED); +} + +bool AwContentBrowserClient::IsHandledURL(const GURL& url) { + if (!url.is_valid()) { + // We handle error cases. + return true; + } + + const std::string scheme = url.scheme(); + DCHECK_EQ(scheme, base::ToLowerASCII(scheme)); + static const char* const kProtocolList[] = { + url::kHttpScheme, + url::kHttpsScheme, +#if BUILDFLAG(ENABLE_WEBSOCKETS) + url::kWsScheme, + url::kWssScheme, +#endif // BUILDFLAG(ENABLE_WEBSOCKETS) + url::kDataScheme, + url::kBlobScheme, + url::kFileSystemScheme, + content::kChromeUIScheme, + url::kContentScheme, + }; + if (scheme == url::kFileScheme) { + // Return false for the "special" file URLs, so they can be loaded + // even if access to file: scheme is not granted to the child process. + return !IsAndroidSpecialFileUrl(url); + } + for (const char* supported_protocol : kProtocolList) { + if (scheme == supported_protocol) { + return true; + } + } + return false; +} + +bool AwContentBrowserClient::ForceSniffingFileUrlsForHtml() { + return sniff_file_urls_; +} + +void AwContentBrowserClient::AppendExtraCommandLineSwitches( + base::CommandLine* command_line, + int child_process_id) { + if (!command_line->HasSwitch(switches::kSingleProcess)) { + // The only kind of a child process WebView can have is renderer or utility. + std::string process_type = + command_line->GetSwitchValueASCII(switches::kProcessType); + DCHECK(process_type == switches::kRendererProcess || + process_type == switches::kUtilityProcess) + << process_type; + + static const char* const kSwitchNames[] = { + ::switches::kEnableCrashReporter, + ::switches::kEnableCrashReporterForTesting, + embedder_support::kOriginTrialDisabledFeatures, + embedder_support::kOriginTrialPublicKey, + }; + + command_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(), + kSwitchNames); + } +} + +std::string AwContentBrowserClient::GetApplicationLocale() { + return base::android::GetDefaultLocaleString(); +} + +std::string AwContentBrowserClient::GetAcceptLangs( + content::BrowserContext* context) { + return GetAcceptLangsImpl(); +} + +gfx::ImageSkia AwContentBrowserClient::GetDefaultFavicon() { + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + // TODO(boliu): Bundle our own default favicon? + return rb.GetImageNamed(IDR_DEFAULT_FAVICON).AsImageSkia(); +} + +content::GeneratedCodeCacheSettings +AwContentBrowserClient::GetGeneratedCodeCacheSettings( + content::BrowserContext* context) { + // WebView limits the main HTTP cache to 20MB; we need to set a comparable + // limit for the code cache since the source file needs to be in the HTTP + // cache for the code cache entry to be used. There are two code caches that + // both use this value, so we pass 10MB to keep the total disk usage to + // roughly 2x what it was before the code cache was implemented. + // TODO(crbug.com/41419561): webview should have smarter cache sizing logic. + AwBrowserContext* browser_context = static_cast(context); + return content::GeneratedCodeCacheSettings( + true, 10 * 1024 * 1024, browser_context->GetHttpCachePath()); +} + +void AwContentBrowserClient::AllowCertificateError( + content::WebContents* web_contents, + int cert_error, + const net::SSLInfo& ssl_info, + const GURL& request_url, + bool is_primary_main_frame_request, + bool strict_enforcement, + base::OnceCallback callback) { + AwContentsClientBridge* client = + AwContentsClientBridge::FromWebContents(web_contents); + bool cancel_request = true; + // We only call the callback once but we must pass ownership to a function + // that conditionally calls it. + auto split_callback = base::SplitOnceCallback(std::move(callback)); + if (client) { + client->AllowCertificateError(cert_error, ssl_info.cert.get(), request_url, + std::move(split_callback.first), + &cancel_request); + } + if (cancel_request) { + std::move(split_callback.second) + .Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY); + } +} + +base::OnceClosure AwContentBrowserClient::SelectClientCertificate( + content::BrowserContext* browser_context, + int process_id, + content::WebContents* web_contents, + net::SSLCertRequestInfo* cert_request_info, + net::ClientCertIdentityList client_certs, + std::unique_ptr delegate) { + AwContentsClientBridge* client = + web_contents ? AwContentsClientBridge::FromWebContents(web_contents) + : nullptr; + if (client) { + client->SelectClientCertificate(cert_request_info, std::move(delegate)); + } + return base::OnceClosure(); +} + +bool AwContentBrowserClient::CanCreateWindow( + content::RenderFrameHost* opener, + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const url::Origin& source_origin, + content::mojom::WindowContainerType container_type, + const GURL& target_url, + const content::Referrer& referrer, + const std::string& frame_name, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + bool* no_javascript_access) { + // We unconditionally allow popup windows at this stage and will give + // the embedder the opporunity to handle displaying of the popup in + // WebContentsDelegate::AddContents (via the + // AwContentsClient.onCreateWindow callback). + // Note that if the embedder has blocked support for creating popup + // windows through AwSettings, then we won't get to this point as + // the popup creation will have been blocked at the WebKit level. + if (no_javascript_access) { + *no_javascript_access = false; + } + + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(opener); + AwSettings* settings = AwSettings::FromWebContents(web_contents); + + return (settings && settings->GetJavaScriptCanOpenWindowsAutomatically()) || + user_gesture; +} + +base::FilePath AwContentBrowserClient::GetDefaultDownloadDirectory() { + // Android WebView does not currently use the Chromium downloads system. + // Download requests are cancelled immediately when recognized. However the + // download system still tries to start up and calls this before recognizing + // the request has been cancelled. + return base::FilePath(); +} + +std::string AwContentBrowserClient::GetDefaultDownloadName() { + NOTREACHED_IN_MIGRATION() + << "Android WebView does not use chromium downloads"; + return std::string(); +} + +std::optional +AwContentBrowserClient::GetLocalTracesDirectory() { + base::FilePath user_data_dir; + if (!base::PathService::Get(android_webview::DIR_LOCAL_TRACES, + &user_data_dir)) { + return std::nullopt; + } + DCHECK(!user_data_dir.empty()); + return user_data_dir; +} + +void AwContentBrowserClient::DidCreatePpapiPlugin( + content::BrowserPpapiHost* browser_host) { + NOTREACHED_IN_MIGRATION() << "Android WebView does not support plugins"; +} + +bool AwContentBrowserClient::AllowPepperSocketAPI( + content::BrowserContext* browser_context, + const GURL& url, + bool private_api, + const content::SocketPermissionRequest* params) { + NOTREACHED_IN_MIGRATION() << "Android WebView does not support plugins"; + return false; +} + +bool AwContentBrowserClient::IsPepperVpnProviderAPIAllowed( + content::BrowserContext* browser_context, + const GURL& url) { + NOTREACHED_IN_MIGRATION() << "Android WebView does not support plugins"; + return false; +} + +std::unique_ptr +AwContentBrowserClient::CreateTracingDelegate() { + return std::make_unique(); +} + +void AwContentBrowserClient::GetAdditionalMappedFilesForChildProcess( + const base::CommandLine& command_line, + int child_process_id, + content::PosixFileDescriptorInfo* mappings) { + base::MemoryMappedFile::Region region; + int fd = ui::GetMainAndroidPackFd(®ion); + if (base::FeatureList::IsEnabled(features::kWebViewCheckPakFileDescriptors)) { + CHECK_GE(fd, 0); + } + mappings->ShareWithRegion(kAndroidWebViewMainPakDescriptor, fd, region); + + fd = ui::GetCommonResourcesPackFd(®ion); + if (base::FeatureList::IsEnabled(features::kWebViewCheckPakFileDescriptors)) { + CHECK_GE(fd, 0); + } + mappings->ShareWithRegion(kAndroidWebView100PercentPakDescriptor, fd, region); + + fd = ui::GetLocalePackFd(®ion); + if (base::FeatureList::IsEnabled(features::kWebViewCheckPakFileDescriptors)) { + CHECK_GE(fd, 0); + } + mappings->ShareWithRegion(kAndroidWebViewLocalePakDescriptor, fd, region); + + int crash_signal_fd = + crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket(); + if (crash_signal_fd >= 0) { + mappings->Share(kCrashDumpSignal, crash_signal_fd); + } +} + +void AwContentBrowserClient::OverrideWebkitPrefs( + content::WebContents* web_contents, + blink::web_pref::WebPreferences* web_prefs) { + AwSettings* aw_settings = AwSettings::FromWebContents(web_contents); + if (aw_settings) { + aw_settings->PopulateWebPreferences(web_prefs); + } + web_prefs->modal_context_menu = + !base::FeatureList::IsEnabled(features::kWebViewImageDrag); +} + +std::vector> +AwContentBrowserClient::CreateThrottlesForNavigation( + content::NavigationHandle* navigation_handle) { + std::vector> throttles; + // We allow intercepting only navigations within main frames. This + // is used to post onPageStarted. We handle shouldOverrideUrlLoading + // via a sync IPC. + if (navigation_handle->IsInMainFrame()) { + // MetricsNavigationThrottle requires that it runs before + // NavigationThrottles that may delay or cancel navigations, so only + // NavigationThrottles that don't delay or cancel navigations (e.g. + // throttles that are only observing callbacks without affecting navigation + // behavior) should be added before MetricsNavigationThrottle. + throttles.push_back(page_load_metrics::MetricsNavigationThrottle::Create( + navigation_handle)); + } + // Use Synchronous mode for the navigation interceptor, since this class + // doesn't actually call into an arbitrary client, it just posts a task to + // call onPageStarted. shouldOverrideUrlLoading happens earlier (see + // ContentBrowserClient::ShouldOverrideUrlLoading). + std::unique_ptr intercept_navigation_throttle = + navigation_interception::InterceptNavigationDelegate:: + MaybeCreateThrottleFor(navigation_handle, + navigation_interception::SynchronyMode::kSync); + if (intercept_navigation_throttle) { + throttles.push_back(std::move(intercept_navigation_throttle)); + } + + throttles.push_back(std::make_unique( + navigation_handle, + AwBrowserContext::FromWebContents(navigation_handle->GetWebContents()))); + + std::unique_ptr safe_browsing_throttle = + AwSafeBrowsingNavigationThrottle::MaybeCreateThrottleFor( + navigation_handle); + if (safe_browsing_throttle) { + throttles.push_back(std::move(safe_browsing_throttle)); + } + if (base::FeatureList::IsEnabled(kWebViewOptimizeXrwNavigationFlow)) { + throttles.push_back( + std::make_unique(navigation_handle)); + } + return throttles; +} + +std::unique_ptr +AwContentBrowserClient::CreateDevToolsManagerDelegate() { + return std::make_unique(); +} + +std::vector> +AwContentBrowserClient::CreateURLLoaderThrottles( + const network::ResourceRequest& request, + content::BrowserContext* browser_context, + const base::RepeatingCallback& wc_getter, + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id, + std::optional navigation_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + // Set lookup mechanism based on feature flag + HashRealTimeSelection hash_real_time_selection; + base::WeakPtr async_check_tracker; + if (base::FeatureList::IsEnabled(safe_browsing::kHashPrefixRealTimeLookups)) { + hash_real_time_selection = HashRealTimeSelection::kDatabaseManager; + async_check_tracker = GetAsyncCheckTracker(wc_getter, frame_tree_node_id); + } else { + hash_real_time_selection = HashRealTimeSelection::kNone; + async_check_tracker = nullptr; + } + + std::vector> result; + result.push_back(safe_browsing::BrowserURLLoaderThrottle::Create( + base::BindRepeating( + [](AwContentBrowserClient* client) { + return client->GetSafeBrowsingUrlCheckerDelegate(); + }, + base::Unretained(this)), + wc_getter, frame_tree_node_id, navigation_id, + // TODO(crbug.com/40663467): rt_lookup_service is + // used to perform real time URL check, which is gated by UKM opted-in. + // Since AW currently doesn't support UKM, this feature is not enabled. + /* rt_lookup_service */ nullptr, + /* hash_realtime_service */ nullptr, + /* hash_realtime_selection */ + hash_real_time_selection, + /* async_check_tracker */ async_check_tracker)); + + if (request.destination == network::mojom::RequestDestination::kDocument) { + const bool is_load_url = + request.transition_type & ui::PAGE_TRANSITION_FROM_API; + const bool is_go_back_forward = + request.transition_type & ui::PAGE_TRANSITION_FORWARD_BACK; + const bool is_reload = ui::PageTransitionCoreTypeIs( + static_cast(request.transition_type), + ui::PAGE_TRANSITION_RELOAD); + if (is_load_url || is_go_back_forward || is_reload) { + result.push_back(std::make_unique( + static_cast(browser_context))); + } + } + + if ((request.destination == network::mojom::RequestDestination::kDocument || + request.destination == network::mojom::RequestDestination::kIframe) && + request.url.SchemeIsHTTPOrHTTPS()) { + AwSupervisedUserUrlClassifier* urlClassifier = + AwSupervisedUserUrlClassifier::GetInstance(); + if (urlClassifier->ShouldCreateThrottle()) { + result.push_back( + std::make_unique(urlClassifier)); + } + } + + return result; +} + +std::vector> +AwContentBrowserClient::CreateURLLoaderThrottlesForKeepAlive( + const network::ResourceRequest& request, + content::BrowserContext* browser_context, + const base::RepeatingCallback& wc_getter, + int frame_tree_node_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Set lookup mechanism based on feature flag + HashRealTimeSelection hash_real_time_selection = + (base::FeatureList::IsEnabled(safe_browsing::kHashPrefixRealTimeLookups)) + ? HashRealTimeSelection::kDatabaseManager + : HashRealTimeSelection::kNone; + + std::vector> result; + + result.push_back(safe_browsing::BrowserURLLoaderThrottle::Create( + base::BindRepeating( + [](AwContentBrowserClient* client) { + return client->GetSafeBrowsingUrlCheckerDelegate(); + }, + base::Unretained(this)), + wc_getter, frame_tree_node_id, /*navigation_id=*/std::nullopt, + // TODO(crbug.com/40663467): rt_lookup_service is + // used to perform real time URL check, which is gated by UKM opted-in. + // Since AW currently doesn't support UKM, this feature is not enabled. + /* rt_lookup_service */ nullptr, + /* hash_realtime_service */ nullptr, + /* hash_realtime_selection */ + hash_real_time_selection, + /* async_check_tracker */ nullptr)); + + return result; +} + +scoped_refptr +AwContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (!safe_browsing_url_checker_delegate_) { + safe_browsing_url_checker_delegate_ = new AwUrlCheckerDelegateImpl( + AwBrowserProcess::GetInstance()->GetSafeBrowsingDBManager(), + AwBrowserProcess::GetInstance()->GetSafeBrowsingUIManager(), + AwBrowserProcess::GetInstance()->GetSafeBrowsingAllowlistManager()); + } + + return safe_browsing_url_checker_delegate_; +} + +bool AwContentBrowserClient::ShouldOverrideUrlLoading( + int frame_tree_node_id, + bool browser_initiated, + const GURL& gurl, + const std::string& request_method, + bool has_user_gesture, + bool is_redirect, + bool is_outermost_main_frame, + bool is_prerendering, + ui::PageTransition transition, + bool* ignore_navigation) { + *ignore_navigation = false; + + // Only GETs can be overridden. + if (request_method != "GET") { + return true; + } + + bool application_initiated = + browser_initiated || transition & ui::PAGE_TRANSITION_FORWARD_BACK; + + // Don't offer application-initiated navigations unless it's a redirect. + if (application_initiated && !is_redirect) { + return true; + } + + // For HTTP schemes, only top-level navigations can be overridden. Similarly, + // WebView Classic lets app override only top level about:blank navigations. + // So we filter out non-top about:blank navigations here. + // + // Note: about:blank navigations are not received in this path at the moment, + // they use the old SYNC IPC path as they are not handled by network stack. + // However, the old path should be removed in future. + if (!is_outermost_main_frame && + (gurl.SchemeIs(url::kHttpScheme) || gurl.SchemeIs(url::kHttpsScheme) || + gurl.SchemeIs(url::kAboutScheme))) { + return true; + } + + WebContents* web_contents = + WebContents::FromFrameTreeNodeId(frame_tree_node_id); + if (web_contents == nullptr) { + return true; + } + AwContentsClientBridge* client_bridge = + AwContentsClientBridge::FromWebContents(web_contents); + if (client_bridge == nullptr) { + return true; + } + + std::u16string url = base::UTF8ToUTF16(gurl.possibly_invalid_spec()); + + AwSettings* aw_settings = AwSettings::FromWebContents(web_contents); + if ((gurl.SchemeIs(url::kHttpScheme) || gurl.SchemeIs(url::kHttpsScheme)) && + aw_settings->enterprise_authentication_app_link_policy_enabled() && + android_webview::AwBrowserProcess::GetInstance() + ->GetEnterpriseAuthenticationAppLinkManager() + ->IsEnterpriseAuthenticationUrl(gurl)) { + bool success = client_bridge->SendBrowseIntent(url); + if (success) { + *ignore_navigation = true; + return true; + } + } + + net::HttpRequestHeaders request_headers; + if (is_prerendering) { + // We pass the `Sec-Purpose` header to tell the embedder that the navigation + // is for prerendering, within the existing API surface. + request_headers.SetHeader("Sec-Purpose", "prefetch;prerender"); + } + + return client_bridge->ShouldOverrideUrlLoading( + url, has_user_gesture, is_redirect, is_outermost_main_frame, + request_headers, ignore_navigation); +} + +std::unique_ptr +AwContentBrowserClient::CreateLoginDelegate( + const net::AuthChallengeInfo& auth_info, + content::WebContents* web_contents, + content::BrowserContext* browser_context, + const content::GlobalRequestID& request_id, + bool is_request_for_primary_main_frame, + const GURL& url, + scoped_refptr response_headers, + bool first_auth_attempt, + LoginAuthRequiredCallback auth_required_callback) { + return std::make_unique(auth_info, web_contents, + first_auth_attempt, + std::move(auth_required_callback)); +} + +bool AwContentBrowserClient::HandleExternalProtocol( + const GURL& url, + content::WebContents::Getter wc_getter, + int frame_tree_node_id, + content::NavigationUIData* navigation_data, + bool is_primary_main_frame, + bool /* is_in_fenced_frame_tree */, + network::mojom::WebSandboxFlags /*sandbox_flags*/, + ui::PageTransition page_transition, + bool has_user_gesture, + const std::optional& initiating_origin, + content::RenderFrameHost* initiator_document, + mojo::PendingRemote* out_factory) { + // Sandbox flags + // ============= + // + // Contrary to the chrome/ implementation, sandbox flags are ignored. Webview + // by itself to not invoke external apps. However it let the embedding + // app to intercept the request and decide what to do. We need to be careful + // here not breaking applications, so the sandbox flags are ignored. + + mojo::PendingReceiver receiver = + out_factory->InitWithNewPipeAndPassReceiver(); + + content::WebContents* web_contents = wc_getter.Run(); + scoped_refptr browser_context_handle = + web_contents == nullptr + ? nullptr + : base::MakeRefCounted( + static_cast( + web_contents->GetBrowserContext())); + + // We don't need to care for |security_options| as the factories constructed + // below are used only for navigation. + // We also don't care about retrieving cookies in this case because these will + // be schemes unrelated to the regular network stack so it doesn't make sense + // to look for cookies. Providing a nullopt for the cookie manager lets + // the AwProxyingURLLoaderFactory know to skip that work. + if (content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) { + // Manages its own lifetime. + new android_webview::AwProxyingURLLoaderFactory( + std::nullopt /* cookie_manager */, nullptr /* cookie_access_policy */, + std::nullopt /* isolation_info*/, frame_tree_node_id, + std::move(receiver), mojo::NullRemote(), true /* intercept_only */, + std::nullopt /* security_options */, + nullptr /* xrw_allowlist_matcher */, std::move(browser_context_handle), + std::nullopt /* navigation_id */); + } else { + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce( + [](mojo::PendingReceiver receiver, + int frame_tree_node_id, + scoped_refptr + browser_context_handle) { + // Manages its own lifetime. + new android_webview::AwProxyingURLLoaderFactory( + std::nullopt /* cookie_manager */, + nullptr /* cookie_access_policy */, + std::nullopt /* isolation_info*/, frame_tree_node_id, + std::move(receiver), mojo::NullRemote(), + true /* intercept_only */, + std::nullopt /* security_options */, + nullptr /* xrw_allowlist_matcher */, + std::move(browser_context_handle), + std::nullopt /* navigation_id */); + }, + std::move(receiver), frame_tree_node_id, + std::move(browser_context_handle))); + } + return false; +} + +void AwContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories( + int render_process_id, + int render_frame_id, + const std::optional& request_initiator_origin, + NonNetworkURLLoaderFactoryMap* factories) { + WebContents* web_contents = content::WebContents::FromRenderFrameHost( + content::RenderFrameHost::FromID(render_process_id, render_frame_id)); + AwSettings* aw_settings = AwSettings::FromWebContents(web_contents); + + if (aw_settings && aw_settings->GetAllowFileAccess()) { + AwBrowserContext* aw_browser_context = + AwBrowserContext::FromWebContents(web_contents); + factories->emplace( + url::kFileScheme, + content::CreateFileURLLoaderFactory( + aw_browser_context->GetPath(), + aw_browser_context->GetSharedCorsOriginAccessList())); + } +} + +bool AwContentBrowserClient::ShouldAllowNoLongerUsedProcessToExit() { + // TODO(crbug.com/40803531): Add Android WebView support for allowing a + // renderer process to exit when only non-live RenderFrameHosts remain, + // without consulting the app's OnRenderProcessGone crash handlers. + return false; +} + +bool AwContentBrowserClient::ShouldIsolateErrorPage(bool in_main_frame) { + return false; +} + +bool AwContentBrowserClient::ShouldEnableStrictSiteIsolation() { + // TODO(lukasza): When/if we eventually add OOPIF support for AW we should + // consider running AW tests with and without site-per-process (and this might + // require returning true below). Adding OOPIF support for AW is tracked by + // https://crbug.com/806404. + return false; +} + +size_t AwContentBrowserClient::GetMaxRendererProcessCountOverride() { + // TODO(crbug.com/40560171): These options can currently can only be turned by + // by manually overriding command line switches because + // `ShouldDisableSiteIsolation` returns true. Should coordinate if/when + // enabling this in production. + if (content::SiteIsolationPolicy::UseDedicatedProcessesForAllSites() || + content::SiteIsolationPolicy::AreIsolatedOriginsEnabled() || + content::SiteIsolationPolicy::IsStrictOriginIsolationEnabled()) { + // Do not restrict the max renderer process count for these site isolation + // modes. This allows OOPIFs to happen on android webview. + return 0u; // Use default. + } + return 1u; +} + +bool AwContentBrowserClient::ShouldDisableSiteIsolation( + content::SiteIsolationMode site_isolation_mode) { + // Since AW does not yet support OOPIFs, we must return true here to disable + // features that may trigger OOPIFs, such as origin isolation. + // + // Adding OOPIF support for AW is tracked by https://crbug.com/806404. + return true; +} + +bool AwContentBrowserClient::ShouldLockProcessToSite( + content::BrowserContext* browser_context, + const GURL& effective_url) { + // TODO(lukasza): https://crbug.com/806404: Once Android WebView supports + // OOPIFs, we should remove this ShouldLockProcess overload. Till then, + // returning false helps avoid accidentally applying citadel-style Site + // Isolation enforcement to Android WebView (and causing incorrect renderer + // kills). + return false; +} + +bool AwContentBrowserClient::ShouldEnforceNewCanCommitUrlChecks() { + // TODO(https://crbug.com/326250356): Diagnose any remaining Android WebView + // crashes from these new checks and then remove this function. + return true; +} + +void AwContentBrowserClient::WillCreateURLLoaderFactory( + content::BrowserContext* browser_context, + content::RenderFrameHost* frame, + int render_process_id, + URLLoaderFactoryType type, + const url::Origin& request_initiator, + const net::IsolationInfo& isolation_info, + std::optional navigation_id, + ukm::SourceIdObj ukm_source_id, + network::URLLoaderFactoryBuilder& factory_builder, + mojo::PendingRemote* + header_client, + bool* bypass_redirect_checks, + bool* disable_secure_dns, + network::mojom::URLLoaderFactoryOverridePtr* factory_override, + scoped_refptr navigation_response_task_runner) { + TRACE_EVENT0("android_webview", + "AwContentBrowserClient::WillCreateURLLoaderFactory"); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + mojo::PendingReceiver proxied_receiver; + mojo::PendingRemote target_factory_remote; + + if (factory_override) { + // We are interested in factories "inside" of CORS, so use + // |factory_override|. + *factory_override = network::mojom::URLLoaderFactoryOverride::New(); + proxied_receiver = + (*factory_override) + ->overriding_factory.InitWithNewPipeAndPassReceiver(); + (*factory_override)->overridden_factory_receiver = + target_factory_remote.InitWithNewPipeAndPassReceiver(); + (*factory_override)->skip_cors_enabled_scheme_check = true; + } else { + // In this case, |factory_override| is not given. But all callers of + // ContentBrowserClient::WillCreateURLLoaderFactory guarantee that + // |factory_override| is null only when the security features on the network + // service is no-op for requests coming to the URLLoaderFactory. Hence we + // can use |factory_builder| here. + std::tie(proxied_receiver, target_factory_remote) = + factory_builder.Append(); + } + scoped_refptr browser_context_handle = + base::MakeRefCounted( + static_cast(browser_context)); + + mojo::PendingRemote cookie_manager; + browser_context->GetDefaultStoragePartition() + ->GetNetworkContext() + ->GetCookieManager(cookie_manager.InitWithNewPipeAndPassReceiver()); + + AwBrowserContext* aw_browser_context = + static_cast(browser_context); + AwCookieAccessPolicy* cookie_access_policy = + aw_browser_context->GetCookieManager()->cookie_access_policy(); + + if (frame) { + auto security_options = + std::make_optional(); + security_options->disable_web_security = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableWebSecurity); + WebContents* web_contents = WebContents::FromRenderFrameHost(frame); + const auto& preferences = web_contents->GetOrCreateWebPreferences(); + // See also //android_webview/docs/cors-and-webview-api.md to understand how + // each settings affect CORS behaviors on file:// and content://. + if (request_initiator.scheme() == url::kFileScheme) { + security_options->disable_web_security |= + preferences.allow_universal_access_from_file_urls; + // Usual file:// to file:// requests are mapped to kNoCors if the setting + // is set to true. Howover, file:///android_{asset|res}/ still uses kCors + // and needs to permit it in the |security_options|. + security_options->allow_cors_to_same_scheme = + preferences.allow_file_access_from_file_urls; + } else if (request_initiator.scheme() == url::kContentScheme) { + security_options->allow_cors_to_same_scheme = + preferences.allow_file_access_from_file_urls || + preferences.allow_universal_access_from_file_urls; + } + + auto xrw_allowlist_matcher = + AwSettings::FromWebContents(web_contents)->xrw_allowlist_matcher(); + + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce( + &AwProxyingURLLoaderFactory::CreateProxy, std::move(cookie_manager), + cookie_access_policy, isolation_info, frame->GetFrameTreeNodeId(), + std::move(proxied_receiver), std::move(target_factory_remote), + security_options, std::move(xrw_allowlist_matcher), + std::move(browser_context_handle), navigation_id)); + } else { + // A service worker and worker subresources set nullptr to |frame|, and + // work without seeing the AllowUniversalAccessFromFileURLs setting. So, + // we don't pass a valid |security_options| here. + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce( + &AwProxyingURLLoaderFactory::CreateProxy, std::move(cookie_manager), + cookie_access_policy, isolation_info, + content::RenderFrameHost::kNoFrameTreeNodeId, + std::move(proxied_receiver), std::move(target_factory_remote), + std::nullopt /* security_options */, + aw_browser_context->service_worker_xrw_allowlist_matcher(), + std::move(browser_context_handle), navigation_id)); + } +} + +uint32_t AwContentBrowserClient::GetWebSocketOptions( + content::RenderFrameHost* frame) { + uint32_t options = network::mojom::kWebSocketOptionNone; + if (!frame) { + return options; + } + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(frame); + AwContents* aw_contents = AwContents::FromWebContents(web_contents); + AwBrowserContext* aw_context = + AwBrowserContext::FromWebContents(web_contents); + + bool global_cookie_policy = aw_context->GetCookieManager() + ->cookie_access_policy() + ->GetShouldAcceptCookies(); + bool third_party_cookie_policy = aw_contents->AllowThirdPartyCookies(); + if (!global_cookie_policy) { + options |= network::mojom::kWebSocketOptionBlockAllCookies; + } else if (!third_party_cookie_policy) { + options |= network::mojom::kWebSocketOptionBlockThirdPartyCookies; + } + return options; +} + +bool AwContentBrowserClient::WillCreateRestrictedCookieManager( + network::mojom::RestrictedCookieManagerRole role, + content::BrowserContext* browser_context, + const url::Origin& origin, + const net::IsolationInfo& isolation_info, + bool is_service_worker, + int process_id, + int routing_id, + mojo::PendingReceiver* receiver) { + mojo::PendingReceiver orig_receiver = + std::move(*receiver); + + mojo::PendingRemote + target_rcm_remote; + *receiver = target_rcm_remote.InitWithNewPipeAndPassReceiver(); + + AwBrowserContext* aw_context = + static_cast(browser_context); + AwCookieAccessPolicy* aw_cookie_access_policy = + aw_context->GetCookieManager()->cookie_access_policy(); + + AwProxyingRestrictedCookieManager::CreateAndBind( + std::move(target_rcm_remote), is_service_worker, process_id, routing_id, + std::move(orig_receiver), aw_cookie_access_policy); + + return false; // only made a proxy, still need the actual impl to be made. +} + +std::string AwContentBrowserClient::GetProduct() { + // Return the unreduced product version regardless of the user agent reduction + // policy. The call sites do not require user agent reduction and having the + // unreduced version is necessary for performance tracing. + if (base::FeatureList::IsEnabled(features::kWebViewUnreducedProductVersion)) { + return std::string(version_info::GetProductNameAndVersionForUserAgent()); + } + return android_webview::GetProduct(); +} + +std::string AwContentBrowserClient::GetUserAgent() { + return android_webview::GetUserAgent(); +} + +blink::UserAgentMetadata AwContentBrowserClient::GetUserAgentMetadata() { + return AwClientHintsControllerDelegate::GetUserAgentMetadataOverrideBrand(); +} + +content::ContentBrowserClient::WideColorGamutHeuristic +AwContentBrowserClient::GetWideColorGamutHeuristic() { + if (base::FeatureList::IsEnabled(features::kWebViewWideColorGamutSupport)) { + return WideColorGamutHeuristic::kUseWindow; + } + + if (display::HasForceDisplayColorProfile() && + display::GetForcedDisplayColorProfile() == + gfx::ColorSpace::CreateDisplayP3D65()) { + return WideColorGamutHeuristic::kUseWindow; + } + + return WideColorGamutHeuristic::kNone; +} + +void AwContentBrowserClient::LogWebFeatureForCurrentPage( + content::RenderFrameHost* render_frame_host, + blink::mojom::WebFeature feature) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage( + render_frame_host, feature); +} + +void AwContentBrowserClient::LogWebDXFeatureForCurrentPage( + content::RenderFrameHost* render_frame_host, + blink::mojom::WebDXFeature feature) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage( + render_frame_host, feature); +} + +content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride +AwContentBrowserClient::ShouldOverridePrivateNetworkRequestPolicy( + content::BrowserContext* browser_context, + const url::Origin& origin) { + // Webview does not implement support for deprecation trials, so webview apps + // broken by Private Network Access restrictions cannot help themselves by + // registering for the trial. + // See crbug.com/1255675. + return content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride:: + kForceAllow; +} + +content::SpeechRecognitionManagerDelegate* +AwContentBrowserClient::CreateSpeechRecognitionManagerDelegate() { + return new AwSpeechRecognitionManagerDelegate(); +} + +bool AwContentBrowserClient::HasErrorPage(int http_status_code) { + return http_status_code >= 400; +} + +bool AwContentBrowserClient::SuppressDifferentOriginSubframeJSDialogs( + content::BrowserContext* browser_context) { + return base::FeatureList::IsEnabled( + features::kWebViewSuppressDifferentOriginSubframeJSDialogs); +} + +bool AwContentBrowserClient::ShouldPreconnectNavigation( + content::RenderFrameHost* render_frame_host) { + // This didn't make a performance improvement in WebView. + return false; +} + +void AwContentBrowserClient::OnDisplayInsecureContent( + content::WebContents* web_contents) { + AwSettings* aw_settings = AwSettings::FromWebContents(web_contents); + if (aw_settings) { + UMA_HISTOGRAM_ENUMERATION( + "Android.WebView.OptionallyBlockableMixedContentLoaded.Mode", + aw_settings->GetMixedContentMode(), + AwSettings::MixedContentMode::COUNT); + } +} + +blink::mojom::OriginTrialsSettingsPtr +AwContentBrowserClient::GetOriginTrialsSettings() { + return AwBrowserProcess::GetInstance() + ->GetOriginTrialsSettingsStorage() + ->GetSettings(); +} + +network::mojom::AttributionSupport +AwContentBrowserClient::GetAttributionSupport( + AttributionReportingOsApiState state, + bool client_os_disabled) { + // WebView only supports OS-level attribution and not web-attribution. + switch (state) { + case AttributionReportingOsApiState::kDisabled: + return network::mojom::AttributionSupport::kNone; + case AttributionReportingOsApiState::kEnabled: + return client_os_disabled ? network::mojom::AttributionSupport::kNone + : network::mojom::AttributionSupport::kOs; + } +} + +bool AwContentBrowserClient::IsAttributionReportingOperationAllowed( + content::BrowserContext* browser_context, + AttributionReportingOperation operation, + content::RenderFrameHost* rfh, + const url::Origin* source_origin, + const url::Origin* destination_origin, + const url::Origin* reporting_origin, + bool* can_bypass) { + AwBrowserContext* aw_context = + static_cast(browser_context); + // WebView only supports OS-level attribution and not web-attribution. + // Note: We do not check here if attribution reporting has been disabled + // for the associated WebView as this is checked at the start of processing + // an attribution event. + switch (operation) { + case AttributionReportingOperation::kAny: + case AttributionReportingOperation::kOsSource: + case AttributionReportingOperation::kOsTrigger: + case AttributionReportingOperation::kOsSourceVerboseDebugReport: + case AttributionReportingOperation::kOsTriggerVerboseDebugReport: + return true; + case AttributionReportingOperation::kSource: + case AttributionReportingOperation::kTrigger: + case AttributionReportingOperation::kSourceVerboseDebugReport: + case AttributionReportingOperation::kTriggerVerboseDebugReport: + case AttributionReportingOperation::kReport: + case AttributionReportingOperation::kSourceTransitionalDebugReporting: + case AttributionReportingOperation::kTriggerTransitionalDebugReporting: + case AttributionReportingOperation::kSourceAggregatableDebugReport: + case AttributionReportingOperation::kTriggerAggregatableDebugReport: + return false; + case AttributionReportingOperation::kOsSourceTransitionalDebugReporting: + case AttributionReportingOperation::kOsTriggerTransitionalDebugReporting: { + if (!aw_context->GetCookieManager() + ->cookie_access_policy() + ->GetShouldAcceptCookies()) { + return false; + } + + WebContents* web_contents = + content::WebContents::FromRenderFrameHost(rfh); + AwSettings* aw_settings = AwSettings::FromWebContents(web_contents); + if (!aw_settings) { + return false; + } + + return aw_settings->GetAllowThirdPartyCookies(); + } + } + + NOTREACHED_NORETURN(); +} + +content::ContentBrowserClient::AttributionReportingOsRegistrars +AwContentBrowserClient::GetAttributionReportingOsRegistrars( + content::WebContents* web_contents) { + // Attribution reporting can register a source to either the top level origin + // or the app. For WebView the default is to register sources against the app + // as: + // 1. WebViews are often used in cases where for sources the top level origin + // is not as relevant as the app context. + // 2. Web registration APIs currently require a special registration from the + // app in Android for registering sources and the more common case is that the + // app does not have this registration. Note: This behaviour can be switched + // to registering against the top level origin via an AndroidX API + + // Attribution reporting can register a trigger to either the top level origin + // or the app. For WebView the default is to register triggers against the top + // level origin as: + // 1. WebViews are mostly used in cases where for triggers the app context is + // not as relevant as the top level origin. Note: This behaviour can be + // switched to registering against the app via an AndroidX API + + AwSettings* aw_settings = AwSettings::FromWebContents(web_contents); + + if (!aw_settings) { + return {AttributionReportingOsRegistrar::kDisabled, + AttributionReportingOsRegistrar::kDisabled}; + } + + AwSettings::AttributionBehavior attribution_behavior = + aw_settings->GetAttributionBehavior(); + + switch (attribution_behavior) { + case AwSettings::AttributionBehavior::WEB_SOURCE_AND_WEB_TRIGGER: + return {AttributionReportingOsRegistrar::kWeb, + AttributionReportingOsRegistrar::kWeb}; + case AwSettings::AttributionBehavior::APP_SOURCE_AND_WEB_TRIGGER: + return {AttributionReportingOsRegistrar::kOs, + AttributionReportingOsRegistrar::kWeb}; + case AwSettings::AttributionBehavior::APP_SOURCE_AND_APP_TRIGGER: + return {AttributionReportingOsRegistrar::kOs, + AttributionReportingOsRegistrar::kOs}; + case AwSettings::AttributionBehavior::DISABLED: + return {AttributionReportingOsRegistrar::kDisabled, + AttributionReportingOsRegistrar::kDisabled}; + } + + NOTREACHED_NORETURN(); +} + +network::mojom::IpProtectionProxyBypassPolicy +AwContentBrowserClient::GetIpProtectionProxyBypassPolicy() { + // The exact WebView-specific exclusion policy that is used will depend + // on android_webview::features::kWebViewIpProtectionExclusionCriteria + return network::mojom::IpProtectionProxyBypassPolicy::kExclusionList; +} + +bool AwContentBrowserClient::WillProvidePublicFirstPartySets() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kWebViewFpsComponent); +} + +bool AwContentBrowserClient::IsFullCookieAccessAllowed( + content::BrowserContext* browser_context, + content::WebContents* web_contents, + const GURL& url, + const blink::StorageKey& storage_key) { + if (!web_contents) { + // We do not allow third-party cookie access from service workers. + return false; + } + AwSettings* aw_settings = AwSettings::FromWebContents(web_contents); + if (!aw_settings) { + return false; + } + + return aw_settings->GetAllowThirdPartyCookies(); +} +} // namespace android_webview diff --git a/tools/under-control/src/android_webview/browser/aw_field_trials.cc b/tools/under-control/src/android_webview/browser/aw_field_trials.cc new file mode 100755 index 000000000..3d249bc4d --- /dev/null +++ b/tools/under-control/src/android_webview/browser/aw_field_trials.cc @@ -0,0 +1,273 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "android_webview/browser/aw_field_trials.h" + +#include "android_webview/common/aw_switches.h" +#include "base/base_paths_android.h" +#include "base/check.h" +#include "base/feature_list.h" +#include "base/memory/raw_ref.h" +#include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" +#include "base/metrics/persistent_histogram_allocator.h" +#include "base/path_service.h" +#include "components/history/core/browser/features.h" +#include "components/metrics/persistent_histograms.h" +#include "components/permissions/features.h" +#include "components/safe_browsing/core/common/features.h" +#include "components/translate/core/common/translate_util.h" +#include "components/viz/common/features.h" +#include "content/public/common/content_features.h" +#include "gpu/config/gpu_finch_features.h" +#include "media/base/media_switches.h" +#include "mojo/public/cpp/bindings/features.h" +#include "net/base/features.h" +#include "services/network/public/cpp/features.h" +#include "third_party/blink/public/common/features.h" +#include "ui/android/ui_android_features.h" +#include "ui/gl/gl_features.h" + +namespace { + +class AwFeatureOverrides { + public: + explicit AwFeatureOverrides(base::FeatureList& feature_list) + : feature_list_(feature_list) {} + + AwFeatureOverrides(const AwFeatureOverrides& other) = delete; + AwFeatureOverrides& operator=(const AwFeatureOverrides& other) = delete; + + ~AwFeatureOverrides() { + for (const auto& field_trial_override : field_trial_overrides_) { + feature_list_->RegisterFieldTrialOverride( + field_trial_override.feature->name, + field_trial_override.override_state, + field_trial_override.field_trial); + } + feature_list_->RegisterExtraFeatureOverrides(std::move(overrides_)); + } + + // Enable a feature with WebView-specific override. + void EnableFeature(const base::Feature& feature) { + overrides_.emplace_back( + std::cref(feature), + base::FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE); + } + + // Disable a feature with WebView-specific override. + void DisableFeature(const base::Feature& feature) { + overrides_.emplace_back( + std::cref(feature), + base::FeatureList::OverrideState::OVERRIDE_DISABLE_FEATURE); + } + + // Enable or disable a feature with a field trial. This can be used for + // setting feature parameters. + void OverrideFeatureWithFieldTrial( + const base::Feature& feature, + base::FeatureList::OverrideState override_state, + base::FieldTrial* field_trial) { + field_trial_overrides_.emplace_back(FieldTrialOverride{ + .feature = raw_ref(feature), + .override_state = override_state, + .field_trial = field_trial, + }); + } + + private: + struct FieldTrialOverride { + raw_ref feature; + base::FeatureList::OverrideState override_state; + raw_ptr field_trial; + }; + + base::raw_ref feature_list_; + std::vector overrides_; + std::vector field_trial_overrides_; +}; + +} // namespace + +void AwFieldTrials::OnVariationsSetupComplete() { + // Persistent histograms must be enabled ASAP, but depends on Features. + base::FilePath metrics_dir; + if (base::PathService::Get(base::DIR_ANDROID_APP_DATA, &metrics_dir)) { + InstantiatePersistentHistogramsWithFeaturesAndCleanup(metrics_dir); + } else { + NOTREACHED_IN_MIGRATION(); + } +} + +// TODO(crbug.com/40271903): Consider to migrate all WebView feature overrides +// from the AwMainDelegate to the new mechanism here. +void AwFieldTrials::RegisterFeatureOverrides(base::FeatureList* feature_list) { + if (!feature_list) { + return; + } + AwFeatureOverrides aw_feature_overrides(*feature_list); + + // Disable third-party storage partitioning on WebView. + aw_feature_overrides.DisableFeature( + net::features::kThirdPartyStoragePartitioning); + + // Disable the passthrough on WebView. + aw_feature_overrides.DisableFeature( + ::features::kDefaultPassthroughCommandDecoder); + + // HDR does not support webview yet. See crbug.com/1493153 for an explanation. + aw_feature_overrides.DisableFeature(ui::kAndroidHDR); + + // Disable Reducing User Agent minor version on WebView. + aw_feature_overrides.DisableFeature( + blink::features::kReduceUserAgentMinorVersion); + + // Disable fenced frames on WebView. + aw_feature_overrides.DisableFeature(blink::features::kFencedFrames); + + // Disable FLEDGE on WebView. + aw_feature_overrides.DisableFeature(blink::features::kAdInterestGroupAPI); + aw_feature_overrides.DisableFeature(blink::features::kFledge); + + // Disable low latency overlay for WebView. There is currently no plan to + // enable these optimizations in WebView though they are not fundamentally + // impossible. + aw_feature_overrides.DisableFeature( + blink::features::kLowLatencyCanvas2dImageChromium); + aw_feature_overrides.DisableFeature( + blink::features::kLowLatencyWebGLImageChromium); + + // Disable Shared Storage on WebView. + aw_feature_overrides.DisableFeature(blink::features::kSharedStorageAPI); + aw_feature_overrides.DisableFeature(blink::features::kSharedStorageAPIM125); + + // Disable scrollbar-color on WebView. + aw_feature_overrides.DisableFeature(blink::features::kScrollbarColor); + + // Disable scrollbar-width on WebView. + aw_feature_overrides.DisableFeature(blink::features::kScrollbarWidth); + + // Disable Populating the VisitedLinkDatabase on WebView. + aw_feature_overrides.DisableFeature(history::kPopulateVisitedLinkDatabase); + + // WebView uses kWebViewVulkan to control vulkan. Pre-emptively disable + // kVulkan in case it becomes enabled by default. + aw_feature_overrides.DisableFeature(::features::kVulkan); + + aw_feature_overrides.DisableFeature(::features::kWebPayments); + aw_feature_overrides.DisableFeature(::features::kServiceWorkerPaymentApps); + + // WebView does not support overlay fullscreen yet for video overlays. + aw_feature_overrides.DisableFeature(media::kOverlayFullscreenVideo); + + // WebView does not support EME persistent license yet, because it's not + // clear on how user can remove persistent media licenses from UI. + aw_feature_overrides.DisableFeature(media::kMediaDrmPersistentLicense); + + aw_feature_overrides.DisableFeature(::features::kBackgroundFetch); + + // SurfaceControl is controlled by kWebViewSurfaceControl flag. + aw_feature_overrides.DisableFeature(::features::kAndroidSurfaceControl); + + // TODO(crbug.com/40627649): WebOTP is not yet supported on + // WebView. + aw_feature_overrides.DisableFeature(::features::kWebOTP); + + // TODO(crbug.com/40652382): WebXR is not yet supported on WebView. + aw_feature_overrides.DisableFeature(::features::kWebXr); + + // TODO(crbug.com/40831925): Digital Goods API is not yet supported + // on WebView. + aw_feature_overrides.DisableFeature(::features::kDigitalGoodsApi); + + aw_feature_overrides.DisableFeature(::features::kDynamicColorGamut); + + // COOP is not supported on WebView yet. See: + // https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/XBKAGb2_7uAi. + aw_feature_overrides.DisableFeature( + network::features::kCrossOriginOpenerPolicy); + + aw_feature_overrides.DisableFeature(::features::kInstalledApp); + + aw_feature_overrides.DisableFeature(::features::kPeriodicBackgroundSync); + + // Disabled until viz scheduling can be improved. + aw_feature_overrides.DisableFeature( + ::features::kUseSurfaceLayerForVideoDefault); + + // Disable dr-dc on webview. + aw_feature_overrides.DisableFeature(::features::kEnableDrDc); + + // TODO(crbug.com/40703318): Web Bluetooth is not yet supported on WebView. + aw_feature_overrides.DisableFeature(::features::kWebBluetooth); + + // TODO(crbug.com/41441927): WebUSB is not yet supported on WebView. + aw_feature_overrides.DisableFeature(::features::kWebUsb); + + // Disable TFLite based language detection on webview until webview supports + // ML model delivery via Optimization Guide component. + // TODO(crbug.com/40819484): Enable the feature on Webview. + aw_feature_overrides.DisableFeature( + ::translate::kTFLiteLanguageDetectionEnabled); + + // Disable key pinning enforcement on webview. + aw_feature_overrides.DisableFeature( + net::features::kStaticKeyPinningEnforcement); + + // FedCM is not yet supported on WebView. + aw_feature_overrides.DisableFeature(::features::kFedCm); + + // TODO(crbug.com/40272633): Web MIDI permission prompt for all usage. + aw_feature_overrides.DisableFeature(blink::features::kBlockMidiByDefault); + + // Disable device posture API as the framework implementation causes + // AwContents to leak in apps that don't call destroy(). + aw_feature_overrides.DisableFeature(blink::features::kDevicePosture); + aw_feature_overrides.DisableFeature(blink::features::kViewportSegments); + + // New Safe Browsing API is still being rolled out on WebView. + aw_feature_overrides.DisableFeature( + safe_browsing::kSafeBrowsingNewGmsApiForBrowseUrlDatabaseCheck); + + // PaintHolding for OOPIFs. This should be a no-op since WebView doesn't use + // site isolation but field trial testing doesn't indicate that. Revisit when + // enabling site isolation. See crbug.com/356170748. + aw_feature_overrides.DisableFeature(blink::features::kPaintHoldingForIframes); + + if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kDebugBsa)) { + // Feature parameters can only be set via a field trial. + const char kTrialName[] = "StudyDebugBsa"; + const char kGroupName[] = "GroupDebugBsa"; + base::FieldTrial* field_trial = + base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName); + // If field_trial is null, there was some unexpected name conflict. + CHECK(field_trial); + base::FieldTrialParams params; + params.emplace(net::features::kIpPrivacyTokenServer.name, + "https://staging-phosphor-pa.sandbox.googleapis.com"); + base::AssociateFieldTrialParams(kTrialName, kGroupName, params); + aw_feature_overrides.OverrideFeatureWithFieldTrial( + net::features::kEnableIpProtectionProxy, + base::FeatureList::OverrideState::OVERRIDE_ENABLE_FEATURE, field_trial); + aw_feature_overrides.EnableFeature(network::features::kMaskedDomainList); + } + + // Delete Incidental Party State (DIPS) feature is not yet supported on + // WebView. + // TODO(b/344852824): Enable the feature for WebView + aw_feature_overrides.DisableFeature(::features::kDIPS); + + // Async Safe Browsing check will be rolled out together with + // kHashPrefixRealTimeLookups on WebView. + aw_feature_overrides.DisableFeature( + safe_browsing::kSafeBrowsingAsyncRealTimeCheck); + + // WebView does not currently support the Permissions API (crbug.com/490120) + aw_feature_overrides.DisableFeature(::features::kWebPermissionsApi); + + // TODO(crbug.com/356827071): Enable the feature for WebView. + // Disable PlzDedicatedWorker as a workaround for crbug.com/356827071. + // Otherwise, importScripts fails on WebView. + aw_feature_overrides.DisableFeature(blink::features::kPlzDedicatedWorker); +} diff --git a/tools/under-control/src/chrome/android/java/AndroidManifest.xml b/tools/under-control/src/chrome/android/java/AndroidManifest.xml new file mode 100755 index 000000000..851497feb --- /dev/null +++ b/tools/under-control/src/chrome/android/java/AndroidManifest.xml @@ -0,0 +1,1363 @@ + + + + + + + + + + + + + + + + + {% if channel in ['default'] %} + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% set enable_vr = enable_vr|default(0) %} + {% if enable_vr == "true" %} + + + + + + + + + + + + + + + {% endif %} + + + + + + + + + + + + + + + + + + + {% block extra_uses_permissions %} + {% endblock %} + + + + + + + + + + + + + {% block extra_keyset_definitions %} + {% endblock %} + + {% if channel in ['default'] %} + + + {% if enable_vr == "true" %} + + {% endif %} + + {% endif %} + + + + + {% if channel in ['canary', 'dev', 'default'] %} + + {% endif %} + + {% macro application_definitions() %} + + + + + + + + + + + {% block common_view_intent_shared_filter_body %} + + + {% if channel in ['stable', 'default'] %}{% endif %} + + + + + {% endblock %} + + + + {{ self.common_view_intent_shared_filter_body() }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% block mhtml_view_intent_shared_filter_body %} + + + + + + {% for i in range(10) %} + + + {% endfor %} + {% endblock %} + + + + {{ self.mhtml_view_intent_shared_filter_body() }} + + + + {% if channel in ['dev', 'canary', 'default'] %} + + {% block wbn_view_intent_shared_filter_body %} + + + + + + {% for i in range(10) %} + + {% endfor %} + {% endblock %} + + + {{ self.wbn_view_intent_shared_filter_body() }} + + + + + + + + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ self.supports_vr() }} + {{ self.extra_web_rendering_activity_definitions() }} + + + {{ self.supports_vr() }} + {{ self.extra_web_rendering_activity_definitions() }} + + + + + + + {% block supports_vr %} + + + + + + {% endblock %} + + {% block extra_web_rendering_activity_definitions %} + {% endblock %} + + + + + + + + + {% if channel in ['dev', 'canary', 'default'] %} + + {% endif %} + + + {{ self.supports_vr() }} + {{ self.extra_web_rendering_activity_definitions() }} + + + {{ self.supports_vr() }} + {{ self.extra_web_rendering_activity_definitions() }} + + + + + + + + + + + + + + {% set enable_cardboard = enable_cardboard|default(0) %} + {% if enable_cardboard == "true" %} + + + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ self.supports_vr() }} + {{ self.extra_web_rendering_activity_definitions() }} + + + + + + {{ self.supports_vr() }} + {{ self.extra_web_rendering_activity_definitions() }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% if channel in ['default'] %} + + + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% set enable_openxr = enable_openxr|default(0) %} + {% if enable_openxr == "true" %} + + + + + + + + + {% endif %} + + {% block extra_application_definitions %} + {% endblock %} + {% endmacro %} + {% if not definitions_in_split %} + {{ application_definitions() }} + {% endif %} + + + + + {% set num_sandboxed_services = 40 %} + + + {% for i in range(num_sandboxed_services) %} + + {% endfor %} + + {% set num_privileged_services = 5 %} + + + {% for i in range(num_privileged_services) %} + {% set privileged_process_name = ':privileged_process%d' % i %} + + + {% endfor %} + + + + + + + + + {% if backup_key is defined %} + + + {% endif %} + + {% if channel in ['dev', 'canary', 'default'] %} + + {% endif %} + + + {% if enable_arcore == 'true' %} + + + + + + {% block base_application_extra_arcore_definitions %} + + {% endblock base_application_extra_arcore_definitions %} + + {% endif %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {% block base_application_definitions %} + {% endblock %} + {% block extra_application_definitions_for_test %} + {% endblock %} + + {% block extra_root_definitions %} + {% endblock %} + diff --git a/tools/under-control/src/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/tools/under-control/src/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc new file mode 100755 index 000000000..3c1287fd5 --- /dev/null +++ b/tools/under-control/src/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc @@ -0,0 +1,1752 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h" + +#include + +#include +#include +#include +#include + +#include "base/barrier_closure.h" +#include "base/containers/flat_set.h" +#include "base/containers/to_vector.h" +#include "base/feature_list.h" +#include "base/functional/bind.h" +#include "base/functional/callback.h" +#include "base/functional/callback_helpers.h" +#include "base/location.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" +#include "base/not_fatal_until.h" +#include "base/ranges/algorithm.h" +#include "base/strings/strcat.h" +#include "base/task/bind_post_task.h" +#include "base/task/thread_pool.h" +#include "base/time/time.h" +#include "base/trace_event/trace_event.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/autocomplete/zero_suggest_cache_service_factory.h" +#include "chrome/browser/autofill/personal_data_manager_factory.h" +#include "chrome/browser/autofill/strike_database_factory.h" +#include "chrome/browser/bookmarks/bookmark_model_factory.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h" +#include "chrome/browser/browsing_data/navigation_entry_remover.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/crash_upload_list/crash_upload_list.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" +#include "chrome/browser/dips/dips_service.h" +#include "chrome/browser/dips/dips_service_factory.h" +#include "chrome/browser/dips/dips_utils.h" +#include "chrome/browser/domain_reliability/service_factory.h" +#include "chrome/browser/downgrade/user_data_downgrade.h" +#include "chrome/browser/download/download_prefs.h" +#include "chrome/browser/external_protocol/external_protocol_handler.h" +#include "chrome/browser/file_system_access/chrome_file_system_access_permission_context.h" +#include "chrome/browser/file_system_access/file_system_access_permission_context_factory.h" +#include "chrome/browser/heavy_ad_intervention/heavy_ad_service_factory.h" +#include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/history/web_history_service_factory.h" +#include "chrome/browser/language/url_language_histogram_factory.h" +#include "chrome/browser/login_detection/login_detection_prefs.h" +#include "chrome/browser/media/media_engagement_service.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" +#include "chrome/browser/media/webrtc/webrtc_event_log_manager.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" +#include "chrome/browser/password_manager/account_password_store_factory.h" +#include "chrome/browser/password_manager/profile_password_store_factory.h" +#include "chrome/browser/permissions/permission_actions_history_factory.h" +#include "chrome/browser/permissions/permission_decision_auto_blocker_factory.h" +#include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h" +#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service.h" +#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_factory.h" +#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h" +#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h" +#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/reading_list/reading_list_model_factory.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/browser/safe_browsing/verdict_cache_manager_factory.h" +#include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/share/share_history.h" +#include "chrome/browser/share/share_ranking.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "chrome/browser/spellchecker/spellcheck_factory.h" +#include "chrome/browser/spellchecker/spellcheck_service.h" +#include "chrome/browser/sync/sync_service_factory.h" +#include "chrome/browser/tpcd/metadata/manager_factory.h" +#include "chrome/browser/translate/chrome_translate_client.h" +#include "chrome/browser/ui/find_bar/find_bar_state.h" +#include "chrome/browser/ui/find_bar/find_bar_state_factory.h" +#include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h" +#include "chrome/browser/webdata_services/web_data_service_factory.h" +#include "chrome/common/buildflags.h" +#include "chrome/common/url_constants.h" +#include "components/autofill/core/browser/personal_data_manager.h" +#include "components/autofill/core/browser/strike_databases/strike_database.h" +#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" +#include "components/autofill/core/common/autofill_features.h" +#include "components/autofill/core/common/autofill_payments_features.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/browsing_data/content/browsing_data_helper.h" +#include "components/content_settings/core/browser/content_settings_registry.h" +#include "components/content_settings/core/browser/content_settings_utils.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_pattern.h" +#include "components/crash/core/app/crashpad.h" +#include "components/custom_handlers/protocol_handler_registry.h" +#include "components/device_event_log/device_event_log.h" +#include "components/feed/buildflags.h" +#include "components/heavy_ad_intervention/heavy_ad_blocklist.h" +#include "components/heavy_ad_intervention/heavy_ad_service.h" +#include "components/history/core/browser/history_service.h" +#include "components/history/core/common/pref_names.h" +#include "components/keyed_service/core/service_access_type.h" +#include "components/language/core/browser/url_language_histogram.h" +#include "components/media_device_salt/media_device_salt_service.h" +#include "components/nacl/browser/nacl_browser.h" +#include "components/nacl/browser/pnacl_host.h" +#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" +#include "components/omnibox/browser/omnibox_prefs.h" +#include "components/open_from_clipboard/clipboard_recent_content.h" +#include "components/password_manager/core/browser/features/password_features.h" +#include "components/password_manager/core/browser/features/password_manager_features_util.h" +#include "components/password_manager/core/browser/password_manager_metrics_util.h" +#include "components/password_manager/core/browser/password_store/password_store_interface.h" +#include "components/password_manager/core/browser/password_store/smart_bubble_stats_store.h" +#include "components/payments/content/payment_manifest_web_data_service.h" +#include "components/performance_manager/public/user_tuning/prefs.h" +#include "components/permissions/permission_actions_history.h" +#include "components/permissions/permission_decision_auto_blocker.h" +#include "components/prefs/pref_service.h" +#include "components/privacy_sandbox/privacy_sandbox_settings.h" +#include "components/reading_list/core/reading_list_model.h" +#include "components/safe_browsing/core/browser/verdict_cache_manager.h" +#include "components/search_engines/template_url_service.h" +#include "components/signin/public/base/consent_level.h" +#include "components/signin/public/base/gaia_id_hash.h" +#include "components/signin/public/identity_manager/account_info.h" +#include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/identity_utils.h" +#include "components/sync/service/sync_service.h" +#include "components/sync/service/sync_user_settings.h" +#include "components/tpcd/metadata/browser/manager.h" +#include "components/web_cache/browser/web_cache_manager.h" +#include "components/webrtc_logging/browser/log_cleanup.h" +#include "components/webrtc_logging/browser/text_log_list.h" +#include "content/public/browser/background_tracing_manager.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/browsing_data_filter_builder.h" +#include "content/public/browser/host_zoom_map.h" +#include "content/public/browser/origin_trials_controller_delegate.h" +#include "content/public/browser/prefetch_service_delegate.h" +#include "content/public/browser/ssl_host_state_delegate.h" +#include "content/public/browser/storage_partition.h" +#include "google_apis/gaia/gaia_urls.h" +#include "media/base/media_switches.h" +#include "media/mojo/services/video_decode_perf_history.h" +#include "media/mojo/services/webrtc_video_perf_history.h" +#include "mojo/public/cpp/bindings/callback_helpers.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "net/http/http_transaction_factory.h" +#include "net/net_buildflags.h" +#include "services/network/public/mojom/clear_data_filter.mojom.h" + +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/android/customtabs/chrome_origin_verifier.h" +#include "chrome/browser/android/oom_intervention/oom_intervention_decider.h" +#include "chrome/browser/android/webapps/webapp_registry.h" +#include "chrome/browser/offline_pages/offline_page_model_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/android/tab_model/tab_model.h" +#include "chrome/browser/ui/android/tab_model/tab_model_list.h" +#include "components/cdm/browser/media_drm_storage_impl.h" // nogncheck crbug.com/1125897 +#include "components/installedapp/android/jni_headers/PackageHash_jni.h" +#include "components/offline_pages/core/offline_page_feature.h" +#include "components/offline_pages/core/offline_page_model.h" +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(ENABLE_FEED_V2) +#include "chrome/browser/feed/feed_service_factory.h" +#include "components/feed/core/v2/public/feed_service.h" // nogncheck +#include "components/feed/feed_feature_list.h" +#endif // BUILDFLAG(ENABLE_FEED_V2) + +#if !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/user_education/browser_feature_promo_storage_service.h" +#include "chrome/browser/web_applications/web_app.h" +#include "chrome/browser/web_applications/web_app_command_scheduler.h" +#include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/web_app_utils.h" +#include "content/public/browser/isolated_web_apps_policy.h" +#include "content/public/browser/storage_partition_config.h" +#endif // !BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "chrome/browser/extensions/activity_log/activity_log.h" +#include "extensions/browser/extension_prefs.h" +#include "extensions/common/constants.h" +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/net/system_proxy_manager.h" +#include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/browser_process_platform_part.h" +#include "chromeos/ash/components/cryptohome/cryptohome_parameters.h" +#include "chromeos/ash/components/dbus/attestation/attestation_client.h" +#include "chromeos/ash/components/dbus/attestation/interface.pb.h" +#include "chromeos/ash/components/dbus/constants/attestation_constants.h" // nogncheck +#include "chromeos/ash/components/dbus/dbus_thread_manager.h" // nogncheck +#include "components/user_manager/user.h" +#include "device/fido/cros/credential_store.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_WIN) +#include "chrome/browser/media/cdm_document_service_impl.h" +#endif // BUILDFLAG(IS_WIN) + +using base::UserMetricsAction; +using content::BrowserContext; +using content::BrowserThread; +using content::BrowsingDataFilterBuilder; + +namespace constants = chrome_browsing_data_remover; + +namespace { + +// Timeout after which the histogram for slow tasks is recorded. +const base::TimeDelta kSlowTaskTimeout = base::Seconds(180); + +// Generic functions but currently only used when ENABLE_NACL. +#if BUILDFLAG(ENABLE_NACL) +// Convenience method to create a callback that can be run on any thread and +// will post the given |callback| back to the UI thread. +base::OnceClosure UIThreadTrampoline(base::OnceClosure callback) { + return base::BindPostTask(content::GetUIThreadTaskRunner({}), + std::move(callback)); +} +#endif // BUILDFLAG(ENABLE_NACL) + +// Returned by ChromeBrowsingDataRemoverDelegate::GetOriginTypeMatcher(). +bool DoesOriginMatchEmbedderMask(uint64_t origin_type_mask, + const url::Origin& origin, + storage::SpecialStoragePolicy* policy) { + DCHECK_EQ(0ULL, + origin_type_mask & (constants::ORIGIN_TYPE_EMBEDDER_BEGIN - 1)) + << "|origin_type_mask| can only contain origin types defined in " + << "the embedder."; + +#if BUILDFLAG(ENABLE_EXTENSIONS) + // Packaged apps and extensions match iff EXTENSION. + if ((origin.scheme() == extensions::kExtensionScheme) && + (origin_type_mask & constants::ORIGIN_TYPE_EXTENSION)) { + return true; + } + origin_type_mask &= ~constants::ORIGIN_TYPE_EXTENSION; +#endif + + DCHECK(!origin_type_mask) + << "DoesOriginMatchEmbedderMask must handle all origin types."; + + return false; +} + +} // namespace + +ChromeBrowsingDataRemoverDelegate::ChromeBrowsingDataRemoverDelegate( + BrowserContext* browser_context) + : profile_(Profile::FromBrowserContext(browser_context)) +#if BUILDFLAG(IS_ANDROID) + , + webapp_registry_(std::make_unique()) +#endif + , + credential_store_(MakeCredentialStore()) { + domain_reliability_clearer_ = base::BindRepeating( + [](BrowserContext* browser_context, + content::BrowsingDataFilterBuilder* filter_builder, + network::mojom::NetworkContext_DomainReliabilityClearMode mode, + network::mojom::NetworkContext::ClearDomainReliabilityCallback + callback) { + network::mojom::NetworkContext* network_context = + browser_context->GetDefaultStoragePartition()->GetNetworkContext(); + network_context->ClearDomainReliability( + filter_builder->BuildNetworkServiceFilter(), mode, + std::move(callback)); + }, + browser_context); +} + +ChromeBrowsingDataRemoverDelegate::~ChromeBrowsingDataRemoverDelegate() = + default; + +void ChromeBrowsingDataRemoverDelegate::Shutdown() { + auto* remover = profile_->GetBrowsingDataRemover(); + DCHECK(remover); + remover->SetEmbedderDelegate(nullptr); + profile_keep_alive_.reset(); + history_task_tracker_.TryCancelAll(); +} + +content::BrowsingDataRemoverDelegate::EmbedderOriginTypeMatcher +ChromeBrowsingDataRemoverDelegate::GetOriginTypeMatcher() { + return base::BindRepeating(&DoesOriginMatchEmbedderMask); +} + +bool ChromeBrowsingDataRemoverDelegate::MayRemoveDownloadHistory() { + return profile_->GetPrefs()->GetBoolean(prefs::kAllowDeletingBrowserHistory); +} + +std::vector +ChromeBrowsingDataRemoverDelegate::GetDomainsForDeferredCookieDeletion( + content::StoragePartition* storage_partition, + uint64_t remove_mask) { +#if BUILDFLAG(IS_ANDROID) + // On Android the identity model isn't based on Gaia cookies, so they can be + // wiped immediately without influencing the wiping of account-scoped data. + return {}; +#else + // The Google/Gaia cookies we care about live in the default StoragePartition. + if (!storage_partition->GetConfig().is_default() || + (remove_mask & constants::DEFERRED_COOKIE_DELETION_DATA_TYPES) == 0) { + return {}; + } + + // Return Google and Gaia domains, so Google signout is deferred until + // account-scoped data is deleted. + auto urls = {GaiaUrls::GetInstance()->google_url(), + GaiaUrls::GetInstance()->gaia_url()}; + std::set domains; + for (const GURL& url : urls) { + std::string domain = GetDomainAndRegistry( + url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + if (domain.empty()) + domain = url.host(); + domains.insert(domain); + } + return {domains.begin(), domains.end()}; +#endif +} + +void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData( + const base::Time& delete_begin, + const base::Time& delete_end, + uint64_t remove_mask, + BrowsingDataFilterBuilder* filter_builder, + uint64_t origin_type_mask, + base::OnceCallback callback) { + DCHECK(((remove_mask & + ~content::BrowsingDataRemover::DATA_TYPE_AVOID_CLOSING_CONNECTIONS & + ~constants::FILTERABLE_DATA_TYPES) == 0) || + filter_builder->MatchesAllOriginsAndDomains()); +#if !BUILDFLAG(IS_ANDROID) + DCHECK(!should_clear_sync_account_settings_); +#endif + + TRACE_EVENT0("browsing_data", + "ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData"); + + // To detect tasks that are causing slow deletions, record running sub tasks + // after a delay. + slow_pending_tasks_closure_.Reset(base::BindOnce( + &ChromeBrowsingDataRemoverDelegate::RecordUnfinishedSubTasks, + weak_ptr_factory_.GetWeakPtr())); + content::GetUIThreadTaskRunner({})->PostDelayedTask( + FROM_HERE, slow_pending_tasks_closure_.callback(), kSlowTaskTimeout); + + // Embedder-defined DOM-accessible storage currently contains only + // one datatype, which is the durable storage permission. + if (remove_mask & + content::BrowsingDataRemover::DATA_TYPE_EMBEDDER_DOM_STORAGE) { + remove_mask |= constants::DATA_TYPE_DURABLE_PERMISSION; + } + + if (origin_type_mask & + content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB) { + base::RecordAction( + UserMetricsAction("ClearBrowsingData_MaskContainsUnprotectedWeb")); + } + if (origin_type_mask & + content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB) { + base::RecordAction( + UserMetricsAction("ClearBrowsingData_MaskContainsProtectedWeb")); + } +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (origin_type_mask & constants::ORIGIN_TYPE_EXTENSION) { + base::RecordAction( + UserMetricsAction("ClearBrowsingData_MaskContainsExtension")); + } +#endif + // If this fires, we added a new BrowsingDataHelper::OriginTypeMask without + // updating the user metrics above. + static_assert( + constants::ALL_ORIGIN_TYPES == + (content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB | +#if BUILDFLAG(ENABLE_EXTENSIONS) + constants::ORIGIN_TYPE_EXTENSION | +#endif + content::BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB), + "OriginTypeMask has been updated without updating user metrics"); + + ////////////////////////////////////////////////////////////////////////////// + // INITIALIZATION + base::ScopedClosureRunner synchronous_clear_operations( + CreateTaskCompletionClosure(TracingDataType::kSynchronous)); + callback_ = std::move(callback); + + delete_begin_ = delete_begin; + delete_end_ = delete_end; + + failed_data_types_ = 0; + + base::RepeatingCallback filter = + filter_builder->BuildUrlFilter(); + + // Some backends support a filter that |is_null()| to make complete deletion + // more efficient. + base::RepeatingCallback nullable_filter = + filter_builder->MatchesAllOriginsAndDomains() + ? base::RepeatingCallback() + : filter; + + HostContentSettingsMap::PatternSourcePredicate website_settings_filter = + browsing_data::CreateWebsiteSettingsFilter(filter_builder); + + // Managed devices and supervised users can have restrictions on history + // deletion. + PrefService* prefs = profile_->GetPrefs(); + bool may_delete_history = + prefs->GetBoolean(prefs::kAllowDeletingBrowserHistory); + + // All the UI entry points into the BrowsingDataRemoverImpl should be + // disabled, but this will fire if something was missed or added. + DCHECK(may_delete_history || + (remove_mask & content::BrowsingDataRemover::DATA_TYPE_NO_CHECKS) || + (!(remove_mask & constants::DATA_TYPE_HISTORY) && + !(remove_mask & content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS))); + + HostContentSettingsMap* host_content_settings_map_ = + HostContentSettingsMapFactory::GetForProfile(profile_); + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_HISTORY + if ((remove_mask & constants::DATA_TYPE_HISTORY) && may_delete_history) { + history::HistoryService* history_service = + HistoryServiceFactory::GetForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + if (history_service) { + // TODO(dmurph): Support all backends with filter (crbug.com/113621). + base::RecordAction(UserMetricsAction("ClearBrowsingData_History")); + history_service->DeleteLocalAndRemoteHistoryBetween( + WebHistoryServiceFactory::GetForProfile(profile_), delete_begin_, + delete_end_, history::kNoAppIdFilter, + CreateTaskCompletionClosure(TracingDataType::kHistory), + &history_task_tracker_); + } + if (ClipboardRecentContent::GetInstance()) + ClipboardRecentContent::GetInstance()->SuppressClipboardContent(); + + language::UrlLanguageHistogram* language_histogram = + UrlLanguageHistogramFactory::GetForBrowserContext(profile_); + if (language_histogram) { + language_histogram->ClearHistory(delete_begin_, delete_end_); + } + +#if BUILDFLAG(ENABLE_EXTENSIONS) + // The extension activity log contains details of which websites extensions + // were active on. It therefore indirectly stores details of websites a + // user has visited so best clean from here as well. + // TODO(msramek): Support all backends with filter (crbug.com/589586). + extensions::ActivityLog::GetInstance(profile_)->RemoveURLs( + std::set()); + + // Clear launch times as they are a form of history. + // BrowsingDataFilterBuilder currently doesn't support extension origins. + // Therefore, clearing history for a small set of origins (deletelist) + // should never delete any extension launch times, while clearing for almost + // all origins (preservelist) should always delete all of extension launch + // times. + if (filter_builder->MatchesAllOriginsAndDomains()) { + extensions::ExtensionPrefs* extension_prefs = + extensions::ExtensionPrefs::Get(profile_); + extension_prefs->ClearLastLaunchTimes(); + } +#endif + + // Need to clear the host cache and accumulated speculative data, as it also + // reveals some history. We have no mechanism to track when these items were + // created, so we'll not honor the time range. + profile_->GetDefaultStoragePartition()->GetNetworkContext()->ClearHostCache( + filter_builder->BuildNetworkServiceFilter(), + CreateTaskCompletionClosureForMojo(TracingDataType::kHostCache)); + + // The NoStatePrefetchManager keeps history of pages scanned for prefetch, + // so clear that. It also may have a scanned page. If so, the page could be + // considered to have a small amount of historical information, so delete + // it, too. + prerender::NoStatePrefetchManager* no_state_prefetch_manager = + prerender::NoStatePrefetchManagerFactory::GetForBrowserContext( + profile_); + if (no_state_prefetch_manager) { + // TODO(dmurph): Support all backends with filter (crbug.com/113621). + no_state_prefetch_manager->ClearData( + prerender::NoStatePrefetchManager::CLEAR_PRERENDER_CONTENTS | + prerender::NoStatePrefetchManager::CLEAR_PRERENDER_HISTORY); + } + + // The saved Autofill profiles and credit cards can include the origin from + // which these profiles and credit cards were learned. These are a form of + // history, so clear them as well. + // TODO(dmurph): Support all backends with filter (crbug.com/113621). + scoped_refptr web_data_service = + WebDataServiceFactory::GetAutofillWebDataForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + if (web_data_service.get()) { + web_data_service->RemoveOriginURLsModifiedBetween(delete_begin_, + delete_end_); + // Ask for a call back when the above call is finished. + web_data_service->GetDBTaskRunner()->PostTaskAndReply( + FROM_HERE, base::DoNothing(), + CreateTaskCompletionClosure(TracingDataType::kAutofillOrigins)); + + autofill::PersonalDataManager* data_manager = + autofill::PersonalDataManagerFactory::GetForBrowserContext(profile_); + if (data_manager) + data_manager->Refresh(); + } + + base::ThreadPool::PostTaskAndReply( + FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, + base::BindOnce( + &webrtc_logging::DeleteOldAndRecentWebRtcLogFiles, + webrtc_logging::TextLogList:: + GetWebRtcLogDirectoryForBrowserContextPath(profile_->GetPath()), + delete_begin_), + CreateTaskCompletionClosure(TracingDataType::kWebrtcLogs)); + +#if BUILDFLAG(IS_ANDROID) + // Clear the history information (last launch time and origin URL) of any + // registered webapps. + webapp_registry_->ClearWebappHistoryForUrls(filter); + + // The ChromeOriginVerifier caches origins for Trusted Web Activities that + // have been verified and stores them in Android Preferences. + customtabs::ChromeOriginVerifier::ClearBrowsingData(); +#endif + + heavy_ad_intervention::HeavyAdService* heavy_ad_service = + HeavyAdServiceFactory::GetForBrowserContext(profile_); + if (heavy_ad_service && heavy_ad_service->heavy_ad_blocklist()) { + heavy_ad_service->heavy_ad_blocklist()->ClearBlockList(delete_begin_, + delete_end_); + } + + OptimizationGuideKeyedService* optimization_guide_keyed_service = + OptimizationGuideKeyedServiceFactory::GetForProfile(profile_); + if (optimization_guide_keyed_service) + optimization_guide_keyed_service->ClearData(); + + content::PrefetchServiceDelegate::ClearData(profile_); + +#if BUILDFLAG(IS_ANDROID) + OomInterventionDecider* oom_intervention_decider = + OomInterventionDecider::GetForBrowserContext(profile_); + if (oom_intervention_decider) + oom_intervention_decider->ClearData(); +#endif + + // The SSL Host State that tracks SSL interstitial "proceed" decisions may + // include origins that the user has visited, so it must be cleared. + // TODO(msramek): We can reuse the plugin filter here, since both plugins + // and SSL host state are scoped to hosts and represent them as std::string. + // Rename the method to indicate its more general usage. + if (profile_->GetSSLHostStateDelegate()) { + profile_->GetSSLHostStateDelegate()->Clear( + filter_builder->MatchesAllOriginsAndDomains() + ? base::RepeatingCallback() + : filter_builder->BuildPluginFilter()); + } + + // Clear VideoDecodePerfHistory and WebrtcVideoPerfHistory only if asked to + // clear from the beginning of time. The perf history is a simple summing of + // decode/encode statistics with no record of when the stats were written + // nor what site the video was played on. + if (IsForAllTime()) { + // TODO(chcunningham): Add UMA to track how often this gets deleted. + media::VideoDecodePerfHistory* video_decode_perf_history = + profile_->GetVideoDecodePerfHistory(); + if (video_decode_perf_history) { + video_decode_perf_history->ClearHistory( + CreateTaskCompletionClosure(TracingDataType::kVideoDecodeHistory)); + } + + media::WebrtcVideoPerfHistory* webrtc_video_perf_history = + profile_->GetWebrtcVideoPerfHistory(); + if (webrtc_video_perf_history) { + webrtc_video_perf_history->ClearHistory(CreateTaskCompletionClosure( + TracingDataType::kWebrtcVideoPerfHistory)); + } + } + + device_event_log::Clear(delete_begin_, delete_end_); + + CreateCrashUploadList()->Clear(delete_begin_, delete_end_); + + content::BackgroundTracingManager::GetInstance().DeleteTracesInDateRange( + delete_begin_, delete_end_); + + FindBarStateFactory::GetForBrowserContext(profile_)->SetLastSearchText( + std::u16string()); + +#if BUILDFLAG(IS_ANDROID) + if (auto* share_history = sharing::ShareHistory::Get(profile_)) + share_history->Clear(delete_begin_, delete_end_); + if (auto* share_ranking = sharing::ShareRanking::Get(profile_)) + share_ranking->Clear(delete_begin_, delete_end_); +#endif + + // Also clear the last used time in bookmarks. + auto* bookmark_model = BookmarkModelFactory::GetForBrowserContext(profile_); + if (bookmark_model && bookmark_model->loaded()) { + bookmark_model->ClearLastUsedTimeInRange(delete_begin, delete_end); + } + +#if !BUILDFLAG(IS_ANDROID) + // Clear any stored User Education session data. Note that we can't clear a + // specific date range, as this is used for longitudinal metrics reporting, + // so selectively deleting entries would make the telemetry invalid. + BrowserFeaturePromoStorageService::ClearUsageHistory(profile_); +#endif + + // Cleared for DATA_TYPE_HISTORY, DATA_TYPE_COOKIES and DATA_TYPE_PASSWORDS. + browsing_data::RemoveFederatedSiteSettingsData(delete_begin_, delete_end_, + website_settings_filter, + host_content_settings_map_); + + // Cleared for both DATA_TYPE_HISTORY and DATA_TYPE_CONTENT_SETTINGS. + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::COOKIE_CONTROLS_METADATA, delete_begin, delete_end, + website_settings_filter); + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_DOWNLOADS + if ((remove_mask & content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS) && + may_delete_history) { + DownloadPrefs* download_prefs = + DownloadPrefs::FromDownloadManager(profile_->GetDownloadManager()); + download_prefs->SetSaveFilePath(download_prefs->DownloadPath()); + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_COOKIES + // We ignore the DATA_TYPE_COOKIES request if UNPROTECTED_WEB is not set, + // so that callers who request DATA_TYPE_SITE_DATA with PROTECTED_WEB + // don't accidentally remove the cookies that are associated with the + // UNPROTECTED_WEB origin. This is necessary because cookies are not separated + // between UNPROTECTED_WEB and PROTECTED_WEB. + if ((remove_mask & content::BrowsingDataRemover::DATA_TYPE_COOKIES) && + (origin_type_mask & + content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB)) { + base::RecordAction(UserMetricsAction("ClearBrowsingData_Cookies")); + + network::mojom::NetworkContext* safe_browsing_context = nullptr; + safe_browsing::SafeBrowsingService* sb_service = + g_browser_process->safe_browsing_service(); + if (sb_service) + safe_browsing_context = sb_service->GetNetworkContext(profile_); + + // Cleared for DATA_TYPE_HISTORY, DATA_TYPE_COOKIES and DATA_TYPE_PASSWORDS. + browsing_data::RemoveFederatedSiteSettingsData(delete_begin_, delete_end_, + website_settings_filter, + host_content_settings_map_); + + if (!filter_builder->PartitionedCookiesOnly()) { + browsing_data::RemoveEmbedderCookieData( + delete_begin, delete_end, filter_builder, host_content_settings_map_, + safe_browsing_context, + base::BindOnce( + &ChromeBrowsingDataRemoverDelegate::CreateTaskCompletionClosure, + base::Unretained(this), TracingDataType::kCookies)); + safe_browsing::VerdictCacheManagerFactory::GetForProfile(profile_) + ->OnCookiesDeleted(); + } + + if (filter_builder->MatchesMostOriginsAndDomains()) { + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile_); + if (privacy_sandbox_settings) { + privacy_sandbox_settings->OnCookiesCleared(); + } + + if (tpcd::metadata::Manager* manager = + tpcd::metadata::ManagerFactory::GetForProfile(profile_)) { + manager->ResetCohorts(); + } + +#if BUILDFLAG(IS_ANDROID) + Java_PackageHash_onCookiesDeleted(base::android::AttachCurrentThread(), + profile_->GetJavaObject()); +#endif + } + +#if !BUILDFLAG(IS_ANDROID) + if (nullable_filter.is_null() || + (!filter_builder->PartitionedCookiesOnly() && + nullable_filter.Run(GaiaUrls::GetInstance()->google_url()))) { + // Set a flag to clear account storage settings later instead of clearing + // it now as we can not reset this setting before passwords are deleted. + should_clear_sync_account_settings_ = true; + } +#endif + + // Persistent Origin Trial tokens are only saved until the next page + // load from the same origin. For that reason, they are not saved with + // last-modified information, so deletion will clear all stored information. + // Sites should omit setting the Origin-Trial header to clear their + // individual information, so rather than filtering origins, we only perform + // the removal if we are removing information for all origins. + if (filter_builder->MatchesAllOriginsAndDomains()) { + content::OriginTrialsControllerDelegate* delegate = + profile_->GetOriginTrialsControllerDelegate(); + if (delegate) + delegate->ClearPersistedTokens(); + } + + if (auto* media_device_salt_service = + MediaDeviceSaltServiceFactory::GetInstance()->GetForBrowserContext( + profile_)) { + content::StoragePartition::StorageKeyMatcherFunction storage_key_matcher; + if (!filter_builder->MatchesAllOriginsAndDomains()) { + storage_key_matcher = filter_builder->BuildStorageKeyFilter(); + } + media_device_salt_service->DeleteSalts( + delete_begin_, delete_end_, std::move(storage_key_matcher), + CreateTaskCompletionClosure(TracingDataType::kMediaDeviceSalts)); + } + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_CONTENT_SETTINGS + if (remove_mask & constants::DATA_TYPE_CONTENT_SETTINGS) { + base::RecordAction(UserMetricsAction("ClearBrowsingData_ContentSettings")); + + browsing_data::RemoveSiteSettingsData(delete_begin, delete_end, + host_content_settings_map_); + +#if !BUILDFLAG(IS_ANDROID) + // The active permission does not have timestamps, so the all active grants + // will be revoked regardless of the time range because all the are expected + // to be recent. + if (auto* permission_context = + FileSystemAccessPermissionContextFactory::GetForProfile(profile_)) { + permission_context->RevokeAllActiveGrants(); + } +#endif + + auto* handler_registry = + ProtocolHandlerRegistryFactory::GetForBrowserContext(profile_); + if (handler_registry) + handler_registry->ClearUserDefinedHandlers(delete_begin_, delete_end_); + + ChromeTranslateClient::CreateTranslatePrefs(prefs) + ->DeleteNeverPromptSitesBetween(delete_begin_, delete_end_); + + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::PERMISSION_AUTOREVOCATION_DATA, delete_begin, + delete_end, website_settings_filter); + + if (auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile_)) { + privacy_sandbox_settings->ClearFledgeJoiningAllowedSettings(delete_begin_, + delete_end_); + privacy_sandbox_settings->ClearTopicSettings(delete_begin_, delete_end_); + } + + // Cleared for both DATA_TYPE_HISTORY and DATA_TYPE_CONTENT_SETTINGS. + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::COOKIE_CONTROLS_METADATA, delete_begin, delete_end, + website_settings_filter); + +#if !BUILDFLAG(IS_ANDROID) + content::HostZoomMap* zoom_map = + content::HostZoomMap::GetDefaultForBrowserContext(profile_); + zoom_map->ClearZoomLevels(delete_begin, delete_end_); + + // Discard exceptions weren't stored with timestamps, so they all must be + // cleared. + performance_manager::user_tuning::prefs::ClearTabDiscardExceptions( + prefs, delete_begin_, delete_end_); +#endif // !BUILDFLAG(IS_ANDROID) + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_BOOKMARKS + if (remove_mask & constants::DATA_TYPE_BOOKMARKS) { + auto* bookmark_model = BookmarkModelFactory::GetForBrowserContext(profile_); + if (bookmark_model && bookmark_model->loaded()) { + if (delete_begin_.is_null() && + (delete_end_.is_null() || delete_end_.is_max())) { + bookmark_model->RemoveAllUserBookmarks(FROM_HERE); + } else { + // Bookmark deletion is only implemented to remove all data after a + // profile deletion. A full implementation would need to traverse the + // whole tree and check timestamps against delete_begin and delete_end. + NOTIMPLEMENTED(); + } + } + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_LOCAL_CUSTOM_DICTIONARY + if (remove_mask & constants::DATA_TYPE_LOCAL_CUSTOM_DICTIONARY) { + auto* spellcheck = SpellcheckServiceFactory::GetForContext(profile_); + if (spellcheck) { + auto* dict = spellcheck->GetCustomDictionary(); + if (dict) + dict->Clear(); + } + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_READING_LIST + if (remove_mask & constants::DATA_TYPE_READING_LIST) { + auto* reading_list_model = + ReadingListModelFactory::GetForBrowserContext(profile_); + if (reading_list_model) { + if (delete_begin_.is_null() && delete_end_.is_max()) { + reading_list_model->DeleteAllEntries(FROM_HERE); + } else { + NOTIMPLEMENTED(); + } + } + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_DURABLE_PERMISSION + if (remove_mask & constants::DATA_TYPE_DURABLE_PERMISSION) { + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::DURABLE_STORAGE, base::Time(), base::Time::Max(), + website_settings_filter); + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_SITE_USAGE_DATA + if (remove_mask & constants::DATA_TYPE_SITE_USAGE_DATA) { + base::RecordAction(UserMetricsAction("ClearBrowsingData_SiteUsageData")); + + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::SITE_ENGAGEMENT, base::Time(), base::Time::Max(), + website_settings_filter); + + if (filter_builder->MatchesMostOriginsAndDomains()) { + if (MediaEngagementService::IsEnabled()) { + MediaEngagementService::Get(profile_)->ClearDataBetweenTime( + delete_begin_, delete_end_); + } + + PermissionActionsHistoryFactory::GetForProfile(profile_)->ClearHistory( + delete_begin_, delete_end_); + } + } + + if ((remove_mask & constants::DATA_TYPE_SITE_USAGE_DATA) || + (remove_mask & constants::DATA_TYPE_HISTORY)) { + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::FORMFILL_METADATA, delete_begin_, delete_end_, + website_settings_filter); + + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::APP_BANNER, base::Time(), base::Time::Max(), + website_settings_filter); + + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::REVOKED_UNUSED_SITE_PERMISSIONS, delete_begin_, + delete_end_, website_settings_filter); + + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS, + delete_begin_, delete_end_, website_settings_filter); + + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::NOTIFICATION_PERMISSION_REVIEW, delete_begin_, + delete_end_, website_settings_filter); + +#if !BUILDFLAG(IS_ANDROID) + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::INTENT_PICKER_DISPLAY, delete_begin_, delete_end_, + website_settings_filter); + + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::FILE_SYSTEM_LAST_PICKED_DIRECTORY, delete_begin, + delete_end, website_settings_filter); + + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::PRIVATE_NETWORK_GUARD, delete_begin_, delete_end_, + website_settings_filter); + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::PRIVATE_NETWORK_CHOOSER_DATA, delete_begin_, + delete_end_, website_settings_filter); +#endif + + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + ContentSettingsType::NOTIFICATION_INTERACTIONS, delete_begin_, + delete_end_, website_settings_filter); + + PermissionDecisionAutoBlockerFactory::GetForProfile(profile_) + ->RemoveEmbargoAndResetCounts(filter); + } + + // Different types of DIPS events are cleared for DATA_TYPE_HISTORY and + // DATA_TYPE_COOKIES. + DIPSEventRemovalType dips_mask = DIPSEventRemovalType::kNone; + if ((remove_mask & content::BrowsingDataRemover::DATA_TYPE_COOKIES) && + !filter_builder->PartitionedCookiesOnly()) { + dips_mask |= DIPSEventRemovalType::kStorage; + } + if (remove_mask & constants::DATA_TYPE_HISTORY) { + dips_mask |= DIPSEventRemovalType::kHistory; + } + + if (dips_mask != DIPSEventRemovalType::kNone) { + auto* dips_service = DIPSServiceFactory::GetForBrowserContext(profile_); + if (dips_service) { + dips_service->RemoveEvents(delete_begin_, delete_end_, + filter_builder->BuildNetworkServiceFilter(), + dips_mask); + } + } + + ////////////////////////////////////////////////////////////////////////////// + // Password manager + if (remove_mask & constants::DATA_TYPE_PASSWORDS) { + base::RecordAction(UserMetricsAction("ClearBrowsingData_Passwords")); + auto password_store = ProfilePasswordStoreFactory::GetForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + + if (password_store) { + // No sync completion callback is needed for profile passwords, since the + // login token is persisted and can be used after cookie deletion. + // TODO:(crbug.com/1167715) - Test that associated compromised credentials + // are removed. + password_store->RemoveLoginsByURLAndTime( + FROM_HERE, filter, delete_begin_, delete_end_, + CreateTaskCompletionClosure(TracingDataType::kPasswords)); + } + + profile_->GetDefaultStoragePartition() + ->GetNetworkContext() + ->ClearHttpAuthCache( + delete_begin_.is_null() ? base::Time::Min() : delete_begin_, + delete_end_.is_null() ? base::Time::Max() : delete_end_, + filter_builder->BuildNetworkServiceFilter(), + CreateTaskCompletionClosureForMojo( + TracingDataType::kHttpAuthCache)); + + scoped_refptr web_data_service = + webdata_services::WebDataServiceWrapperFactory:: + GetPaymentManifestWebDataServiceForBrowserContext( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + if (web_data_service) { + web_data_service->ClearSecurePaymentConfirmationCredentials( + delete_begin_, delete_end_, + CreateTaskCompletionClosure( + TracingDataType::kSecurePaymentConfirmationCredentials)); + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (ash::SystemProxyManager::Get()) { + // Sends a request to the System-proxy daemon to clear the proxy user + // credentials. System-proxy retrieves proxy username and password from + // the NetworkService, but not the creation time of the credentials. The + // |ClearUserCredentials| request will remove all the cached proxy + // credentials. If credentials prior to |delete_begin_| are removed from + // System-proxy, the daemon will send a D-Bus request to Chrome to fetch + // them from the NetworkService when needed. + ash::SystemProxyManager::Get()->ClearUserCredentials(); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + if (credential_store_) { + credential_store_->DeleteCredentials( + delete_begin_, delete_end_, + CreateTaskCompletionClosure(TracingDataType::kWebAuthnCredentials)); + } + + // Cleared for DATA_TYPE_HISTORY, DATA_TYPE_COOKIES and DATA_TYPE_PASSWORDS. + browsing_data::RemoveFederatedSiteSettingsData(delete_begin_, delete_end_, + website_settings_filter, + host_content_settings_map_); + + // Record that a password removal action happened for the profile store. + AddPasswordRemovalReason( + profile_->GetPrefs(), password_manager::IsAccountStore(false), + password_manager::metrics_util::PasswordManagerCredentialRemovalReason:: + kClearBrowsingData); + } + + if (remove_mask & constants::DATA_TYPE_ACCOUNT_PASSWORDS) { + auto account_store = AccountPasswordStoreFactory::GetForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + + if (account_store) { + // Desktop must wait for DATA_TYPE_ACCOUNT_PASSWORDS deletions to be + // uploaded to the sync server before deleting any other types (because + // deleting DATA_TYPE_COOKIES first would revoke the account storage + // opt-in and prevent the upload). + // On Android, the account storage doesn't depend on cookies, so there's + // no need to wait. + base::OnceCallback sync_completion; +#if !BUILDFLAG(IS_ANDROID) + sync_completion = + CreateTaskCompletionCallback(TracingDataType::kAccountPasswordsSynced, + constants::DATA_TYPE_ACCOUNT_PASSWORDS); +#endif + account_store->RemoveLoginsByURLAndTime( + FROM_HERE, filter, delete_begin_, delete_end_, + CreateTaskCompletionClosure(TracingDataType::kAccountPasswords), + std::move(sync_completion)); + } + + // Record that a password removal action happened for the account store. + AddPasswordRemovalReason( + profile_->GetPrefs(), password_manager::IsAccountStore(true), + password_manager::metrics_util::PasswordManagerCredentialRemovalReason:: + kClearBrowsingData); + } + + CHECK(deferred_disable_passwords_auto_signin_cb_.is_null(), + base::NotFatalUntil::M125); + if ((remove_mask & content::BrowsingDataRemover::DATA_TYPE_COOKIES) && + !filter_builder->PartitionedCookiesOnly()) { + // Unretained() is safe, this is only executed in OnTasksComplete() if the + // object is still alive. Also, see the field docs for motivation. + deferred_disable_passwords_auto_signin_cb_ = base::BindOnce( + &ChromeBrowsingDataRemoverDelegate::DisablePasswordsAutoSignin, + base::Unretained(this), filter); + } + + if (remove_mask & constants::DATA_TYPE_HISTORY) { + password_manager::PasswordStoreInterface* password_store = + ProfilePasswordStoreFactory::GetForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS) + .get(); + + if (password_store) { + password_manager::SmartBubbleStatsStore* stats_store = + password_store->GetSmartBubbleStatsStore(); + if (stats_store) { + stats_store->RemoveStatisticsByOriginAndTime( + nullable_filter, delete_begin_, delete_end_, + CreateTaskCompletionClosure(TracingDataType::kPasswordsStatistics)); + } + } + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_FORM_DATA + // TODO(dmurph): Support all backends with filter (crbug.com/113621). + if (remove_mask & constants::DATA_TYPE_FORM_DATA) { + base::RecordAction(UserMetricsAction("ClearBrowsingData_Autofill")); + scoped_refptr web_data_service = + WebDataServiceFactory::GetAutofillWebDataForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + + if (web_data_service.get()) { + web_data_service->RemoveFormElementsAddedBetween(delete_begin_, + delete_end_); + web_data_service->RemoveAutofillDataModifiedBetween(delete_begin_, + delete_end_); + // Clear out the Autofill StrikeDatabase in its entirety. + // TODO(crbug.com/40594007): Respect |delete_begin_| and |delete_end_| and + // only clear out entries whose last strikes were created in that + // timeframe. + autofill::StrikeDatabase* strike_database = + autofill::StrikeDatabaseFactory::GetForProfile(profile_); + if (strike_database) + strike_database->ClearAllStrikes(); + + // Ask for a call back when the above calls are finished. + web_data_service->GetDBTaskRunner()->PostTaskAndReply( + FROM_HERE, base::DoNothing(), + CreateTaskCompletionClosure(TracingDataType::kAutofillData)); + + autofill::PersonalDataManager* data_manager = + autofill::PersonalDataManagerFactory::GetForBrowserContext(profile_); + if (data_manager) + data_manager->Refresh(); + } + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_CACHE + if (remove_mask & content::BrowsingDataRemover::DATA_TYPE_CACHE) { + // Tell the renderers associated with |profile_| to clear their cache. + // TODO(crbug.com/40495069): Renderer cache is a platform concept, and + // should live in BrowsingDataRemoverImpl. However, WebCacheManager itself + // is a component with dependency on content/browser. Untangle these + // dependencies or reimplement the relevant part of WebCacheManager + // in content/browser. + // TODO(crbug.com/40657761): add a test for this. + if (filter_builder->MatchesMostOriginsAndDomains()) { + for (content::RenderProcessHost::iterator iter = + content::RenderProcessHost::AllHostsIterator(); + !iter.IsAtEnd(); iter.Advance()) { + content::RenderProcessHost* render_process_host = + iter.GetCurrentValue(); + if (render_process_host->GetBrowserContext() == profile_ && + render_process_host->IsInitializedAndNotDead()) { + web_cache::WebCacheManager::GetInstance()->ClearCacheForProcess( + render_process_host->GetID()); + } + } + } + +#if BUILDFLAG(ENABLE_NACL) + if (filter_builder->MatchesMostOriginsAndDomains()) { + nacl::NaClBrowser::GetInstance()->ClearValidationCache(UIThreadTrampoline( + CreateTaskCompletionClosure(TracingDataType::kNaclCache))); + + pnacl::PnaclHost::GetInstance()->ClearTranslationCacheEntriesBetween( + delete_begin_, delete_end_, + UIThreadTrampoline( + CreateTaskCompletionClosure(TracingDataType::kPnaclCache))); + } +#endif + + if (filter_builder->MatchesMostOriginsAndDomains()) { + browsing_data::RemovePrerenderCacheData( + prerender::NoStatePrefetchManagerFactory::GetForBrowserContext( + profile_)); + } + +#if BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(ENABLE_FEED_V2) + if (filter_builder->MatchesMostOriginsAndDomains()) { + // Don't bridge through if the service isn't present, which means + // we're probably running in a native unit test. + feed::FeedService* service = + feed::FeedServiceFactory::GetForBrowserContext(profile_); + if (service) { + service->ClearCachedData(); + } + } +#endif // BUILDFLAG(ENABLE_FEED_V2) + +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_ANDROID) + // For now we're considering offline pages as cache, so if we're removing + // cache we should remove offline pages as well. + if (remove_mask & content::BrowsingDataRemover::DATA_TYPE_CACHE) { + auto* offline_page_model = + offline_pages::OfflinePageModelFactory::GetForBrowserContext( + profile_); + if (offline_page_model) + offline_page_model->DeleteCachedPagesByURLPredicate( + filter, + base::IgnoreArgs( + CreateTaskCompletionClosure(TracingDataType::kOfflinePages))); + } +#endif + + // TODO(crbug.com/41380998): Remove null-check. + if (filter_builder->MatchesMostOriginsAndDomains()) { + auto* webrtc_event_log_manager = WebRtcEventLogManager::GetInstance(); + if (webrtc_event_log_manager) { + webrtc_event_log_manager->ClearCacheForBrowserContext( + profile_, delete_begin_, delete_end_, + CreateTaskCompletionClosure(TracingDataType::kWebrtcEventLogs)); + } else { + LOG(ERROR) << "WebRtcEventLogManager not instantiated."; + } + } + + // Mark cached favicons as expired to force redownload on next visit. + if (filter_builder->MatchesMostOriginsAndDomains()) { + history::HistoryService* history_service = + HistoryServiceFactory::GetForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + if (history_service) { + history_service->SetFaviconsOutOfDateBetween( + delete_begin_, delete_end_, + CreateTaskCompletionClosure( + TracingDataType::kFaviconCacheExpiration), + &history_task_tracker_); + } + } + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_MEDIA_LICENSES + if (remove_mask & content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES) { + // TODO(jrummell): This UMA should be renamed to indicate it is for Media + // Licenses. + base::RecordAction(UserMetricsAction("ClearBrowsingData_ContentLicenses")); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // On Chrome OS, delete any content protection platform keys. + // Platform keys do not support filtering by domain, so skip this if + // clearing only a specified set of sites. + if (filter_builder->MatchesMostOriginsAndDomains()) { + const user_manager::User* user = + ash::ProfileHelper::Get()->GetUserByProfile(profile_); + if (!user) { + LOG(WARNING) << "Failed to find user for current profile."; + } else { + ::attestation::DeleteKeysRequest request; + request.set_username(cryptohome::CreateAccountIdentifierFromAccountId( + user->GetAccountId()) + .account_id()); + request.set_key_label_match( + ash::attestation::kContentProtectionKeyPrefix); + request.set_match_behavior( + ::attestation::DeleteKeysRequest::MATCH_BEHAVIOR_PREFIX); + + auto clear_platform_keys_callback = base::BindOnce( + &ChromeBrowsingDataRemoverDelegate::OnClearPlatformKeys, + weak_ptr_factory_.GetWeakPtr(), + CreateTaskCompletionClosure(TracingDataType::kTpmAttestationKeys)); + ash::AttestationClient::Get()->DeleteKeys( + request, base::BindOnce( + [](decltype(clear_platform_keys_callback) cb, + const ::attestation::DeleteKeysReply& reply) { + std::move(cb).Run(reply.status() == + ::attestation::STATUS_SUCCESS); + }, + std::move(clear_platform_keys_callback))); + } + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_ANDROID) + cdm::MediaDrmStorageImpl::ClearMatchingLicenses( + prefs, delete_begin_, delete_end, nullable_filter, + CreateTaskCompletionClosure(TracingDataType::kCdmLicenses)); +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_WIN) + CdmDocumentServiceImpl::ClearCdmData( + profile_, delete_begin, delete_end, nullable_filter, + CreateTaskCompletionClosure(TracingDataType::kCdmLicenses)); +#endif // BUILDFLAG(IS_WIN) + } + + ////////////////////////////////////////////////////////////////////////////// + // Zero suggest, Search prefetch, and search session token. + // Remove omnibox zero-suggest cache results and Search Prefetch cached + // results only when their respective URLs are in the filter. + if ((remove_mask & (content::BrowsingDataRemover::DATA_TYPE_CACHE | + content::BrowsingDataRemover::DATA_TYPE_COOKIES)) && + !filter_builder->PartitionedCookiesOnly()) { + // If there is no template service or DSE, clear the caches. + bool should_clear_zero_suggest_and_session_token = true; + bool should_clear_search_prefetch = true; + + auto* template_url_service = + TemplateURLServiceFactory::GetForProfile(profile_); + + // If there is no default search engine, clearing the cache is fine. + if (template_url_service && + template_url_service->GetDefaultSearchProvider()) { + // The suggest URL is used for zero suggest. + GURL suggest_url( + template_url_service->GetDefaultSearchProvider()->suggestions_url()); + should_clear_zero_suggest_and_session_token = + nullable_filter.is_null() || nullable_filter.Run(suggest_url); + + // The search URL is used for search prefetch. + GURL search_url(template_url_service->GetDefaultSearchProvider()->url()); + should_clear_search_prefetch = + nullable_filter.is_null() || nullable_filter.Run(search_url); + } + + // `zero_suggest_cache_service` is null if `profile_` is off the record. + auto* zero_suggest_cache_service = + ZeroSuggestCacheServiceFactory::GetForProfile(profile_); + if (should_clear_zero_suggest_and_session_token && + zero_suggest_cache_service) { + zero_suggest_cache_service->ClearCache(); + } + + // |search_prefetch_service| is null if |profile_| is off the record. + auto* search_prefetch_service = + SearchPrefetchServiceFactory::GetForProfile(profile_); + if (should_clear_search_prefetch && search_prefetch_service) + search_prefetch_service->ClearPrefetches(); + + if (should_clear_zero_suggest_and_session_token && template_url_service) + template_url_service->ClearSessionToken(); + } + + ////////////////////////////////////////////////////////////////////////////// + // Domain reliability. + if (remove_mask & (content::BrowsingDataRemover::DATA_TYPE_COOKIES | + constants::DATA_TYPE_HISTORY)) { + network::mojom::NetworkContext_DomainReliabilityClearMode mode; + if (remove_mask & content::BrowsingDataRemover::DATA_TYPE_COOKIES) + mode = network::mojom::NetworkContext::DomainReliabilityClearMode:: + CLEAR_CONTEXTS; + else + mode = network::mojom::NetworkContext::DomainReliabilityClearMode:: + CLEAR_BEACONS; + domain_reliability_clearer_.Run(filter_builder, mode, + CreateTaskCompletionClosureForMojo( + TracingDataType::kDomainReliability)); + } + + ////////////////////////////////////////////////////////////////////////////// + // Persisted isolated origins. + // Clear persisted isolated origins when cookies and other site data are + // cleared (DATA_TYPE_ISOLATED_ORIGINS is part of DATA_TYPE_SITE_DATA), or + // when history is cleared. This is because (1) clearing cookies implies + // forgetting that the user has logged into sites, which also implies + // forgetting that a user has typed a password on them, and (2) saved + // isolated origins are a form of history, since the user has visited them in + // the past and triggered isolation via heuristics like typing a password on + // them. Note that the Clear-Site-Data header should not clear isolated + // origins: they should only be cleared by user-driven actions. + // + // TODO(alexmos): Support finer-grained filtering based on time ranges and + // |filter|. For now, conservatively delete all saved isolated origins. + if (remove_mask & (constants::DATA_TYPE_ISOLATED_ORIGINS | + constants::DATA_TYPE_HISTORY) && + filter_builder->MatchesMostOriginsAndDomains()) { + browsing_data::RemoveSiteIsolationData(prefs); + } + + if (remove_mask & constants::DATA_TYPE_HISTORY) { + network::mojom::NetworkContext* network_context = + profile_->GetDefaultStoragePartition()->GetNetworkContext(); + network_context->ClearReportingCacheReports( + filter_builder->BuildNetworkServiceFilter(), + CreateTaskCompletionClosureForMojo(TracingDataType::kReportingCache)); + network_context->ClearNetworkErrorLogging( + filter_builder->BuildNetworkServiceFilter(), + CreateTaskCompletionClosureForMojo( + TracingDataType::kNetworkErrorLogging)); + } + +////////////////////////////////////////////////////////////////////////////// +// DATA_TYPE_WEB_APP_DATA +#if BUILDFLAG(IS_ANDROID) + // Clear all data associated with registered webapps. + if (remove_mask & constants::DATA_TYPE_WEB_APP_DATA) + webapp_registry_->UnregisterWebappsForUrls(filter); +#endif + +////////////////////////////////////////////////////////////////////////////// +// Remove web app history. +#if !BUILDFLAG(IS_ANDROID) + if (remove_mask & constants::DATA_TYPE_HISTORY && + web_app::AreWebAppsEnabled(profile_)) { + auto* web_app_provider = + web_app::WebAppProvider::GetForLocalAppsUnchecked(profile_); + web_app_provider->scheduler().ClearWebAppBrowsingData( + delete_begin, delete_end, + CreateTaskCompletionClosure(TracingDataType::kWebAppHistory)); + } +#endif // !BUILDFLAG(IS_ANDROID) + + ////////////////////////////////////////////////////////////////////////////// + // Remove external protocol data. + if (remove_mask & constants::DATA_TYPE_EXTERNAL_PROTOCOL_DATA && + filter_builder->MatchesMostOriginsAndDomains()) { + ExternalProtocolHandler::ClearData(profile_); + } + +#if BUILDFLAG(ENABLE_DOWNGRADE_PROCESSING) + ////////////////////////////////////////////////////////////////////////////// + // Remove data for this profile contained in any snapshots. + if (remove_mask && filter_builder->MatchesMostOriginsAndDomains()) { + base::ThreadPool::PostTaskAndReply( + FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()}, + base::BindOnce(&downgrade::RemoveDataForProfile, delete_begin_, + profile_->GetPath(), remove_mask), + CreateTaskCompletionClosure(TracingDataType::kUserDataSnapshot)); + } +#endif // BUILDFLAG(ENABLE_DOWNGRADE_PROCESSING) + + ////////////////////////////////////////////////////////////////////////////// + // Login detection data: + // Clear the origins where login has been detected, when cookies and other + // site data are cleared, or when history is cleared. This is because clearing + // cookies or history implies forgetting that the user has logged into sites. + if (remove_mask & + (constants::DATA_TYPE_SITE_DATA | constants::DATA_TYPE_HISTORY) && + filter_builder->MatchesMostOriginsAndDomains()) { + login_detection::prefs::RemoveLoginDetectionData(prefs); + } + +#if !BUILDFLAG(IS_ANDROID) + ////////////////////////////////////////////////////////////////////////////// + // Isolated Web Apps. + // If no StoragePartition was specified in the filter, make additional + // BrowsingDataRemover::Remove* calls for each StoragePartition of Isolated + // Web Apps (IWA) that match the filter. + // + // The data types specified in `remove_mask` will be removed from the primary + // StoragePartition of an IWA, and all Controlled Frame StoragePartitions if + // DATA_TYPE_CONTROLLED_FRAME is specified in `remove_mask`. + if (!filter_builder->GetStoragePartitionConfig().has_value() && + content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled(profile_)) { + const web_app::WebAppRegistrar& web_app_registrar = + web_app::WebAppProvider::GetForLocalAppsUnchecked(profile_) + ->registrar_unsafe(); + for (const web_app::WebApp& web_app : + web_app_registrar.GetAppsIncludingStubs()) { + if (!web_app_registrar.IsIsolated(web_app.app_id()) || + !filter.Run(web_app.scope())) { + continue; + } + std::vector partitions = + web_app_registrar.GetIsolatedWebAppStoragePartitionConfigs( + web_app.app_id()); + for (const content::StoragePartitionConfig& partition : partitions) { + // Only delete data types that live on a StoragePartition. + uint64_t iwa_remove_mask = + content::BrowsingDataRemover::DATA_TYPE_ON_STORAGE_PARTITION & + remove_mask; + + // COOKIES are a domain-scoped datatype. ISOLATED_WEB_APP_COOKIES are + // attributed to the Isolated Web App's origin, so we're tracking them + // as a separate origin-scoped datatype. A deletion request for an + // app's ISOLATED_WEB_APP_COOKIES is implemented as a deletion request + // for COOKIES for all domains on the app's StoragePartition. + if (remove_mask & constants::DATA_TYPE_ISOLATED_WEB_APP_COOKIES) { + iwa_remove_mask |= content::BrowsingDataRemover::DATA_TYPE_COOKIES; + } + + // We can't wait for the `RemoveWithFilter` call to finish because + // BrowsingDataRemover doesn't support nested Remove calls. + auto iwa_filter_builder = content::BrowsingDataFilterBuilder::Create( + content::BrowsingDataFilterBuilder::Mode::kPreserve); + iwa_filter_builder->SetStoragePartitionConfig(partition); + profile_->GetBrowsingDataRemover()->RemoveWithFilter( + delete_begin, delete_end, iwa_remove_mask, origin_type_mask, + std::move(iwa_filter_builder)); + } + } + } +#endif // !BUILDFLAG(IS_ANDROID) + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_TABS + if (remove_mask & constants::DATA_TYPE_TABS) { +#if BUILDFLAG(IS_ANDROID) + base::RecordAction(UserMetricsAction("ClearBrowsingData_Tabs")); + + for (TabModel* tab_model : TabModelList::models()) { + if (tab_model->GetProfile() != profile_ || tab_model->IsOffTheRecord()) { + continue; + } + + tab_model->CloseTabsNavigatedInTimeWindow(delete_begin, delete_end); + } +#else // BUILDFLAG(IS_ANDROID) + NOTIMPLEMENTED(); +#endif // BUILDFLAG(IS_ANDROID) + } + + ////////////////////////////////////////////////////////////////////////////// + // DATA_TYPE_RELATED_WEBSITE_SETS_PERMISSIONS + if (remove_mask & content::BrowsingDataRemover:: + DATA_TYPE_RELATED_WEBSITE_SETS_PERMISSIONS) { + for (ContentSettingsType type_to_clear : + {ContentSettingsType::STORAGE_ACCESS, + ContentSettingsType::TOP_LEVEL_STORAGE_ACCESS}) { + host_content_settings_map_->ClearSettingsForOneTypeWithPredicate( + type_to_clear, [&](const ContentSettingPatternSource& setting) { + return content_settings::IsGrantedByRelatedWebsiteSets( + type_to_clear, setting.metadata) && + base::ranges::any_of( + filter_builder->GetOrigins(), + [&](const url::Origin& origin) -> bool { + return setting.primary_pattern.Matches( + origin.GetURL()) || + setting.secondary_pattern.Matches( + origin.GetURL()); + }); + }); + } + } +} + +void ChromeBrowsingDataRemoverDelegate::OnTaskStarted( + TracingDataType data_type) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + auto result = pending_sub_tasks_.insert(data_type); + DCHECK(result.second) << "Task already started: " + << static_cast(data_type); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "browsing_data", "ChromeBrowsingDataRemoverDelegate", + TRACE_ID_WITH_SCOPE("ChromeBrowsingDataRemoverDelegate", + static_cast(data_type)), + "data_type", static_cast(data_type)); +} + +void ChromeBrowsingDataRemoverDelegate::OnTaskComplete( + TracingDataType data_type, + uint64_t data_type_mask, + base::TimeTicks started, + bool success) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + size_t num_erased = pending_sub_tasks_.erase(data_type); + DCHECK_EQ(num_erased, 1U); + TRACE_EVENT_NESTABLE_ASYNC_END1( + "browsing_data", "ChromeBrowsingDataRemoverDelegate", + TRACE_ID_WITH_SCOPE("ChromeBrowsingDataRemoverDelegate", + static_cast(data_type)), + "data_type", static_cast(data_type)); + base::UmaHistogramMediumTimes( + base::StrCat({"History.ClearBrowsingData.Duration.ChromeTask.", + GetHistogramSuffix(data_type)}), + base::TimeTicks::Now() - started); + + if (!success) { + base::UmaHistogramEnumeration("History.ClearBrowsingData.FailedTasksChrome", + data_type); + failed_data_types_ |= data_type_mask; + } + + if (!pending_sub_tasks_.empty()) + return; + + if (deferred_disable_passwords_auto_signin_cb_) { + std::move(deferred_disable_passwords_auto_signin_cb_).Run(); + + // Might have added new tasks. + if (!pending_sub_tasks_.empty()) { + return; + } + } + +#if !BUILDFLAG(IS_ANDROID) + // Explicitly clear any per account sync settings when cookies are being + // cleared. This needs to happen after the corresponding data has been + // deleted, so it is performed when all other tasks are completed. + // Note: These usually get cleared automatically when the Google cookies are + // deleted, but there is one edge case where that doesn't work: If the user + // clears cookies via CBD while they are already signed out (but their + // account is still present in the account chooser). In that case, without the + // code below, the settings-clearing would only happen when the Google cookies + // are refreshed the next time, typically on the next browser restart. + if (should_clear_sync_account_settings_) { + should_clear_sync_account_settings_ = false; + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(profile_); + base::flat_set gaia_ids = + signin::GetAllGaiaIdsForKeyedPreferences( + identity_manager, + signin::AccountsInCookieJarInfo() /* empty_cookies */); + if (syncer::SyncService* sync_service = + SyncServiceFactory::GetForProfile(profile_); + sync_service) { + sync_service->GetUserSettings()->KeepAccountSettingsPrefsOnlyForUsers( + base::ToVector(gaia_ids, &signin::GaiaIdHash::FromGaiaId)); + } + password_manager::features_util::KeepAccountStorageSettingsOnlyForUsers( + profile_->GetPrefs(), std::move(gaia_ids).extract()); + } +#endif // !BUILDFLAG(IS_ANDROID) + + slow_pending_tasks_closure_.Cancel(); + + DCHECK(!callback_.is_null()); + std::move(callback_).Run(failed_data_types_); +} + +const char* ChromeBrowsingDataRemoverDelegate::GetHistogramSuffix( + TracingDataType task) { + switch (task) { + case TracingDataType::kSynchronous: + return "Synchronous"; + case TracingDataType::kHistory: + return "History"; + case TracingDataType::kNaclCache: + return "NaclCache"; + case TracingDataType::kPnaclCache: + return "PnaclCache"; + case TracingDataType::kAutofillData: + return "AutofillData"; + case TracingDataType::kAutofillOrigins: + return "AutofillOrigins"; + case TracingDataType::kDomainReliability: + return "DomainReliability"; + case TracingDataType::kWebrtcLogs: + return "WebrtcLogs"; + case TracingDataType::kVideoDecodeHistory: + return "VideoDecodeHistory"; + case TracingDataType::kCookies: + return "Cookies"; + case TracingDataType::kPasswords: + return "Passwords"; + case TracingDataType::kHttpAuthCache: + return "HttpAuthCache"; + case TracingDataType::kDisableAutoSigninForProfilePasswords: + return "DisableAutoSigninForProfilePasswords"; + case TracingDataType::kDisableAutoSigninForAccountPasswords: + return "DisableAutoSigninForAccountPasswords"; + case TracingDataType::kPasswordsStatistics: + return "PasswordsStatistics"; + case TracingDataType::kReportingCache: + return "ReportingCache"; + case TracingDataType::kNetworkErrorLogging: + return "NetworkErrorLogging"; + case TracingDataType::kOfflinePages: + return "OfflinePages"; + case TracingDataType::kWebrtcEventLogs: + return "WebrtcEventLogs"; + case TracingDataType::kCdmLicenses: + return "CdmLicenses"; + case TracingDataType::kHostCache: + return "HostCache"; + case TracingDataType::kTpmAttestationKeys: + return "TpmAttestationKeys"; + case TracingDataType::kUserDataSnapshot: + return "UserDataSnapshot"; + case TracingDataType::kAccountPasswords: + return "AccountPasswords"; + case TracingDataType::kAccountPasswordsSynced: + return "AccountPasswordsSynced"; + case TracingDataType::kFaviconCacheExpiration: + return "FaviconCacheExpiration"; + case TracingDataType::kSecurePaymentConfirmationCredentials: + return "SecurePaymentConfirmationCredentials"; + case TracingDataType::kWebAppHistory: + return "WebAppHistory"; + case TracingDataType::kWebAuthnCredentials: + return "WebAuthnCredentials"; + case TracingDataType::kWebrtcVideoPerfHistory: + return "WebrtcVideoPerfHistory"; + case TracingDataType::kMediaDeviceSalts: + return "MediaDeviceSalts"; + } +} + +void ChromeBrowsingDataRemoverDelegate::OnStartRemoving() { + profile_keep_alive_ = std::make_unique( + profile_->GetOriginalProfile(), + ProfileKeepAliveOrigin::kClearingBrowsingData); +} + +void ChromeBrowsingDataRemoverDelegate::OnDoneRemoving() { + profile_keep_alive_.reset(); +} + +base::OnceClosure +ChromeBrowsingDataRemoverDelegate::CreateTaskCompletionClosure( + TracingDataType data_type) { + OnTaskStarted(data_type); + return base::BindOnce(&ChromeBrowsingDataRemoverDelegate::OnTaskComplete, + weak_ptr_factory_.GetWeakPtr(), data_type, + /*data_type_mask=*/0, base::TimeTicks::Now(), + /*success=*/true); +} + +base::OnceCallback +ChromeBrowsingDataRemoverDelegate::CreateTaskCompletionCallback( + TracingDataType data_type, + uint64_t data_type_mask) { + OnTaskStarted(data_type); + return base::BindOnce(&ChromeBrowsingDataRemoverDelegate::OnTaskComplete, + weak_ptr_factory_.GetWeakPtr(), data_type, + data_type_mask, base::TimeTicks::Now()); +} + +base::OnceClosure +ChromeBrowsingDataRemoverDelegate::CreateTaskCompletionClosureForMojo( + TracingDataType data_type) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Note num_pending_tasks++ unnecessary here because it's done by the call to + // CreateTaskCompletionClosure(). + return mojo::WrapCallbackWithDropHandler( + CreateTaskCompletionClosure(data_type), + base::BindOnce(&ChromeBrowsingDataRemoverDelegate::OnTaskComplete, + weak_ptr_factory_.GetWeakPtr(), data_type, + /*data_type_mask=*/0, base::TimeTicks::Now(), + /*success=*/true)); +} + +void ChromeBrowsingDataRemoverDelegate::RecordUnfinishedSubTasks() { + DCHECK(!pending_sub_tasks_.empty()); + for (TracingDataType task : pending_sub_tasks_) { + UMA_HISTOGRAM_ENUMERATION( + "History.ClearBrowsingData.Duration.SlowTasks180sChrome", task); + } +} + +#if BUILDFLAG(IS_ANDROID) +void ChromeBrowsingDataRemoverDelegate::OverrideWebappRegistryForTesting( + std::unique_ptr webapp_registry) { + webapp_registry_ = std::move(webapp_registry); +} +#endif + +void ChromeBrowsingDataRemoverDelegate:: + OverrideDomainReliabilityClearerForTesting( + DomainReliabilityClearer clearer) { + domain_reliability_clearer_ = std::move(clearer); +} + +bool ChromeBrowsingDataRemoverDelegate::IsForAllTime() const { + return delete_begin_ == base::Time() && delete_end_ == base::Time::Max(); +} + +#if BUILDFLAG(IS_CHROMEOS_ASH) +void ChromeBrowsingDataRemoverDelegate::OnClearPlatformKeys( + base::OnceClosure done, + bool result) { + LOG_IF(ERROR, !result) << "Failed to clear platform keys."; + std::move(done).Run(); +} +#endif + +std::unique_ptr +ChromeBrowsingDataRemoverDelegate::MakeCredentialStore() { + return +#if BUILDFLAG(IS_CHROMEOS_ASH) + std::make_unique< + device::fido::cros::PlatformAuthenticatorCredentialStore>(); +#else + nullptr; +#endif +} + +void ChromeBrowsingDataRemoverDelegate::DisablePasswordsAutoSignin( + const base::RepeatingCallback& url_filter) { + scoped_refptr profile_store = + ProfilePasswordStoreFactory::GetForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + scoped_refptr account_store = + AccountPasswordStoreFactory::GetForProfile( + profile_, ServiceAccessType::EXPLICIT_ACCESS); + syncer::SyncService* sync_service = + SyncServiceFactory::GetForProfile(profile_); + if (profile_store) { + profile_store->DisableAutoSignInForOrigins( + url_filter, + CreateTaskCompletionClosure( + TracingDataType::kDisableAutoSigninForProfilePasswords)); + } + if (account_store && + password_manager::features_util::IsOptedInForAccountStorage( + profile_->GetPrefs(), sync_service)) { + account_store->DisableAutoSignInForOrigins( + url_filter, + CreateTaskCompletionClosure( + TracingDataType::kDisableAutoSigninForAccountPasswords)); + } +} diff --git a/tools/under-control/src/chrome/browser/chrome_browser_interface_binders.cc b/tools/under-control/src/chrome/browser/chrome_browser_interface_binders.cc new file mode 100755 index 000000000..2730ad90d --- /dev/null +++ b/tools/under-control/src/chrome/browser/chrome_browser_interface_binders.cc @@ -0,0 +1,1956 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chrome_browser_interface_binders.h" + +#include + +#include "base/feature_list.h" +#include "base/functional/bind.h" +#include "base/strings/stringprintf.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/accessibility/accessibility_labels_service.h" +#include "chrome/browser/accessibility/accessibility_labels_service_factory.h" +#include "chrome/browser/ash/drive/file_system_util.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/buildflags.h" +#include "chrome/browser/cart/commerce_hint_service.h" +#include "chrome/browser/companion/core/features.h" +#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" +#include "chrome/browser/history_clusters/history_clusters_service_factory.h" +#include "chrome/browser/media/media_engagement_score_details.mojom.h" +#include "chrome/browser/navigation_predictor/navigation_predictor.h" +#include "chrome/browser/on_device_translation/translation_manager_impl.h" +#include "chrome/browser/optimization_guide/optimization_guide_internals_ui.h" +#include "chrome/browser/password_manager/chrome_password_manager_client.h" +#include "chrome/browser/predictors/lcp_critical_path_predictor/lcp_critical_path_predictor_host.h" +#include "chrome/browser/predictors/network_hints_handler_impl.h" +#include "chrome/browser/preloading/prefetch/no_state_prefetch/chrome_no_state_prefetch_contents_delegate.h" +#include "chrome/browser/preloading/prefetch/no_state_prefetch/chrome_no_state_prefetch_processor_impl_delegate.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "chrome/browser/ssl/security_state_tab_helper.h" +#include "chrome/browser/translate/translate_frame_binder.h" +#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h" +#include "chrome/browser/ui/ui_features.h" +#include "chrome/browser/ui/views/side_panel/companion/companion_utils.h" +#include "chrome/browser/ui/webui/browsing_topics/browsing_topics_internals_ui.h" +#include "chrome/browser/ui/webui/data_sharing_internals/data_sharing_internals_ui.h" +#include "chrome/browser/ui/webui/engagement/site_engagement_ui.h" +#include "chrome/browser/ui/webui/internals/internals_ui.h" +#include "chrome/browser/ui/webui/location_internals/location_internals.mojom.h" +#include "chrome/browser/ui/webui/location_internals/location_internals_ui.h" +#include "chrome/browser/ui/webui/media/media_engagement_ui.h" +#include "chrome/browser/ui/webui/omnibox/omnibox.mojom.h" +#include "chrome/browser/ui/webui/omnibox/omnibox_ui.h" +#include "chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_internals_ui.h" +#include "chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.h" +#include "chrome/browser/ui/webui/suggest_internals/suggest_internals.mojom.h" +#include "chrome/browser/ui/webui/suggest_internals/suggest_internals_ui.h" +#include "chrome/browser/ui/webui/usb_internals/usb_internals.mojom.h" +#include "chrome/browser/ui/webui/usb_internals/usb_internals_ui.h" +#include "chrome/browser/web_applications/web_app_utils.h" +#include "chrome/common/buildflags.h" +#include "chrome/common/chrome_features.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/services/speech/buildflags/buildflags.h" +#include "components/browsing_topics/mojom/browsing_topics_internals.mojom.h" +#include "components/commerce/content/browser/commerce_internals_ui.h" +#include "components/commerce/core/internals/mojom/commerce_internals.mojom.h" +#include "components/compose/buildflags.h" +#include "components/data_sharing/public/features.h" +#include "components/dom_distiller/content/browser/distillability_driver.h" +#include "components/dom_distiller/content/browser/distiller_javascript_service_impl.h" +#include "components/dom_distiller/content/common/mojom/distillability_service.mojom.h" +#include "components/dom_distiller/content/common/mojom/distiller_javascript_service.mojom.h" +#include "components/dom_distiller/core/dom_distiller_service.h" +#include "components/feed/buildflags.h" +#include "components/history_clusters/core/features.h" +#include "components/history_clusters/core/history_clusters_service.h" +#include "components/history_clusters/history_clusters_internals/webui/history_clusters_internals_ui.h" +#include "components/history_embeddings/history_embeddings_features.h" +#include "components/lens/lens_features.h" +#include "components/live_caption/caption_util.h" +#include "components/live_caption/pref_names.h" +#include "components/no_state_prefetch/browser/no_state_prefetch_contents.h" +#include "components/no_state_prefetch/browser/no_state_prefetch_processor_impl.h" +#include "components/performance_manager/embedder/binders.h" +#include "components/performance_manager/public/performance_manager.h" +#include "components/prefs/pref_service.h" +#include "components/privacy_sandbox/privacy_sandbox_features.h" +#include "components/reading_list/features/reading_list_switches.h" +#include "components/safe_browsing/buildflags.h" +#include "components/search_engines/search_engine_choice/search_engine_choice_utils.h" +#include "components/security_state/content/content_utils.h" +#include "components/security_state/core/security_state.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/site_engagement/core/mojom/site_engagement_details.mojom.h" +#include "components/translate/content/common/translate.mojom.h" +#include "components/user_notes/user_notes_features.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/web_ui_browser_interface_broker_registry.h" +#include "content/public/browser/web_ui_controller_interface_binder.h" +#include "content/public/common/content_features.h" +#include "content/public/common/url_constants.h" +#include "extensions/buildflags/buildflags.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "services/image_annotation/public/mojom/image_annotation.mojom.h" +#include "services/screen_ai/buildflags/buildflags.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/features_generated.h" +#include "third_party/blink/public/mojom/credentialmanagement/credential_manager.mojom.h" +#include "third_party/blink/public/mojom/facilitated_payments/payment_link_handler.mojom.h" +#include "third_party/blink/public/mojom/lcp_critical_path_predictor/lcp_critical_path_predictor.mojom.h" +#include "third_party/blink/public/mojom/loader/navigation_predictor.mojom.h" +#include "third_party/blink/public/mojom/on_device_translation/translation_manager.mojom.h" +#include "third_party/blink/public/mojom/payments/payment_credential.mojom.h" +#include "third_party/blink/public/mojom/payments/payment_request.mojom.h" +#include "third_party/blink/public/mojom/prerender/prerender.mojom.h" +#include "third_party/blink/public/public_buildflags.h" +#include "ui/accessibility/accessibility_features.h" + +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) +#include "chrome/browser/screen_ai/screen_ai_service_router.h" +#include "chrome/browser/screen_ai/screen_ai_service_router_factory.h" +#endif + +#if BUILDFLAG(ENABLE_UNHANDLED_TAP) +#include "chrome/browser/android/contextualsearch/unhandled_tap_notifier_impl.h" +#include "chrome/browser/android/contextualsearch/unhandled_tap_web_contents_observer.h" +#include "third_party/blink/public/mojom/unhandled_tap_notifier/unhandled_tap_notifier.mojom.h" +#endif // BUILDFLAG(ENABLE_UNHANDLED_TAP) + +#if BUILDFLAG(FULL_SAFE_BROWSING) +#include "chrome/browser/ui/webui/reset_password/reset_password.mojom.h" +#include "chrome/browser/ui/webui/reset_password/reset_password_ui.h" +#endif // BUILDFLAG(FULL_SAFE_BROWSING) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ui/webui/connectors_internals/connectors_internals.mojom.h" +#include "chrome/browser/ui/webui/connectors_internals/connectors_internals_ui.h" +#endif + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) +#include "chrome/browser/ui/webui/app_settings/web_app_settings_ui.h" +#include "ui/webui/resources/cr_components/app_management/app_management.mojom.h" +#endif + +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h" +#include "chrome/browser/facilitated_payments/payment_link_handler_factory.h" +#include "chrome/browser/offline_pages/android/offline_page_auto_fetcher.h" +#include "chrome/browser/ui/webui/feed_internals/feed_internals.mojom.h" +#include "chrome/browser/ui/webui/feed_internals/feed_internals_ui.h" +#include "chrome/common/offline_page_auto_fetcher.mojom.h" +#include "components/commerce/core/commerce_feature_list.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom.h" +#include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom.h" +#else +#include "chrome/browser/badging/badge_manager.h" +#include "chrome/browser/cart/chrome_cart.mojom.h" +#include "chrome/browser/new_tab_page/modules/feed/feed.mojom.h" +#include "chrome/browser/new_tab_page/modules/file_suggestion/file_suggestion.mojom.h" +#include "chrome/browser/new_tab_page/modules/history_clusters/history_clusters.mojom.h" +#include "chrome/browser/new_tab_page/modules/v2/calendar/google_calendar.mojom.h" +#include "chrome/browser/new_tab_page/modules/v2/most_relevant_tab_resumption/most_relevant_tab_resumption.mojom.h" +#include "chrome/browser/new_tab_page/modules/v2/tab_resumption/tab_resumption.mojom.h" +#include "chrome/browser/new_tab_page/new_tab_page_util.h" +#include "chrome/browser/payments/payment_request_factory.h" +#include "chrome/browser/ui/webui/access_code_cast/access_code_cast.mojom.h" +#include "chrome/browser/ui/webui/access_code_cast/access_code_cast_ui.h" +#include "chrome/browser/ui/webui/app_service_internals/app_service_internals.mojom.h" +#include "chrome/browser/ui/webui/app_service_internals/app_service_internals_ui.h" +#include "chrome/browser/ui/webui/downloads/downloads.mojom.h" +#include "chrome/browser/ui/webui/downloads/downloads_ui.h" +#include "chrome/browser/ui/webui/on_device_internals/on_device_internals_ui.h" +#include "chrome/browser/ui/webui/web_app_internals/web_app_internals.mojom.h" +#include "chrome/browser/ui/webui/web_app_internals/web_app_internals_ui.h" +#if !defined(OFFICIAL_BUILD) +#include "chrome/browser/ui/webui/new_tab_page/foo/foo.mojom.h" // nogncheck crbug.com/1125897 +#endif +#include "chrome/browser/ui/lens/lens_untrusted_ui.h" +#include "chrome/browser/ui/lens/search_bubble_ui.h" +#include "chrome/browser/ui/views/side_panel/customize_chrome/customize_chrome_utils.h" +#include "chrome/browser/ui/webui/commerce/product_specifications_ui.h" +#include "chrome/browser/ui/webui/commerce/shopping_insights_side_panel_ui.h" +#include "chrome/browser/ui/webui/data_sharing/data_sharing.mojom.h" +#include "chrome/browser/ui/webui/data_sharing/data_sharing_ui.h" +#include "chrome/browser/ui/webui/hats/hats_ui.h" +#include "chrome/browser/ui/webui/history/history_ui.h" +#include "chrome/browser/ui/webui/internals/user_education/user_education_internals.mojom.h" +#include "chrome/browser/ui/webui/new_tab_page/new_tab_page.mojom.h" +#include "chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h" +#include "chrome/browser/ui/webui/new_tab_page_third_party/new_tab_page_third_party_ui.h" +#include "chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.h" +#include "chrome/browser/ui/webui/password_manager/password_manager_ui.h" +#include "chrome/browser/ui/webui/privacy_sandbox/related_website_sets/related_website_sets.mojom.h" +#include "chrome/browser/ui/webui/search_engine_choice/search_engine_choice.mojom.h" // nogncheck crbug.com/1125897 +#include "chrome/browser/ui/webui/search_engine_choice/search_engine_choice_ui.h" +#include "chrome/browser/ui/webui/settings/settings_ui.h" +#include "chrome/browser/ui/webui/side_panel/bookmarks/bookmarks_side_panel_ui.h" +#include "chrome/browser/ui/webui/side_panel/companion/companion_side_panel_untrusted_ui.h" +#include "chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome.mojom.h" +#include "chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.h" +#include "chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search.mojom.h" +#include "chrome/browser/ui/webui/side_panel/history_clusters/history_clusters_side_panel_ui.h" +#include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_ui.h" +#include "chrome/browser/ui/webui/side_panel/reading_list/reading_list.mojom.h" +#include "chrome/browser/ui/webui/side_panel/reading_list/reading_list_ui.h" +#include "chrome/browser/ui/webui/tab_search/tab_search.mojom.h" +#include "chrome/browser/ui/webui/tab_search/tab_search_ui.h" +#include "chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.h" +#include "chrome/common/webui_url_constants.h" +#include "components/optimization_guide/core/optimization_guide_features.h" +#include "components/page_image_service/mojom/page_image_service.mojom.h" +#include "components/search/ntp_features.h" +#include "ui/webui/resources/cr_components/color_change_listener/color_change_listener.mojom.h" +#include "ui/webui/resources/cr_components/commerce/shopping_service.mojom.h" // nogncheck crbug.com/1125897 +#include "ui/webui/resources/cr_components/customize_color_scheme_mode/customize_color_scheme_mode.mojom.h" +#include "ui/webui/resources/cr_components/help_bubble/help_bubble.mojom.h" +#include "ui/webui/resources/cr_components/history_clusters/history_clusters.mojom.h" +#include "ui/webui/resources/cr_components/history_embeddings/history_embeddings.mojom.h" +#include "ui/webui/resources/cr_components/most_visited/most_visited.mojom.h" +#include "ui/webui/resources/cr_components/searchbox/searchbox.mojom.h" +#include "ui/webui/resources/cr_components/theme_color_picker/theme_color_picker.mojom.h" +#include "ui/webui/resources/js/browser_command/browser_command.mojom.h" +#include "ui/webui/resources/js/metrics_reporter/metrics_reporter.mojom.h" +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) +#include "chrome/browser/companion/visual_query/visual_query_suggestions_service_factory.h" +#include "chrome/browser/ui/web_applications/sub_apps_service_impl.h" +#include "chrome/browser/ui/webui/discards/discards.mojom.h" +#include "chrome/browser/ui/webui/discards/discards_ui.h" +#include "chrome/browser/ui/webui/discards/site_data.mojom.h" +#include "chrome/common/companion/visual_query.mojom.h" +#include "chrome/common/companion/visual_query/features.h" +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) +#include "chrome/browser/ui/webui/whats_new/whats_new_ui.h" +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + +#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/ui/webui/app_home/app_home.mojom.h" +#include "chrome/browser/ui/webui/app_home/app_home_ui.h" +#endif // !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID) + +#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/ui/webui/signin/profile_customization_ui.h" +#include "chrome/browser/ui/webui/signin/profile_picker_ui.h" +#endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "ash/constants/ash_features.h" +#include "ash/public/mojom/hid_preserving_bluetooth_state_controller.mojom.h" +#include "ash/webui/annotator/mojom/untrusted_annotator.mojom.h" +#include "ash/webui/annotator/untrusted_annotator_ui.h" +#include "ash/webui/boca_ui/boca_ui.h" +#include "ash/webui/boca_ui/mojom/boca.mojom.h" +#include "ash/webui/camera_app_ui/camera_app_helper.mojom.h" +#include "ash/webui/camera_app_ui/camera_app_ui.h" +#include "ash/webui/color_internals/color_internals_ui.h" +#include "ash/webui/color_internals/mojom/color_internals.mojom.h" +#include "ash/webui/common/mojom/accelerator_fetcher.mojom.h" +#include "ash/webui/common/mojom/accessibility_features.mojom.h" +#include "ash/webui/common/mojom/sea_pen.mojom.h" +#include "ash/webui/common/mojom/shortcut_input_provider.mojom.h" +#include "ash/webui/connectivity_diagnostics/connectivity_diagnostics_ui.h" +#include "ash/webui/demo_mode_app_ui/demo_mode_app_untrusted_ui.h" +#include "ash/webui/diagnostics_ui/diagnostics_ui.h" +#include "ash/webui/diagnostics_ui/mojom/input_data_provider.mojom.h" +#include "ash/webui/diagnostics_ui/mojom/network_health_provider.mojom.h" +#include "ash/webui/diagnostics_ui/mojom/system_data_provider.mojom.h" +#include "ash/webui/diagnostics_ui/mojom/system_routine_controller.mojom.h" +#include "ash/webui/eche_app_ui/eche_app_ui.h" +#include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h" +#include "ash/webui/file_manager/file_manager_ui.h" +#include "ash/webui/file_manager/mojom/file_manager.mojom.h" +#include "ash/webui/files_internals/files_internals_ui.h" +#include "ash/webui/files_internals/mojom/files_internals.mojom.h" +#include "ash/webui/firmware_update_ui/firmware_update_app_ui.h" +#include "ash/webui/firmware_update_ui/mojom/firmware_update.mojom.h" +#include "ash/webui/focus_mode/focus_mode_ui.h" +#include "ash/webui/focus_mode/mojom/focus_mode.mojom.h" +#include "ash/webui/help_app_ui/help_app_ui.h" +#include "ash/webui/help_app_ui/help_app_ui.mojom.h" +#include "ash/webui/help_app_ui/help_app_untrusted_ui.h" +#include "ash/webui/help_app_ui/search/search.mojom.h" +#include "ash/webui/mall/mall_ui.h" +#include "ash/webui/mall/mall_ui.mojom.h" +#include "ash/webui/media_app_ui/media_app_guest_ui.h" +#include "ash/webui/media_app_ui/media_app_ui.h" +#include "ash/webui/media_app_ui/media_app_ui.mojom.h" +#include "ash/webui/media_app_ui/media_app_ui_untrusted.mojom.h" +#include "ash/webui/multidevice_debug/proximity_auth_ui.h" +#include "ash/webui/os_feedback_ui/mojom/os_feedback_ui.mojom.h" +#include "ash/webui/os_feedback_ui/os_feedback_ui.h" +#include "ash/webui/os_feedback_ui/os_feedback_untrusted_ui.h" +#include "ash/webui/personalization_app/mojom/personalization_app.mojom.h" +#include "ash/webui/personalization_app/personalization_app_ui.h" +#include "ash/webui/personalization_app/search/search.mojom.h" +#include "ash/webui/print_management/print_management_ui.h" +#include "ash/webui/print_preview_cros/mojom/destination_provider.mojom.h" +#include "ash/webui/print_preview_cros/print_preview_cros_ui.h" +#include "ash/webui/projector_app/mojom/untrusted_projector.mojom.h" +#include "ash/webui/projector_app/untrusted_projector_ui.h" +#include "ash/webui/recorder_app_ui/mojom/recorder_app.mojom.h" +#include "ash/webui/recorder_app_ui/recorder_app_ui.h" +#include "ash/webui/sanitize_ui/sanitize_ui.h" +#include "ash/webui/scanning/mojom/scanning.mojom.h" +#include "ash/webui/scanning/scanning_ui.h" +#include "ash/webui/shimless_rma/shimless_rma.h" +#include "ash/webui/shortcut_customization_ui/backend/search/search.mojom.h" +#include "ash/webui/shortcut_customization_ui/mojom/shortcut_customization.mojom.h" +#include "ash/webui/shortcut_customization_ui/shortcut_customization_app_ui.h" +#include "ash/webui/vc_background_ui/vc_background_ui.h" +#include "chrome/browser/apps/digital_goods/digital_goods_factory_impl.h" +#include "chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.h" +#include "chrome/browser/nearby_sharing/common/nearby_share_features.h" +#include "chrome/browser/speech/cros_speech_recognition_service_factory.h" +#include "chrome/browser/ui/webui/ash/add_supervision/add_supervision.mojom.h" +#include "chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui.h" +#include "chrome/browser/ui/webui/ash/app_install/app_install.mojom.h" +#include "chrome/browser/ui/webui/ash/app_install/app_install_dialog.h" +#include "chrome/browser/ui/webui/ash/app_install/app_install_ui.h" +#include "chrome/browser/ui/webui/ash/audio/audio.mojom.h" +#include "chrome/browser/ui/webui/ash/audio/audio_ui.h" +#include "chrome/browser/ui/webui/ash/bluetooth_pairing_dialog.h" +#include "chrome/browser/ui/webui/ash/borealis_installer/borealis_installer.mojom.h" +#include "chrome/browser/ui/webui/ash/borealis_installer/borealis_installer_ui.h" +#include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload.mojom.h" +#include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.h" +#include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_ui.h" +#include "chrome/browser/ui/webui/ash/crostini_installer/crostini_installer.mojom.h" +#include "chrome/browser/ui/webui/ash/crostini_installer/crostini_installer_ui.h" +#include "chrome/browser/ui/webui/ash/crostini_upgrader/crostini_upgrader.mojom.h" +#include "chrome/browser/ui/webui/ash/crostini_upgrader/crostini_upgrader_ui.h" +#include "chrome/browser/ui/webui/ash/emoji/emoji_picker.mojom.h" +#include "chrome/browser/ui/webui/ash/emoji/emoji_search_proxy.h" +#include "chrome/browser/ui/webui/ash/emoji/emoji_ui.h" +#include "chrome/browser/ui/webui/ash/emoji/new_window_proxy.mojom.h" +#include "chrome/browser/ui/webui/ash/emoji/seal.mojom.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting.mojom.h" +#include "chrome/browser/ui/webui/ash/enterprise_reporting/enterprise_reporting_ui.h" +#include "chrome/browser/ui/webui/ash/extended_updates/extended_updates.mojom.h" +#include "chrome/browser/ui/webui/ash/extended_updates/extended_updates_ui.h" +#include "chrome/browser/ui/webui/ash/internet_config_dialog.h" +#include "chrome/browser/ui/webui/ash/internet_detail_dialog.h" +#include "chrome/browser/ui/webui/ash/launcher_internals/launcher_internals.mojom.h" +#include "chrome/browser/ui/webui/ash/launcher_internals/launcher_internals_ui.h" +#include "chrome/browser/ui/webui/ash/lock_screen_reauth/lock_screen_network_ui.h" +#include "chrome/browser/ui/webui/ash/login/mojom/screens_factory.mojom.h" +#include "chrome/browser/ui/webui/ash/login/oobe_ui.h" +#include "chrome/browser/ui/webui/ash/mako/mako_ui.h" +#include "chrome/browser/ui/webui/ash/manage_mirrorsync/manage_mirrorsync.mojom.h" +#include "chrome/browser/ui/webui/ash/manage_mirrorsync/manage_mirrorsync_ui.h" +#include "chrome/browser/ui/webui/ash/multidevice_setup/multidevice_setup_dialog.h" +#include "chrome/browser/ui/webui/ash/network_ui.h" +#include "chrome/browser/ui/webui/ash/office_fallback/office_fallback.mojom.h" +#include "chrome/browser/ui/webui/ash/office_fallback/office_fallback_ui.h" +#include "chrome/browser/ui/webui/ash/parent_access/parent_access_ui.h" +#include "chrome/browser/ui/webui/ash/parent_access/parent_access_ui.mojom.h" +#include "chrome/browser/ui/webui/ash/remote_maintenance_curtain_ui.h" +#include "chrome/browser/ui/webui/ash/sensor_info/sensor.mojom.h" +#include "chrome/browser/ui/webui/ash/sensor_info/sensor_info_ui.h" +#include "chrome/browser/ui/webui/ash/set_time_ui.h" +#include "chrome/browser/ui/webui/ash/settings/os_settings_ui.h" +#include "chrome/browser/ui/webui/ash/settings/pages/apps/mojom/app_notification_handler.mojom.h" +#include "chrome/browser/ui/webui/ash/settings/pages/apps/mojom/app_parental_controls_handler.mojom.h" +#include "chrome/browser/ui/webui/ash/settings/pages/date_time/mojom/date_time_handler.mojom.h" +#include "chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider.mojom.h" +#include "chrome/browser/ui/webui/ash/settings/pages/device/input_device_settings/input_device_settings_provider.mojom.h" +#include "chrome/browser/ui/webui/ash/settings/pages/files/mojom/google_drive_handler.mojom.h" +#include "chrome/browser/ui/webui/ash/settings/pages/files/mojom/one_drive_handler.mojom.h" +#include "chrome/browser/ui/webui/ash/settings/pages/privacy/mojom/app_permission_handler.mojom.h" +#include "chrome/browser/ui/webui/ash/settings/search/mojom/search.mojom.h" +#include "chrome/browser/ui/webui/ash/settings/search/mojom/user_action_recorder.mojom.h" +#include "chrome/browser/ui/webui/ash/smb_shares/smb_credentials_dialog.h" +#include "chrome/browser/ui/webui/ash/smb_shares/smb_share_dialog.h" +#include "chrome/browser/ui/webui/ash/vm/vm.mojom.h" +#include "chrome/browser/ui/webui/ash/vm/vm_ui.h" +#include "chrome/browser/ui/webui/feedback/feedback_ui.h" +#include "chrome/browser/ui/webui/nearby_share/nearby_share.mojom.h" +#include "chrome/browser/ui/webui/nearby_share/nearby_share_dialog_ui.h" +#include "chromeos/ash/components/audio/public/mojom/cros_audio_config.mojom.h" +#include "chromeos/ash/components/emoji/emoji_search.mojom.h" +#include "chromeos/ash/components/kiosk/vision/webui/kiosk_vision_internals.mojom.h" +#include "chromeos/ash/components/kiosk/vision/webui/ui_controller.h" +#include "chromeos/ash/components/local_search_service/public/mojom/index.mojom.h" +#include "chromeos/ash/services/auth_factor_config/public/mojom/auth_factor_config.mojom.h" +#include "chromeos/ash/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h" +#include "chromeos/ash/services/cellular_setup/public/mojom/cellular_setup.mojom.h" +#include "chromeos/ash/services/cellular_setup/public/mojom/esim_manager.mojom.h" +#include "chromeos/ash/services/connectivity/public/mojom/passpoint.mojom.h" +#include "chromeos/ash/services/hotspot_config/public/mojom/cros_hotspot_config.mojom.h" +#include "chromeos/ash/services/ime/public/mojom/input_method_user_data.mojom.h" +#include "chromeos/ash/services/multidevice_setup/multidevice_setup_service.h" +#include "chromeos/ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" +#include "chromeos/ash/services/nearby/public/mojom/nearby_share_settings.mojom.h" // nogncheck crbug.com/1125897 +#include "chromeos/ash/services/orca/public/mojom/orca_service.mojom.h" +#include "chromeos/components/print_management/mojom/printing_manager.mojom.h" // nogncheck +#include "chromeos/constants/chromeos_features.h" +#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h" // nogncheck +#include "chromeos/services/network_health/public/mojom/network_diagnostics.mojom.h" // nogncheck +#include "chromeos/services/network_health/public/mojom/network_health.mojom.h" // nogncheck +#include "media/capture/video/chromeos/mojom/camera_app.mojom.h" +#include "third_party/blink/public/mojom/digital_goods/digital_goods.mojom.h" +#include "ui/webui/resources/cr_components/app_management/app_management.mojom.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/apps/digital_goods/digital_goods_factory_stub.h" +#include "chrome/browser/apps/digital_goods/digital_goods_lacros.h" +#include "chrome/browser/chromeos/cros_apps/api/cros_apps_api_frame_context.h" +#include "chrome/browser/chromeos/cros_apps/api/cros_apps_api_registry.h" +#include "chrome/browser/lacros/cros_apps/api/diagnostics/cros_diagnostics_impl.h" +#include "chromeos/constants/chromeos_features.h" +#include "chromeos/lacros/lacros_service.h" +#include "third_party/blink/public/mojom/chromeos/diagnostics/cros_diagnostics.mojom.h" +#else +#include "chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals.mojom.h" // nogncheck +#include "chrome/browser/ui/webui/bluetooth_internals/bluetooth_internals_ui.h" // nogncheck +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || \ + BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) +#include "chrome/browser/webshare/share_service_impl.h" +#endif +#include "third_party/blink/public/mojom/webshare/webshare.mojom.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OFFICIAL_BUILD) +#include "ash/webui/sample_system_web_app_ui/mojom/sample_system_web_app_ui.mojom.h" +#include "ash/webui/sample_system_web_app_ui/sample_system_web_app_ui.h" +#include "ash/webui/sample_system_web_app_ui/sample_system_web_app_untrusted_ui.h" +#include "ash/webui/status_area_internals/mojom/status_area_internals.mojom.h" +#include "ash/webui/status_area_internals/status_area_internals_ui.h" +#endif + +#if BUILDFLAG(ENABLE_SPEECH_SERVICE) +#include "chrome/browser/accessibility/live_caption/live_caption_speech_recognition_host.h" +#include "chrome/browser/accessibility/live_caption/live_caption_unavailability_notifier.h" +#include "chrome/browser/speech/speech_recognition_client_browser_interface.h" +#include "chrome/browser/speech/speech_recognition_client_browser_interface_factory.h" +#include "chrome/browser/speech/speech_recognition_service.h" +#include "media/mojo/mojom/renderer_extensions.mojom.h" +#include "media/mojo/mojom/speech_recognition.mojom.h" // nogncheck +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/accessibility/live_caption/live_caption_surface.h" +#include "chromeos/crosapi/mojom/speech_recognition.mojom.h" +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) +#endif // BUILDFLAG(ENABLE_SPEECH_SERVICE) + +#if BUILDFLAG(IS_WIN) +#include "chrome/browser/media/media_foundation_service_monitor.h" +#include "media/mojo/mojom/media_foundation_preferences.mojom.h" +#include "media/mojo/services/media_foundation_preferences.h" +#endif // BUILDFLAG(IS_WIN) + +#if BUILDFLAG(ENABLE_BROWSER_SPEECH_SERVICE) +#include "chrome/browser/speech/speech_recognition_service_factory.h" +#include "media/mojo/mojom/speech_recognition_service.mojom.h" +#endif // BUILDFLAG(ENABLE_BROWSER_SPEECH_SERVICE) + +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "extensions/browser/api/mime_handler_private/mime_handler_private.h" +#include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h" +#include "extensions/common/api/mime_handler.mojom.h" // nogncheck +#endif + +#if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) +#include "chrome/browser/ui/webui/tab_strip/tab_strip.mojom.h" +#include "chrome/browser/ui/webui/tab_strip/tab_strip_ui.h" +#endif + +#if BUILDFLAG(ENABLE_COMPOSE) +#include "chrome/browser/ui/webui/compose/compose_untrusted_ui.h" +#include "chrome/common/compose/compose.mojom.h" +#endif + +#if BUILDFLAG(ENABLE_PRINT_PREVIEW) +#include "chrome/browser/printing/web_api/web_printing_service_binder.h" +#include "third_party/blink/public/mojom/printing/web_printing.mojom.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS) +#include "chrome/browser/ui/webui/dlp_internals/dlp_internals.mojom.h" +#include "chrome/browser/ui/webui/dlp_internals/dlp_internals_ui.h" +#endif + +#if BUILDFLAG(CHROME_ROOT_STORE_CERT_MANAGEMENT_UI) +#include "chrome/browser/ui/webui/certificate_manager/certificate_manager_ui.h" +#include "ui/webui/resources/cr_components/certificate_manager/certificate_manager_v2.mojom.h" +#endif // BUILDFLAG(CHROME_ROOT_STORE_CERT_MANAGEMENT_UI) + +namespace chrome::internal { + +using content::RegisterWebUIControllerInterfaceBinder; + +#if BUILDFLAG(ENABLE_UNHANDLED_TAP) +void BindUnhandledTapWebContentsObserver( + content::RenderFrameHost* const host, + mojo::PendingReceiver receiver) { + auto* web_contents = content::WebContents::FromRenderFrameHost(host); + if (!web_contents) { + return; + } + + auto* unhandled_tap_notifier_observer = + contextual_search::UnhandledTapWebContentsObserver::FromWebContents( + web_contents); + if (!unhandled_tap_notifier_observer) { + return; + } + + contextual_search::CreateUnhandledTapNotifierImpl( + unhandled_tap_notifier_observer->unhandled_tap_callback(), + std::move(receiver)); +} +#endif // BUILDFLAG(ENABLE_UNHANDLED_TAP) + +// Forward image Annotator requests to the profile's AccessibilityLabelsService. +void BindImageAnnotator( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver receiver) { + AccessibilityLabelsServiceFactory::GetForProfile( + Profile::FromBrowserContext( + frame_host->GetProcess()->GetBrowserContext())) + ->BindImageAnnotator(std::move(receiver)); +} + +void BindCommerceHintObserver( + content::RenderFrameHost* const frame_host, + mojo::PendingReceiver receiver) { + // This is specifically restricting this to main frames, whether they are the + // main frame of the tab, while preventing this from working in subframes and + // fenced frames. + if (frame_host->GetParent() || frame_host->IsFencedFrameRoot()) { + mojo::ReportBadMessage( + "Unexpected the message from subframe or fenced frame."); + return; + } + +// Check if features require CommerceHint are enabled. +#if !BUILDFLAG(IS_ANDROID) + if (!IsCartModuleEnabled()) { + return; + } +#else + if (!base::FeatureList::IsEnabled(commerce::kCommerceHintAndroid)) { + return; + } +#endif + +// On Android, commerce hint observer is enabled for all users with the feature +// enabled since the observer is only used for collecting metrics for now, and +// we want to maximize the user population exposed; on Desktop, ChromeCart is +// not available for non-signin single-profile users and therefore neither does +// commerce hint observer. +#if !BUILDFLAG(IS_ANDROID) + Profile* profile = Profile::FromBrowserContext( + frame_host->GetProcess()->GetBrowserContext()); + auto* identity_manager = IdentityManagerFactory::GetForProfile(profile); + ProfileManager* profile_manager = g_browser_process->profile_manager(); + if (!identity_manager || !profile_manager) { + return; + } + if (!identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin) && + profile_manager->GetNumberOfProfiles() <= 1) { + return; + } +#endif + auto* web_contents = content::WebContents::FromRenderFrameHost(frame_host); + if (!web_contents) { + return; + } + content::BrowserContext* browser_context = web_contents->GetBrowserContext(); + if (!browser_context) { + return; + } + if (browser_context->IsOffTheRecord()) { + return; + } + + cart::CommerceHintService::CreateForWebContents(web_contents); + cart::CommerceHintService* service = + cart::CommerceHintService::FromWebContents(web_contents); + if (!service) { + return; + } + service->BindCommerceHintObserver(frame_host, std::move(receiver)); +} + +void BindDistillabilityService( + content::RenderFrameHost* const frame_host, + mojo::PendingReceiver + receiver) { + auto* web_contents = content::WebContents::FromRenderFrameHost(frame_host); + if (!web_contents) { + return; + } + + dom_distiller::DistillabilityDriver* driver = + dom_distiller::DistillabilityDriver::FromWebContents(web_contents); + if (!driver) { + return; + } + driver->SetIsSecureCallback( + base::BindRepeating([](content::WebContents* contents) { + // SecurityStateTabHelper uses chrome-specific + // GetVisibleSecurityState to determine if a page is SECURE. + return SecurityStateTabHelper::FromWebContents(contents) + ->GetSecurityLevel() == + security_state::SecurityLevel::SECURE; + })); + driver->CreateDistillabilityService(std::move(receiver)); +} + +void BindDistillerJavaScriptService( + content::RenderFrameHost* const frame_host, + mojo::PendingReceiver + receiver) { + auto* web_contents = content::WebContents::FromRenderFrameHost(frame_host); + if (!web_contents) { + return; + } + + dom_distiller::DomDistillerService* dom_distiller_service = + dom_distiller::DomDistillerServiceFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); +#if BUILDFLAG(IS_ANDROID) + static_cast( + dom_distiller_service->GetDistillerUIHandle()) + ->set_render_frame_host(frame_host); +#endif + CreateDistillerJavaScriptService(dom_distiller_service->GetWeakPtr(), + std::move(receiver)); +} + +void BindPrerenderCanceler( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver receiver) { + auto* web_contents = content::WebContents::FromRenderFrameHost(frame_host); + if (!web_contents) { + return; + } + + auto* no_state_prefetch_contents = + prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents( + web_contents); + if (!no_state_prefetch_contents) { + return; + } + no_state_prefetch_contents->AddPrerenderCancelerReceiver(std::move(receiver)); +} + +void BindNoStatePrefetchProcessor( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver receiver) { + prerender::NoStatePrefetchProcessorImpl::Create( + frame_host, std::move(receiver), + std::make_unique< + prerender::ChromeNoStatePrefetchProcessorImplDelegate>()); +} + +#if BUILDFLAG(IS_ANDROID) +template +void ForwardToJavaWebContents(content::RenderFrameHost* frame_host, + mojo::PendingReceiver receiver) { + content::WebContents* contents = + content::WebContents::FromRenderFrameHost(frame_host); + if (contents) { + contents->GetJavaInterfaces()->GetInterface(std::move(receiver)); + } +} + +template +void ForwardToJavaFrame(content::RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) { + render_frame_host->GetJavaInterfaces()->GetInterface(std::move(receiver)); +} +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) +void BindMimeHandlerService( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver + receiver) { + auto* guest_view = + extensions::MimeHandlerViewGuest::FromRenderFrameHost(frame_host); + if (!guest_view) { + return; + } + extensions::MimeHandlerServiceImpl::Create(guest_view->GetStreamWeakPtr(), + std::move(receiver)); +} + +void BindBeforeUnloadControl( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver + receiver) { + auto* guest_view = + extensions::MimeHandlerViewGuest::FromRenderFrameHost(frame_host); + if (!guest_view) { + return; + } + guest_view->FuseBeforeUnloadControl(std::move(receiver)); +} +#endif + +void BindNetworkHintsHandler( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver receiver) { + predictors::NetworkHintsHandlerImpl::Create(frame_host, std::move(receiver)); +} + +#if BUILDFLAG(ENABLE_SPEECH_SERVICE) +void BindSpeechRecognitionContextHandler( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver receiver) { + if (!captions::IsLiveCaptionFeatureSupported()) { + return; + } + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // On LaCrOS, forward to Ash. + auto* service = chromeos::LacrosService::Get(); + if (service && service->IsAvailable()) { + service->GetRemote() + ->BindSpeechRecognitionContext(std::move(receiver)); + } +#else + // On other platforms (Ash, desktop), bind via the appropriate factory. + Profile* profile = Profile::FromBrowserContext( + frame_host->GetProcess()->GetBrowserContext()); +#if BUILDFLAG(ENABLE_BROWSER_SPEECH_SERVICE) + auto* factory = SpeechRecognitionServiceFactory::GetForProfile(profile); +#elif BUILDFLAG(IS_CHROMEOS_ASH) + auto* factory = CrosSpeechRecognitionServiceFactory::GetForProfile(profile); +#else +#error "No speech recognition service factory on this platform." +#endif + factory->BindSpeechRecognitionContext(std::move(receiver)); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) +} + +void BindSpeechRecognitionClientBrowserInterfaceHandler( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver + receiver) { + if (captions::IsLiveCaptionFeatureSupported()) { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // On LaCrOS, forward to Ash. + auto* service = chromeos::LacrosService::Get(); + if (service && service->IsAvailable()) { + service->GetRemote() + ->BindSpeechRecognitionClientBrowserInterface(std::move(receiver)); + } +#else + // On other platforms (Ash, desktop), bind in this process. + Profile* profile = Profile::FromBrowserContext( + frame_host->GetProcess()->GetBrowserContext()); + SpeechRecognitionClientBrowserInterfaceFactory::GetForProfile(profile) + ->BindReceiver(std::move(receiver)); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + } +} + +void BindSpeechRecognitionRecognizerClientHandler( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver + client_receiver) { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // On LaCrOS, forward to Ash. + + // Hold a client-browser interface just long enough to bootstrap a remote + // recognizer client. + mojo::Remote + interface_remote; + auto* service = chromeos::LacrosService::Get(); + if (!service || !service->IsAvailable()) { + return; + } + service->GetRemote() + ->BindSpeechRecognitionClientBrowserInterface( + interface_remote.BindNewPipeAndPassReceiver()); + + // Grab the per-web-contents logic on our end to drive the remote client. + auto* surface = captions::LiveCaptionSurface::GetOrCreateForWebContents( + content::WebContents::FromRenderFrameHost(frame_host)); + mojo::PendingRemote surface_remote; + mojo::PendingReceiver + surface_client_receiver; + surface->BindToSurfaceClient( + surface_remote.InitWithNewPipeAndPassReceiver(), + surface_client_receiver.InitWithNewPipeAndPassRemote()); + + // Populate static info to send to the client. + auto metadata = media::mojom::SpeechRecognitionSurfaceMetadata::New(); + metadata->session_id = surface->session_id(); + + // Bootstrap the recognizer client. + interface_remote->BindRecognizerToRemoteClient( + std::move(client_receiver), std::move(surface_client_receiver), + std::move(surface_remote), std::move(metadata)); +#else + Profile* profile = Profile::FromBrowserContext( + frame_host->GetProcess()->GetBrowserContext()); + PrefService* profile_prefs = profile->GetPrefs(); + if (profile_prefs->GetBoolean(prefs::kLiveCaptionEnabled) && + captions::IsLiveCaptionFeatureSupported()) { + captions::LiveCaptionSpeechRecognitionHost::Create( + frame_host, std::move(client_receiver)); + } +#endif +} + +#if BUILDFLAG(IS_WIN) +void BindMediaFoundationRendererNotifierHandler( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver + receiver) { + if (captions::IsLiveCaptionFeatureSupported()) { + captions::LiveCaptionUnavailabilityNotifier::Create(frame_host, + std::move(receiver)); + } +} +#endif // BUILDFLAG(IS_WIN) +#endif // BUILDFLAG(ENABLE_SPEECH_SERVICE) + +#if BUILDFLAG(IS_WIN) +void BindMediaFoundationPreferences( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver receiver) { + MediaFoundationPreferencesImpl::Create( + frame_host->GetSiteInstance()->GetSiteURL(), + base::BindRepeating(&MediaFoundationServiceMonitor:: + IsHardwareSecureDecryptionAllowedForSite), + std::move(receiver)); +} +#endif // BUILDFLAG(IS_WIN) + +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) +void BindScreenAIAnnotator( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver receiver) { + content::BrowserContext* browser_context = + frame_host->GetProcess()->GetBrowserContext(); + + screen_ai::ScreenAIServiceRouterFactory::GetForBrowserContext(browser_context) + ->BindScreenAIAnnotator(std::move(receiver)); +} + +void BindScreen2xMainContentExtractor( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver + receiver) { + screen_ai::ScreenAIServiceRouterFactory::GetForBrowserContext( + frame_host->GetProcess()->GetBrowserContext()) + ->BindMainContentExtractor(std::move(receiver)); +} +#endif + +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || \ + BUILDFLAG(IS_WIN) +void BindVisualSuggestionsModelProvider( + content::RenderFrameHost* frame_host, + mojo::PendingReceiver< + companion::visual_query::mojom::VisualSuggestionsModelProvider> + receiver) { + companion::visual_query::VisualQuerySuggestionsServiceFactory::GetForProfile( + Profile::FromBrowserContext( + frame_host->GetProcess()->GetBrowserContext())) + ->BindModelReceiver(std::move(receiver)); +} +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +// A helper class to register ChromeOS Apps API binders. This includes the logic +// that checks that the feature is allowed on Profile before registering a +// binder, and wraps the binder with per-frame feature enablement checks before +// binding the Mojo pipe. +class CrosAppsApiFrameBinderMap { + STACK_ALLOCATED(); + + public: + CrosAppsApiFrameBinderMap( + content::RenderFrameHost* rfh, + mojo::BinderMapWithContext& map) + : api_registry_(CrosAppsApiRegistry::GetInstance( + Profile::FromBrowserContext(rfh->GetBrowserContext()))), + map_(map) {} + ~CrosAppsApiFrameBinderMap() = default; + + // If `api_feature` is enabled (e.g. base::Feature is enabled), and it can be + // enabled on the profile, registers a binder that performs context dependent + // checks (e.g. whether the frame's last committed URL is in the allowlist) + // before calling `binder_func`. + template + void MaybeAdd() { + if (!api_registry_->CanEnableApi(api_feature)) { + return; + } + + map_->template Add( + base::BindRepeating([](content::RenderFrameHost* rfh, + mojo::PendingReceiver receiver) { + auto* profile = Profile::FromBrowserContext(rfh->GetBrowserContext()); + const auto& api_registry = CrosAppsApiRegistry::GetInstance(profile); + + if (!api_registry.IsApiEnabledForFrame( + api_feature, CrosAppsApiFrameContext(*rfh))) { + mojo::ReportBadMessage(base::StringPrintf( + "The requesting context isn't allowed to access interface %s " + "because it isn't allowed to access the corresponding API: %s", + Interface::Name_, base::ToString(api_feature).c_str())); + return; + } + + binder_func(rfh, std::move(receiver)); + })); + } + + private: + const raw_ref api_registry_; + raw_ref> map_; +}; +#endif + +void PopulateChromeFrameBinders( + mojo::BinderMapWithContext* map, + content::RenderFrameHost* render_frame_host) { + map->Add( + base::BindRepeating(&BindImageAnnotator)); + + map->Add( + base::BindRepeating(&BindCommerceHintObserver)); + + map->Add( + base::BindRepeating(&NavigationPredictor::Create)); + + map->Add( + base::BindRepeating(&predictors::LCPCriticalPathPredictorHost::Create)); + + map->Add( + base::BindRepeating(&BindDistillabilityService)); + + map->Add( + base::BindRepeating(&BindDistillerJavaScriptService)); + + map->Add( + base::BindRepeating(&BindPrerenderCanceler)); + + map->Add( + base::BindRepeating(&BindNoStatePrefetchProcessor)); + + if (performance_manager::PerformanceManager::IsAvailable()) { + map->Add( + base::BindRepeating( + &performance_manager::BindDocumentCoordinationUnit)); + } + + map->Add( + base::BindRepeating(&translate::BindContentTranslateDriver)); + + map->Add( + base::BindRepeating(&ChromePasswordManagerClient::BindCredentialManager)); + + map->Add( + base::BindRepeating( + &SearchEngineTabHelper::BindOpenSearchDescriptionDocumentHandler)); + +#if BUILDFLAG(IS_ANDROID) + map->Add(base::BindRepeating( + &ForwardToJavaFrame)); + map->Add(base::BindRepeating( + &ForwardToJavaFrame)); +#if defined(BROWSER_MEDIA_CONTROLS_MENU) + map->Add(base::BindRepeating( + &ForwardToJavaFrame)); +#endif + map->Add( + base::BindRepeating(&offline_pages::OfflinePageAutoFetcher::Create)); + if (base::FeatureList::IsEnabled(features::kWebPayments)) { + map->Add(base::BindRepeating( + &ForwardToJavaFrame)); + } + map->Add(base::BindRepeating( + &ForwardToJavaWebContents)); + +#if BUILDFLAG(ENABLE_UNHANDLED_TAP) + map->Add( + base::BindRepeating(&BindUnhandledTapWebContentsObserver)); +#endif // BUILDFLAG(ENABLE_UNHANDLED_TAP) + +#else + map->Add( + base::BindRepeating(&badging::BadgeManager::BindFrameReceiverIfAllowed)); + if (base::FeatureList::IsEnabled(features::kWebPayments)) { + map->Add( + base::BindRepeating(&payments::CreatePaymentRequest)); + } +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + map->Add(base::BindRepeating( + &apps::DigitalGoodsFactoryImpl::BindDigitalGoodsFactory)); +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + if (web_app::IsWebAppsCrosapiEnabled()) { + map->Add( + base::BindRepeating(&apps::DigitalGoodsFactoryLacros::Bind)); + } else { + map->Add( + base::BindRepeating(&apps::DigitalGoodsFactoryStub::Bind)); + } + + if (chromeos::features::IsBlinkExtensionEnabled()) { + // Add frame binders for ChromeOS Apps APIs here using `binder_map_wrapper`. + CrosAppsApiFrameBinderMap binder_map_wrapper(render_frame_host, *map); + binder_map_wrapper + .MaybeAdd(); + } +#endif + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) + if (base::FeatureList::IsEnabled(features::kWebShare)) { + map->Add( + base::BindRepeating(&ShareServiceImpl::Create)); + } +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + map->Add( + base::BindRepeating(&BindMimeHandlerService)); + map->Add( + base::BindRepeating(&BindBeforeUnloadControl)); +#endif + + map->Add( + base::BindRepeating(&BindNetworkHintsHandler)); + +#if BUILDFLAG(ENABLE_SPEECH_SERVICE) + map->Add( + base::BindRepeating(&BindSpeechRecognitionContextHandler)); + map->Add( + base::BindRepeating(&BindSpeechRecognitionClientBrowserInterfaceHandler)); + map->Add( + base::BindRepeating(&BindSpeechRecognitionRecognizerClientHandler)); +#if BUILDFLAG(IS_WIN) + map->Add( + base::BindRepeating(&BindMediaFoundationRendererNotifierHandler)); +#endif +#endif // BUILDFLAG(ENABLE_SPEECH_SERVICE) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) + if (base::FeatureList::IsEnabled(blink::features::kDesktopPWAsSubApps) && + !render_frame_host->GetParentOrOuterDocument()) { + // The service binder will reject non-primary main frames, but we still need + // to register it for them because a non-primary main frame could become a + // primary main frame at a later time (eg. a prerendered page). + map->Add( + base::BindRepeating(&web_app::SubAppsServiceImpl::CreateIfAllowed)); + } + + if (companion::visual_query::features:: + IsVisualQuerySuggestionsAgentEnabled()) { + map->Add( + base::BindRepeating(&BindVisualSuggestionsModelProvider)); + } +#endif + +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + if (features::IsPdfOcrEnabled()) { + map->Add( + base::BindRepeating(&BindScreenAIAnnotator)); + } + + if (features::IsReadAnythingWithScreen2xEnabled()) { + map->Add( + base::BindRepeating(&BindScreen2xMainContentExtractor)); + } +#endif + +#if BUILDFLAG(IS_WIN) + map->Add( + base::BindRepeating(&BindMediaFoundationPreferences)); +#endif + +#if BUILDFLAG(ENABLE_PRINT_PREVIEW) + map->Add( + base::BindRepeating(&printing::CreateWebPrintingServiceForFrame)); +#endif + + if (base::FeatureList::IsEnabled(blink::features::kEnableTranslationAPI)) { + map->Add( + base::BindRepeating(&TranslationManagerImpl::Create)); + } + +#if BUILDFLAG(IS_ANDROID) + if (base::FeatureList::IsEnabled(blink::features::kPaymentLinkDetection)) { + map->Add( + base::BindRepeating(&CreatePaymentLinkHandler)); + } +#endif +} + +void PopulateChromeWebUIFrameBinders( + mojo::BinderMapWithContext* map, + content::RenderFrameHost* render_frame_host) { +#if !BUILDFLAG(IS_CHROMEOS_LACROS) + RegisterWebUIControllerInterfaceBinder<::mojom::BluetoothInternalsHandler, + BluetoothInternalsUI>(map); +#endif + + RegisterWebUIControllerInterfaceBinder< + media::mojom::MediaEngagementScoreDetailsProvider, MediaEngagementUI>( + map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder<::mojom::OmniboxPageHandler, + OmniboxUI>(map); + + RegisterWebUIControllerInterfaceBinder< + site_engagement::mojom::SiteEngagementDetailsProvider, SiteEngagementUI>( + map); + + RegisterWebUIControllerInterfaceBinder<::mojom::UsbInternalsPageHandler, + UsbInternalsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + history_clusters_internals::mojom::PageHandlerFactory, + HistoryClustersInternalsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + optimization_guide_internals::mojom::PageHandlerFactory, + OptimizationGuideInternalsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + segmentation_internals::mojom::PageHandlerFactory, + SegmentationInternalsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + commerce::mojom::CommerceInternalsHandlerFactory, + commerce::CommerceInternalsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + data_sharing_internals::mojom::PageHandlerFactory, + DataSharingInternalsUI>(map); + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS_ASH) + RegisterWebUIControllerInterfaceBinder< + connectors_internals::mojom::PageHandler, + enterprise_connectors::ConnectorsInternalsUI>(map); +#endif + +#if BUILDFLAG(IS_CHROMEOS) + RegisterWebUIControllerInterfaceBinder(map); +#endif + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + RegisterWebUIControllerInterfaceBinder< + app_management::mojom::PageHandlerFactory, WebAppSettingsUI>(map); +#endif + +#if !BUILDFLAG(IS_ANDROID) + if (search_engines::IsChoiceScreenFlagEnabled( + search_engines::ChoicePromo::kAny)) { + RegisterWebUIControllerInterfaceBinder< + search_engine_choice::mojom::PageHandlerFactory, SearchEngineChoiceUI>( + map); + } + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder< + new_tab_page_third_party::mojom::PageHandlerFactory, + NewTabPageThirdPartyUI>(map); + + if (lens::features::IsLensOverlayEnabled()) { + RegisterWebUIControllerInterfaceBinder(map); + } + + if (lens::features::IsLensOverlaySearchBubbleEnabled()) { + RegisterWebUIControllerInterfaceBinder< + lens::mojom::SearchBubblePageHandlerFactory, lens::SearchBubbleUI>(map); + } + + RegisterWebUIControllerInterfaceBinder< + color_change_listener::mojom::PageHandler, +#if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) + TabStripUI, +#endif +#if BUILDFLAG(IS_CHROMEOS_ASH) + ash::OobeUI, ash::personalization_app::PersonalizationAppUI, + ash::vc_background_ui::VcBackgroundUI, ash::settings::OSSettingsUI, + ash::DiagnosticsDialogUI, ash::FirmwareUpdateAppUI, ash::ScanningUI, + ash::OSFeedbackUI, ash::ShortcutCustomizationAppUI, + ash::printing::printing_manager::PrintManagementUI, + ash::InternetConfigDialogUI, ash::InternetDetailDialogUI, ash::SetTimeUI, + ash::BluetoothPairingDialogUI, nearby_share::NearbyShareDialogUI, + ash::cloud_upload::CloudUploadUI, ash::office_fallback::OfficeFallbackUI, + ash::multidevice_setup::MultiDeviceSetupDialogUI, ash::ParentAccessUI, + ash::EmojiUI, ash::RemoteMaintenanceCurtainUI, + ash::app_install::AppInstallDialogUI, ash::SanitizeDialogUI, + ash::printing::print_preview::PrintPreviewCrosUI, + ash::extended_updates::ExtendedUpdatesUI, +#endif + NewTabPageUI, OmniboxPopupUI, BookmarksSidePanelUI, CustomizeChromeUI, + InternalsUI, ReadingListUI, TabSearchUI, WebuiGalleryUI, + HistoryClustersSidePanelUI, ShoppingInsightsSidePanelUI, + media_router::AccessCodeCastUI, commerce::ProductSpecificationsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + new_tab_page::mojom::PageHandlerFactory, NewTabPageUI>(map); + + RegisterWebUIControllerInterfaceBinder< + most_visited::mojom::MostVisitedPageHandlerFactory, NewTabPageUI, + NewTabPageThirdPartyUI>(map); + + auto* history_clusters_service = + HistoryClustersServiceFactory::GetForBrowserContext( + render_frame_host->GetProcess()->GetBrowserContext()); + if (history_clusters_service && + history_clusters_service->is_journeys_feature_flag_enabled()) { + if (base::FeatureList::IsEnabled(history_clusters::kSidePanelJourneys)) { + RegisterWebUIControllerInterfaceBinder< + history_clusters::mojom::PageHandler, HistoryUI, + HistoryClustersSidePanelUI>(map); + } else { + RegisterWebUIControllerInterfaceBinder< + history_clusters::mojom::PageHandler, HistoryUI>(map); + } + } + if (history_embeddings::IsHistoryEmbeddingsEnabled()) { + RegisterWebUIControllerInterfaceBinder< + history_embeddings::mojom::PageHandler, HistoryUI>(map); + } + + RegisterWebUIControllerInterfaceBinder< + page_image_service::mojom::PageImageServiceHandler, HistoryUI, + HistoryClustersSidePanelUI, NewTabPageUI, BookmarksSidePanelUI>(map); + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + RegisterWebUIControllerInterfaceBinder(map); +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + + RegisterWebUIControllerInterfaceBinder< + browser_command::mojom::CommandHandlerFactory, +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + WhatsNewUI, +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + NewTabPageUI>(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder< + customize_color_scheme_mode::mojom:: + CustomizeColorSchemeModeHandlerFactory, + CustomizeChromeUI, settings::SettingsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + theme_color_picker::mojom::ThemeColorPickerHandlerFactory, + CustomizeChromeUI +#if !BUILDFLAG(IS_CHROMEOS_ASH) + , + ProfileCustomizationUI, settings::SettingsUI +#endif // !BUILDFLAG(IS_CHROMEOS_ASH) + >(map); + +#if BUILDFLAG(CHROME_ROOT_STORE_CERT_MANAGEMENT_UI) + RegisterWebUIControllerInterfaceBinder< + certificate_manager_v2::mojom::CertificateManagerPageHandlerFactory, + CertificateManagerUI>(map); +#endif // BUILDFLAG(CHROME_ROOT_STORE_CERT_MANAGEMENT_UI) + + RegisterWebUIControllerInterfaceBinder< + help_bubble::mojom::HelpBubbleHandlerFactory, InternalsUI, + settings::SettingsUI, ReadingListUI, NewTabPageUI, CustomizeChromeUI, + PasswordManagerUI, HistoryUI +#if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID) + , + ProfilePickerUI +#endif //! BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID) + >(map); + +#if !defined(OFFICIAL_BUILD) + RegisterWebUIControllerInterfaceBinder( + map); +#endif // !defined(OFFICIAL_BUILD) + + if (IsDriveModuleEnabled()) { + RegisterWebUIControllerInterfaceBinder< + file_suggestion::mojom::FileSuggestionHandler, NewTabPageUI>(map); + } + + if (base::FeatureList::IsEnabled(ntp_features::kNtpFeedModule)) { + RegisterWebUIControllerInterfaceBinder(map); + } + + if (base::FeatureList::IsEnabled(ntp_features::kNtpTabResumptionModule)) { + RegisterWebUIControllerInterfaceBinder< + ntp::tab_resumption::mojom::PageHandler, NewTabPageUI>(map); + } + + if (base::FeatureList::IsEnabled( + ntp_features::kNtpMostRelevantTabResumptionModule)) { + RegisterWebUIControllerInterfaceBinder< + ntp::most_relevant_tab_resumption::mojom::PageHandler, NewTabPageUI>( + map); + } + + if (base::FeatureList::IsEnabled(ntp_features::kNtpCalendarModule)) { + RegisterWebUIControllerInterfaceBinder< + ntp::calendar::mojom::GoogleCalendarPageHandler, NewTabPageUI>(map); + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (ash::features::IsBluetoothDisconnectWarningEnabled()) { + RegisterWebUIControllerInterfaceBinder< + ash::mojom::HidPreservingBluetoothStateController, + ash::settings::OSSettingsUI>(map); + } +#endif // defined(IS_CHROMEOS_ASH) + + RegisterWebUIControllerInterfaceBinder< + reading_list::mojom::PageHandlerFactory, ReadingListUI>(map); + RegisterWebUIControllerInterfaceBinder< + side_panel::mojom::BookmarksPageHandlerFactory, BookmarksSidePanelUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + shopping_service::mojom::ShoppingServiceHandlerFactory, + BookmarksSidePanelUI, commerce::ProductSpecificationsUI, + ShoppingInsightsSidePanelUI, HistoryUI>(map); + + RegisterWebUIControllerInterfaceBinder< + side_panel::mojom::CustomizeChromePageHandlerFactory, CustomizeChromeUI>( + map); + + if (base::FeatureList::IsEnabled( + ntp_features::kCustomizeChromeWallpaperSearch) && + base::FeatureList::IsEnabled( + optimization_guide::features::kOptimizationGuideModelExecution)) { + RegisterWebUIControllerInterfaceBinder< + side_panel::customize_chrome::mojom::WallpaperSearchHandlerFactory, + CustomizeChromeUI>(map); + } + + if (features::IsToolbarPinningEnabled()) { + RegisterWebUIControllerInterfaceBinder< + side_panel::customize_chrome::mojom::CustomizeToolbarHandlerFactory, + CustomizeChromeUI>(map); + } + + RegisterWebUIControllerInterfaceBinder< + read_anything::mojom::UntrustedPageHandlerFactory, + ReadAnythingUntrustedUI>(map); + + RegisterWebUIControllerInterfaceBinder(map); + RegisterWebUIControllerInterfaceBinder< + metrics_reporter::mojom::PageMetricsHost, TabSearchUI, NewTabPageUI, + OmniboxPopupUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ::mojom::user_education_internals::UserEducationInternalsPageHandler, + InternalsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ::mojom::app_service_internals::AppServiceInternalsPageHandler, + AppServiceInternalsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + access_code_cast::mojom::PageHandlerFactory, + media_router::AccessCodeCastUI>(map); +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) + RegisterWebUIControllerInterfaceBinder(map); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + RegisterWebUIControllerInterfaceBinder< + ash::file_manager::mojom::PageHandlerFactory, + ash::file_manager::FileManagerUI>(map); + + RegisterWebUIControllerInterfaceBinder< + add_supervision::mojom::AddSupervisionHandler, ash::AddSupervisionUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + app_management::mojom::PageHandlerFactory, ash::settings::OSSettingsUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::settings::mojom::UserActionRecorder, ash::settings::OSSettingsUI>( + map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder< + ash::personalization_app::mojom::SearchHandler, + ash::settings::OSSettingsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::settings::app_notification::mojom::AppNotificationsHandler, + ash::settings::OSSettingsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::settings::app_permission::mojom::AppPermissionsHandler, + ash::settings::OSSettingsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::settings::app_parental_controls::mojom::AppParentalControlsHandler, + ash::settings::OSSettingsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::settings::mojom::InputDeviceSettingsProvider, + ash::settings::OSSettingsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::settings::mojom::DisplaySettingsProvider, + ash::settings::OSSettingsUI>(map); + + if (::features::IsShortcutCustomizationEnabled()) { + RegisterWebUIControllerInterfaceBinder< + ash::common::mojom::AcceleratorFetcher, ash::settings::OSSettingsUI>( + map); + } + + RegisterWebUIControllerInterfaceBinder< + ash::common::mojom::ShortcutInputProvider, ash::settings::OSSettingsUI, + ash::ShortcutCustomizationAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::cellular_setup::mojom::CellularSetup, ash::settings::OSSettingsUI>( + map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder< + ash::cellular_setup::mojom::ESimManager, ash::settings::OSSettingsUI, + ash::NetworkUI, ash::OobeUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::borealis_installer::mojom::PageHandlerFactory, + ash::BorealisInstallerUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::crostini_installer::mojom::PageHandlerFactory, + ash::CrostiniInstallerUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::crostini_upgrader::mojom::PageHandlerFactory, + ash::CrostiniUpgraderUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::multidevice_setup::mojom::MultiDeviceSetup, ash::OobeUI, + ash::multidevice::ProximityAuthUI, + ash::multidevice_setup::MultiDeviceSetupDialogUI>(map); + + RegisterWebUIControllerInterfaceBinder< + parent_access_ui::mojom::ParentAccessUiHandler, ash::ParentAccessUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::multidevice_setup::mojom::PrivilegedHostDeviceSetter, ash::OobeUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + chromeos::network_config::mojom::CrosNetworkConfig, + ash::InternetConfigDialogUI, ash::InternetDetailDialogUI, ash::NetworkUI, + ash::OobeUI, ash::settings::OSSettingsUI, ash::LockScreenNetworkUI, + ash::ShimlessRMADialogUI>(map); + + if (ash::features::IsPasspointSettingsEnabled()) { + RegisterWebUIControllerInterfaceBinder< + chromeos::connectivity::mojom::PasspointService, + ash::InternetDetailDialogUI, ash::NetworkUI, + ash::settings::OSSettingsUI>(map); + } + + RegisterWebUIControllerInterfaceBinder< + chromeos::printing::printing_manager::mojom::PrintingMetadataProvider, + ash::printing::printing_manager::PrintManagementUI>(map); + + RegisterWebUIControllerInterfaceBinder< + chromeos::printing::printing_manager::mojom::PrintManagementHandler, + ash::printing::printing_manager::PrintManagementUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::help_app::mojom::PageHandlerFactory, ash::HelpAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::local_search_service::mojom::Index, ash::HelpAppUI>(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder< + ash::eche_app::mojom::SignalingMessageExchanger, + ash::eche_app::EcheAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::eche_app::mojom::SystemInfoProvider, ash::eche_app::EcheAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::eche_app::mojom::AccessibilityProvider, ash::eche_app::EcheAppUI>( + map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder< + ash::eche_app::mojom::NotificationGenerator, ash::eche_app::EcheAppUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::eche_app::mojom::DisplayStreamHandler, ash::eche_app::EcheAppUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::eche_app::mojom::StreamOrientationObserver, + ash::eche_app::EcheAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::eche_app::mojom::ConnectionStatusObserver, ash::eche_app::EcheAppUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::eche_app::mojom::KeyboardLayoutHandler, ash::eche_app::EcheAppUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::media_app_ui::mojom::PageHandlerFactory, ash::MediaAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + chromeos::network_health::mojom::NetworkHealthService, ash::NetworkUI, + ash::ConnectivityDiagnosticsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + chromeos::network_diagnostics::mojom::NetworkDiagnosticsRoutines, + ash::NetworkUI, ash::ConnectivityDiagnosticsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::diagnostics::mojom::InputDataProvider, ash::DiagnosticsDialogUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::diagnostics::mojom::NetworkHealthProvider, ash::DiagnosticsDialogUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::diagnostics::mojom::SystemDataProvider, ash::DiagnosticsDialogUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::diagnostics::mojom::SystemRoutineController, + ash::DiagnosticsDialogUI>(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder< + ash::common::mojom::AccessibilityFeatures, ash::ScanningUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::os_feedback_ui::mojom::HelpContentProvider, ash::OSFeedbackUI>(map); + RegisterWebUIControllerInterfaceBinder< + ash::os_feedback_ui::mojom::FeedbackServiceProvider, ash::OSFeedbackUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::shimless_rma::mojom::ShimlessRmaService, ash::ShimlessRMADialogUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::shortcut_customization::mojom::AcceleratorConfigurationProvider, + ash::ShortcutCustomizationAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::shortcut_customization::mojom::SearchHandler, + ash::ShortcutCustomizationAppUI>(map); + + if (ash::features::IsPrinterPreviewCrosAppEnabled()) { + RegisterWebUIControllerInterfaceBinder< + ash::printing::print_preview::mojom::DestinationProvider, + ash::printing::print_preview::PrintPreviewCrosUI>(map); + } + + RegisterWebUIControllerInterfaceBinder< + emoji_picker::mojom::PageHandlerFactory, ash::EmojiUI>(map); + + if (base::FeatureList::IsEnabled( + ash::features::kImeSystemEmojiPickerMojoSearch)) { + RegisterWebUIControllerInterfaceBinder(map); + } + + RegisterWebUIControllerInterfaceBinder(map); + RegisterWebUIControllerInterfaceBinder< + enterprise_reporting::mojom::PageHandlerFactory, + ash::reporting::EnterpriseReportingUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::personalization_app::mojom::WallpaperProvider, + ash::personalization_app::PersonalizationAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::personalization_app::mojom::AmbientProvider, + ash::personalization_app::PersonalizationAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::personalization_app::mojom::ThemeProvider, + ash::personalization_app::PersonalizationAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::personalization_app::mojom::UserProvider, + ash::personalization_app::PersonalizationAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::personalization_app::mojom::KeyboardBacklightProvider, + ash::personalization_app::PersonalizationAppUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::personalization_app::mojom::SeaPenProvider, + ash::personalization_app::PersonalizationAppUI, + ash::vc_background_ui::VcBackgroundUI>(map); + + RegisterWebUIControllerInterfaceBinder< + launcher_internals::mojom::PageHandlerFactory, ash::LauncherInternalsUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::bluetooth_config::mojom::CrosBluetoothConfig, + ash::BluetoothPairingDialogUI, ash::settings::OSSettingsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::audio_config::mojom::CrosAudioConfig, ash::settings::OSSettingsUI>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::hotspot_config::mojom::CrosHotspotConfig, + ash::settings::OSSettingsUI>(map); + + if (base::FeatureList::IsEnabled( + ash::features::kSystemJapanesePhysicalTyping)) { + RegisterWebUIControllerInterfaceBinder< + ash::ime::mojom::InputMethodUserDataService, + ash::settings::OSSettingsUI>(map); + } + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder< + ash::kiosk_vision::mojom::PageConnector, ash::kiosk_vision::UIController>( + map); + + RegisterWebUIControllerInterfaceBinder< + ash::extended_updates::mojom::PageHandlerFactory, + ash::extended_updates::ExtendedUpdatesUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::firmware_update::mojom::UpdateProvider, ash::FirmwareUpdateAppUI>( + map); + + if (ash::features::IsDriveFsMirroringEnabled()) { + RegisterWebUIControllerInterfaceBinder< + ash::manage_mirrorsync::mojom::PageHandlerFactory, + ash::ManageMirrorSyncUI>(map); + } + + Profile* profile = + Profile::FromBrowserContext(render_frame_host->GetBrowserContext()); + if (chromeos::IsEligibleAndEnabledUploadOfficeToCloud(profile)) { + RegisterWebUIControllerInterfaceBinder< + ash::cloud_upload::mojom::PageHandlerFactory, + ash::cloud_upload::CloudUploadUI>(map); + RegisterWebUIControllerInterfaceBinder< + ash::office_fallback::mojom::PageHandlerFactory, + ash::office_fallback::OfficeFallbackUI>(map); + } + + if (ash::cloud_upload:: + IsMicrosoftOfficeOneDriveIntegrationAllowedAndOdfsInstalled( + profile)) { + RegisterWebUIControllerInterfaceBinder< + ash::settings::one_drive::mojom::PageHandlerFactory, + ash::settings::OSSettingsUI>(map); + } + + RegisterWebUIControllerInterfaceBinder< + ash::settings::google_drive::mojom::PageHandlerFactory, + ash::settings::OSSettingsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::settings::date_time::mojom::PageHandlerFactory, + ash::settings::OSSettingsUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::screens_factory::mojom::ScreensFactory, ash::OobeUI>(map); + + RegisterWebUIControllerInterfaceBinder< + ash::app_install::mojom::PageHandlerFactory, + ash::app_install::AppInstallDialogUI>(map); + + RegisterWebUIControllerInterfaceBinder< + new_window_proxy::mojom::NewWindowProxy, ash::EmojiUI>(map); + RegisterWebUIControllerInterfaceBinder(map); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder(map); + + RegisterWebUIControllerInterfaceBinder(map); +#endif + +#if BUILDFLAG(ENABLE_FEED_V2) && BUILDFLAG(IS_ANDROID) + RegisterWebUIControllerInterfaceBinder(map); +#endif + +#if BUILDFLAG(FULL_SAFE_BROWSING) + RegisterWebUIControllerInterfaceBinder<::mojom::ResetPasswordHandler, + ResetPasswordUI>(map); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Because Nearby Share is only currently supported for the primary profile, + // we should only register binders in that scenario. However, we don't want to + // plumb the profile through to this function, so we 1) ensure that + // NearbyShareDialogUI will not be created for non-primary profiles, and 2) + // rely on the BindInterface implementation of OSSettingsUI to ensure that no + // Nearby Share receivers are bound. + if (base::FeatureList::IsEnabled(features::kNearbySharing)) { + RegisterWebUIControllerInterfaceBinder< + nearby_share::mojom::NearbyShareSettings, ash::settings::OSSettingsUI, + nearby_share::NearbyShareDialogUI>(map); + RegisterWebUIControllerInterfaceBinder( + map); + RegisterWebUIControllerInterfaceBinder< + nearby_share::mojom::DiscoveryManager, + nearby_share::NearbyShareDialogUI>(map); + RegisterWebUIControllerInterfaceBinder(map); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID) + RegisterWebUIControllerInterfaceBinder<::app_home::mojom::PageHandlerFactory, + webapps::AppHomeUI>(map); +#endif // !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID) + +#if !BUILDFLAG(IS_ANDROID) + RegisterWebUIControllerInterfaceBinder<::mojom::WebAppInternalsHandler, + WebAppInternalsUI>(map); +#endif + + RegisterWebUIControllerInterfaceBinder<::mojom::LocationInternalsHandler, + LocationInternalsUI>(map); + +#if !BUILDFLAG(IS_ANDROID) + if (base::FeatureList::IsEnabled( + optimization_guide::features::kOptimizationGuideOnDeviceModel)) { + RegisterWebUIControllerInterfaceBinder<::mojom::OnDeviceInternalsPage, + OnDeviceInternalsUI>(map); + } +#endif + + if (base::FeatureList::IsEnabled( + privacy_sandbox::kPrivacySandboxInternalsDevUI)) { + RegisterWebUIControllerInterfaceBinder< + privacy_sandbox_internals::mojom::PageHandler, + privacy_sandbox_internals::PrivacySandboxInternalsUI>(map); + } + +#if !BUILDFLAG(IS_ANDROID) + if (base::FeatureList::IsEnabled(privacy_sandbox::kRelatedWebsiteSetsDevUI)) { + RegisterWebUIControllerInterfaceBinder< + related_website_sets::mojom::RelatedWebsiteSetsPageHandler, + privacy_sandbox_internals::PrivacySandboxInternalsUI>(map); + } +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (ash::features::IsFocusModeEnabled()) { + RegisterWebUIControllerInterfaceBinder< + ash::focus_mode::mojom::TrackProvider, ash::FocusModeUI>(map); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) +} + +void PopulateChromeWebUIFrameInterfaceBrokers( + content::WebUIBrowserInterfaceBrokerRegistry& registry) { + // This function is broken up into sections based on WebUI types. + + // --- Section 1: chrome:// WebUIs: + +#if BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OFFICIAL_BUILD) + registry.ForWebUI() + .Add() + .Add(); + + registry.ForWebUI() + .Add(); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OFFICIAL_BUILD) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry.ForWebUI() + .Add() + .Add(); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry.ForWebUI() + .Add() + .Add() + .Add(); + registry.ForWebUI() + .Add() + .Add(); + registry.ForWebUI() + .Add(); + registry.ForWebUI() + .Add(); + registry.ForWebUI() + .Add(); + registry.ForWebUI() + .Add(); + registry.ForWebUI() + .Add(); + registry.ForWebUI().Add(); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // --- Section 2: chrome-untrusted:// WebUIs: +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (ash::features::IsBocaEnabled()) { + registry.ForWebUI() + .Add() + .Add(); + } + + if (chromeos::features::IsOrcaEnabled()) { + registry.ForWebUI() + .Add(); + } + + registry.ForWebUI() + .Add(); + + registry.ForWebUI() + .Add(); + + registry.ForWebUI() + .Add() + .Add(); + + registry.ForWebUI() + .Add(); + + registry.ForWebUI() + .Add() + .Add(); + + registry.ForWebUI() + .Add(); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OFFICIAL_BUILD) + registry.ForWebUI() + .Add(); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) && !defined(OFFICIAL_BUILD) + +#if BUILDFLAG(ENABLE_COMPOSE) + registry.ForWebUI() + .Add() + .Add(); +#endif // BUILDFLAG(ENABLE_COMPOSE) +#if !BUILDFLAG(IS_ANDROID) + if (lens::features::IsLensOverlayEnabled()) { + registry.ForWebUI() + .Add() + .Add() + .Add(); + } + if (companion::IsCompanionFeatureEnabled()) { + registry.ForWebUI() + .Add(); + } + registry.ForWebUI() + .Add(); + if (base::FeatureList::IsEnabled(features::kHaTSWebUI)) { + registry.ForWebUI().Add(); + } + + if (base::FeatureList::IsEnabled( + data_sharing::features::kDataSharingFeature)) { + registry.ForWebUI() + .Add(); + } + +#endif // !BUILDFLAG(IS_ANDROID) +} + +} // namespace chrome::internal diff --git a/tools/under-control/src/chrome/browser/chrome_content_browser_client.cc b/tools/under-control/src/chrome/browser/chrome_content_browser_client.cc new file mode 100755 index 000000000..c4b98aa0e --- /dev/null +++ b/tools/under-control/src/chrome/browser/chrome_content_browser_client.cc @@ -0,0 +1,8661 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chrome_content_browser_client.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "base/base_switches.h" +#include "base/check_deref.h" +#include "base/command_line.h" +#include "base/containers/contains.h" +#include "base/containers/fixed_flat_set.h" +#include "base/dcheck_is_on.h" +#include "base/feature_list.h" +#include "base/functional/bind.h" +#include "base/functional/callback.h" +#include "base/i18n/base_i18n_switches.h" +#include "base/i18n/character_encoding.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/scoped_refptr.h" +#include "base/metrics/field_trial_params.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "base/no_destructor.h" +#include "base/path_service.h" +#include "base/ranges/algorithm.h" +#include "base/stl_util.h" +#include "base/strings/strcat.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/task/sequenced_task_runner.h" +#include "base/types/expected.h" +#include "base/types/expected_macros.h" +#include "base/values.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "build/config/chromebox_for_meetings/buildflags.h" // PLATFORM_CFM +#include "chrome/browser/after_startup_task_utils.h" +#include "chrome/browser/ai/ai_manager_keyed_service_factory.h" +#include "chrome/browser/app_mode/app_mode_utils.h" +#include "chrome/browser/bluetooth/chrome_bluetooth_delegate_impl_client.h" +#include "chrome/browser/browser_about_handler.h" +#include "chrome/browser/browser_features.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/browsing_data/chrome_browsing_data_model_delegate.h" +#include "chrome/browser/browsing_topics/browsing_topics_service_factory.h" +#include "chrome/browser/captive_portal/captive_portal_service_factory.h" +#include "chrome/browser/child_process_host_flags.h" +#include "chrome/browser/chrome_browser_main_extra_parts_nacl_deprecation.h" +#include "chrome/browser/chrome_content_browser_client_binder_policies.h" +#include "chrome/browser/chrome_content_browser_client_parts.h" +#include "chrome/browser/content_settings/cookie_settings_factory.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" +#include "chrome/browser/data_saver/data_saver.h" +#include "chrome/browser/data_sharing/data_sharing_navigation_throttle.h" +#include "chrome/browser/defaults.h" +#include "chrome/browser/device_api/device_service_impl.h" +#include "chrome/browser/device_api/managed_configuration_service.h" +#include "chrome/browser/dips/chrome_dips_delegate.h" +#include "chrome/browser/download/chrome_download_manager_delegate.h" +#include "chrome/browser/download/download_prefs.h" +#include "chrome/browser/enterprise/browser_management/management_service_factory.h" +#include "chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.h" +#include "chrome/browser/enterprise/reporting/prefs.h" +#include "chrome/browser/enterprise/util/managed_browser_utils.h" +#include "chrome/browser/extensions/chrome_extension_cookies.h" +#include "chrome/browser/external_protocol/external_protocol_handler.h" +#include "chrome/browser/favicon/favicon_utils.h" +#include "chrome/browser/first_party_sets/first_party_sets_navigation_throttle.h" +#include "chrome/browser/font_family_cache.h" +#include "chrome/browser/gpu/chrome_browser_main_extra_parts_gpu.h" +#include "chrome/browser/hid/chrome_hid_delegate.h" +#include "chrome/browser/history/history_service_factory.h" +#include "chrome/browser/interstitials/enterprise_util.h" +#include "chrome/browser/lifetime/browser_shutdown.h" +#include "chrome/browser/lookalikes/lookalike_url_navigation_throttle.h" +#include "chrome/browser/media/audio_service_util.h" +#include "chrome/browser/media/prefs/capture_device_ranking.h" +#include "chrome/browser/media/router/media_router_feature.h" +#include "chrome/browser/media/webrtc/audio_debug_recordings_handler.h" +#include "chrome/browser/media/webrtc/capture_policy_utils.h" +#include "chrome/browser/media/webrtc/chrome_screen_enumerator.h" +#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" +#include "chrome/browser/media/webrtc/media_device_salt_service_factory.h" +#include "chrome/browser/media/webrtc/webrtc_logging_controller.h" +#include "chrome/browser/memory/chrome_browser_main_extra_parts_memory.h" +#include "chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.h" +#include "chrome/browser/metrics/chrome_feature_list_creator.h" +#include "chrome/browser/navigation_predictor/anchor_element_preloader.h" +#include "chrome/browser/net/chrome_network_delegate.h" +#include "chrome/browser/net/profile_network_context_service.h" +#include "chrome/browser/net/profile_network_context_service_factory.h" +#include "chrome/browser/net/system_network_context_manager.h" +#include "chrome/browser/optimization_guide/chrome_browser_main_extra_parts_optimization_guide.h" +#include "chrome/browser/payments/payment_request_display_manager_factory.h" +#include "chrome/browser/performance_manager/public/chrome_browser_main_extra_parts_performance_manager.h" +#include "chrome/browser/performance_manager/public/chrome_content_browser_client_performance_manager_part.h" +#include "chrome/browser/performance_monitor/chrome_browser_main_extra_parts_performance_monitor.h" +#include "chrome/browser/plugins/pdf_iframe_navigation_throttle.h" +#include "chrome/browser/plugins/plugin_utils.h" +#include "chrome/browser/policy/policy_util.h" +#include "chrome/browser/policy/profile_policy_connector.h" +#include "chrome/browser/predictors/loading_predictor.h" +#include "chrome/browser/predictors/loading_predictor_factory.h" +#include "chrome/browser/preloading/navigation_ablation_throttle.h" +#include "chrome/browser/preloading/prefetch/no_state_prefetch/chrome_no_state_prefetch_contents_delegate.h" +#include "chrome/browser/preloading/prefetch/no_state_prefetch/chrome_speculation_host_delegate.h" +#include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h" +#include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_navigation_throttle.h" +#include "chrome/browser/preloading/prefetch/prefetch_service/chrome_prefetch_service_delegate.h" +#include "chrome/browser/preloading/prefetch/search_prefetch/field_trial_settings.h" +#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_url_loader.h" +#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_url_loader_interceptor.h" +#include "chrome/browser/preloading/preloading_features.h" +#include "chrome/browser/preloading/preloading_prefs.h" +#include "chrome/browser/preloading/prerender/prerender_web_contents_delegate.h" +#include "chrome/browser/privacy_budget/identifiability_study_state.h" +#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h" +#include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h" +#include "chrome/browser/private_network_access/chrome_private_network_device_delegate.h" +#include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_io_data.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/profiles/profile_selections.h" +#include "chrome/browser/profiles/renderer_updater.h" +#include "chrome/browser/profiles/renderer_updater_factory.h" +#include "chrome/browser/profiling_host/chrome_browser_main_extra_parts_profiling.h" +#include "chrome/browser/renderer_host/chrome_navigation_ui_data.h" +#include "chrome/browser/renderer_preferences_util.h" +#include "chrome/browser/request_header_integrity/buildflags.h" +#include "chrome/browser/safe_browsing/chrome_ping_manager_factory.h" +#include "chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_utils.h" +#include "chrome/browser/safe_browsing/delayed_warning_navigation_throttle.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/browser/safe_browsing/url_checker_delegate_impl.h" +#include "chrome/browser/safe_browsing/url_lookup_service_factory.h" +#include "chrome/browser/search/search.h" +#include "chrome/browser/segmentation_platform/chrome_browser_main_extra_parts_segmentation_platform.h" +#include "chrome/browser/sharing/sms/sms_remote_fetcher.h" +#include "chrome/browser/signin/chrome_signin_proxying_url_loader_factory.h" +#include "chrome/browser/signin/chrome_signin_url_loader_throttle.h" +#include "chrome/browser/signin/header_modification_delegate_impl.h" +#include "chrome/browser/speech/chrome_speech_recognition_manager_delegate.h" +#include "chrome/browser/ssl/chrome_security_blocking_page_factory.h" +#include "chrome/browser/ssl/https_defaulted_callbacks.h" +#include "chrome/browser/ssl/https_upgrades_interceptor.h" +#include "chrome/browser/ssl/https_upgrades_navigation_throttle.h" +#include "chrome/browser/ssl/sct_reporting_service.h" +#include "chrome/browser/ssl/security_state_tab_helper.h" +#include "chrome/browser/ssl/ssl_client_certificate_selector.h" +#include "chrome/browser/ssl/typed_navigation_upgrade_throttle.h" +#include "chrome/browser/supervised_user/supervised_user_google_auth_navigation_throttle.h" +#include "chrome/browser/supervised_user/supervised_user_navigation_throttle.h" +#include "chrome/browser/task_manager/sampling/task_manager_impl.h" +#include "chrome/browser/themes/theme_service.h" +#include "chrome/browser/themes/theme_service_factory.h" +#include "chrome/browser/tracing/chrome_tracing_delegate.h" +#include "chrome/browser/translate/translate_service.h" +#include "chrome/browser/ui/blocked_content/blocked_window_params.h" +#include "chrome/browser/ui/blocked_content/chrome_popup_navigation_delegate.h" +#include "chrome/browser/ui/blocked_content/tab_under_navigation_throttle.h" +#include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator_params.h" +#include "chrome/browser/ui/chrome_select_file_policy.h" +#include "chrome/browser/ui/lens/lens_overlay_side_panel_navigation_throttle.h" +#include "chrome/browser/ui/login/http_auth_coordinator.h" +#include "chrome/browser/ui/login/login_navigation_throttle.h" +#include "chrome/browser/ui/passwords/password_manager_navigation_throttle.h" +#include "chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h" +#include "chrome/browser/ui/prefs/pref_watcher.h" +#include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h" +#include "chrome/browser/ui/ui_features.h" +#include "chrome/browser/ui/webid/identity_dialog_controller.h" +#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h" +#include "chrome/browser/ui/webui/log_web_ui_url.h" +#include "chrome/browser/ui/webui/top_chrome/webui_url_utils.h" +#include "chrome/browser/universal_web_contents_observers.h" +#include "chrome/browser/usb/chrome_usb_delegate.h" +#include "chrome/browser/vr/vr_tab_helper.h" +#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h" +#include "chrome/browser/webapps/web_app_offline.h" +#include "chrome/browser/webauthn/webauthn_pref_names.h" +#include "chrome/common/buildflags.h" +#include "chrome/common/channel_info.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_content_client.h" +#include "chrome/common/chrome_features.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_paths_internal.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/env_vars.h" +#include "chrome/common/google_url_loader_throttle.h" +#include "chrome/common/logging_chrome.h" +#include "chrome/common/ppapi_utils.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/profiler/main_thread_stack_sampling_profiler.h" +#include "chrome/common/profiler/process_type.h" +#include "chrome/common/profiler/thread_profiler_configuration.h" +#include "chrome/common/renderer_configuration.mojom.h" +#include "chrome/common/secure_origin_allowlist.h" +#include "chrome/common/url_constants.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/grit/generated_resources.h" +#include "chrome/installer/util/google_update_settings.h" +#include "components/autofill/core/common/autofill_switches.h" +#include "components/blocked_content/popup_blocker.h" +#include "components/browsing_topics/browsing_topics_service.h" +#include "components/captive_portal/core/buildflags.h" +#include "components/content_settings/browser/page_specific_content_settings.h" +#include "components/content_settings/core/browser/content_settings_utils.h" +#include "components/content_settings/core/browser/cookie_settings.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/browser/private_network_settings.h" +#include "components/content_settings/core/common/content_settings.h" +#include "components/content_settings/core/common/content_settings_types.h" +#include "components/custom_handlers/protocol_handler_registry.h" +#include "components/custom_handlers/protocol_handler_throttle.h" +#include "components/dom_distiller/core/dom_distiller_switches.h" +#include "components/dom_distiller/core/url_constants.h" +#include "components/embedder_support/content_settings_utils.h" +#include "components/embedder_support/origin_trials/origin_trials_settings_storage.h" +#include "components/embedder_support/switches.h" +#include "components/embedder_support/user_agent_utils.h" +#include "components/enterprise/buildflags/buildflags.h" +#include "components/enterprise/common/proto/connectors.pb.h" +#include "components/enterprise/content/clipboard_restriction_service.h" +#include "components/enterprise/content/pref_names.h" +#include "components/error_page/common/error.h" +#include "components/error_page/common/error_page_switches.h" +#include "components/error_page/common/localized_error.h" +#include "components/error_page/content/browser/net_error_auto_reloader.h" +#include "components/fingerprinting_protection_filter/browser/throttle_manager.h" +#include "components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.h" +#include "components/google/core/common/google_switches.h" +#include "components/heap_profiling/in_process/heap_profiler_controller.h" +#include "components/history/content/browser/visited_link_navigation_throttle.h" +#include "components/keep_alive_registry/keep_alive_types.h" +#include "components/keep_alive_registry/scoped_keep_alive.h" +#include "components/language/core/browser/pref_names.h" +#include "components/lens/buildflags.h" +#include "components/live_caption/caption_util.h" +#include "components/media_device_salt/media_device_salt_service.h" +#include "components/media_router/browser/presentation/presentation_service_delegate_impl.h" +#include "components/media_router/browser/presentation/receiver_presentation_service_delegate_impl.h" +#include "components/media_router/browser/presentation/web_contents_presentation_manager.h" +#include "components/metrics/client_info.h" +#include "components/metrics_services_manager/metrics_services_manager.h" +#include "components/net_log/chrome_net_log.h" +#include "components/network_session_configurator/common/network_switches.h" +#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" +#include "components/no_state_prefetch/common/no_state_prefetch_final_status.h" +#include "components/no_state_prefetch/common/no_state_prefetch_url_loader_throttle.h" +#include "components/omnibox/common/omnibox_features.h" +#include "components/page_load_metrics/browser/metrics_navigation_throttle.h" +#include "components/page_load_metrics/browser/metrics_web_contents_observer.h" +#include "components/payments/content/payment_credential_factory.h" +#include "components/payments/content/payment_handler_navigation_throttle.h" +#include "components/payments/content/payment_request_display_manager.h" +#include "components/pdf/common/pdf_util.h" +#include "components/performance_manager/embedder/performance_manager_registry.h" +#include "components/permissions/bluetooth_delegate_impl.h" +#include "components/permissions/permission_context_base.h" +#include "components/policy/content/policy_blocklist_navigation_throttle.h" +#include "components/policy/content/policy_blocklist_service.h" +#include "components/policy/core/common/management/management_service.h" +#include "components/policy/core/common/policy_pref_names.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/scoped_user_pref_update.h" +#include "components/privacy_sandbox/privacy_sandbox_attestations/privacy_sandbox_attestations.h" +#include "components/privacy_sandbox/privacy_sandbox_features.h" +#include "components/privacy_sandbox/privacy_sandbox_prefs.h" +#include "components/privacy_sandbox/privacy_sandbox_settings.h" +#include "components/privacy_sandbox/tracking_protection_settings.h" +#include "components/safe_browsing/content/browser/async_check_tracker.h" +#include "components/safe_browsing/content/browser/browser_url_loader_throttle.h" +#include "components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition.h" +#include "components/safe_browsing/content/browser/safe_browsing_navigation_throttle.h" +#include "components/safe_browsing/content/browser/ui_manager.h" +#include "components/safe_browsing/core/browser/hashprefix_realtime/hash_realtime_service.h" +#include "components/safe_browsing/core/browser/realtime/policy_engine.h" +#include "components/safe_browsing/core/browser/realtime/url_lookup_service.h" +#include "components/safe_browsing/core/browser/url_checker_delegate.h" +#include "components/safe_browsing/core/common/features.h" +#include "components/safe_browsing/core/common/hashprefix_realtime/hash_realtime_utils.h" +#include "components/safe_browsing/core/common/safe_browsing_prefs.h" +#include "components/security_interstitials/content/insecure_form_navigation_throttle.h" +#include "components/security_interstitials/content/ssl_error_handler.h" +#include "components/security_interstitials/content/ssl_error_navigation_throttle.h" +#include "components/security_state/core/security_state.h" +#include "components/site_isolation/pref_names.h" +#include "components/site_isolation/preloaded_isolated_origins.h" +#include "components/site_isolation/site_isolation_policy.h" +#include "components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.h" +#include "components/translate/core/common/translate_switches.h" +#include "components/user_prefs/user_prefs.h" +#include "components/variations/variations_associated_data.h" +#include "components/variations/variations_switches.h" +#include "components/version_info/version_info.h" +#include "components/webapps/common/web_app_id.h" +#include "content/public/browser/attribution_data_model.h" +#include "content/public/browser/browser_accessibility_state.h" +#include "content/public/browser/browser_child_process_host.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_main_parts.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/browser_url_handler.h" +#include "content/public/browser/certificate_request_result_type.h" +#include "content/public/browser/child_process_data.h" +#include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/client_certificate_delegate.h" +#include "content/public/browser/digital_identity_provider.h" +#include "content/public/browser/file_url_loader.h" +#include "content/public/browser/isolated_web_apps_policy.h" +#include "content/public/browser/legacy_tech_cookie_issue_details.h" +#include "content/public/browser/navigation_handle.h" +#include "content/public/browser/navigation_throttle.h" +#include "content/public/browser/network_service_instance.h" +#include "content/public/browser/overlay_window.h" +#include "content/public/browser/permission_controller.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/site_isolation_mode.h" +#include "content/public/browser/sms_fetcher.h" +#include "content/public/browser/tts_controller.h" +#include "content/public/browser/tts_platform.h" +#include "content/public/browser/url_loader_request_interceptor.h" +#include "content/public/browser/vpn_service_proxy.h" +#include "content/public/browser/weak_document_ptr.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_view_delegate.h" +#include "content/public/browser/web_ui_url_loader_factory.h" +#include "content/public/browser/webui_config_map.h" +#include "content/public/common/content_descriptors.h" +#include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/url_utils.h" +#include "content/public/common/window_container_type.mojom-shared.h" +#include "device/vr/buildflags/buildflags.h" +#include "extensions/browser/browser_frame_context_data.h" +#include "extensions/buildflags/buildflags.h" +#include "google_apis/gaia/gaia_urls.h" +#include "google_apis/google_api_keys.h" +#include "gpu/config/gpu_switches.h" +#include "media/base/media_switches.h" +#include "media/media_buildflags.h" +#include "media/mojo/buildflags.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "net/base/features.h" +#include "net/cookies/site_for_cookies.h" +#include "net/ssl/client_cert_store.h" +#include "net/ssl/ssl_cert_request_info.h" +#include "net/ssl/ssl_private_key.h" +#include "pdf/buildflags.h" +#include "ppapi/buildflags/buildflags.h" +#include "printing/buildflags/buildflags.h" +#include "sandbox/policy/features.h" +#include "sandbox/policy/mojom/sandbox.mojom.h" +#include "sandbox/policy/switches.h" +#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" +#include "services/metrics/public/cpp/ukm_source_id.h" +#include "services/network/public/cpp/features.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" +#include "services/network/public/cpp/network_switches.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/self_deleting_url_loader_factory.h" +#include "services/network/public/cpp/web_sandbox_flags.h" +#include "services/network/public/mojom/cert_verifier_service.mojom.h" +#include "services/network/public/mojom/network_service.mojom.h" +#include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "services/network/public/mojom/web_transport.mojom.h" +#include "services/video_effects/public/mojom/video_effects_processor.mojom-forward.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/loader/url_loader_throttle.h" +#include "third_party/blink/public/common/navigation/navigation_policy.h" +#include "third_party/blink/public/common/permissions/permission_utils.h" +#include "third_party/blink/public/common/permissions_policy/permissions_policy.h" +#include "third_party/blink/public/common/switches.h" +#include "third_party/blink/public/mojom/browsing_topics/browsing_topics.mojom.h" +#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h" +#include "third_party/blink/public/public_buildflags.h" +#include "third_party/widevine/cdm/buildflags.h" +#include "ui/base/clipboard/clipboard_format_type.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/page_transition_types.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/color/color_provider_key.h" +#include "ui/gfx/switches.h" +#include "ui/native_theme/native_theme.h" +#include "url/gurl.h" +#include "url/origin.h" +#include "url/third_party/mozilla/url_parse.h" +#include "url/url_constants.h" + +#if BUILDFLAG(IS_WIN) +#include "base/files/file_util.h" +#include "base/strings/string_tokenizer.h" +#include "base/win/win_util.h" +#include "base/win/windows_version.h" +#include "chrome/browser/chrome_browser_main_win.h" +#include "chrome/browser/enterprise/platform_auth/platform_auth_navigation_throttle.h" +#include "chrome/browser/lifetime/application_lifetime_desktop.h" +#include "chrome/install_static/install_util.h" +#include "chrome/services/util_win/public/mojom/util_win.mojom.h" +#include "sandbox/win/src/sandbox_policy.h" +#elif BUILDFLAG(IS_MAC) +#include "chrome/browser/browser_process_platform_part_mac.h" +#include "chrome/browser/chrome_browser_main_mac.h" +#include "chrome/browser/mac/auth_session_request.h" +#include "chrome/browser/mac/chrome_browser_main_extra_parts_mac.h" +#include "components/soda/constants.h" +#include "sandbox/mac/sandbox_compiler.h" +#include "sandbox/policy/mac/params.h" +#include "sandbox/policy/mac/sandbox_mac.h" +#elif BUILDFLAG(IS_CHROMEOS_ASH) +#include "ash/constants/ash_features.h" +#include "ash/constants/ash_pref_names.h" +#include "ash/constants/ash_switches.h" +#include "ash/public/cpp/tablet_mode.h" +#include "ash/webui/camera_app_ui/url_constants.h" +#include "ash/webui/help_app_ui/url_constants.h" +#include "ash/webui/media_app_ui/url_constants.h" +#include "ash/webui/scanning/url_constants.h" +#include "chrome/app/chrome_crash_reporter_client.h" +#include "chrome/browser/ash/arc/fileapi/arc_content_file_system_backend_delegate.h" +#include "chrome/browser/ash/arc/fileapi/arc_documents_provider_backend_delegate.h" +#include "chrome/browser/ash/chrome_browser_main_parts_ash.h" +#include "chrome/browser/ash/crosapi/browser_util.h" +#include "chrome/browser/ash/drive/fileapi/drivefs_file_system_backend_delegate.h" +#include "chrome/browser/ash/file_manager/app_id.h" +#include "chrome/browser/ash/file_system_provider/fileapi/backend_delegate.h" +#include "chrome/browser/ash/fileapi/external_file_url_loader_factory.h" +#include "chrome/browser/ash/fileapi/file_system_backend.h" +#include "chrome/browser/ash/fileapi/mtp_file_system_backend_delegate.h" +#include "chrome/browser/ash/http_auth_dialog.h" +#include "chrome/browser/ash/login/signin/merge_session_navigation_throttle.h" +#include "chrome/browser/ash/login/signin/merge_session_throttling_utils.h" +#include "chrome/browser/ash/login/signin_partition_manager.h" +#include "chrome/browser/ash/login/startup_utils.h" +#include "chrome/browser/ash/net/network_health/network_health_manager.h" +#include "chrome/browser/ash/net/system_proxy_manager.h" +#include "chrome/browser/ash/profiles/profile_helper.h" +#include "chrome/browser/ash/smb_client/fileapi/smbfs_file_system_backend_delegate.h" +#include "chrome/browser/ash/system/input_device_settings.h" +#include "chrome/browser/ash/url_handler.h" +#include "chrome/browser/chromeos/app_mode/kiosk_settings_navigation_throttle.h" +#include "chrome/browser/speech/tts_chromeos.h" +#include "chrome/browser/speech/tts_controller_delegate_impl.h" +#include "chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h" +#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" +#include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/webui/ash/kerberos/kerberos_in_browser_dialog.h" +#include "chrome/common/webui_url_constants.h" +#include "chromeos/ash/components/browser_context_helper/browser_context_types.h" +#include "chromeos/ash/components/settings/cros_settings.h" +#include "chromeos/ash/services/network_health/public/cpp/network_health_helper.h" +#include "components/user_manager/user.h" +#include "components/user_manager/user_manager.h" +#include "services/service_manager/public/mojom/interface_provider_spec.mojom.h" +#include "storage/browser/file_system/external_mount_points.h" +// TODO(crbug.com/40118868): Revisit the macro expression once build flag switch +// of lacros-chrome is complete. +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/chrome_browser_main_linux.h" +#include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views_linux.h" +#elif BUILDFLAG(IS_ANDROID) +#include "base/android/application_status_listener.h" +#include "base/android/build_info.h" +#include "base/feature_list.h" +#include "chrome/android/features/dev_ui/buildflags.h" +#include "chrome/browser/android/customtabs/client_data_header_web_contents_observer.h" +#include "chrome/browser/android/devtools_manager_delegate_android.h" +#include "chrome/browser/android/ntp/new_tab_page_url_handler.h" +#include "chrome/browser/android/service_tab_launcher.h" +#include "chrome/browser/android/tab_android.h" +#include "chrome/browser/android/tab_web_contents_delegate_android.h" +#include "chrome/browser/chrome_browser_main_android.h" +#include "chrome/browser/digital_credentials/digital_identity_provider_android.h" +#include "chrome/browser/download/android/available_offline_content_provider.h" +#include "chrome/browser/download/android/intercept_oma_download_navigation_throttle.h" +#include "chrome/browser/flags/android/chrome_feature_list.h" +#include "chrome/browser/ui/android/tab_model/tab_model_list.h" +#include "chrome/common/chrome_descriptors.h" +#include "components/browser_ui/accessibility/android/font_size_prefs_android.h" +#include "components/crash/content/browser/child_exit_observer_android.h" +#include "components/crash/content/browser/crash_memory_metrics_collector_android.h" +#include "components/navigation_interception/intercept_navigation_delegate.h" +#include "components/viz/common/features.h" +#include "components/viz/common/viz_utils.h" +#include "content/public/browser/android/java_interfaces.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "ui/base/resource/resource_bundle_android.h" +#include "ui/base/ui_base_paths.h" +#include "ui/display/util/display_util.h" +#if BUILDFLAG(DFMIFY_DEV_UI) +#include "chrome/browser/dev_ui/android/dev_ui_loader_throttle.h" +#endif // BUILDFLAG(DFMIFY_DEV_UI) +#elif BUILDFLAG(IS_POSIX) +#include "chrome/browser/chrome_browser_main_posix.h" +#endif + +#if !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/digital_credentials/digital_identity_provider_desktop.h" +#include "chrome/browser/preloading/preview/preview_navigation_throttle.h" +#include "chrome/browser/web_applications/isolated_web_apps/chrome_content_browser_client_isolated_web_apps_part.h" +#include "chrome/browser/web_applications/locks/app_lock.h" +#include "chrome/browser/web_applications/proto/web_app_install_state.pb.h" +#include "chrome/browser/web_applications/web_app_helpers.h" +#include "third_party/blink/public/mojom/installedapp/related_application.mojom.h" +#endif // !BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_CHROMEOS) +#include "base/debug/leak_annotations.h" +#include "chrome/browser/apps/app_service/app_install/app_install_navigation_throttle.h" +#include "chrome/browser/apps/intent_helper/chromeos_disabled_apps_throttle.h" +#include "chrome/browser/apps/link_capturing/chromeos_link_capturing_delegate.h" +#include "chrome/browser/chromeos/enterprise/incognito_navigation_throttle.h" +#include "chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h" +#include "chrome/browser/chromeos/quickoffice/quickoffice_prefs.h" +#include "chrome/browser/chromeos/tablet_mode/chrome_content_browser_client_tablet_mode_part.h" +#include "chrome/browser/file_system_access/cloud_identifier/cloud_identifier_util_cros.h" +#include "chrome/browser/policy/networking/policy_cert_service.h" +#include "chrome/browser/policy/networking/policy_cert_service_factory.h" +#include "chrome/browser/policy/system_features_disable_list_policy_handler.h" +#include "chrome/browser/smart_card/chromeos_smart_card_delegate.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" +#include "chrome/common/chromeos/extensions/chromeos_system_extension_info.h" +#include "chromeos/components/kiosk/kiosk_utils.h" +#include "chromeos/constants/chromeos_features.h" +#include "content/public/browser/chromeos/multi_capture_service.h" +#include "third_party/cros_system_api/switches/chrome_switches.h" +#endif + +#if !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/apps/link_capturing/link_capturing_navigation_throttle.h" +#include "chrome/browser/devtools/chrome_devtools_manager_delegate.h" +#include "chrome/browser/devtools/devtools_window.h" +#include "chrome/browser/direct_sockets/chrome_direct_sockets_delegate.h" +#include "chrome/browser/enterprise/connectors/connectors_service.h" +#include "chrome/browser/headless/chrome_browser_main_extra_parts_headless.h" +#include "chrome/browser/media/unified_autoplay_config.h" +#include "chrome/browser/media_effects/media_effects_manager_binder.h" +#include "chrome/browser/metrics/usage_scenario/chrome_responsiveness_calculator_delegate.h" +#include "chrome/browser/new_tab_page/new_tab_page_util.h" +#include "chrome/browser/page_info/about_this_site_side_panel_throttle.h" +#include "chrome/browser/search/instant_service.h" +#include "chrome/browser/search/instant_service_factory.h" +#include "chrome/browser/serial/chrome_serial_delegate.h" +#include "chrome/browser/task_manager/task_manager_interface.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_dialogs.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/search/new_tab_page_navigation_throttle.h" +#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_navigation_throttle.h" +#include "chrome/browser/ui/web_applications/tabbed_web_app_navigation_throttle.h" +#include "chrome/browser/ui/web_applications/webui_web_app_navigation_throttle.h" +#include "chrome/browser/ui/webui/chrome_content_browser_client_webui_part.h" +#include "chrome/browser/ui/webui/webui_util_desktop.h" +#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_error_page.h" +#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_loader_factory.h" +#include "chrome/browser/web_applications/policy/web_app_policy_manager.h" +#include "chrome/browser/web_applications/web_app_helpers.h" +#include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/browser/web_applications/web_app_registrar.h" +#include "chrome/browser/web_applications/web_app_utils.h" +#include "chrome/browser/webauthn/authenticator_request_scheduler.h" +#include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h" +#include "chrome/grit/chrome_unscaled_resources.h" // nogncheck crbug.com/1125897 +#include "components/commerce/core/commerce_feature_list.h" +#include "components/lens/lens_features.h" +#include "components/password_manager/content/common/web_ui_constants.h" +#include "components/password_manager/core/common/password_manager_features.h" +#include "third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom.h" +#endif // !BUILDFLAG(IS_ANDROID) + +// TODO(crbug.com/40118868): Revisit the macro expression once build flag switch +// of lacros-chrome is complete. +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \ + (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) +#include "chrome/browser/browser_switcher/browser_switcher_navigation_throttle.h" +#endif + +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +#include "components/crash/core/app/crash_switches.h" +#include "components/crash/core/app/crashpad.h" +#endif + +#if BUILDFLAG(IS_ANDROID) +#include "components/crash/content/browser/crash_handler_host_linux.h" +#else +#include "chrome/browser/apps/link_capturing/web_app_link_capturing_delegate.h" +#endif + +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) +#include "chrome/browser/enterprise/chrome_browser_main_extra_parts_enterprise.h" +#include "chrome/browser/enterprise/profile_management/oidc_auth_response_capture_navigation_throttle.h" +#include "chrome/browser/enterprise/profile_management/profile_management_navigation_throttle.h" +#include "chrome/browser/ui/webui/app_settings/web_app_settings_navigation_throttle.h" +#endif + +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || \ + BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/enterprise/connectors/device_trust/navigation_throttle.h" +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || + // BUILDFLAG(IS_CHROMEOS_ASH) + +#if defined(TOOLKIT_VIEWS) +#include "chrome/browser/ui/side_search/side_search_side_contents_helper.h" +#include "chrome/browser/ui/side_search/side_search_utils.h" +#include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views.h" +#endif + +#if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES) +#include "chrome/browser/ui/views/lens/lens_side_panel_navigation_helper.h" +#endif + +#if BUILDFLAG(IS_LINUX) +#include "chrome/browser/chrome_browser_main_extra_parts_linux.h" +#elif BUILDFLAG(IS_OZONE) +#include "chrome/browser/chrome_browser_main_extra_parts_ozone.h" +#endif + +#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) +#include "components/captive_portal/content/captive_portal_tab_helper.h" +#include "components/captive_portal/content/captive_portal_url_loader_throttle.h" +#endif + +#if BUILDFLAG(ENABLE_NACL) +#include "components/nacl/browser/nacl_host_message_filter.h" +#include "components/nacl/browser/nacl_process_host.h" +#include "components/nacl/common/nacl_process_type.h" +#include "components/nacl/common/nacl_switches.h" +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "chrome/browser/accessibility/animation_policy_prefs.h" +#include "chrome/browser/apps/platform_apps/platform_app_navigation_redirector.h" +#include "chrome/browser/extensions/chrome_content_browser_client_extensions_part.h" +#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h" +#include "chrome/browser/extensions/extension_util.h" +#include "chrome/browser/extensions/user_script_listener.h" +#include "chrome/browser/speech/extension_api/tts_engine_extension_api.h" +#include "chrome/browser/ui/web_applications/app_browser_controller.h" +#include "chrome/browser/web_applications/web_app_utils.h" +#include "content/public/browser/site_isolation_policy.h" +#include "extensions/browser/api/web_request/web_request_api.h" +#include "extensions/browser/api/web_request/web_request_proxying_webtransport.h" +#include "extensions/browser/extension_navigation_throttle.h" +#include "extensions/browser/extension_protocols.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/browser/extension_util.h" +#include "extensions/browser/guest_view/web_view/web_view_guest.h" +#include "extensions/browser/guest_view/web_view/web_view_permission_helper.h" +#include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" +#include "extensions/browser/process_map.h" +#include "extensions/browser/script_injection_tracker.h" +#include "extensions/common/constants.h" +#include "extensions/common/extension.h" +#include "extensions/common/extension_set.h" +#include "extensions/common/manifest_handlers/background_info.h" +#include "extensions/common/permissions/permissions_data.h" +#include "extensions/common/switches.h" +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + +#if BUILDFLAG(ENABLE_PLUGINS) +#include "chrome/browser/plugins/chrome_content_browser_client_plugins_part.h" +#include "chrome/browser/plugins/plugin_response_interceptor_url_loader_throttle.h" +#endif + +#if BUILDFLAG(ENABLE_PDF) +#include "chrome/browser/pdf/chrome_pdf_stream_delegate.h" +#include "components/pdf/browser/pdf_navigation_throttle.h" +#include "components/pdf/browser/pdf_url_loader_request_interceptor.h" +#include "components/pdf/common/constants.h" +#if BUILDFLAG(IS_WIN) +#include "pdf/pdf_features.h" +#endif // BUILDFLAG(IS_WIN) +#endif // BUILDFLAG(ENABLE_PDF) + + +#if BUILDFLAG(ENABLE_MEDIA_REMOTING) +#include "chrome/browser/media/cast_remoting_connector.h" +#endif + +#if BUILDFLAG(ENABLE_REQUEST_HEADER_INTEGRITY) +#include "chrome/browser/request_header_integrity/request_header_integrity_url_loader_throttle.h" // nogncheck crbug.com/1125897 +#endif + +#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) +#include "chrome/browser/safe_browsing/chrome_password_protection_service.h" +#endif + +#if BUILDFLAG(SAFE_BROWSING_DB_LOCAL) +#include "chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service.h" // nogncheck crbug.com/1125897 +#include "chrome/browser/safe_browsing/chrome_enterprise_url_lookup_service_factory.h" // nogncheck crbug.com/1125897 +#endif + +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) +#include "chrome/browser/offline_pages/offline_page_navigation_throttle.h" +#include "chrome/browser/offline_pages/offline_page_tab_helper.h" +#include "chrome/browser/offline_pages/offline_page_url_loader_request_interceptor.h" +#endif + +#if BUILDFLAG(FULL_SAFE_BROWSING) +#include "chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.h" +#endif + +#if BUILDFLAG(ENABLE_VR) +#include "chrome/browser/vr/chrome_xr_integration_client.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/chrome_browser_main_parts_lacros.h" +#include "chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.h" +#include "chrome/browser/speech/tts_lacros.h" +#include "chrome/browser/ui/views/chrome_browser_main_extra_parts_views_lacros.h" +#include "chrome/common/chrome_descriptors.h" +#include "chromeos/crosapi/mojom/kerberos_in_browser.mojom.h" +#include "chromeos/lacros/lacros_service.h" +#include "chromeos/startup/browser_init_params.h" +#include "chromeos/startup/browser_postlogin_params.h" +#include "chromeos/startup/startup.h" // nogncheck +#include "chromeos/startup/startup_switches.h" // nogncheck +#include "mojo/core/embedder/embedder.h" +#include "ui/base/ui_base_switches.h" +#endif + +#if BUILDFLAG(USE_MINIKIN_HYPHENATION) && !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/component_updater/hyphenation_component_installer.h" +#endif + +#if BUILDFLAG(FULL_SAFE_BROWSING) +#include "components/enterprise/common/files_scan_data.h" +#endif + +// This should be after all other #includes. +#if defined(_WINDOWS_) // Detect whether windows.h was included. +#include "base/win/windows_h_disallowed.h" +#endif // defined(_WINDOWS_) + +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) +#include "chrome/browser/screen_ai/screen_ai_install_state.h" +#endif + +#if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) +#include "chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service.h" +#include "chrome/browser/signin/bound_session_credentials/bound_session_cookie_refresh_service_factory.h" +#include "chrome/browser/signin/bound_session_credentials/bound_session_request_throttled_handler_browser_impl.h" +#include "chrome/common/bound_session_request_throttled_handler.h" +#endif // BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + +#if BUILDFLAG(IS_CHROMEOS) +#include "chromeos/components/kiosk/kiosk_utils.h" +#endif // BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(ENTERPRISE_DATA_CONTROLS) +#include "chrome/browser/enterprise/data_protection/data_protection_clipboard_utils.h" +#include "chrome/browser/enterprise/data_protection/paste_allowed_request.h" +#endif // BUILDFLAG(ENTERPRISE_DATA_CONTROLS) + +#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED) +#include "services/device/public/cpp/geolocation/geolocation_system_permission_manager.h" +#endif // BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED) + +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/feed/feed_service_factory.h" +#include "components/feed/feed_feature_list.h" +#endif // BUILDFLAG(IS_ANDROID) + +using blink::mojom::EffectiveConnectionType; +using blink::web_pref::WebPreferences; +using content::BrowserThread; +using content::BrowserURLHandler; +using content::ChildProcessSecurityPolicy; +using content::RenderFrameHost; +using content::SiteInstance; +using content::WebContents; + +#if BUILDFLAG(IS_POSIX) +using content::PosixFileDescriptorInfo; +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) +using extensions::APIPermission; +using extensions::ChromeContentBrowserClientExtensionsPart; +using extensions::Extension; +using extensions::Manifest; +using extensions::mojom::APIPermissionID; +#endif + +#if BUILDFLAG(ENABLE_PLUGINS) +using plugins::ChromeContentBrowserClientPluginsPart; +#endif + +#if !BUILDFLAG(IS_ANDROID) +using web_apps::ChromeContentBrowserClientIsolatedWebAppsPart; +#endif + +namespace { + +#if BUILDFLAG(IS_ANDROID) +// Kill switch that allows falling back to the legacy behavior on Android when +// it comes to site isolation for Gaia's origin (|GaiaUrls::gaia_origin()|). +BASE_FEATURE(kAllowGaiaOriginIsolationOnAndroid, + "AllowGaiaOriginIsolationOnAndroid", + base::FEATURE_ENABLED_BY_DEFAULT); + +BASE_FEATURE(kPrivateNetworkAccessRestrictionsForAutomotive, + "PrivateNetworkAccessRestrictionsForAutomotive", + base::FEATURE_ENABLED_BY_DEFAULT); +#endif // BUILDFLAG(IS_ANDROID) + +// A small ChromeBrowserMainExtraParts that invokes a callback when threads are +// ready. Used to initialize ChromeContentBrowserClient data that needs the UI +// thread. +class ChromeBrowserMainExtraPartsThreadNotifier final + : public ChromeBrowserMainExtraParts { + public: + explicit ChromeBrowserMainExtraPartsThreadNotifier( + base::OnceClosure threads_ready_closure) + : threads_ready_closure_(std::move(threads_ready_closure)) {} + + // ChromeBrowserMainExtraParts: + void PostCreateThreads() final { std::move(threads_ready_closure_).Run(); } + + private: + base::OnceClosure threads_ready_closure_; +}; + +// Wrapper for SSLErrorHandler::HandleSSLError() that supplies //chrome-level +// parameters. +void HandleSSLErrorWrapper( + content::WebContents* web_contents, + int cert_error, + const net::SSLInfo& ssl_info, + const GURL& request_url, + SSLErrorHandler::BlockingPageReadyCallback blocking_page_ready_callback) { + DCHECK(request_url.SchemeIsCryptographic()); + + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + // Profile should always outlive a WebContents + DCHECK(profile); + + captive_portal::CaptivePortalService* captive_portal_service = nullptr; + +#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) + captive_portal_service = CaptivePortalServiceFactory::GetForProfile(profile); +#endif + + const bool is_ssl_error_override_allowed_for_origin = + policy::IsOriginInAllowlist(request_url, profile->GetPrefs(), + prefs::kSSLErrorOverrideAllowedForOrigins, + prefs::kSSLErrorOverrideAllowed); + + SSLErrorHandler::HandleSSLError( + web_contents, cert_error, ssl_info, request_url, + std::move(blocking_page_ready_callback), + g_browser_process->network_time_tracker(), captive_portal_service, + std::make_unique(), + is_ssl_error_override_allowed_for_origin); +} + +// Cached version of the locale so we can return the locale on the I/O +// thread. +std::string& GetIOThreadApplicationLocale() { + static base::NoDestructor s; + return *s; +} + +// Returns a copy of the given url with its host set to given host and path set +// to given path. Other parts of the url will be the same. +GURL ReplaceURLHostAndPath(const GURL& url, + const std::string& host, + const std::string& path) { + GURL::Replacements replacements; + replacements.SetHostStr(host); + replacements.SetPathStr(path); + return url.ReplaceComponents(replacements); +} + +// Handles the rewriting of the new tab page URL based on group policy. +bool HandleNewTabPageLocationOverride( + GURL* url, + content::BrowserContext* browser_context) { + if (!url->SchemeIs(content::kChromeUIScheme) || + url->host() != chrome::kChromeUINewTabHost) { + return false; + } + + Profile* profile = Profile::FromBrowserContext(browser_context); + + // Don't change the URL when incognito mode. + if (profile->IsOffTheRecord()) + return false; + + std::string ntp_location = + profile->GetPrefs()->GetString(prefs::kNewTabPageLocationOverride); + if (ntp_location.empty()) + return false; + url::Component scheme; + if (!url::ExtractScheme(ntp_location.data(), + static_cast(ntp_location.length()), &scheme)) { + ntp_location = base::StrCat( + {url::kHttpsScheme, url::kStandardSchemeSeparator, ntp_location}); + } + + *url = GURL(ntp_location); + return true; +} + +#if !BUILDFLAG(IS_ANDROID) +bool IsFileOrDirectoryPickerWithoutGestureAllowed( + content::WebContents* contents) { + if (!contents) { + return true; + } + + Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); + if (!profile) { + return true; + } + + PrefService* prefs = profile->GetPrefs(); + if (!prefs) { + return true; + } + + return !policy::IsOriginInAllowlist( + contents->GetURL(), prefs, + prefs::kFileOrDirectoryPickerWithoutGestureAllowedForOrigins); +} + +// Check if autoplay is allowed by policy configuration. +bool IsAutoplayAllowedByPolicy(content::WebContents* contents, + PrefService* prefs) { + if (!contents) { + return false; + } + + return policy::IsOriginInAllowlist(contents->GetURL(), prefs, + prefs::kAutoplayAllowlist, + prefs::kAutoplayAllowed); +} +#endif // !BUILDFLAG(IS_ANDROID) + +blink::mojom::AutoplayPolicy GetAutoplayPolicyForWebContents( + WebContents* web_contents) { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + + std::string autoplay_policy = media::GetEffectiveAutoplayPolicy(command_line); + auto result = blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired; + + if (autoplay_policy == switches::autoplay::kNoUserGestureRequiredPolicy) { + result = blink::mojom::AutoplayPolicy::kNoUserGestureRequired; + } else if (autoplay_policy == + switches::autoplay::kUserGestureRequiredPolicy) { + result = blink::mojom::AutoplayPolicy::kUserGestureRequired; + } else if (autoplay_policy == + switches::autoplay::kDocumentUserActivationRequiredPolicy) { + result = blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired; + } else { + NOTREACHED_IN_MIGRATION(); + } + +#if !BUILDFLAG(IS_ANDROID) + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + PrefService* prefs = profile->GetPrefs(); + + // Override autoplay policy used in internal switch in case of enabling + // features such as policy, allowlisting or disabling from settings. + if (IsAutoplayAllowedByPolicy(web_contents, prefs)) { + result = blink::mojom::AutoplayPolicy::kNoUserGestureRequired; + } else if (base::FeatureList::IsEnabled(media::kAutoplayDisableSettings) && + result == blink::mojom::AutoplayPolicy:: + kDocumentUserActivationRequired) { + result = UnifiedAutoplayConfig::ShouldBlockAutoplay(profile) + ? blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired + : blink::mojom::AutoplayPolicy::kNoUserGestureRequired; + } else if (web_contents->GetPrimaryMainFrame()->IsFeatureEnabled( + blink::mojom::PermissionsPolicyFeature::kAutoplay) && + IsAutoplayAllowedByPolicy(web_contents->GetOuterWebContents(), + prefs)) { + // If the domain policy allows autoplay and has delegated that to an iframe, + // allow autoplay within the iframe. Only allow a nesting of single depth. + result = blink::mojom::AutoplayPolicy::kNoUserGestureRequired; + } +#else // !BUILDFLAG(IS_ANDROID) + // TWAs don't require a user gesture for unmuted autoplay. + if (base::FeatureList::IsEnabled(features::kAllowUnmutedAutoplayForTWA)) { + if (auto* delegate = TabAndroid::FromWebContents(web_contents)) { + if (delegate->IsTrustedWebActivity()) { + result = blink::mojom::AutoplayPolicy::kNoUserGestureRequired; + } + } + } +#endif // BUILDFLAG(IS_ANDROID) + return result; +} + +#if BUILDFLAG(IS_ANDROID) +int GetCrashSignalFD(const base::CommandLine& command_line) { + return crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket(); +} +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) +int GetCrashSignalFD(const base::CommandLine& command_line) { + int fd; + return crash_reporter::GetHandlerSocket(&fd, nullptr) ? fd : -1; +} +#endif // BUILDFLAG(IS_ANDROID) + +void SetApplicationLocaleOnIOThread(const std::string& locale) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + GetIOThreadApplicationLocale() = locale; +} + +#if BUILDFLAG(ENABLE_EXTENSIONS) + +// Returns true if there is is an extension matching `url` in +// `render_process_id` with `permission`. +// +// GetExtensionOrAppByURL requires a full URL in order to match with a hosted +// app, even though normal extensions just use the host. +bool URLHasExtensionPermission(extensions::ProcessMap* process_map, + extensions::ExtensionRegistry* registry, + const GURL& url, + int render_process_id, + APIPermissionID permission) { + // Includes web URLs that are part of an extension's web extent. + const Extension* extension = + registry->enabled_extensions().GetExtensionOrAppByURL(url); + return extension && + extension->permissions_data()->HasAPIPermission(permission) && + process_map->Contains(extension->id(), render_process_id); +} + +// Returns true if |extension_id| is allowed to run as an Isolated Context, +// giving it access to additional APIs. +bool IsExtensionIdAllowedToUseIsolatedContext(std::string_view extension_id) { + constexpr auto kAllowedIsolatedContextExtensionIds = + base::MakeFixedFlatSet({ + "algkcnfjnajfhgimadimbjhmpaeohhln", // Secure Shell Extension (dev) + "iodihamcpbpeioajjeobimgagajmlibd", // Secure Shell Extension + // (stable) + // Extension IDs used in tests. + "bbobefdodiifgmhhdijgpelmkdaebfpn", // Controlled Frame Service + // Worker Test + }); + return base::Contains(kAllowedIsolatedContextExtensionIds, extension_id); +} + +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + +mojo::PendingRemote GetPrerenderCanceler( + base::OnceCallback wc_getter) { + mojo::PendingRemote canceler; + prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents( + std::move(wc_getter).Run()) + ->AddPrerenderCancelerReceiver(canceler.InitWithNewPipeAndPassReceiver()); + return canceler; +} + +bool ShouldHonorPolicies() { +#if BUILDFLAG(IS_WIN) + return policy::ManagementServiceFactory::GetForPlatform() + ->GetManagementAuthorityTrustworthiness() >= + policy::ManagementAuthorityTrustworthiness::TRUSTED; +#else + return true; +#endif +} + +// Used by Enterprise policy. Disable blocking of navigations toward external +// applications from a sandboxed iframe. +// https://chromestatus.com/feature/5680742077038592 +const char kDisableSandboxExternalProtocolSwitch[] = + "disable-sandbox-external-protocols"; + +void LaunchURL( + base::WeakPtr client, + const GURL& url, + content::WebContents::Getter web_contents_getter, + ui::PageTransition page_transition, + bool is_primary_main_frame, + bool is_in_fenced_frame_tree, + network::mojom::WebSandboxFlags sandbox_flags, + bool has_user_gesture, + const std::optional& initiating_origin, + content::WeakDocumentPtr initiator_document, + mojo::PendingRemote* out_factory) { + // If there is no longer a WebContents, the request may have raced with tab + // closing. Don't fire the external request. (It may have been a prerender.) + content::WebContents* web_contents = web_contents_getter.Run(); + if (!web_contents) + return; + + // Do not launch external requests attached to unswapped no-state prefetchers. + prerender::NoStatePrefetchContents* no_state_prefetch_contents = + prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents( + web_contents); + if (no_state_prefetch_contents) { + no_state_prefetch_contents->Destroy( + prerender::FINAL_STATUS_UNSUPPORTED_SCHEME); + return; + } + + // Do not launch external requests for schemes that have a handler registered. + custom_handlers::ProtocolHandlerRegistry* protocol_handler_registry = + ProtocolHandlerRegistryFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); + if (protocol_handler_registry && + protocol_handler_registry->IsHandledProtocol(url.scheme())) + return; + + // Sandbox flags + // ============= + // + // Navigations to external protocol in iframe can be seen as "top-level" + // navigations somehow, because they cause the user to switch from Chrome's + // page toward a different application. + // + // Internally in Chrome, they are seen as aborted iframe navigation, so the + // regular sandbox logic do not really apply. + // + // This block adds an extra logic, gating external protocol in iframes to have + // one of: + // - 'allow-top-navigation' + // - 'allow-top-navigation-to-custom-protocols' + // - 'allow-top-navigation-by-user-navigation' + user-activation + // - 'allow-popups' + // + // See https://crbug.com/1148777 + if (!is_primary_main_frame) { + using SandboxFlags = network::mojom::WebSandboxFlags; + auto allow = [&](SandboxFlags flag) { + return (sandbox_flags & flag) == SandboxFlags::kNone; + }; + bool allowed = (allow(SandboxFlags::kTopNavigationToCustomProtocols)) || + (allow(SandboxFlags::kTopNavigationByUserActivation) && + has_user_gesture); + + if (!allowed) { + content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame(); + if (client) { + client->LogWebFeatureForCurrentPage( + rfh, blink::mojom::WebFeature::kExternalProtocolBlockedBySandbox); + } + + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + kDisableSandboxExternalProtocolSwitch)) { + if (base::FeatureList::IsEnabled( + features::kSandboxExternalProtocolBlocked)) { + rfh->AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kError, + "Navigation to external protocol blocked by sandbox, because it " + "doesn't contain any of: " + "'allow-top-navigation-to-custom-protocols', " + "'allow-top-navigation-by-user-activation', " + "'allow-top-navigation', or " + "'allow-popups'. See " + "https://chromestatus.com/feature/5680742077038592 and " + "https://chromeenterprise.google/policies/" + "#SandboxExternalProtocolBlocked"); + return; + } + + if (base::FeatureList::IsEnabled( + features::kSandboxExternalProtocolBlockedWarning)) { + rfh->AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kError, + "After Chrome M103, navigation toward external protocol " + "will be blocked by sandbox, if it doesn't contain any of:" + "'allow-top-navigation-to-custom-protocols', " + "'allow-top-navigation-by-user-activation', " + "'allow-top-navigation', or " + "'allow-popups'. See " + "https://chromestatus.com/feature/5680742077038592 and " + "https://chromeenterprise.google/policies/" + "#SandboxExternalProtocolBlocked"); + } + } + } + } + + bool is_allowlisted = false; + PolicyBlocklistService* service = + PolicyBlocklistFactory::GetForBrowserContext( + web_contents->GetBrowserContext()); + if (ShouldHonorPolicies() && service) { + const policy::URLBlocklist::URLBlocklistState url_state = + service->GetURLBlocklistState(url); + is_allowlisted = + url_state == policy::URLBlocklist::URLBlocklistState::URL_IN_ALLOWLIST; + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Never skip security checks for the intent:// scheme because + // `ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck` does not handle + // intent:// URLs correctly (or any URLs that should be opened in ARC). + // TODO(b/331400224): Fix `LaunchUrlWithoutSecurityCheck` to handle intent:// + // URLs correctly and stop treating them in a special way here. + if (url.SchemeIs("intent")) { + is_allowlisted = false; + } +#endif + + // If the URL is in allowlist, we launch it without asking the user and + // without any additional security checks. Since the URL is allowlisted, + // we assume it can be executed. + if (is_allowlisted) { + ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( + url, web_contents, std::move(initiator_document)); + } else { + ExternalProtocolHandler::LaunchUrl( + url, std::move(web_contents_getter), page_transition, has_user_gesture, + is_in_fenced_frame_tree, initiating_origin, + std::move(initiator_document) +#if BUILDFLAG(IS_ANDROID) + , + out_factory +#endif + ); + } +} + +void MaybeAppendSecureOriginsAllowlistSwitch(base::CommandLine* cmdline) { + // |allowlist| combines pref/policy + cmdline switch in the browser process. + // For renderer and utility (e.g. NetworkService) processes the switch is the + // only available source, so below the combined (pref/policy + cmdline) + // allowlist of secure origins is injected into |cmdline| for these other + // processes. + std::vector allowlist = + network::SecureOriginAllowlist::GetInstance().GetCurrentAllowlist(); + if (!allowlist.empty()) { + cmdline->AppendSwitchASCII( + network::switches::kUnsafelyTreatInsecureOriginAsSecure, + base::JoinString(allowlist, ",")); + } +} + +#if BUILDFLAG(IS_WIN) && !defined(COMPONENT_BUILD) && \ + !defined(ADDRESS_SANITIZER) +// Returns the full path to |module_name|. Both dev builds (where |module_name| +// is in the current executable's directory) and proper installs (where +// |module_name| is in a versioned sub-directory of the current executable's +// directory) are supported. The identified file is not guaranteed to exist. +base::FilePath GetModulePath(std::wstring_view module_name) { + base::FilePath exe_dir; + const bool has_path = base::PathService::Get(base::DIR_EXE, &exe_dir); + DCHECK(has_path); + + // Look for the module in a versioned sub-directory of the current + // executable's directory and return the path if it can be read. This is the + // expected location of modules for proper installs. + const base::FilePath module_path = + exe_dir.AppendASCII(chrome::kChromeVersion).Append(module_name); + if (base::PathExists(module_path)) + return module_path; + + // Otherwise, return the path to the module in the current executable's + // directory. This is the expected location of modules for dev builds. + return exe_dir.Append(module_name); +} +#endif // BUILDFLAG(IS_WIN) && !defined(COMPONENT_BUILD) && + // !defined(ADDRESS_SANITIZER) + +void MaybeAddThrottle( + std::unique_ptr maybe_throttle, + std::vector>* throttles) { + if (maybe_throttle) + throttles->push_back(std::move(maybe_throttle)); +} + +#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) +void MaybeAddCondition( + std::unique_ptr maybe_condition, + std::vector>* + conditions) { + if (maybe_condition) + conditions->push_back(std::move(maybe_condition)); +} +#endif + +void MaybeAddThrottles( + std::vector> additional, + std::vector>* combined) { + combined->insert(combined->end(), std::make_move_iterator(additional.begin()), + std::make_move_iterator(additional.end())); +} + +// Returns whether |web_contents| is within a hosted app. +bool IsInHostedApp(WebContents* web_contents) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + Browser* browser = chrome::FindBrowserWithTab(web_contents); + return web_app::AppBrowserController::IsWebApp(browser); +#else + return false; +#endif +} + +bool IsErrorPageAutoReloadEnabled() { + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kEnableAutomation)) + return false; + if (command_line.HasSwitch(embedder_support::kEnableAutoReload)) + return true; + if (command_line.HasSwitch(embedder_support::kDisableAutoReload)) + return false; + return true; +} + +// Checks whether a render process hosting a top chrome page exists. +bool IsTopChromeRendererPresent(Profile* profile) { + for (auto rph_iterator = content::RenderProcessHost::AllHostsIterator(); + !rph_iterator.IsAtEnd(); rph_iterator.Advance()) { + content::RenderProcessHost* rph = rph_iterator.GetCurrentValue(); + + // Consider only valid RenderProcessHosts that belong to the current + // profile. + if (rph->IsInitializedAndNotDead() && + profile->IsSameOrParent( + Profile::FromBrowserContext(rph->GetBrowserContext()))) { + bool is_top_chrome_renderer_present = false; + rph->ForEachRenderFrameHost( + [&is_top_chrome_renderer_present](content::RenderFrameHost* rfh) { + is_top_chrome_renderer_present |= + IsTopChromeWebUIURL(rfh->GetSiteInstance()->GetSiteURL()); + }); + + // Return true if a rph hosting a top chrome WebUI has been found. + if (is_top_chrome_renderer_present) + return true; + } + } + return false; +} + +// Return false if a top chrome renderer exists. This is done to ensure the +// spare renderer is not taken and the existing top chrome renderer is +// considered instead. +// TODO(crbug.com/1291351, tluk): This is needed since spare renderers are +// considered before existing processes for reuse. This can be simplified by +// migrating to SiteInstanceGroups once the project has landed. +bool ShouldUseSpareRenderProcessHostForTopChromePage(Profile* profile) { + return base::FeatureList::IsEnabled( + features::kTopChromeWebUIUsesSpareRenderer) && + !IsTopChromeRendererPresent(profile); +} + +#if BUILDFLAG(IS_CHROMEOS) +void NotifyMultiCaptureStarted(const std::string& label, + content::WebContents* web_contents, + const webapps::AppId* app_id) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (app_id && + video_capture::mojom::MultiCaptureServiceClient::Version_ >= + video_capture::mojom::MultiCaptureServiceClient::MethodMinVersions:: + kMultiCaptureStartedFromAppMinVersion) { + content::GetMultiCaptureService().NotifyMultiCaptureStartedFromApp( + label, *app_id, + web_app::WebAppProvider::GetForWebContents(web_contents) + ->registrar_unsafe() + .GetAppShortName(*app_id)); + } else { + // TODO(b/319317165): Remove this case once the pivot to web apps is + // complete. + content::GetMultiCaptureService().NotifyMultiCaptureStarted( + label, url::Origin::Create(web_contents->GetLastCommittedURL())); + } +#elif BUILDFLAG(IS_CHROMEOS_LACROS) + chromeos::LacrosService& service = + CHECK_DEREF(chromeos::LacrosService::Get()); + crosapi::mojom::MultiCaptureService& multi_capture_service = CHECK_DEREF( + service.GetRemote().get()); + if (app_id && + service.GetInterfaceVersion() >= + (int)crosapi::mojom::MultiCaptureService::MethodMinVersions:: + kMultiCaptureStartedFromAppMinVersion) { + multi_capture_service.MultiCaptureStartedFromApp( + label, *app_id, + web_app::WebAppProvider::GetForWebContents(web_contents) + ->registrar_unsafe() + .GetAppShortName(*app_id)); + } else { + // TODO(b/319317165): Remove this case once the pivot to web apps is + // complete. + multi_capture_service.MultiCaptureStarted( + label, web_contents->GetLastCommittedURL().host()); + } +#endif +} + +void NotifyMultiCaptureStopped(const std::string& label) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + content::GetMultiCaptureService().NotifyMultiCaptureStopped(label); +#elif BUILDFLAG(IS_CHROMEOS_LACROS) + crosapi::mojom::MultiCaptureService& multi_capture_service = + CHECK_DEREF(chromeos::LacrosService::Get() + ->GetRemote() + .get()); + multi_capture_service.MultiCaptureStopped(label); +#endif +} + +bool IsSubAppsPermissionGrantedByAdmins(content::WebContents* contents) { + if (!contents) { + return false; + } + + Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); + if (!profile) { + return false; + } + + PrefService* prefs = profile->GetPrefs(); + if (!prefs) { + return false; + } + + return policy::IsOriginInAllowlist( + contents->GetURL(), prefs, + prefs::kSubAppsAPIsAllowedWithoutGestureAndAuthorizationForOrigins); +} + +// Checks if installation and removal of subapps require a user gesture and +// authorization. Both requirements can be overridden via admin policy. +bool SubAppsAPIsRequireUserGestureAndAuthorization( + content::WebContents* web_contents) { + return !IsSubAppsPermissionGrantedByAdmins(web_contents); +} +#endif // BUILDFLAG(IS_CHROMEOS) + +std::unique_ptr +CreatePopupNavigationDelegate(NavigateParams params) { + return std::make_unique(std::move(params)); +} + +// NOTE: MaybeCreateVisitedLinkNavigationThrottleFor is defined here due to +// usage of Profile code which lives in chrome/. The rest of the +// VisitedLinkNavigationThrottle class lives in components/, which cannot access +// chrome/ code due to layering. +std::unique_ptr +MaybeCreateVisitedLinkNavigationThrottleFor( + content::NavigationHandle* navigation_handle) { + if (!base::FeatureList::IsEnabled( + blink::features::kPartitionVisitedLinkDatabase)) { + return nullptr; + } + Profile* profile = Profile::FromBrowserContext( + navigation_handle->GetWebContents()->GetBrowserContext()); + // Off-the-record profiles do not record history or visited links. + if (profile->IsOffTheRecord()) { + return nullptr; + } + history::HistoryService* history_service = + HistoryServiceFactory::GetForProfile(profile, + ServiceAccessType::IMPLICIT_ACCESS); + if (!history_service) { + return nullptr; + } + return std::make_unique( + std::move(navigation_handle), history_service); +} + +ChromeContentBrowserClient::PopupNavigationDelegateFactory + g_popup_navigation_delegate_factory = &CreatePopupNavigationDelegate; + +bool DetermineIfDevtoolsUserForProcessPerSite() { + bool is_devtools_user = false; + if (ProfileManager* profile_manager = g_browser_process->profile_manager()) { + std::vector profiles = profile_manager->GetLoadedProfiles(); + for (auto* profile : profiles) { + if (profile->GetPrefs()->HasPrefPath( + prefs::kDevToolsSyncedPreferencesSyncDisabled) || + profile->GetPrefs()->HasPrefPath(prefs::kDevToolsPreferences)) { + is_devtools_user = true; + break; + } + } + } + base::UmaHistogramBoolean( + "SiteIsolation.ProcessPerSiteWithMainFrameThreshold.IsDevToolsUser", + is_devtools_user); + return is_devtools_user; +} + +net::handles::NetworkHandle GetBoundNetworkFromRenderFrameHost( + content::RenderFrameHost* frame) { + auto* web_contents = WebContents::FromRenderFrameHost(frame); + if (!web_contents) { + return net::handles::kInvalidNetworkHandle; + } + return web_contents->GetTargetNetwork(); +} + +} // namespace + +// static +ChromeContentBrowserClient::PopupNavigationDelegateFactory& +ChromeContentBrowserClient::GetPopupNavigationDelegateFactoryForTesting() { + return g_popup_navigation_delegate_factory; +} + +ChromeContentBrowserClient::ChromeContentBrowserClient() { +#if BUILDFLAG(ENABLE_PLUGINS) + extra_parts_.push_back( + std::make_unique()); +#endif + +#if BUILDFLAG(IS_CHROMEOS) + extra_parts_.push_back( + std::make_unique()); +#endif // BUILDFLAG(IS_CHROMEOS) + +#if !BUILDFLAG(IS_ANDROID) + extra_parts_.push_back( + std::make_unique()); +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + extra_parts_.push_back( + std::make_unique()); +#endif + +#if !BUILDFLAG(IS_ANDROID) + extra_parts_.push_back( + std::make_unique()); +#endif + + extra_parts_.push_back( + std::make_unique()); +} + +ChromeContentBrowserClient::~ChromeContentBrowserClient() { + // std::vector<> does not guarantee any specific destruction order, so + // explicitly destroy elements in the reverse order per header comment. + while (!extra_parts_.empty()) { + extra_parts_.pop_back(); + } +} + +// static +void ChromeContentBrowserClient::RegisterLocalStatePrefs( + PrefRegistrySimple* registry) { + registry->RegisterFilePathPref(prefs::kDiskCacheDir, base::FilePath()); + registry->RegisterIntegerPref(prefs::kDiskCacheSize, 0); + registry->RegisterStringPref(prefs::kIsolateOrigins, std::string()); + registry->RegisterBooleanPref(prefs::kSitePerProcess, false); + registry->RegisterBooleanPref(prefs::kTabFreezingEnabled, true); + registry->RegisterIntegerPref(prefs::kSCTAuditingHashdanceReportCount, 0); +#if BUILDFLAG(IS_CHROMEOS) + registry->RegisterBooleanPref(prefs::kNativeClientForceAllowed, false); +#endif // BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref(prefs::kOutOfProcessSystemDnsResolutionEnabled, + true); +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) +} + +// static +void ChromeContentBrowserClient::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterBooleanPref(prefs::kDisable3DAPIs, false); + registry->RegisterBooleanPref(prefs::kEnableHyperlinkAuditing, true); + // Register user prefs for mapping SitePerProcess and IsolateOrigins in + // user policy in addition to the same named ones in Local State (which are + // used for mapping the command-line flags). + registry->RegisterStringPref(prefs::kIsolateOrigins, std::string()); + registry->RegisterBooleanPref(prefs::kSitePerProcess, false); + registry->RegisterListPref( + site_isolation::prefs::kUserTriggeredIsolatedOrigins); + registry->RegisterDictionaryPref( + site_isolation::prefs::kWebTriggeredIsolatedOrigins); + registry->RegisterDictionaryPref( + prefs::kDevToolsBackgroundServicesExpirationDict); + registry->RegisterBooleanPref(prefs::kSignedHTTPExchangeEnabled, true); +#if !BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref(prefs::kAutoplayAllowed, false); + registry->RegisterListPref(prefs::kAutoplayAllowlist); + registry->RegisterListPref( + prefs::kScreenCaptureWithoutGestureAllowedForOrigins); + registry->RegisterListPref( + prefs::kFileOrDirectoryPickerWithoutGestureAllowedForOrigins); + registry->RegisterIntegerPref(prefs::kFetchKeepaliveDurationOnShutdown, 0); + registry->RegisterBooleanPref( + prefs::kSharedArrayBufferUnrestrictedAccessAllowed, false); +#endif + registry->RegisterBooleanPref(prefs::kSandboxExternalProtocolBlocked, true); + registry->RegisterBooleanPref(prefs::kSSLErrorOverrideAllowed, true); + registry->RegisterListPref(prefs::kSSLErrorOverrideAllowedForOrigins); + registry->RegisterBooleanPref(prefs::kCompressionDictionaryTransportEnabled, + true); + registry->RegisterBooleanPref( + prefs::kSuppressDifferentOriginSubframeJSDialogs, true); +#if BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref(prefs::kWebXRImmersiveArEnabled, true); +#endif + registry->RegisterBooleanPref(prefs::kPromptOnMultipleMatchingCertificates, + false); + registry->RegisterBooleanPref(prefs::kCorsNonWildcardRequestHeadersSupport, + true); + registry->RegisterBooleanPref(prefs::kIPv6ReachabilityOverrideEnabled, false); + registry->RegisterDictionaryPref( + enterprise::content::kCopyPreventionSettings); + registry->RegisterIntegerPref( + prefs::kUserAgentReduction, + static_cast( + embedder_support::UserAgentReductionEnterprisePolicyState::kDefault)); + registry->RegisterBooleanPref(prefs::kOriginAgentClusterDefaultEnabled, true); + + registry->RegisterBooleanPref( + prefs::kStrictMimetypeCheckForWorkerScriptsEnabled, true); + registry->RegisterBooleanPref(policy::policy_prefs::kFeedbackSurveysEnabled, + true); + registry->RegisterBooleanPref( + prefs::kAccessControlAllowMethodsInCORSPreflightSpecConformant, true); + registry->RegisterBooleanPref(prefs::kDataUrlInSvgUseEnabled, false); + + registry->RegisterBooleanPref(policy::policy_prefs::kMutationEventsEnabled, + false); + + registry->RegisterBooleanPref( + policy::policy_prefs::kCSSCustomStateDeprecatedSyntaxEnabled, + /*default_value=*/false); + + registry->RegisterBooleanPref( + policy::policy_prefs::kBeforeunloadEventCancelByPreventDefaultEnabled, + true); + + registry->RegisterBooleanPref( + policy::policy_prefs::kKeyboardFocusableScrollersEnabled, true); + registry->RegisterBooleanPref( + policy::policy_prefs::kStandardizedBrowserZoomEnabled, true); + + registry->RegisterBooleanPref( + policy::policy_prefs:: + kAllowBackForwardCacheForCacheControlNoStorePageEnabled, + true); + + registry->RegisterBooleanPref( + policy::policy_prefs::kForcePermissionPolicyUnloadDefaultEnabled, false); + +#if BUILDFLAG(IS_CHROMEOS) + registry->RegisterListPref(prefs::kMandatoryExtensionsForIncognitoNavigation); + registry->RegisterListPref( + prefs::kSubAppsAPIsAllowedWithoutGestureAndAuthorizationForOrigins); +#endif +} + +// static +void ChromeContentBrowserClient::SetApplicationLocale( + const std::string& locale) { + // The common case is that this function is called early in Chrome startup + // before any threads are created or registered. When there are no threads, + // we can just set the string without worrying about threadsafety. + if (!BrowserThread::IsThreadInitialized(BrowserThread::IO)) { + GetIOThreadApplicationLocale() = locale; + return; + } + + // Otherwise we're being called to change the locale. In this case set it on + // the IO thread. + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + content::GetIOThreadTaskRunner({})->PostTask( + FROM_HERE, base::BindOnce(&SetApplicationLocaleOnIOThread, locale)); +} + +void ChromeContentBrowserClient::MaybeProxyNetworkBoundRequest( + content::BrowserContext* browser_context, + net::handles::NetworkHandle bound_network, + network::URLLoaderFactoryBuilder& factory_builder, + network::mojom::URLLoaderFactoryOverridePtr* factory_override, + const net::IsolationInfo& isolation_info) { + if (bound_network == net::handles::kInvalidNetworkHandle) { + return; + } + + // We support one network-bound NetworkContext at most. If a new one is + // needed, make sure to clean up the previous one first. + if (bound_network != target_network_for_network_bound_network_context_) { + network_bound_network_context_ = + mojo::Remote(); + network::mojom::NetworkContextParamsPtr context_params = + network::mojom::NetworkContextParams::New(); + context_params->bound_network = bound_network; + context_params->cert_verifier_params = content::GetCertVerifierParams( + cert_verifier::mojom::CertVerifierCreationParams::New()); + ConfigureNetworkContextParams( + browser_context, true, base::FilePath(), context_params.get(), + cert_verifier::mojom::CertVerifierCreationParams::New().get()); + content::CreateNetworkContextInNetworkService( + network_bound_network_context_.BindNewPipeAndPassReceiver(), + std::move(context_params)); + target_network_for_network_bound_network_context_ = bound_network; + } + + // TLDR; if `factory_override` != nullptr, this is being called for the + // creation of a 2-layer URLLoaderFactory (see + // network.mojom.URLLoaderFactoryOverride documentation). In this case, we + // want to substitute the internal (defined by + // factory_override->overriding_factory, with a URLLoaderFactory that targets + // `bound_network`. If `factory_override` == nullptr, this is a single-layer + // URLLoaderFactory. In this case, we want the last URLLoaderFactory in the + // `factory_builder` chain to be a URLLoaderFactory that targets + // `bound_network`. + mojo::PendingReceiver proxied_receiver; + mojo::PendingRemote bypassed_remote; + if (!factory_override) { + // Hijack the receiver end returned by network::URLLoaderFactoryBuilder. + // This will be then redirected to a network-bound URLLoaderFactory. + std::tie(proxied_receiver, bypassed_remote) = factory_builder.Append(); + } else { + // Hijack the remote end stored in network::mojom::URLLoaderFactoryOverride. + // This will be then redirected to a network-bound URLLoaderFactory. + *factory_override = network::mojom::URLLoaderFactoryOverride::New(); + proxied_receiver = + (*factory_override) + ->overriding_factory.InitWithNewPipeAndPassReceiver(); + (*factory_override)->overridden_factory_receiver = + bypassed_remote.InitWithNewPipeAndPassReceiver(); + (*factory_override)->skip_cors_enabled_scheme_check = true; + } + + // Create a network-bound URLLoaderFactory and redirect the receiver end of + // the hijacked remote to this. + network::mojom::URLLoaderFactoryParamsPtr params = + network::mojom::URLLoaderFactoryParams::New(); + params->process_id = network::mojom::kBrowserProcessId; + params->is_trusted = true; + params->isolation_info = isolation_info; + // Disable CORS wrapping, this is already handled by the caller. + params->disable_web_security = true; + network_bound_network_context_->CreateURLLoaderFactory( + std::move(proxied_receiver), std::move(params)); +} + +std::unique_ptr +ChromeContentBrowserClient::CreateBrowserMainParts(bool is_integration_test) { + std::unique_ptr main_parts; + // Construct the Main browser parts based on the OS type. +#if BUILDFLAG(IS_WIN) + main_parts = std::make_unique(is_integration_test, + &startup_data_); +#elif BUILDFLAG(IS_MAC) + main_parts = std::make_unique(is_integration_test, + &startup_data_); +#elif BUILDFLAG(IS_CHROMEOS_ASH) + main_parts = std::make_unique( + is_integration_test, &startup_data_); +#elif BUILDFLAG(IS_CHROMEOS_LACROS) + main_parts = std::make_unique( + is_integration_test, &startup_data_); +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) + main_parts = std::make_unique( + is_integration_test, &startup_data_); +#elif BUILDFLAG(IS_ANDROID) + main_parts = std::make_unique( + is_integration_test, &startup_data_); +#elif BUILDFLAG(IS_POSIX) + main_parts = std::make_unique( + is_integration_test, &startup_data_); +#else +#error "Unimplemented platform" +#endif + + main_parts->AddParts( + std::make_unique( + base::BindOnce(&ChromeContentBrowserClient::InitOnUIThread, + weak_factory_.GetWeakPtr()))); + + bool add_profiles_extra_parts = true; +#if BUILDFLAG(IS_ANDROID) + if (startup_data_.HasBuiltProfilePrefService()) + add_profiles_extra_parts = false; +#endif + if (add_profiles_extra_parts) + chrome::AddProfilesExtraParts(main_parts.get()); + + // Construct additional browser parts. Stages are called in the order in + // which they are added. +#if defined(TOOLKIT_VIEWS) +#if BUILDFLAG(IS_CHROMEOS_LACROS) + main_parts->AddParts( + std::make_unique()); +// TODO(crbug.com/40118868): Revisit the macro expression once build flag switch +// of lacros-chrome is complete. +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) + main_parts->AddParts( + std::make_unique()); +#else + main_parts->AddParts(std::make_unique()); +#endif +#endif + +#if BUILDFLAG(IS_MAC) + main_parts->AddParts(std::make_unique()); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // TODO(jamescook): Combine with `ChromeBrowserMainPartsAsh`. + main_parts->AddParts(std::make_unique()); +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + main_parts->AddParts(std::make_unique()); +#endif + +#if BUILDFLAG(IS_LINUX) + main_parts->AddParts(std::make_unique()); +#elif BUILDFLAG(IS_OZONE) + main_parts->AddParts(std::make_unique()); +#endif + + main_parts->AddParts( + std::make_unique()); + + main_parts->AddParts( + std::make_unique()); + + main_parts->AddParts( + std::make_unique()); + + main_parts->AddParts(std::make_unique()); + + chrome::AddMetricsExtraParts(main_parts.get()); + +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) + main_parts->AddParts( + std::make_unique< + chrome::enterprise_util::ChromeBrowserMainExtraPartsEnterprise>()); +#endif + +#if !BUILDFLAG(IS_ANDROID) + main_parts->AddParts( + std::make_unique()); +#endif + + // Always add ChromeBrowserMainExtraPartsGpu last to make sure + // GpuDataManager initialization could pick up about:flags settings. + main_parts->AddParts(std::make_unique()); + + main_parts->AddParts( + std::make_unique()); + + main_parts->AddParts( + std::make_unique()); + + main_parts->AddParts( + std::make_unique()); + + return main_parts; +} + +void ChromeContentBrowserClient::PostAfterStartupTask( + const base::Location& from_here, + const scoped_refptr& task_runner, + base::OnceClosure task) { + AfterStartupTaskUtils::PostTask(from_here, task_runner, std::move(task)); +} + +bool ChromeContentBrowserClient::IsBrowserStartupComplete() { + return AfterStartupTaskUtils::IsBrowserStartupComplete(); +} + +void ChromeContentBrowserClient::SetBrowserStartupIsCompleteForTesting() { + AfterStartupTaskUtils::SetBrowserStartupIsCompleteForTesting(); +} + +bool ChromeContentBrowserClient::IsShuttingDown() { + return browser_shutdown::HasShutdownStarted(); +} + +void ChromeContentBrowserClient::ThreadPoolWillTerminate() { + sampling_profiler_.reset(); +} + +content::StoragePartitionConfig +ChromeContentBrowserClient::GetStoragePartitionConfigForSite( + content::BrowserContext* browser_context, + const GURL& site) { + // Default to the browser-wide storage partition and override based on |site| + // below. + content::StoragePartitionConfig default_storage_partition_config = + content::StoragePartitionConfig::CreateDefault(browser_context); + + // A non-default storage partition is used in the following situations: + // - To enforce process isolation between a more-trusted content (Chrome Apps, + // Extensions, and Isolated Web Apps) and regular web content. + // - For the tag, which Chrome Apps, Isolated Web Apps and WebUI use + // to create temporary storage buckets for loading various kinds of web + // content. + // + // In general, those use cases aren't considered part of the user's normal + // browsing activity. +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (site.SchemeIs(extensions::kExtensionScheme)) { + // The host in an extension site URL is the extension_id. + CHECK(site.has_host()); + return extensions::util::GetStoragePartitionConfigForExtensionId( + site.host(), browser_context); + } + + if (content::SiteIsolationPolicy::ShouldUrlUseApplicationIsolationLevel( + browser_context, site)) { + CHECK(site.SchemeIs(chrome::kIsolatedAppScheme)); + ASSIGN_OR_RETURN(const auto iwa_url_info, + web_app::IsolatedWebAppUrlInfo::Create(site), [&](auto) { + LOG(ERROR) << "Invalid isolated-app URL: " << site; + return default_storage_partition_config; + }); + return iwa_url_info.storage_partition_config(browser_context); + } +#endif + + return default_storage_partition_config; +} + +std::unique_ptr +ChromeContentBrowserClient::GetWebContentsViewDelegate( + content::WebContents* web_contents) { + if (auto* registry = + performance_manager::PerformanceManagerRegistry::GetInstance()) { + registry->MaybeCreatePageNodeForWebContents(web_contents); + } + return CreateWebContentsViewDelegate(web_contents); +} + +bool ChromeContentBrowserClient::AllowGpuLaunchRetryOnIOThread() { +#if BUILDFLAG(IS_ANDROID) + const base::android::ApplicationState app_state = + base::android::ApplicationStatusListener::GetState(); + return base::android::APPLICATION_STATE_UNKNOWN == app_state || + base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES == app_state || + base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES == app_state; +#else + return true; +#endif +} + +void ChromeContentBrowserClient::RenderProcessWillLaunch( + content::RenderProcessHost* host) { + Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext()); + + WebRtcLoggingController::AttachToRenderProcessHost(host); + + // The audio manager outlives the host, so it's safe to hand a raw pointer to + // it to the AudioDebugRecordingsHandler, which is owned by the host. + AudioDebugRecordingsHandler* audio_debug_recordings_handler = + new AudioDebugRecordingsHandler(profile); + host->SetUserData( + AudioDebugRecordingsHandler::kAudioDebugRecordingsHandlerKey, + std::make_unique>( + audio_debug_recordings_handler)); + +#if BUILDFLAG(ENABLE_NACL) + if (IsNaclAllowed() && !profile->IsSystemProfile()) { + host->AddFilter(new nacl::NaClHostMessageFilter( + host->GetID(), profile->IsOffTheRecord(), profile->GetPath())); + } +#endif + +#if BUILDFLAG(IS_ANDROID) + // Register CrashMemoryMetricsCollector to report oom related metrics. + host->SetUserData( + CrashMemoryMetricsCollector::kCrashMemoryMetricsCollectorKey, + std::make_unique(host)); +#endif + + IdentifiabilityStudyState* identifiability_study_state = + g_browser_process->GetMetricsServicesManager() + ->GetIdentifiabilityStudyState(); + if (identifiability_study_state) { + identifiability_study_state->InitializeRenderer(host); + } + + // The RendereUpdater might be null for some irregular profiles, e.g. the + // System Profile. + if (RendererUpdater* service = RendererUpdaterFactory::GetForProfile(profile)) + service->InitializeRenderer(host); + + for (auto& part : extra_parts_) { + part->RenderProcessWillLaunch(host); + } +} + +GURL ChromeContentBrowserClient::GetEffectiveURL( + content::BrowserContext* browser_context, + const GURL& url) { + Profile* profile = Profile::FromBrowserContext(browser_context); + if (!profile) + return url; + +#if !BUILDFLAG(IS_ANDROID) + // If the input |url| should be assigned to the Instant renderer, make its + // effective URL distinct from other URLs on the search provider's domain. + // This needs to happen even if |url| corresponds to an isolated origin; see + // https://crbug.com/755595. + if (search::ShouldAssignURLToInstantRenderer(url, profile)) + return search::GetEffectiveURLForInstant(url, profile); +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile( + profile)) + return url; + + return ChromeContentBrowserClientExtensionsPart::GetEffectiveURL(profile, + url); +#else + return url; +#endif +} + +bool ChromeContentBrowserClient:: + ShouldCompareEffectiveURLsForSiteInstanceSelection( + content::BrowserContext* browser_context, + content::SiteInstance* candidate_site_instance, + bool is_outermost_main_frame, + const GURL& candidate_url, + const GURL& destination_url) { + DCHECK(browser_context); + DCHECK(candidate_site_instance); +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile( + browser_context)) { + return true; + } + + return ChromeContentBrowserClientExtensionsPart:: + ShouldCompareEffectiveURLsForSiteInstanceSelection( + browser_context, candidate_site_instance, is_outermost_main_frame, + candidate_url, destination_url); +#else + return true; +#endif +} + +bool ChromeContentBrowserClient::ShouldUseProcessPerSite( + content::BrowserContext* browser_context, + const GURL& site_url) { + Profile* profile = Profile::FromBrowserContext(browser_context); + if (!profile) + return false; + + // NTP should use process-per-site. This is a performance optimization to + // reduce process count associated with NTP tabs. + if (site_url == GURL(chrome::kChromeUINewTabURL) || + site_url == GURL(chrome::kChromeUINewTabPageURL)) { + return true; + } + +#if !BUILDFLAG(IS_ANDROID) + if (search::ShouldUseProcessPerSiteForInstantSiteURL(site_url, profile)) + return true; +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (ChromeContentBrowserClientExtensionsPart::ShouldUseProcessPerSite( + profile, site_url)) + return true; +#endif + + // Non-extension, non-NTP URLs should generally use process-per-site-instance + // (rather than process-per-site). + return false; +} + +bool ChromeContentBrowserClient::ShouldAllowProcessPerSiteForMultipleMainFrames( + content::BrowserContext* browser_context) { + static bool is_devtools_user = DetermineIfDevtoolsUserForProcessPerSite(); + + // TODO(dtapuska): Implement enterprise policy support here. + if (is_devtools_user && base::FeatureList::IsEnabled( + features::kProcessPerSiteSkipDevtoolsUsers)) { + return false; + } + return true; +} + +std::optional< + content::ContentBrowserClient::SpareProcessRefusedByEmbedderReason> +ChromeContentBrowserClient::ShouldUseSpareRenderProcessHost( + content::BrowserContext* browser_context, + const GURL& site_url) { + Profile* profile = Profile::FromBrowserContext(browser_context); + if (!profile) { + return SpareProcessRefusedByEmbedderReason::NoProfile; + } + + // Returning false here will ensure existing Top Chrome WebUI renderers are + // considered for process reuse over the spare renderer. + if (IsTopChromeWebUIURL(site_url) && + !ShouldUseSpareRenderProcessHostForTopChromePage(profile)) { + return SpareProcessRefusedByEmbedderReason::TopFrameChromeWebUI; + } + +#if !BUILDFLAG(IS_ANDROID) + // Instant renderers should not use a spare process, because they require + // passing switches::kInstantProcess to the renderer process when it + // launches. A spare process is launched earlier, before it is known which + // navigation will use it, so it lacks this flag. + if (search::ShouldAssignURLToInstantRenderer(site_url, profile)) { + // The NTP page chrome://new-tab-page and chrome://new-tab-page-third-party + // are using WebUI and will not use instant renderer. + // The only usecase is chrome-search:// URLs. + return SpareProcessRefusedByEmbedderReason::InstantRendererForNewTabPage; + } +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (!ChromeContentBrowserClientExtensionsPart:: + ShouldUseSpareRenderProcessHost(profile, site_url)) { + return SpareProcessRefusedByEmbedderReason::ExtensionProcess; + } +#endif + return std::nullopt; +} + +bool ChromeContentBrowserClient::DoesSiteRequireDedicatedProcess( + content::BrowserContext* browser_context, + const GURL& effective_site_url) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (ChromeContentBrowserClientExtensionsPart::DoesSiteRequireDedicatedProcess( + browser_context, effective_site_url)) { + return true; + } +#endif + return false; +} + +bool ChromeContentBrowserClient:: + ShouldAllowCrossProcessSandboxedFrameForPrecursor( + content::BrowserContext* browser_context, + const GURL& precursor, + const GURL& url) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (!ChromeContentBrowserClientExtensionsPart:: + ShouldAllowCrossProcessSandboxedFrameForPrecursor(browser_context, + precursor, url)) { + return false; + } +#endif + return true; +} + +bool ChromeContentBrowserClient::DoesWebUIUrlRequireProcessLock( + const GURL& url) { + // Note: This method can be called from multiple threads. It is not safe to + // assume it runs only on the UI thread. + + // We only allow the most visited tiles on third-party NTPs to not require a + // process lock. Everything else, including the actual third-party NTP which + // embeds those tiles, should be locked. This allows most visited tiles to + // stay in their parent (i.e., third-party NTP's) process. + if (url.SchemeIs(chrome::kChromeSearchScheme) && + url.host() == chrome::kChromeSearchMostVisitedHost) { + return false; + } + + // All other WebUIs must be locked to origin. + return true; +} + +bool ChromeContentBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel( + std::string_view scheme, + bool is_embedded_origin_secure) { + // This is needed to bypass the normal SameSite rules for any chrome:// page + // embedding a secure origin, regardless of the registrable domains of any + // intervening frames. For example, this is needed for browser UI to interact + // with SameSite cookies on accounts.google.com, which is used for displaying + // a list of available accounts on the NTP (chrome://new-tab-page), etc. + if (is_embedded_origin_secure && scheme == content::kChromeUIScheme) + return true; +#if BUILDFLAG(ENABLE_EXTENSIONS) + return scheme == extensions::kExtensionScheme; +#else + return false; +#endif +} + +bool ChromeContentBrowserClient:: + ShouldIgnoreSameSiteCookieRestrictionsWhenTopLevel( + std::string_view scheme, + bool is_embedded_origin_secure) { + return is_embedded_origin_secure && scheme == content::kChromeUIScheme; +} + +// TODO(crbug.com/40694933): This is based on SubframeTask::GetTitle() +// implementation. Find a general solution to avoid code duplication. +std::string ChromeContentBrowserClient::GetSiteDisplayNameForCdmProcess( + content::BrowserContext* browser_context, + const GURL& site_url) { + // By default, use the |site_url| spec as the display name. + std::string name = site_url.spec(); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + // If |site_url| wraps a chrome extension ID, we can display the extension + // name instead, which is more human-readable. + if (site_url.SchemeIs(extensions::kExtensionScheme)) { + const extensions::Extension* extension = + extensions::ExtensionRegistry::Get(browser_context) + ->enabled_extensions() + .GetExtensionOrAppByURL(site_url); + if (extension) + name = extension->name(); + } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + + return name; +} + +void ChromeContentBrowserClient::OverrideURLLoaderFactoryParams( + content::BrowserContext* browser_context, + const url::Origin& origin, + bool is_for_isolated_world, + network::mojom::URLLoaderFactoryParams* factory_params) { +#if BUILDFLAG(IS_ANDROID) + // Loading state text isn't used on Android, only in desktop UI. + factory_params->provide_loading_state_updates = false; +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile( + browser_context)) { + return; + } + + ChromeContentBrowserClientExtensionsPart::OverrideURLLoaderFactoryParams( + browser_context, origin, is_for_isolated_world, factory_params); +#endif +} + +// These are treated as WebUI schemes but do not get WebUI bindings. Also, +// view-source is allowed for these schemes. +void ChromeContentBrowserClient::GetAdditionalWebUISchemes( + std::vector* additional_schemes) { + additional_schemes->emplace_back(chrome::kChromeSearchScheme); + additional_schemes->emplace_back(dom_distiller::kDomDistillerScheme); + additional_schemes->emplace_back(content::kChromeDevToolsScheme); +} + +void ChromeContentBrowserClient::GetAdditionalViewSourceSchemes( + std::vector* additional_schemes) { + GetAdditionalWebUISchemes(additional_schemes); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + additional_schemes->push_back(extensions::kExtensionScheme); +#endif +} + +network::mojom::IPAddressSpace +ChromeContentBrowserClient::DetermineAddressSpaceFromURL(const GURL& url) { + if (url.SchemeIs(chrome::kChromeSearchScheme)) + return network::mojom::IPAddressSpace::kLocal; + if (url.SchemeIs(dom_distiller::kDomDistillerScheme)) + return network::mojom::IPAddressSpace::kPublic; +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (url.SchemeIs(extensions::kExtensionScheme)) + return network::mojom::IPAddressSpace::kLocal; +#endif + + return network::mojom::IPAddressSpace::kUnknown; +} + +bool ChromeContentBrowserClient::LogWebUIUrl(const GURL& web_ui_url) { + return webui::LogWebUIUrl(web_ui_url); +} + +bool ChromeContentBrowserClient::IsWebUIAllowedToMakeNetworkRequests( + const url::Origin& origin) { + return ChromeWebUIControllerFactory::IsWebUIAllowedToMakeNetworkRequests( + origin); +} + +bool ChromeContentBrowserClient::IsHandledURL(const GURL& url) { + return ProfileIOData::IsHandledURL(url); +} + +bool ChromeContentBrowserClient::HasCustomSchemeHandler( + content::BrowserContext* browser_context, + const std::string& scheme) { + if (custom_handlers::ProtocolHandlerRegistry* protocol_handler_registry = + ProtocolHandlerRegistryFactory::GetForBrowserContext( + browser_context)) { + return protocol_handler_registry->IsHandledProtocol(scheme); + } + + return false; +} + +bool ChromeContentBrowserClient::CanCommitURL( + content::RenderProcessHost* process_host, + const GURL& url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientExtensionsPart::CanCommitURL(process_host, + url); +#else + return true; +#endif +} + +void ChromeContentBrowserClient::OverrideNavigationParams( + std::optional source_process_site_url, + ui::PageTransition* transition, + bool* is_renderer_initiated, + content::Referrer* referrer, + std::optional* initiator_origin) { + DCHECK(transition); + DCHECK(is_renderer_initiated); + DCHECK(referrer); + // IsNTPURL only looks at the origin of the parameter, so it is safe to use + // the effective site URL for the source process. + if (source_process_site_url && + search::IsNTPURL(source_process_site_url.value()) && + ui::PageTransitionCoreTypeIs(*transition, ui::PAGE_TRANSITION_LINK)) { + // Clicks on tiles of the new tab page should be treated as if a user + // clicked on a bookmark. This is consistent with native implementations + // like Android's. This also helps ensure that security features (like + // Sec-Fetch-Site and SameSite-cookies) will treat the navigation as + // browser-initiated. + *transition = ui::PAGE_TRANSITION_AUTO_BOOKMARK; + *is_renderer_initiated = false; + *referrer = content::Referrer(); + *initiator_origin = std::nullopt; + } +} + +bool ChromeContentBrowserClient::ShouldStayInParentProcessForNTP( + const GURL& url, + const GURL& parent_site_url) { + // Allow most visited iframes to stay in the parent process but only if that + // process is for NTP. + // + // TODO(alexmos): Consider further tightening this exception to just the + // third-party remote NTP in the parent, rather than any NTP. + // + // TODO(crbug.com/40447789): place those iframes into OOPIFs and remove this + // exception. Relaxing site isolation like this is a bad idea and should be + // avoided. + // + // TODO(crbug.com/41261582): clean up the logic for detecting NTP. + return url.SchemeIs(chrome::kChromeSearchScheme) && + url.host() == chrome::kChromeSearchMostVisitedHost && + search::IsNTPURL(parent_site_url); +} + +bool ChromeContentBrowserClient::IsSuitableHost( + content::RenderProcessHost* process_host, + const GURL& site_url) { + Profile* profile = + Profile::FromBrowserContext(process_host->GetBrowserContext()); + // This may be nullptr during tests. In that case, just assume any site can + // share any host. + if (!profile) + return true; + +#if !BUILDFLAG(IS_ANDROID) + // Instant URLs should only be in the instant process and instant process + // should only have Instant URLs. + InstantService* instant_service = + InstantServiceFactory::GetForProfile(profile); + if (instant_service) { + bool is_instant_process = + instant_service->IsInstantProcess(process_host->GetID()); + bool should_be_in_instant_process = + search::ShouldAssignURLToInstantRenderer(site_url, profile); + if (is_instant_process || should_be_in_instant_process) + return is_instant_process && should_be_in_instant_process; + } +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientExtensionsPart::IsSuitableHost( + profile, process_host, site_url); +#else + return true; +#endif +} + +bool ChromeContentBrowserClient::MayReuseHost( + content::RenderProcessHost* process_host) { + // If there is currently a no-state prefetcher in progress for the host + // provided, it may not be shared. We require prefetchers to be by themselves + // in a separate process so that we can monitor their resource usage. + prerender::NoStatePrefetchManager* no_state_prefetch_manager = + prerender::NoStatePrefetchManagerFactory::GetForBrowserContext( + process_host->GetBrowserContext()); + if (no_state_prefetch_manager && + !no_state_prefetch_manager->MayReuseProcessHost(process_host)) { + return false; + } + + return true; +} + +size_t ChromeContentBrowserClient::GetProcessCountToIgnoreForLimit() { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientExtensionsPart:: + GetProcessCountToIgnoreForLimit(); +#else + return 0; +#endif +} + +std::optional +ChromeContentBrowserClient::GetPermissionsPolicyForIsolatedWebApp( + content::WebContents* web_contents, + const url::Origin& app_origin) { +#if !BUILDFLAG(IS_ANDROID) + // Extensions are exempt from manifest policy enforcement and retain the + // default frame permissions policy. + if (app_origin.scheme() == extensions::kExtensionScheme) { + return std::nullopt; + } + + CHECK(web_contents); + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + auto& registrar = + web_app::WebAppProvider::GetForWebApps(profile)->registrar_unsafe(); + std::vector app_ids_for_origin = + registrar.FindAppsInScope(app_origin.GetURL()); + if (app_ids_for_origin.empty()) { + return blink::ParsedPermissionsPolicy(); + } + + return registrar.GetPermissionsPolicy(app_ids_for_origin[0]); +#else + NOTIMPLEMENTED(); + return blink::ParsedPermissionsPolicy(); +#endif +} + +bool ChromeContentBrowserClient::ShouldTryToUseExistingProcessHost( + content::BrowserContext* browser_context, + const GURL& url) { + // Top Chrome WebUI should try to share a RenderProcessHost with other + // existing Top Chrome WebUI. + if (IsTopChromeWebUIURL(url)) { + return true; + } + + return false; +} + +bool ChromeContentBrowserClient::ShouldEmbeddedFramesTryToReuseExistingProcess( + content::RenderFrameHost* outermost_main_frame) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientExtensionsPart:: + ShouldEmbeddedFramesTryToReuseExistingProcess(outermost_main_frame); +#else + return true; +#endif +} + +void ChromeContentBrowserClient::SiteInstanceGotProcessAndSite( + SiteInstance* site_instance) { + CHECK(site_instance->HasProcess()); + + Profile* profile = + Profile::FromBrowserContext(site_instance->GetBrowserContext()); + if (!profile) + return; + +#if !BUILDFLAG(IS_ANDROID) + // Remember the ID of the Instant process to signal the renderer process + // on startup in |AppendExtraCommandLineSwitches| below. + if (search::ShouldAssignURLToInstantRenderer(site_instance->GetSiteURL(), + profile)) { + InstantService* instant_service = + InstantServiceFactory::GetForProfile(profile); + if (instant_service) + instant_service->AddInstantProcess(site_instance->GetProcess()); + } +#endif + + for (auto& part : extra_parts_) { + part->SiteInstanceGotProcessAndSite(site_instance); + } +} + +bool ChromeContentBrowserClient::ShouldSwapBrowsingInstancesForNavigation( + SiteInstance* site_instance, + const GURL& current_effective_url, + const GURL& destination_effective_url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientExtensionsPart:: + ShouldSwapBrowsingInstancesForNavigation( + site_instance, current_effective_url, destination_effective_url); +#else + return false; +#endif +} + +bool ChromeContentBrowserClient::ShouldIsolateErrorPage(bool in_main_frame) { + // TODO(nasko): Consider supporting error page isolation in subframes if + // Site Isolation is enabled. + return in_main_frame; +} + +std::vector +ChromeContentBrowserClient::GetOriginsRequiringDedicatedProcess() { + std::vector isolated_origin_list; + + if (DoesGaiaOriginRequireDedicatedProcess()) { + isolated_origin_list.push_back(GaiaUrls::GetInstance()->gaia_origin()); + } + +#if BUILDFLAG(ENABLE_EXTENSIONS) + auto origins_from_extensions = ChromeContentBrowserClientExtensionsPart:: + GetOriginsRequiringDedicatedProcess(); + std::move(std::begin(origins_from_extensions), + std::end(origins_from_extensions), + std::back_inserter(isolated_origin_list)); +#endif + + // Include additional origins preloaded with specific browser configurations, + // if any. For example, this is used on Google Chrome for Android to preload + // a list of important sites to isolate. + auto built_in_origins = + site_isolation::GetBrowserSpecificBuiltInIsolatedOrigins(); + std::move(std::begin(built_in_origins), std::end(built_in_origins), + std::back_inserter(isolated_origin_list)); + + return isolated_origin_list; +} + +bool ChromeContentBrowserClient::ShouldEnableStrictSiteIsolation() { + return base::FeatureList::IsEnabled(features::kSitePerProcess); +} + +bool ChromeContentBrowserClient::ShouldDisableSiteIsolation( + content::SiteIsolationMode site_isolation_mode) { + return site_isolation::SiteIsolationPolicy:: + ShouldDisableSiteIsolationDueToMemoryThreshold(site_isolation_mode); +} + +std::vector +ChromeContentBrowserClient::GetAdditionalSiteIsolationModes() { + std::vector modes; + if (site_isolation::SiteIsolationPolicy::IsIsolationForPasswordSitesEnabled()) + modes.push_back("Password Sites"); + if (site_isolation::SiteIsolationPolicy::IsIsolationForOAuthSitesEnabled()) + modes.push_back("Logged-in Sites"); + return modes; +} + +void ChromeContentBrowserClient::PersistIsolatedOrigin( + content::BrowserContext* context, + const url::Origin& origin, + content::ChildProcessSecurityPolicy::IsolatedOriginSource source) { + site_isolation::SiteIsolationPolicy::PersistIsolatedOrigin(context, origin, + source); +} + +bool ChromeContentBrowserClient::ShouldUrlUseApplicationIsolationLevel( + content::BrowserContext* browser_context, + const GURL& url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + + if (!content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled( + browser_context)) { + return false; + } + + // Convert |url| to an origin to resolve blob: URLs. + auto origin = url::Origin::Create(url); + if (origin.scheme() == chrome::kIsolatedAppScheme) { + return true; + } +#endif + return false; +} + +bool ChromeContentBrowserClient::IsIsolatedContextAllowedForUrl( + content::BrowserContext* browser_context, + const GURL& lock_url) { +#if BUILDFLAG(IS_CHROMEOS) + if (base::FeatureList::IsEnabled(features::kWebKioskEnableIwaApis) && + chromeos::IsWebKioskSession()) { + return true; + } +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile( + browser_context)) { + return false; + } + + // Allow restricted context APIs in Chrome Apps. + auto* extension = extensions::ExtensionRegistry::Get(browser_context) + ->enabled_extensions() + .GetExtensionOrAppByURL(lock_url); + return extension && + (extension->is_platform_app() || + IsExtensionIdAllowedToUseIsolatedContext(extension->id())); +#else + return false; +#endif +} + +void ChromeContentBrowserClient::CheckGetAllScreensMediaAllowed( + content::RenderFrameHost* render_frame_host, + base::OnceCallback callback) { + capture_policy::CheckGetAllScreensMediaAllowed( + render_frame_host->GetBrowserContext(), + render_frame_host->GetMainFrame()->GetLastCommittedOrigin().GetURL(), + std::move(callback)); +} + +bool ChromeContentBrowserClient::IsFileAccessAllowed( + const base::FilePath& path, + const base::FilePath& absolute_path, + const base::FilePath& profile_path) { + return ChromeNetworkDelegate::IsAccessAllowed(path, absolute_path, + profile_path); +} + +namespace { + +void MaybeAppendBlinkSettingsSwitchForFieldTrial( + const base::CommandLine& browser_command_line, + base::CommandLine* command_line) { + // List of field trials that modify the blink-settings command line flag. No + // two field trials in the list should specify the same keys, otherwise one + // field trial may overwrite another. See Source/core/frame/Settings.in in + // Blink for the list of valid keys. + static const char* const kBlinkSettingsFieldTrials[] = { + // Keys: disallowFetchForDocWrittenScriptsInMainFrame + // disallowFetchForDocWrittenScriptsInMainFrameOnSlowConnections + // disallowFetchForDocWrittenScriptsInMainFrameIfEffectively2G + "DisallowFetchForDocWrittenScriptsInMainFrame", + }; + + std::vector blink_settings; + for (const char* field_trial_name : kBlinkSettingsFieldTrials) { + // Each blink-settings field trial should include a forcing_flag group, + // to make sure that clients that specify the blink-settings flag on the + // command line are excluded from the experiment groups. To make + // sure we assign clients that specify this flag to the forcing_flag + // group, we must call GetFieldTrialParams for each field trial first + // (for example, before checking HasSwitch() and returning), since + // GetFieldTrialParams has the side-effect of assigning the client to + // a field trial group. + std::map params; + if (base::GetFieldTrialParams(field_trial_name, ¶ms)) { + for (const auto& param : params) { + blink_settings.push_back(base::StringPrintf( + "%s=%s", param.first.c_str(), param.second.c_str())); + } + } + } + + if (blink_settings.empty()) { + return; + } + + if (browser_command_line.HasSwitch(blink::switches::kBlinkSettings) || + command_line->HasSwitch(blink::switches::kBlinkSettings)) { + // The field trials should be configured to force users that specify the + // blink-settings flag into a group with no params, and we return + // above if no params were specified, so it's an error if we reach + // this point. + LOG(WARNING) << "Received field trial params, " + "but blink-settings switch already specified."; + return; + } + + command_line->AppendSwitchASCII(blink::switches::kBlinkSettings, + base::JoinString(blink_settings, ",")); +} + +} // namespace + +void ChromeContentBrowserClient::AppendExtraCommandLineSwitches( + base::CommandLine* command_line, + int child_process_id) { +#if BUILDFLAG(IS_MAC) + std::unique_ptr client_info = + GoogleUpdateSettings::LoadMetricsClientInfo(); + if (client_info) { + command_line->AppendSwitchASCII(switches::kMetricsClientID, + client_info->client_id); + } +#elif BUILDFLAG(IS_POSIX) +#if !BUILDFLAG(IS_ANDROID) + pid_t pid; + if (crash_reporter::GetHandlerSocket(nullptr, &pid)) { + command_line->AppendSwitchASCII( + crash_reporter::switches::kCrashpadHandlerPid, + base::NumberToString(pid)); + } +#endif + std::string switch_value; + std::unique_ptr client_info = + GoogleUpdateSettings::LoadMetricsClientInfo(); + if (client_info) { + switch_value = client_info->client_id; + } + switch_value.push_back(','); + switch_value.append(chrome::GetChannelName(chrome::WithExtendedStable(true))); + command_line->AppendSwitchASCII(switches::kEnableCrashReporter, switch_value); +#endif + + if (logging::DialogsAreSuppressed()) + command_line->AppendSwitch(switches::kNoErrorDialogs); + + std::string process_type = + command_line->GetSwitchValueASCII(switches::kProcessType); + const base::CommandLine& browser_command_line = + *base::CommandLine::ForCurrentProcess(); + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // Pass startup and post-login parameter FDs to child processes in Lacros. + if (process_type != switches::kZygoteProcess) { + constexpr int kStartupDataFD = + kCrosStartupDataDescriptor + base::GlobalDescriptors::kBaseDescriptor; + command_line->AppendSwitchASCII(chromeos::switches::kCrosStartupDataFD, + base::NumberToString(kStartupDataFD)); + + if (chromeos::IsLaunchedWithPostLoginParams()) { + constexpr int kPostLoginDataFD = kCrosPostLoginDataDescriptor + + base::GlobalDescriptors::kBaseDescriptor; + command_line->AppendSwitchASCII(chromeos::switches::kCrosPostLoginDataFD, + base::NumberToString(kPostLoginDataFD)); + } + } +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + + static const char* const kCommonSwitchNames[] = { + embedder_support::kUserAgent, + switches::kUserDataDir, // Make logs go to the right file. + }; + command_line->CopySwitchesFrom(browser_command_line, kCommonSwitchNames); + + static const char* const kDinosaurEasterEggSwitches[] = { + error_page::switches::kDisableDinosaurEasterEgg, + error_page::switches::kEnableDinosaurEasterEggAltGameImages, + }; + command_line->CopySwitchesFrom(browser_command_line, + kDinosaurEasterEggSwitches); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // On Chrome OS need to pass primary user homedir (in multi-profiles session). + base::FilePath homedir; + base::PathService::Get(base::DIR_HOME, &homedir); + command_line->AppendSwitchASCII(ash::switches::kHomedir, homedir.value()); +#endif + + if (process_type == switches::kRendererProcess) { + content::RenderProcessHost* process = + content::RenderProcessHost::FromID(child_process_id); + if (process) { + for (auto& part : extra_parts_) { + part->AppendExtraRendererCommandLineSwitches(command_line, *process); + } + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + const std::string& login_profile = + browser_command_line.GetSwitchValueASCII(ash::switches::kLoginProfile); + if (!login_profile.empty()) { + command_line->AppendSwitchASCII(ash::switches::kLoginProfile, + login_profile); + } +#endif + + MaybeCopyDisableWebRtcEncryptionSwitch(command_line, browser_command_line, + chrome::GetChannel()); + if (process) { + Profile* profile = + Profile::FromBrowserContext(process->GetBrowserContext()); + PrefService* prefs = profile->GetPrefs(); + // Currently this pref is only registered if applied via a policy. + if (prefs->HasPrefPath(prefs::kDisable3DAPIs) && + prefs->GetBoolean(prefs::kDisable3DAPIs)) { + // Turn this policy into a command line switch. + command_line->AppendSwitch(switches::kDisable3DAPIs); + } + + if (prefs->GetBoolean(prefs::kPrintPreviewDisabled)) + command_line->AppendSwitch(switches::kDisablePrintPreview); + + if (prefs->GetBoolean(prefs::kDataUrlInSvgUseEnabled)) { + command_line->AppendSwitch(blink::switches::kDataUrlInSvgUseEnabled); + } + + if (prefs->GetBoolean(policy::policy_prefs::kMutationEventsEnabled)) { + command_line->AppendSwitch(blink::switches::kMutationEventsEnabled); + } + + if (!prefs->GetBoolean( + policy::policy_prefs::kKeyboardFocusableScrollersEnabled)) { + command_line->AppendSwitch( + blink::switches::kKeyboardFocusableScrollersOptOut); + } + if (!prefs->GetBoolean( + policy::policy_prefs::kStandardizedBrowserZoomEnabled)) { + command_line->AppendSwitch( + blink::switches::kDisableStandardizedBrowserZoom); + } + if (prefs->GetBoolean( + policy::policy_prefs::kCSSCustomStateDeprecatedSyntaxEnabled)) { + command_line->AppendSwitch( + blink::switches::kCSSCustomStateDeprecatedSyntaxEnabled); + } + + if (prefs->GetBoolean(policy::policy_prefs:: + kForcePermissionPolicyUnloadDefaultEnabled)) { + command_line->AppendSwitch( + blink::switches::kForcePermissionPolicyUnloadDefaultEnabled); + } + +#if !BUILDFLAG(IS_ANDROID) + InstantService* instant_service = + InstantServiceFactory::GetForProfile(profile); + if (instant_service && + instant_service->IsInstantProcess(process->GetID())) { + command_line->AppendSwitch(switches::kInstantProcess); + } + + // Enable SharedArrayBuffer on desktop if allowed by Enterprise Policy. + // TODO(crbug.com/40155376) Remove when migration to COOP+COEP is + // complete. + if (prefs->GetBoolean( + prefs::kSharedArrayBufferUnrestrictedAccessAllowed)) { + command_line->AppendSwitch( + switches::kSharedArrayBufferUnrestrictedAccessAllowed); + } +#endif + if (!prefs->GetBoolean(prefs::kSandboxExternalProtocolBlocked)) + command_line->AppendSwitch(kDisableSandboxExternalProtocolSwitch); + + if (prefs->HasPrefPath(prefs::kAllowDinosaurEasterEgg) && + !prefs->GetBoolean(prefs::kAllowDinosaurEasterEgg)) { + command_line->AppendSwitch( + error_page::switches::kDisableDinosaurEasterEgg); + } + + auto* management_service_factory = + policy::ManagementServiceFactory::GetInstance(); + auto* browser_managment_service = + management_service_factory->GetForProfile(profile); + if ((browser_managment_service && + browser_managment_service->IsManaged()) || + management_service_factory->GetForPlatform()->IsManaged()) { + command_line->AppendSwitch( + error_page::switches::kEnableDinosaurEasterEggAltGameImages); + } + + MaybeAppendSecureOriginsAllowlistSwitch(command_line); + + if (prefs->HasPrefPath(prefs::kScrollToTextFragmentEnabled) && + !prefs->GetBoolean(prefs::kScrollToTextFragmentEnabled)) { + command_line->AppendSwitch(switches::kDisableScrollToTextFragment); + } + + if (!prefs->GetList(enterprise_reporting::kCloudLegacyTechReportAllowlist) + .empty()) { + command_line->AppendSwitch( + blink::switches::kLegacyTechReportPolicyEnabled); + } + + // The IntensiveWakeUpThrottling feature is typically managed via a + // base::Feature, but it has a managed policy override. The override is + // communicated to blink via a custom command-line flag. See + // PageSchedulerImpl for the other half of related logic. + PrefService* local_state = g_browser_process->local_state(); + const PrefService::Preference* pref = local_state->FindPreference( + policy::policy_prefs::kIntensiveWakeUpThrottlingEnabled); + if (pref && pref->IsManaged()) { + command_line->AppendSwitchASCII( + blink::switches::kIntensiveWakeUpThrottlingPolicy, + pref->GetValue()->GetBool() + ? blink::switches::kIntensiveWakeUpThrottlingPolicy_ForceEnable + : blink::switches:: + kIntensiveWakeUpThrottlingPolicy_ForceDisable); + } + +#if BUILDFLAG(IS_ANDROID) + // Communicating to content/ for BackForwardCache. + if (prefs->HasPrefPath(policy::policy_prefs::kBackForwardCacheEnabled) && + !prefs->GetBoolean(policy::policy_prefs::kBackForwardCacheEnabled)) { + command_line->AppendSwitch(switches::kDisableBackForwardCache); + } +#endif // BUILDFLAG(IS_ANDROID) + +#if !BUILDFLAG(IS_ANDROID) + // Make the WebAuthenticationRemoteProxiedRequestsAllowed policy enable + // the experimental WebAuthenticationRemoteDesktopSupport Blink runtime + // feature. + if (prefs->GetBoolean( + webauthn::pref_names::kRemoteProxiedRequestsAllowed)) { + command_line->AppendSwitch(switches::kWebAuthRemoteDesktopSupport); + } + + if (IsCartModuleEnabled()) { + command_line->AppendSwitch(commerce::switches::kEnableChromeCart); + } +#endif + } + + MaybeAppendBlinkSettingsSwitchForFieldTrial(browser_command_line, + command_line); + +#if BUILDFLAG(IS_ANDROID) + // If the platform is Android, force the distillability service on. + command_line->AppendSwitch(switches::kEnableDistillabilityService); +#endif + +#if BUILDFLAG(ENABLE_NACL) + AppendDisableNaclSwitchIfNecessary(command_line); +#endif + + // Please keep this in alphabetical order. + static const char* const kSwitchNames[] = { + autofill::switches::kIgnoreAutocompleteOffForAutofill, + autofill::switches::kShowAutofillSignatures, +#if BUILDFLAG(IS_CHROMEOS_ASH) + switches::kShortMergeSessionTimeoutForTest, // For tests only. +#endif +#if BUILDFLAG(ENABLE_EXTENSIONS) + extensions::switches::kAllowHTTPBackgroundPage, + extensions::switches::kAllowLegacyExtensionManifests, + extensions::switches::kDisableExtensionsHttpThrottling, + extensions::switches::kEnableExperimentalExtensionApis, + extensions::switches::kExtensionsOnChromeURLs, + extensions::switches::kSetExtensionThrottleTestParams, // For tests only. + extensions::switches::kAllowlistedExtensionID, + extensions::switches::kExtensionTestApiOnWebPages, // For tests only. +#endif + switches::kAllowInsecureLocalhost, + switches::kAppsGalleryURL, + switches::kDisableJavaScriptHarmonyShipping, + variations::switches::kEnableBenchmarking, + switches::kEnableDistillabilityService, + switches::kEnableNaCl, +#if BUILDFLAG(ENABLE_NACL) + switches::kEnableNaClDebug, +#endif + switches::kEnableNetBenchmarking, +#if BUILDFLAG(IS_CHROMEOS) + chromeos::switches:: + kTelemetryExtensionPwaOriginOverrideForTesting, // For tests only. + switches::kForceAppMode, +#endif +#if BUILDFLAG(ENABLE_NACL) + switches::kForcePNaClSubzero, +#endif + switches::kForceUIDirection, + switches::kIgnoreGooglePortNumbers, + switches::kJavaScriptHarmony, + switches::kEnableExperimentalWebAssemblyFeatures, + embedder_support::kOriginTrialDisabledFeatures, + embedder_support::kOriginTrialPublicKey, + switches::kReaderModeHeuristics, + translate::switches::kTranslateSecurityOrigin, + }; + + command_line->CopySwitchesFrom(browser_command_line, kSwitchNames); + } else if (process_type == switches::kUtilityProcess) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + static const char* const kSwitchNames[] = { + extensions::switches::kAllowHTTPBackgroundPage, + extensions::switches::kEnableExperimentalExtensionApis, + extensions::switches::kExtensionsOnChromeURLs, + extensions::switches::kAllowlistedExtensionID, + }; + + command_line->CopySwitchesFrom(browser_command_line, kSwitchNames); +#endif + MaybeAppendSecureOriginsAllowlistSwitch(command_line); + } else if (process_type == switches::kZygoteProcess) { + // It would be preferable to call AppendDisableNaclSwitchIfNecessary to + // disable NaCl for the zygote process. Unfortunately that method depends on + // state (including policy) that is determined after the zygote is forked. + // Instead we rely on renderers overriding the zygote state. + + // Load (in-process) Pepper plugins in-process in the zygote pre-sandbox. +#if BUILDFLAG(ENABLE_NACL) + static const char* const kSwitchNames[] = { + switches::kEnableNaClDebug, + switches::kForcePNaClSubzero, + switches::kVerboseLoggingInNacl, + }; + + command_line->CopySwitchesFrom(browser_command_line, kSwitchNames); +#endif +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // Ensure zygote loads the resource bundle for the right locale. + static const char* const kMoreSwitchNames[] = {switches::kLang}; + command_line->CopySwitchesFrom(browser_command_line, kMoreSwitchNames); +#endif +#if BUILDFLAG(IS_CHROMEOS) + // This is called before feature flags are parsed, so pass them in their raw + // form. + static const char* const kMoreCrOSSwitchNames[] = { + chromeos::switches::kFeatureFlags}; + command_line->CopySwitchesFrom(browser_command_line, kMoreCrOSSwitchNames); +#endif + } else if (process_type == switches::kGpuProcess) { + // If --ignore-gpu-blocklist is passed in, don't send in crash reports + // because GPU is expected to be unreliable. + if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlocklist) && + !command_line->HasSwitch(switches::kDisableBreakpad)) + command_line->AppendSwitch(switches::kDisableBreakpad); + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (ChromeCrashReporterClient::ShouldPassCrashLoopBefore(process_type)) { + static const char* const kSwitchNames[] = { + crash_reporter::switches::kCrashLoopBefore, + }; + command_line->CopySwitchesFrom(browser_command_line, kSwitchNames); + } +#endif + +#if BUILDFLAG(IS_WIN) + if (base::FeatureList::IsEnabled(features::kNoPreReadMainDll)) { + command_line->AppendSwitch(switches::kNoPreReadMainDll); + } +#endif + + ThreadProfilerConfiguration::Get()->AppendCommandLineSwitchForChildProcess( + command_line); + + if (process_type != switches::kZygoteProcess) { + // The switch value depends on the "HeapProfilerCentralControl" feature, and + // the zygote starts before the FeatureList is available. + if (const auto* heap_profiler_controller = + heap_profiling::HeapProfilerController::GetInstance()) { + heap_profiler_controller->AppendCommandLineSwitchForChildProcess( + command_line, GetProfileParamsProcess(*command_line), + child_process_id); + } + } + +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_ASH) + // Opt into a hardened stack canary mitigation if it hasn't already been + // force-disabled. + if (!browser_command_line.HasSwitch(switches::kChangeStackGuardOnFork)) { + command_line->AppendSwitchASCII(switches::kChangeStackGuardOnFork, + switches::kChangeStackGuardOnForkEnabled); + } +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(IS_ANDROID) + // Communicating to renderer for starting the reader for web feed. + if (feed::IsWebFeedEnabledForLocale(feed::FeedServiceFactory::GetCountry())) { + command_line->AppendSwitch(feed::switches::kEnableRssLinkReader); + } +#endif +} + +std::string +ChromeContentBrowserClient::GetApplicationClientGUIDForQuarantineCheck() { + return std::string(chrome::kApplicationClientIDStringForAVScanning); +} + +download::QuarantineConnectionCallback +ChromeContentBrowserClient::GetQuarantineConnectionCallback() { + return base::BindRepeating( + &ChromeDownloadManagerDelegate::ConnectToQuarantineService); +} + +std::string ChromeContentBrowserClient::GetApplicationLocale() { + if (BrowserThread::CurrentlyOn(BrowserThread::IO)) + return GetIOThreadApplicationLocale(); + return g_browser_process->GetApplicationLocale(); +} + +std::string ChromeContentBrowserClient::GetAcceptLangs( + content::BrowserContext* context) { + Profile* profile = Profile::FromBrowserContext(context); + return profile->GetPrefs()->GetString(language::prefs::kAcceptLanguages); +} + +gfx::ImageSkia ChromeContentBrowserClient::GetDefaultFavicon() { + return favicon::GetDefaultFavicon().AsImageSkia(); +} + +bool ChromeContentBrowserClient::IsDataSaverEnabled( + content::BrowserContext* browser_context) { + if (!browser_context || browser_context->IsOffTheRecord()) + return false; + + return data_saver::IsDataSaverEnabled(); +} + +void ChromeContentBrowserClient::UpdateRendererPreferencesForWorker( + content::BrowserContext* browser_context, + blink::RendererPreferences* out_prefs) { + DCHECK(browser_context); + DCHECK(out_prefs); + renderer_preferences_util::UpdateFromSystemSettings( + out_prefs, Profile::FromBrowserContext(browser_context)); +} + +content::AllowServiceWorkerResult +ChromeContentBrowserClient::AllowServiceWorker( + const GURL& scope, + const net::SiteForCookies& site_for_cookies, + const std::optional& top_frame_origin, + const GURL& script_url, + content::BrowserContext* context) { + DCHECK(context); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + GURL first_party_url = top_frame_origin ? top_frame_origin->GetURL() : GURL(); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + // Check if this is an extension-related service worker, and, if so, if it's + // allowed (this can return false if, e.g., the extension is disabled). + // If it's not allowed, return immediately. We deliberately do *not* report + // to the PageSpecificContentSettings, since the service worker is blocked + // because of the extension, rather than because of the user's content + // settings. + if (!ChromeContentBrowserClientExtensionsPart::AllowServiceWorker( + scope, first_party_url, script_url, context)) { + return content::AllowServiceWorkerResult::No(); + } +#endif + + Profile* profile = Profile::FromBrowserContext(context); + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile(profile); + return embedder_support::AllowServiceWorker( + scope, site_for_cookies, top_frame_origin, cookie_settings.get(), + HostContentSettingsMapFactory::GetForProfile(profile)); +} + +bool ChromeContentBrowserClient::MayDeleteServiceWorkerRegistration( + const GURL& scope, + content::BrowserContext* browser_context) { + DCHECK(browser_context); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (!ChromeContentBrowserClientExtensionsPart:: + MayDeleteServiceWorkerRegistration(scope, browser_context)) { + return false; + } +#endif + + return true; +} + +bool ChromeContentBrowserClient::ShouldTryToUpdateServiceWorkerRegistration( + const GURL& scope, + content::BrowserContext* browser_context) { + DCHECK(browser_context); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (!ChromeContentBrowserClientExtensionsPart:: + ShouldTryToUpdateServiceWorkerRegistration(scope, browser_context)) { + return false; + } +#endif + + return true; +} + +bool ChromeContentBrowserClient::AllowSharedWorker( + const GURL& worker_url, + const net::SiteForCookies& site_for_cookies, + const std::optional& top_frame_origin, + const std::string& name, + const blink::StorageKey& storage_key, + const blink::mojom::SharedWorkerSameSiteCookies same_site_cookies, + content::BrowserContext* context, + int render_process_id, + int render_frame_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + // Check if cookies are allowed. + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile( + Profile::FromBrowserContext(context)); + return embedder_support::AllowSharedWorker( + worker_url, site_for_cookies, top_frame_origin, name, storage_key, + same_site_cookies, render_process_id, render_frame_id, + cookie_settings.get()); +} + +bool ChromeContentBrowserClient::DoesSchemeAllowCrossOriginSharedWorker( + const std::string& scheme) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + // Extensions are allowed to start cross-origin shared workers. + if (scheme == extensions::kExtensionScheme) + return true; +#endif + + return false; +} + +bool ChromeContentBrowserClient::AllowSignedExchange( + content::BrowserContext* browser_context) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + Profile* profile = Profile::FromBrowserContext(browser_context); + return profile->GetPrefs()->GetBoolean(prefs::kSignedHTTPExchangeEnabled); +} + +bool ChromeContentBrowserClient::AllowCompressionDictionaryTransport( + content::BrowserContext* browser_context) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + Profile* profile = Profile::FromBrowserContext(browser_context); + return profile->GetPrefs()->GetBoolean( + prefs::kCompressionDictionaryTransportEnabled); +} + +void ChromeContentBrowserClient::RequestFilesAccess( + const std::vector& files, + const GURL& destination_url, + base::OnceCallback + continuation_callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +#if BUILDFLAG(IS_CHROMEOS) + auto* delegate = policy::DlpScopedFileAccessDelegate::Get(); + if (delegate) { + delegate->RequestFilesAccess(files, destination_url, + std::move(continuation_callback)); + } else { + std::move(continuation_callback) + .Run(file_access::ScopedFileAccess::Allowed()); + } +#else + std::move(continuation_callback) + .Run(file_access::ScopedFileAccess::Allowed()); +#endif +} + +void ChromeContentBrowserClient::AllowWorkerFileSystem( + const GURL& url, + content::BrowserContext* browser_context, + const std::vector& render_frames, + base::OnceCallback callback) { + // An empty list is passed for render_frames here since we manually notify + // PageSpecificContentSettings that the file system was accessed below. + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + bool allow = + embedder_support::AllowWorkerFileSystem(url, {}, cookie_settings.get()); +#if BUILDFLAG(ENABLE_EXTENSIONS) + GuestPermissionRequestHelper(url, render_frames, std::move(callback), allow); +#else + FileSystemAccessed(url, render_frames, std::move(callback), allow); +#endif +} + +#if BUILDFLAG(ENABLE_EXTENSIONS) +void ChromeContentBrowserClient::GuestPermissionRequestHelper( + const GURL& url, + const std::vector& render_frames, + base::OnceCallback callback, + bool allow) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + std::map process_map; + bool has_web_view_guest = false; + // Record access to file system for potential display in UI. + for (const auto& it : render_frames) { + if (process_map.find(it.child_id) != process_map.end()) + continue; + + process_map.insert(std::pair(it.child_id, it.frame_routing_id)); + + if (extensions::WebViewRendererState::GetInstance()->IsGuest(it.child_id)) + has_web_view_guest = true; + } + if (!has_web_view_guest) { + FileSystemAccessed(url, render_frames, std::move(callback), allow); + return; + } + DCHECK_EQ(1U, process_map.size()); + std::map::const_iterator it = process_map.begin(); + + extensions::WebViewPermissionHelper* web_view_permission_helper = + extensions::WebViewPermissionHelper::FromRenderFrameHostId( + content::GlobalRenderFrameHostId(it->first, it->second)); + web_view_permission_helper->RequestFileSystemPermission( + url, allow, + base::BindOnce(&ChromeContentBrowserClient::FileSystemAccessed, + weak_factory_.GetWeakPtr(), url, render_frames, + std::move(callback))); +} +#endif + +void ChromeContentBrowserClient::FileSystemAccessed( + const GURL& url, + const std::vector& render_frames, + base::OnceCallback callback, + bool allow) { + // Record access to file system for potential display in UI. + for (const auto& it : render_frames) { + auto* rfh = content::RenderFrameHost::FromID(it); + if (!rfh) { + continue; + } + content_settings::PageSpecificContentSettings::StorageAccessed( + content_settings::mojom::ContentSettingsManager::StorageType:: + FILE_SYSTEM, + it, rfh->GetStorageKey(), !allow); + } + std::move(callback).Run(allow); +} + +bool ChromeContentBrowserClient::AllowWorkerIndexedDB( + const GURL& url, + content::BrowserContext* browser_context, + const std::vector& render_frames) { + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + return embedder_support::AllowWorkerIndexedDB(url, render_frames, + cookie_settings.get()); +} + +bool ChromeContentBrowserClient::AllowWorkerCacheStorage( + const GURL& url, + content::BrowserContext* browser_context, + const std::vector& render_frames) { + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + return embedder_support::AllowWorkerCacheStorage(url, render_frames, + cookie_settings.get()); +} + +bool ChromeContentBrowserClient::AllowWorkerWebLocks( + const GURL& url, + content::BrowserContext* browser_context, + const std::vector& render_frames) { + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + return embedder_support::AllowWorkerWebLocks(url, cookie_settings.get()); +} + +ChromeContentBrowserClient::AllowWebBluetoothResult +ChromeContentBrowserClient::AllowWebBluetooth( + content::BrowserContext* browser_context, + const url::Origin& requesting_origin, + const url::Origin& embedding_origin) { + // TODO(crbug.com/40462828): Don't disable if + // base::CommandLine::ForCurrentProcess()-> + // HasSwitch(switches::kEnableWebBluetooth) is true. + if (base::GetFieldTrialParamValue( + permissions::PermissionContextBase::kPermissionsKillSwitchFieldStudy, + "Bluetooth") == + permissions::PermissionContextBase::kPermissionsKillSwitchBlockedValue) { + // The kill switch is enabled for this permission. Block requests. + return AllowWebBluetoothResult::BLOCK_GLOBALLY_DISABLED; + } + + const HostContentSettingsMap* const content_settings = + HostContentSettingsMapFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + + if (content_settings->GetContentSetting( + requesting_origin.GetURL(), embedding_origin.GetURL(), + ContentSettingsType::BLUETOOTH_GUARD) == CONTENT_SETTING_BLOCK) { + return AllowWebBluetoothResult::BLOCK_POLICY; + } + return AllowWebBluetoothResult::ALLOW; +} + +std::string ChromeContentBrowserClient::GetWebBluetoothBlocklist() { + return base::GetFieldTrialParamValue("WebBluetoothBlocklist", + "blocklist_additions"); +} + +bool ChromeContentBrowserClient::IsInterestGroupAPIAllowed( + content::RenderFrameHost* render_frame_host, + InterestGroupApiOperation operation, + const url::Origin& top_frame_origin, + const url::Origin& api_origin) { + Profile* profile = + Profile::FromBrowserContext(render_frame_host->GetBrowserContext()); + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + DCHECK(privacy_sandbox_settings); + + bool allowed = privacy_sandbox_settings->IsFledgeAllowed( + top_frame_origin, api_origin, operation, render_frame_host); + + if (operation == InterestGroupApiOperation::kJoin) { + content_settings::PageSpecificContentSettings::InterestGroupJoined( + render_frame_host, api_origin, !allowed); + content_settings::PageSpecificContentSettings::BrowsingDataAccessed( + render_frame_host, + content::InterestGroupManager::InterestGroupDataKey{api_origin, + top_frame_origin}, + BrowsingDataModel::StorageType::kInterestGroup, !allowed); + } + + return allowed; +} + +bool ChromeContentBrowserClient::IsPrivacySandboxReportingDestinationAttested( + content::BrowserContext* browser_context, + const url::Origin& destination_origin, + content::PrivacySandboxInvokingAPI invoking_api, + bool post_impression_reporting) { + Profile* profile = Profile::FromBrowserContext(browser_context); + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + DCHECK(privacy_sandbox_settings); + + if (invoking_api == content::PrivacySandboxInvokingAPI::kProtectedAudience) { + if (base::FeatureList::IsEnabled( + blink::features::kFencedFramesReportingAttestationsChanges) && + post_impression_reporting) { + // M120 and afterwards: For beacons sent by `reportEvent()` and automatic + // beacons, the destination is required to be attested for either + // Protected Audience or Attribution Reporting. + return privacy_sandbox_settings->IsEventReportingDestinationAttested( + destination_origin, + privacy_sandbox::PrivacySandboxAttestationsGatedAPI:: + kProtectedAudience) || + privacy_sandbox_settings->IsEventReportingDestinationAttested( + destination_origin, + privacy_sandbox::PrivacySandboxAttestationsGatedAPI:: + kAttributionReporting); + } else { + // Before M120: The reporting destination is required to be attested for + // its invoking API only. + // M120 and afterwards: For beacons sent by `reportResult()` and + // `reportWin()`, the destination is required to be attested for Protected + // Audience only. + return privacy_sandbox_settings->IsEventReportingDestinationAttested( + destination_origin, + privacy_sandbox::PrivacySandboxAttestationsGatedAPI:: + kProtectedAudience); + } + } else if (invoking_api == + content::PrivacySandboxInvokingAPI::kSharedStorage) { + return privacy_sandbox_settings->IsEventReportingDestinationAttested( + destination_origin, + privacy_sandbox::PrivacySandboxAttestationsGatedAPI::kSharedStorage); + } + + return false; +} + +void ChromeContentBrowserClient::OnAuctionComplete( + content::RenderFrameHost* render_frame_host, + content::InterestGroupManager::InterestGroupDataKey winner_data_key) { + content_settings::PageSpecificContentSettings::BrowsingDataAccessed( + render_frame_host, winner_data_key, + BrowsingDataModel::StorageType::kInterestGroup, + /*blocked=*/false); +} + +bool ChromeContentBrowserClient::IsAttributionReportingOperationAllowed( + content::BrowserContext* browser_context, + AttributionReportingOperation operation, + content::RenderFrameHost* rfh, + const url::Origin* source_origin, + const url::Origin* destination_origin, + const url::Origin* reporting_origin, + bool* can_bypass) { + Profile* profile = Profile::FromBrowserContext(browser_context); + + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + if (!privacy_sandbox_settings) + return false; + + switch (operation) { + case AttributionReportingOperation::kSource: + case AttributionReportingOperation::kOsSource: { + DCHECK(source_origin); + DCHECK(reporting_origin); + bool allowed = privacy_sandbox_settings->IsAttributionReportingAllowed( + *source_origin, *reporting_origin, rfh); + if (rfh) { + content_settings::PageSpecificContentSettings::BrowsingDataAccessed( + rfh, content::AttributionDataModel::DataKey(*reporting_origin), + BrowsingDataModel::StorageType::kAttributionReporting, + /*blocked=*/!allowed); + } + return allowed; + } + case AttributionReportingOperation::kSourceVerboseDebugReport: + case AttributionReportingOperation::kSourceAggregatableDebugReport: + case AttributionReportingOperation::kOsSourceVerboseDebugReport: + DCHECK(source_origin); + DCHECK(reporting_origin); + return privacy_sandbox_settings->IsAttributionReportingAllowed( + *source_origin, *reporting_origin, rfh); + case AttributionReportingOperation::kTrigger: + case AttributionReportingOperation::kOsTrigger: { + DCHECK(destination_origin); + DCHECK(reporting_origin); + bool allowed = privacy_sandbox_settings->IsAttributionReportingAllowed( + *destination_origin, *reporting_origin, rfh); + if (rfh) { + content_settings::PageSpecificContentSettings::BrowsingDataAccessed( + rfh, content::AttributionDataModel::DataKey(*reporting_origin), + BrowsingDataModel::StorageType::kAttributionReporting, + /*blocked=*/!allowed); + } + return allowed; + } + case AttributionReportingOperation::kTriggerVerboseDebugReport: + case AttributionReportingOperation::kTriggerAggregatableDebugReport: + case AttributionReportingOperation::kOsTriggerVerboseDebugReport: + DCHECK(destination_origin); + DCHECK(reporting_origin); + return privacy_sandbox_settings->IsAttributionReportingAllowed( + *destination_origin, *reporting_origin, rfh); + case AttributionReportingOperation::kReport: + DCHECK(source_origin); + DCHECK(destination_origin); + DCHECK(reporting_origin); + return privacy_sandbox_settings->MaySendAttributionReport( + *source_origin, *destination_origin, *reporting_origin, rfh); + case AttributionReportingOperation::kSourceTransitionalDebugReporting: + case AttributionReportingOperation::kOsSourceTransitionalDebugReporting: + DCHECK(source_origin); + DCHECK(reporting_origin); + DCHECK(can_bypass); + return privacy_sandbox_settings + ->IsAttributionReportingTransitionalDebuggingAllowed( + *source_origin, *reporting_origin, *can_bypass); + case AttributionReportingOperation::kTriggerTransitionalDebugReporting: + case AttributionReportingOperation::kOsTriggerTransitionalDebugReporting: + DCHECK(destination_origin); + DCHECK(reporting_origin); + DCHECK(can_bypass); + return privacy_sandbox_settings + ->IsAttributionReportingTransitionalDebuggingAllowed( + *destination_origin, *reporting_origin, *can_bypass); + case AttributionReportingOperation::kAny: + return privacy_sandbox_settings->IsAttributionReportingEverAllowed(); + } +} + +bool ChromeContentBrowserClient::IsAttributionReportingAllowedForContext( + content::BrowserContext* browser_context, + content::RenderFrameHost* rfh, + const url::Origin& context_origin, + const url::Origin& reporting_origin) { + Profile* profile = Profile::FromBrowserContext(browser_context); + + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + if (!privacy_sandbox_settings) { + return false; + } + + return privacy_sandbox_settings->IsAttributionReportingAllowed( + context_origin, reporting_origin, rfh); +} + +bool ChromeContentBrowserClient::IsSharedStorageAllowed( + content::BrowserContext* browser_context, + content::RenderFrameHost* rfh, + const url::Origin& top_frame_origin, + const url::Origin& accessing_origin, + std::string* out_debug_message, + bool* out_block_is_site_setting_specific) { + Profile* profile = Profile::FromBrowserContext(browser_context); + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + DCHECK(privacy_sandbox_settings); + bool allowed = privacy_sandbox_settings->IsSharedStorageAllowed( + top_frame_origin, accessing_origin, out_debug_message, rfh, + out_block_is_site_setting_specific); + if (rfh) { + content_settings::PageSpecificContentSettings::BrowsingDataAccessed( + rfh, blink::StorageKey::CreateFirstParty(accessing_origin), + BrowsingDataModel::StorageType::kSharedStorage, !allowed); + } + return allowed; +} + +bool ChromeContentBrowserClient::IsSharedStorageSelectURLAllowed( + content::BrowserContext* browser_context, + const url::Origin& top_frame_origin, + const url::Origin& accessing_origin, + std::string* out_debug_message, + bool* out_block_is_site_setting_specific) { + Profile* profile = Profile::FromBrowserContext(browser_context); + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + DCHECK(privacy_sandbox_settings); + return privacy_sandbox_settings->IsSharedStorageSelectURLAllowed( + top_frame_origin, accessing_origin, out_debug_message, + out_block_is_site_setting_specific); +} + +bool ChromeContentBrowserClient::IsPrivateAggregationAllowed( + content::BrowserContext* browser_context, + const url::Origin& top_frame_origin, + const url::Origin& reporting_origin, + bool* out_block_is_site_setting_specific) { + Profile* profile = Profile::FromBrowserContext(browser_context); + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + DCHECK(privacy_sandbox_settings); + + return privacy_sandbox_settings->IsPrivateAggregationAllowed( + top_frame_origin, reporting_origin, out_block_is_site_setting_specific); +} + +bool ChromeContentBrowserClient::IsPrivateAggregationDebugModeAllowed( + content::BrowserContext* browser_context, + const url::Origin& top_frame_origin, + const url::Origin& reporting_origin) { + Profile* profile = Profile::FromBrowserContext(browser_context); + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + DCHECK(privacy_sandbox_settings); + + return privacy_sandbox_settings->IsPrivateAggregationDebugModeAllowed( + top_frame_origin, reporting_origin); +} + +bool ChromeContentBrowserClient::IsCookieDeprecationLabelAllowed( + content::BrowserContext* browser_context) { + Profile* profile = Profile::FromBrowserContext(browser_context); + + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + if (!privacy_sandbox_settings) { + return false; + } + return privacy_sandbox_settings->IsCookieDeprecationLabelAllowed(); +} + +bool ChromeContentBrowserClient::IsCookieDeprecationLabelAllowedForContext( + content::BrowserContext* browser_context, + const url::Origin& top_frame_origin, + const url::Origin& context_origin) { + Profile* profile = Profile::FromBrowserContext(browser_context); + + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + DCHECK(privacy_sandbox_settings); + return privacy_sandbox_settings->IsCookieDeprecationLabelAllowedForContext( + top_frame_origin, context_origin); +} + +bool ChromeContentBrowserClient::IsFullCookieAccessAllowed( + content::BrowserContext* browser_context, + content::WebContents* web_contents, + const GURL& url, + const blink::StorageKey& storage_key) { + Profile* profile = Profile::FromBrowserContext(browser_context); + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile(profile); + if (!cookie_settings) { + return true; + } + return cookie_settings->IsFullCookieAccessAllowed( + url, storage_key.ToNetSiteForCookies(), + url::Origin::Create(storage_key.top_level_site().GetURL()), + cookie_settings->SettingOverridesForStorage()); +} + +#if BUILDFLAG(IS_CHROMEOS) +void ChromeContentBrowserClient::OnTrustAnchorUsed( + content::BrowserContext* browser_context) { + policy::PolicyCertService* service = + policy::PolicyCertServiceFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + if (!service) { + NOTREACHED_IN_MIGRATION(); + return; + } + service->SetUsedPolicyCertificates(); +} +#endif + +bool ChromeContentBrowserClient::CanSendSCTAuditingReport( + content::BrowserContext* browser_context) { + return SCTReportingService::CanSendSCTAuditingReport(); +} + +void ChromeContentBrowserClient::OnNewSCTAuditingReportSent( + content::BrowserContext* browser_context) { + SCTReportingService::OnNewSCTAuditingReportSent(); +} + +scoped_refptr +ChromeContentBrowserClient::GetSystemSharedURLLoaderFactory() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || + !BrowserThread::IsThreadInitialized(BrowserThread::UI)); + + if (!SystemNetworkContextManager::GetInstance()) + return nullptr; + + return SystemNetworkContextManager::GetInstance() + ->GetSharedURLLoaderFactory(); +} + +network::mojom::NetworkContext* +ChromeContentBrowserClient::GetSystemNetworkContext() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(g_browser_process->system_network_context_manager()); + return g_browser_process->system_network_context_manager()->GetContext(); +} + +std::string ChromeContentBrowserClient::GetGeolocationApiKey() { + return google_apis::GetAPIKey(); +} + +#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED) +device::GeolocationSystemPermissionManager* +ChromeContentBrowserClient::GetGeolocationSystemPermissionManager() { + return device::GeolocationSystemPermissionManager::GetInstance(); +} +#endif + +#if BUILDFLAG(IS_ANDROID) +bool ChromeContentBrowserClient::ShouldUseGmsCoreGeolocationProvider() { + // Indicate that Chrome uses the GMS core location provider. + return true; +} +#endif + +content::GeneratedCodeCacheSettings +ChromeContentBrowserClient::GetGeneratedCodeCacheSettings( + content::BrowserContext* context) { + base::FilePath cache_path; + chrome::GetUserCacheDirectory(context->GetPath(), &cache_path); + // If we pass 0 for size, disk_cache will pick a default size using the + // heuristics based on available disk size. These are implemented in + // disk_cache::PreferredCacheSize in net/disk_cache/cache_util.cc. + int64_t size_in_bytes = 0; + DCHECK(g_browser_process); + PrefService* local_state = g_browser_process->local_state(); + if (local_state) { + size_in_bytes = local_state->GetInteger(prefs::kDiskCacheSize); + base::FilePath disk_cache_dir = + local_state->GetFilePath(prefs::kDiskCacheDir); + if (!disk_cache_dir.empty()) + cache_path = disk_cache_dir.Append(cache_path.BaseName()); + } + return content::GeneratedCodeCacheSettings(true, size_in_bytes, cache_path); +} + +std::string ChromeContentBrowserClient::GetWebUIHostnameForCodeCacheMetrics( + const GURL& webui_url) const { +#if !BUILDFLAG(IS_ANDROID) + return webui::GetWebUIHostnameForCodeCacheMetrics(webui_url); +#else + return ContentBrowserClient::GetWebUIHostnameForCodeCacheMetrics(webui_url); +#endif +} + +void ChromeContentBrowserClient::AllowCertificateError( + content::WebContents* web_contents, + int cert_error, + const net::SSLInfo& ssl_info, + const GURL& request_url, + bool is_primary_main_frame_request, + bool strict_enforcement, + base::OnceCallback callback) { + DCHECK(web_contents); + if (!is_primary_main_frame_request) { + // A sub-resource has a certificate error. The user doesn't really + // have a context for making the right decision, so block the + // request hard, without an info bar to allow showing the insecure + // content. + if (!callback.is_null()) + std::move(callback).Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY); + return; + } + + // If the tab is being no-state prefetched, cancel the prefetcher and the + // request. + prerender::NoStatePrefetchContents* no_state_prefetch_contents = + prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents( + web_contents); + if (no_state_prefetch_contents) { + no_state_prefetch_contents->Destroy(prerender::FINAL_STATUS_SSL_ERROR); + if (!callback.is_null()) { + std::move(callback).Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL); + } + return; + } + + std::move(callback).Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY); + return; +} + +#if !BUILDFLAG(IS_ANDROID) +bool ChromeContentBrowserClient::ShouldDenyRequestOnCertificateError( + const GURL main_page_url) { + // Desktop Reader Mode pages should never load resources with certificate + // errors. Desktop Reader Mode is more strict about security than Reader Mode + // on Android: the desktop version has its own security indicator and + // is not downgraded to a WARNING, whereas Android will show "Not secure" + // in the omnibox (for low-end devices which show the omnibox on Reader Mode + // pages). + return main_page_url.SchemeIs(dom_distiller::kDomDistillerScheme); +} +#endif + +namespace { + +bool ShouldDisableForcedColorsForWebContent(content::WebContents* contents) { + if (!contents) { + return false; + } + + PrefService* prefs = + Profile::FromBrowserContext(contents->GetBrowserContext())->GetPrefs(); + CHECK(prefs); + + const base::Value::List& forced_colors_blocklist = + prefs->GetList(prefs::kPageColorsBlockList); + + if (forced_colors_blocklist.empty()) { + return false; + } + + GURL url = contents->GetLastCommittedURL(); + + // Forced Colors should be disabled for the current URL if it is in the block + // list. + for (auto const& value : forced_colors_blocklist) { + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString(value.GetString()); + + if (pattern == ContentSettingsPattern::Wildcard() || !pattern.IsValid()) { + continue; + } + + if (pattern.Matches(url)) { + return true; + } + } + + return false; +} + +bool IsForcedColorsEnabledForWebContent(content::WebContents* contents, + const ui::NativeTheme* native_theme) { + return native_theme->InForcedColorsMode() && + !ShouldDisableForcedColorsForWebContent(contents); +} + +#if !BUILDFLAG(IS_ANDROID) +blink::mojom::PreferredColorScheme ToBlinkPreferredColorScheme( + ui::NativeTheme::PreferredColorScheme native_theme_scheme) { + switch (native_theme_scheme) { + case ui::NativeTheme::PreferredColorScheme::kDark: + return blink::mojom::PreferredColorScheme::kDark; + case ui::NativeTheme::PreferredColorScheme::kLight: + return blink::mojom::PreferredColorScheme::kLight; + } +} +#endif // !BUILDFLAG(IS_ANDROID) + +// Returns true if preferred color scheme is modified based on at least one of +// the following - +// |url| - Last committed url. +// |web_contents| - For Android based on IsNightModeEnabled(). +// |native_theme| - For other platforms based on native theme scheme. +bool UpdatePreferredColorScheme(WebPreferences* web_prefs, + const GURL& url, + WebContents* web_contents, + const ui::NativeTheme* native_theme) { + auto old_preferred_color_scheme = web_prefs->preferred_color_scheme; + +#if BUILDFLAG(IS_ANDROID) + auto* delegate = TabAndroid::FromWebContents(web_contents) + ? static_cast( + web_contents->GetDelegate()) + : nullptr; + if (delegate) { + web_prefs->preferred_color_scheme = + delegate->IsNightModeEnabled() + ? blink::mojom::PreferredColorScheme::kDark + : blink::mojom::PreferredColorScheme::kLight; + web_prefs->preferred_root_scrollbar_color_scheme = + web_prefs->preferred_color_scheme; + } +#else + // Update based on native theme scheme. + web_prefs->preferred_color_scheme = + ToBlinkPreferredColorScheme(native_theme->GetPreferredColorScheme()); + + bool using_different_colored_frame = false; + if (Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext())) { + if (ThemeService* theme_service = + ThemeServiceFactory::GetForProfile(profile)) { + using_different_colored_frame = !theme_service->UsingDefaultTheme() || + theme_service->GetUserColor().has_value(); + } + } + + // Update based on the ColorProvider associated with `web_contents`. Depends + // on the browser color mode settings and whether the user profile has set a + // custom coloring for the browser ui. + web_prefs->preferred_root_scrollbar_color_scheme = + web_contents->GetColorMode() == ui::ColorProviderKey::ColorMode::kLight || + using_different_colored_frame + ? blink::mojom::PreferredColorScheme::kLight + : blink::mojom::PreferredColorScheme::kDark; +#endif // BUILDFLAG(IS_ANDROID) + + // Reauth WebUI doesn't support dark mode yet because it shares the dialog + // with GAIA web contents that is not correctly themed. + const bool force_light = + url.SchemeIs(content::kChromeUIScheme) && + url.host_piece() == chrome::kChromeUISigninReauthHost; + + if (force_light) { + web_prefs->preferred_color_scheme = + blink::mojom::PreferredColorScheme::kLight; + } else if (content::HasWebUIScheme(url)) { + // If color scheme is not forced, WebUI should track the color mode of the + // ColorProvider associated with `web_contents`. + web_prefs->preferred_color_scheme = + web_contents->GetColorMode() == ui::ColorProviderKey::ColorMode::kLight + ? blink::mojom::PreferredColorScheme::kLight + : blink::mojom::PreferredColorScheme::kDark; + } + + return old_preferred_color_scheme != web_prefs->preferred_color_scheme; +} + +// Returns whether the user can be prompted to select a client certificate after +// no certificate got auto-selected. +bool CanPromptWithNonmatchingCertificates(const Profile* profile) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (ash::ProfileHelper::IsSigninProfile(profile) || + ash::ProfileHelper::IsLockScreenProfile(profile) || + ash::ProfileHelper::IsLockScreenAppProfile(profile)) { + // On non-regular profiles (e.g. sign-in profile or lock-screen profile), + // never show certificate selection to the user. A client certificate is an + // identifier that can be stable for a long time, so only the administrator + // is allowed to decide which endpoints should see it. + // This also returns false for the lock screen app profile which can + // not use client certificates anyway - to be on the safe side in case + // support for client certificates is added later. + return false; + } +#endif + return true; +} + +// Returns whether the user should be prompted to select a client certificate +// when multiple certificates got auto-selected. +bool ShouldPromptOnMultipleMatchingCertificates(const Profile* profile) { + const PrefService* const prefs = profile->GetPrefs(); + DCHECK(prefs); + const PrefService::Preference* pref = + prefs->FindPreference(prefs::kPromptOnMultipleMatchingCertificates); + if (pref && pref->IsManaged() && pref->GetValue()->is_bool()) + return pref->GetValue()->GetBool(); + return false; +} + +} // namespace + +base::OnceClosure ChromeContentBrowserClient::SelectClientCertificate( + content::BrowserContext* browser_context, + int process_id, + content::WebContents* web_contents, + net::SSLCertRequestInfo* cert_request_info, + net::ClientCertIdentityList client_certs, + std::unique_ptr delegate) { + prerender::NoStatePrefetchContents* no_state_prefetch_contents = + web_contents + ? prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents( + web_contents) + : nullptr; + if (no_state_prefetch_contents) { + no_state_prefetch_contents->Destroy( + prerender::FINAL_STATUS_SSL_CLIENT_CERTIFICATE_REQUESTED); + return base::OnceClosure(); + } + + Profile* profile = Profile::FromBrowserContext(browser_context); +#if BUILDFLAG(IS_CHROMEOS_ASH) + // On the sign-in or lock screen profile, only allow client certs in the + // context of the sign-in frame. + // Note that this is explicitly not happening for the lock screen app profile + // which does not support a gaia / SAML IdP sign-in frame. + if (ash::ProfileHelper::IsSigninProfile(profile) || + ash::ProfileHelper::IsLockScreenProfile(profile)) { + const char* profile_name = ash::ProfileHelper::IsSigninProfile(profile) + ? "sign-in" + : "lock screen"; + + // TODO(b/290262513): See also comment below -- if the continuation should + // be a cancelation, this check is unnecessary and we can just fall-through + // without treating signin profiles differently for service workers. + if (!web_contents) { + LOG(WARNING) << "Client cert requested in " << profile_name + << " profile from service worker. This is not supported."; + // Return without calling anything on `delegate`. This results in the + // `delegate` being deleted, which implicitly calls to cancel the request. + return base::OnceClosure(); + } + + content::StoragePartition* storage_partition = + profile->GetStoragePartition(web_contents->GetSiteInstance()); + auto* signin_partition_manager = + ash::login::SigninPartitionManager::Factory::GetForBrowserContext( + profile); + if (!signin_partition_manager->IsCurrentSigninStoragePartition( + storage_partition)) { + LOG(WARNING) << "Client cert requested in " << profile_name + << " profile in wrong context."; + // Continue without client certificate. We do this to mimic the case of no + // client certificate being present in the profile's certificate store. + // TODO(b/290262513): Should this be a cancel? Selecting "no certificate" + // is a sticky decision. + delegate->ContinueWithCertificate(nullptr, nullptr); + return base::OnceClosure(); + } + VLOG(1) << "Client cert requested in " << profile_name << " profile."; + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + GURL requesting_url = chrome::enterprise_util::GetRequestingUrl( + cert_request_info->host_and_port); + DCHECK(requesting_url.is_valid()) << "Invalid URL string: " << requesting_url; + + net::ClientCertIdentityList matching_certificates, nonmatching_certificates; + chrome::enterprise_util::AutoSelectCertificates( + profile, requesting_url, std::move(client_certs), &matching_certificates, + &nonmatching_certificates); + + if (matching_certificates.size() == 1 || + (matching_certificates.size() > 1 && + !ShouldPromptOnMultipleMatchingCertificates(profile))) { + // Always take the first certificate, even if multiple ones matched - + // there's no other criteria available for tie-breaking, and user prompts + // aren't enabled. + std::unique_ptr auto_selected_identity = + std::move(matching_certificates[0]); + // The callback will own |auto_selected_identity| and |delegate|, keeping + // them alive until after ContinueWithCertificate is called. + scoped_refptr cert = + auto_selected_identity->certificate(); + net::ClientCertIdentity::SelfOwningAcquirePrivateKey( + std::move(auto_selected_identity), + base::BindOnce( + &content::ClientCertificateDelegate::ContinueWithCertificate, + std::move(delegate), std::move(cert))); + return base::OnceClosure(); + } + + // At this point, we're going to either a) continue without a valid + // certificate (if we're not allowed to prompt) or b) show the picker for the + // user to select a valid cert. b) requires an associated WebContents; we + // don't want to show a picker with no context. In the case of a), we don't + // need a WebContents to display a picker. However, we don't always know + // whether a) or b) will happen on all platforms. In particular, on Android, + // the process to check for a cert will *also* show the picker. Thus, we + // typically just early-out here unless we're ready to show a cert picker. + if (!web_contents) { + // There's one exception to the above. In the case of extensions, we allow + // the request to continue without a certificate if there are no client + // certs. This allows extension service workers to behave in the same way + // as extension offscreen documents and legacy extension background pages. + // Those cases would lead to the SSLClientCertificateSelector, which would + // automatically continue if the associated certificate list was empty. + // See https://crbug.com/333954429. + // Note: the !IS_ANDROID here is currently moot, but is important in case + // this ever changes. On Android, `matching_certificates` and + // `nonmatching_certificates` are always empty at this stage, even when + // there are matching certificates available in the OS, so this would + // result in always proceeding with no certificate for any request from an + // extension service worker. That decision would be remembered across the + // entire profile, potentially locking the user out of the origin. +#if BUILDFLAG(ENABLE_EXTENSIONS) && !BUILDFLAG(IS_ANDROID) + if (matching_certificates.empty() && nonmatching_certificates.empty()) { + extensions::ProcessMap* process_map = + extensions::ProcessMap::Get(profile); + if (process_map && process_map->Contains(process_id)) { + delegate->ContinueWithCertificate(nullptr, nullptr); + return base::OnceClosure(); + } + } +#endif + + // Return without calling anything on `delegate`. This results in the + // `delegate` being deleted, which implicitly calls to cancel the request. + return base::OnceClosure(); + } + + if (matching_certificates.empty() && + !CanPromptWithNonmatchingCertificates(profile)) { + LOG(WARNING) << "No client cert matched by policy and user selection is " + "not allowed."; + // Continue without client certificate. We do this to mimic the case of no + // client certificate being present in the profile's certificate store. + delegate->ContinueWithCertificate(nullptr, nullptr); + return base::OnceClosure(); + } + + // Note: It can happen that both lists are empty, still the selector needs to + // be shown - see the comment in SSLClientAuthHandler::DidGetClientCerts() + // about platforms not having a client cert store. + net::ClientCertIdentityList client_cert_choices = + !matching_certificates.empty() ? std::move(matching_certificates) + : std::move(nonmatching_certificates); + + return chrome::ShowSSLClientCertificateSelector( + web_contents, cert_request_info, std::move(client_cert_choices), + std::move(delegate)); +} + +content::MediaObserver* ChromeContentBrowserClient::GetMediaObserver() { + return MediaCaptureDevicesDispatcher::GetInstance(); +} + +content::FeatureObserverClient* +ChromeContentBrowserClient::GetFeatureObserverClient() { + return ChromeBrowserMainExtraPartsPerformanceManager::GetInstance() + ->GetFeatureObserverClient(); +} + +bool ChromeContentBrowserClient::CanCreateWindow( + RenderFrameHost* opener, + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const url::Origin& source_origin, + content::mojom::WindowContainerType container_type, + const GURL& target_url, + const content::Referrer& referrer, + const std::string& frame_name, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + bool* no_javascript_access) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + DCHECK(opener); + + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(opener); + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + DCHECK(profile); + *no_javascript_access = false; + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Try to intercept the request and open the URL with Lacros. + if (ash::TryOpenUrl(target_url, disposition)) { + return false; + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // If the opener is trying to create a background window but doesn't have + // the appropriate permission, fail the attempt. + if (container_type == content::mojom::WindowContainerType::BACKGROUND) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + auto* process_map = extensions::ProcessMap::Get(profile); + auto* registry = extensions::ExtensionRegistry::Get(profile); + if (!URLHasExtensionPermission(process_map, registry, opener_url, + opener->GetProcess()->GetID(), + APIPermissionID::kBackground)) { + return false; + } + + // Note: this use of GetExtensionOrAppByURL is safe but imperfect. It may + // return a recently installed Extension even if this CanCreateWindow call + // was made by an old copy of the page in a normal web process. That's ok, + // because the permission check above would have caused an early return + // already. We must use the full URL to find hosted apps, though, and not + // just the origin. + const Extension* extension = + registry->enabled_extensions().GetExtensionOrAppByURL(opener_url); + if (extension && !extensions::BackgroundInfo::AllowJSAccess(extension)) + *no_javascript_access = true; +#endif + + return true; + } + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (extensions::WebViewRendererState::GetInstance()->IsGuest( + opener->GetProcess()->GetID())) { + return true; + } + + if (target_url.SchemeIs(extensions::kExtensionScheme)) { + // Intentionally duplicating |registry| code from above because we want to + // reduce calls to retrieve them as this function is a SYNC IPC handler. + auto* registry = extensions::ExtensionRegistry::Get(profile); + const Extension* extension = + registry->enabled_extensions().GetExtensionOrAppByURL(target_url); + if (extension && extension->is_platform_app()) { + // window.open() may not be used to load v2 apps in a regular tab. + return false; + } + } +#endif + + DCHECK(!prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents( + web_contents)); + + BlockedWindowParams blocked_params( + target_url, source_origin, opener->GetSiteInstance(), referrer, + frame_name, disposition, features, user_gesture, opener_suppressed); + NavigateParams nav_params = + blocked_params.CreateNavigateParams(opener->GetProcess(), web_contents); + return !blocked_content::ConsiderForPopupBlocking(disposition) || + blocked_content::MaybeBlockPopup( + web_contents, &opener_top_level_frame_url, + (*g_popup_navigation_delegate_factory)(std::move(nav_params)), + nullptr /*=open_url_params*/, blocked_params.features(), + HostContentSettingsMapFactory::GetForProfile(profile)) != nullptr; +} + +content::SpeechRecognitionManagerDelegate* +ChromeContentBrowserClient::CreateSpeechRecognitionManagerDelegate() { + return new speech::ChromeSpeechRecognitionManagerDelegate(); +} + +#if BUILDFLAG(IS_CHROMEOS_ASH) +content::TtsControllerDelegate* +ChromeContentBrowserClient::GetTtsControllerDelegate() { + return TtsControllerDelegateImpl::GetInstance(); +} +#endif + +void ChromeContentBrowserClient::MaybeOverrideManifest( + content::RenderFrameHost* render_frame_host, + blink::mojom::ManifestPtr& manifest) { +#if !BUILDFLAG(IS_ANDROID) + Profile* profile = + Profile::FromBrowserContext(render_frame_host->GetBrowserContext()); + auto* provider = web_app::WebAppProvider::GetForWebApps(profile); + if (provider) + provider->policy_manager().MaybeOverrideManifest(render_frame_host, + manifest); +#endif +} + +content::TtsPlatform* ChromeContentBrowserClient::GetTtsPlatform() { +#if !BUILDFLAG(IS_ANDROID) + content::TtsController::GetInstance()->SetTtsEngineDelegate( + TtsExtensionEngine::GetInstance()); +#endif +#if BUILDFLAG(IS_CHROMEOS_ASH) + return TtsPlatformImplChromeOs::GetInstance(); +#elif BUILDFLAG(IS_CHROMEOS_LACROS) + return TtsPlatformImplLacros::GetInstance(); +#else + return nullptr; +#endif +} + +void ChromeContentBrowserClient::OverrideWebkitPrefs( + WebContents* web_contents, + WebPreferences* web_prefs) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + PrefService* prefs = profile->GetPrefs(); + +// Fill font preferences. These are not registered on Android +// - http://crbug.com/308033, http://crbug.com/696364. +#if !BUILDFLAG(IS_ANDROID) + // Enabling the FontFamilyCache needs some KeyedService that might not be + // available for some irregular profiles, like the System Profile. + if (!AreKeyedServicesDisabledForProfileByDefault(profile)) { + FontFamilyCache::FillFontFamilyMap(profile, + prefs::kWebKitStandardFontFamilyMap, + &web_prefs->standard_font_family_map); + FontFamilyCache::FillFontFamilyMap(profile, + prefs::kWebKitFixedFontFamilyMap, + &web_prefs->fixed_font_family_map); + FontFamilyCache::FillFontFamilyMap(profile, + prefs::kWebKitSerifFontFamilyMap, + &web_prefs->serif_font_family_map); + FontFamilyCache::FillFontFamilyMap(profile, + prefs::kWebKitSansSerifFontFamilyMap, + &web_prefs->sans_serif_font_family_map); + FontFamilyCache::FillFontFamilyMap(profile, + prefs::kWebKitCursiveFontFamilyMap, + &web_prefs->cursive_font_family_map); + FontFamilyCache::FillFontFamilyMap(profile, + prefs::kWebKitFantasyFontFamilyMap, + &web_prefs->fantasy_font_family_map); + FontFamilyCache::FillFontFamilyMap(profile, prefs::kWebKitMathFontFamilyMap, + &web_prefs->math_font_family_map); + } + + web_prefs->default_font_size = + prefs->GetInteger(prefs::kWebKitDefaultFontSize); + web_prefs->default_fixed_font_size = + prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize); + web_prefs->minimum_font_size = + prefs->GetInteger(prefs::kWebKitMinimumFontSize); + web_prefs->minimum_logical_font_size = + prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize); +#endif + + web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset); + + web_prefs->dom_paste_enabled = + prefs->GetBoolean(prefs::kWebKitDomPasteEnabled); + web_prefs->javascript_can_access_clipboard = + prefs->GetBoolean(prefs::kWebKitJavascriptCanAccessClipboard); + web_prefs->tabs_to_links = prefs->GetBoolean(prefs::kWebkitTabsToLinks); + + if (!prefs->GetBoolean(prefs::kWebKitJavascriptEnabled)) + web_prefs->javascript_enabled = false; + + if (!prefs->GetBoolean(prefs::kWebKitWebSecurityEnabled)) + web_prefs->web_security_enabled = false; + + if (!prefs->GetBoolean(prefs::kWebKitPluginsEnabled)) + web_prefs->plugins_enabled = false; + web_prefs->loads_images_automatically = + prefs->GetBoolean(prefs::kWebKitLoadsImagesAutomatically); + + if (prefs->GetBoolean(prefs::kDisable3DAPIs)) { + web_prefs->webgl1_enabled = false; + web_prefs->webgl2_enabled = false; + } + + web_prefs->allow_running_insecure_content = + prefs->GetBoolean(prefs::kWebKitAllowRunningInsecureContent); +#if BUILDFLAG(IS_ANDROID) + web_prefs->font_scale_factor = static_cast( + prefs->GetDouble(browser_ui::prefs::kWebKitFontScaleFactor)); + web_prefs->text_size_contrast_factor = + prefs->GetInteger(prefs::kAccessibilityTextSizeContrastFactor); + web_prefs->force_enable_zoom = + prefs->GetBoolean(browser_ui::prefs::kWebKitForceEnableZoom); + web_prefs->font_weight_adjustment = + prefs->GetInteger(prefs::kAccessibilityFontWeightAdjustment); +#endif + web_prefs->force_dark_mode_enabled = + prefs->GetBoolean(prefs::kWebKitForceDarkModeEnabled); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + web_prefs->always_show_focus = + prefs->GetBoolean(ash::prefs::kAccessibilityFocusHighlightEnabled); +#else + web_prefs->always_show_focus = + prefs->GetBoolean(prefs::kAccessibilityFocusHighlightEnabled); +#endif + +#if BUILDFLAG(IS_ANDROID) + web_prefs->password_echo_enabled = + prefs->GetBoolean(prefs::kWebKitPasswordEchoEnabled); +#else + web_prefs->password_echo_enabled = false; +#endif + + web_prefs->text_areas_are_resizable = + prefs->GetBoolean(prefs::kWebKitTextAreasAreResizable); + web_prefs->hyperlink_auditing_enabled = + prefs->GetBoolean(prefs::kEnableHyperlinkAuditing); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + std::string image_animation_policy = + prefs->GetString(prefs::kAnimationPolicy); + if (image_animation_policy == kAnimationPolicyOnce) { + web_prefs->animation_policy = + blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAnimateOnce; + } else if (image_animation_policy == kAnimationPolicyNone) { + web_prefs->animation_policy = + blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyNoAnimation; + } else { + web_prefs->animation_policy = + blink::mojom::ImageAnimationPolicy::kImageAnimationPolicyAllowed; + } +#endif + + // Make sure we will set the default_encoding with canonical encoding name. + web_prefs->default_encoding = + base::GetCanonicalEncodingNameByAliasName(web_prefs->default_encoding); + if (web_prefs->default_encoding.empty()) { + prefs->ClearPref(prefs::kDefaultCharset); + web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset); + } + DCHECK(!web_prefs->default_encoding.empty()); + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnablePotentiallyAnnoyingSecurityFeatures)) { + web_prefs->disable_reading_from_canvas = true; + web_prefs->strict_mixed_content_checking = true; + web_prefs->strict_powerful_feature_restrictions = true; + } + + // See crbug.com/1238157: the Native Client flag (chrome://flags/#enable-nacl) + // can be manually re-enabled. In that case, we also need to return the full + // plugins list, for compat. + web_prefs->allow_non_empty_navigator_plugins |= + base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableNaCl); + + web_prefs->data_saver_enabled = IsDataSaverEnabled(profile); + + if (web_contents) { +#if BUILDFLAG(IS_ANDROID) + auto* delegate = TabAndroid::FromWebContents(web_contents) + ? static_cast( + web_contents->GetDelegate()) + : nullptr; + if (delegate) { + web_prefs->embedded_media_experience_enabled = + delegate->ShouldEnableEmbeddedMediaExperience(); + + web_prefs->picture_in_picture_enabled = + delegate->IsPictureInPictureEnabled(); + + web_prefs->force_dark_mode_enabled = + delegate->IsForceDarkWebContentEnabled(); + + web_prefs->modal_context_menu = delegate->IsModalContextMenu(); + } +#endif // BUILDFLAG(IS_ANDROID) + + // web_app_scope value is platform specific. +#if BUILDFLAG(IS_ANDROID) + if (delegate) + web_prefs->web_app_scope = delegate->GetManifestScope(); +#elif BUILDFLAG(ENABLE_EXTENSIONS) + { + web_prefs->web_app_scope = GURL(); + // Set |web_app_scope| based on the app associated with the app window if + // any. Note that the app associated with the window never changes, even + // if the app navigates off scope. This is not a problem because we still + // want to use the scope of the app associated with the window, not the + // WebContents. + Browser* browser = chrome::FindBrowserWithTab(web_contents); + if (browser && browser->app_controller()) { + web_app::WebAppProvider* const web_app_provider = + web_app::WebAppProvider::GetForLocalAppsUnchecked(profile); + const webapps::AppId& app_id = browser->app_controller()->app_id(); + const web_app::WebAppRegistrar& registrar = + web_app_provider->registrar_unsafe(); + if (registrar.IsInstallState( + app_id, {web_app::proto::INSTALLED_WITH_OS_INTEGRATION, + web_app::proto::INSTALLED_WITHOUT_OS_INTEGRATION})) { + web_prefs->web_app_scope = registrar.GetAppScope(app_id); + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + auto* system_app = browser->app_controller()->system_app(); + if (system_app) { + web_prefs->allow_scripts_to_close_windows = + system_app->ShouldAllowScriptsToCloseWindows(); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + } + } +#endif + + web_prefs->immersive_mode_enabled = vr::VrTabHelper::IsInVr(web_contents); + } + + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableLazyLoading)) { + web_prefs->lazy_load_enabled = false; + } else { + web_prefs->lazy_load_enabled = + !web_contents || !web_contents->GetDelegate() || + web_contents->GetDelegate()->ShouldAllowLazyLoad(); + } + + if (base::FeatureList::IsEnabled( + features::kNetworkQualityEstimatorWebHoldback)) { + std::string effective_connection_type_param = + base::GetFieldTrialParamValueByFeature( + features::kNetworkQualityEstimatorWebHoldback, + "web_effective_connection_type_override"); + + std::optional effective_connection_type = + net::GetEffectiveConnectionTypeForName(effective_connection_type_param); + DCHECK(effective_connection_type_param.empty() || + effective_connection_type); + if (effective_connection_type) { + DCHECK_NE(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN, + effective_connection_type.value()); + web_prefs->network_quality_estimator_web_holdback = + static_cast( + effective_connection_type.value()); + } + } + + web_prefs->autoplay_policy = GetAutoplayPolicyForWebContents(web_contents); +#if !BUILDFLAG(IS_ANDROID) + web_prefs->require_transient_activation_for_get_display_media = + capture_policy::IsTransientActivationRequiredForGetDisplayMedia( + web_contents); + web_prefs->require_transient_activation_for_show_file_or_directory_picker = + IsFileOrDirectoryPickerWithoutGestureAllowed(web_contents); +#endif // !BUILDFLAG(IS_ANDROID) + // TODO(crbug.com/40941384): Remove this pref and solely rely on permissions. + web_prefs->require_transient_activation_for_html_fullscreen = + IsTransientActivationRequiredForHtmlFullscreen( + web_contents->GetPrimaryMainFrame()); + +#if BUILDFLAG(IS_CHROMEOS) + web_prefs->subapps_apis_require_user_gesture_and_authorization = + SubAppsAPIsRequireUserGestureAndAuthorization(web_contents); +#endif // BUILDFLAG(IS_CHROMEOS) + + switch (GetWebTheme()->GetPreferredContrast()) { + case ui::NativeTheme::PreferredContrast::kNoPreference: + web_prefs->preferred_contrast = + blink::mojom::PreferredContrast::kNoPreference; + break; + case ui::NativeTheme::PreferredContrast::kMore: + web_prefs->preferred_contrast = blink::mojom::PreferredContrast::kMore; + break; + case ui::NativeTheme::PreferredContrast::kLess: + web_prefs->preferred_contrast = blink::mojom::PreferredContrast::kLess; + break; + case ui::NativeTheme::PreferredContrast::kCustom: + web_prefs->preferred_contrast = blink::mojom::PreferredContrast::kCustom; + break; + } + + web_prefs->in_forced_colors = + IsForcedColorsEnabledForWebContent(web_contents, GetWebTheme()); + + web_prefs->is_forced_colors_disabled = + ShouldDisableForcedColorsForWebContent(web_contents); + + UpdatePreferredColorScheme( + web_prefs, + web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL(), + web_contents, GetWebTheme()); + + web_prefs->translate_service_available = TranslateService::IsAvailable(prefs); + + std::optional style = + captions::GetCaptionStyleFromUserSettings(prefs, + true /* record_metrics */); + if (style) { + web_prefs->text_track_background_color = style->background_color; + web_prefs->text_track_text_color = style->text_color; + web_prefs->text_track_text_size = style->text_size; + web_prefs->text_track_text_shadow = style->text_shadow; + web_prefs->text_track_font_family = style->font_family; + web_prefs->text_track_font_variant = style->font_variant; + web_prefs->text_track_window_color = style->window_color; + web_prefs->text_track_window_radius = style->window_radius; + } + +#if BUILDFLAG(IS_ANDROID) + // If the pref is not set, the default value (true) will be used: + web_prefs->webxr_immersive_ar_allowed = + prefs->GetBoolean(prefs::kWebXRImmersiveArEnabled); + + // Only set `databases_enabled` if disabled, otherwise check blink::feature + // settings. + web_prefs->databases_enabled = + !web_prefs->databases_enabled + ? false + : base::FeatureList::IsEnabled(blink::features::kWebSQLAccess); +#else + // TODO(crbug.com/333756088): WebSQL is disabled everywhere except Android + // WebView. + web_prefs->databases_enabled = false; +#endif + + for (auto& parts : extra_parts_) { + parts->OverrideWebkitPrefs(web_contents, web_prefs); + } + + web_prefs->prefers_default_scrollbar_styles = + prefs->GetBoolean(prefs::kPrefersDefaultScrollbarStyles); +} + +bool ChromeContentBrowserClientParts::OverrideWebPreferencesAfterNavigation( + WebContents* web_contents, + WebPreferences* web_prefs) { + return false; +} + +bool ChromeContentBrowserClient::OverrideWebPreferencesAfterNavigation( + WebContents* web_contents, + WebPreferences* web_prefs) { + bool prefs_changed = false; + + const auto autoplay_policy = GetAutoplayPolicyForWebContents(web_contents); + prefs_changed |= (web_prefs->autoplay_policy != autoplay_policy); + web_prefs->autoplay_policy = autoplay_policy; + +#if !BUILDFLAG(IS_ANDROID) + const bool require_transient_activation_for_get_display_media = + capture_policy::IsTransientActivationRequiredForGetDisplayMedia( + web_contents); + prefs_changed |= + (web_prefs->require_transient_activation_for_get_display_media != + require_transient_activation_for_get_display_media); + web_prefs->require_transient_activation_for_get_display_media = + require_transient_activation_for_get_display_media; + + const bool require_transient_activation_for_show_file_or_directory_picker = + IsFileOrDirectoryPickerWithoutGestureAllowed(web_contents); + prefs_changed |= + (web_prefs + ->require_transient_activation_for_show_file_or_directory_picker != + require_transient_activation_for_show_file_or_directory_picker); + web_prefs->require_transient_activation_for_show_file_or_directory_picker = + require_transient_activation_for_show_file_or_directory_picker; +#endif // !BUILDFLAG(IS_ANDROID) + // TODO(crbug.com/40941384): Remove this pref and solely rely on permissions. + const bool require_transient_activation_for_html_fullscreen = + IsTransientActivationRequiredForHtmlFullscreen( + web_contents->GetPrimaryMainFrame()); + prefs_changed |= + (web_prefs->require_transient_activation_for_html_fullscreen != + require_transient_activation_for_html_fullscreen); + web_prefs->require_transient_activation_for_html_fullscreen = + require_transient_activation_for_html_fullscreen; + + for (auto& parts : extra_parts_) { + prefs_changed |= + parts->OverrideWebPreferencesAfterNavigation(web_contents, web_prefs); + } + + const bool in_forced_colors = + IsForcedColorsEnabledForWebContent(web_contents, GetWebTheme()); + prefs_changed |= (web_prefs->in_forced_colors != in_forced_colors); + web_prefs->in_forced_colors = in_forced_colors; + + const bool is_forced_colors_disabled = + ShouldDisableForcedColorsForWebContent(web_contents); + prefs_changed |= + (web_prefs->is_forced_colors_disabled != is_forced_colors_disabled); + web_prefs->is_forced_colors_disabled = is_forced_colors_disabled; + + prefs_changed |= + UpdatePreferredColorScheme(web_prefs, web_contents->GetLastCommittedURL(), + web_contents, GetWebTheme()); + +#if BUILDFLAG(IS_ANDROID) + auto* delegate = TabAndroid::FromWebContents(web_contents) + ? static_cast( + web_contents->GetDelegate()) + : nullptr; + if (delegate) { + bool force_dark_mode_new_state = delegate->IsForceDarkWebContentEnabled(); + prefs_changed |= + (web_prefs->force_dark_mode_enabled != force_dark_mode_new_state); + web_prefs->force_dark_mode_enabled = force_dark_mode_new_state; + } +#endif + +#if BUILDFLAG(IS_CHROMEOS) + const bool subapps_apis_require_user_gesture_and_authorization = + SubAppsAPIsRequireUserGestureAndAuthorization(web_contents); + prefs_changed |= + (web_prefs->subapps_apis_require_user_gesture_and_authorization != + subapps_apis_require_user_gesture_and_authorization); +#endif // BUILDFLAG(IS_CHROMEOS) + + return prefs_changed; +} + +void ChromeContentBrowserClient::BrowserURLHandlerCreated( + BrowserURLHandler* handler) { + // The group policy NTP URL handler must be registered before the other NTP + // URL handlers below. Also register it before the "parts" handlers, so the + // NTP policy takes precedence over extensions that override the NTP. + handler->AddHandlerPair(&HandleNewTabPageLocationOverride, + BrowserURLHandler::null_handler()); + + for (auto& part : extra_parts_) { + part->BrowserURLHandlerCreated(handler); + } + + // Handler to rewrite chrome://about and chrome://sync URLs. + handler->AddHandlerPair(&HandleChromeAboutAndChromeSyncRewrite, + BrowserURLHandler::null_handler()); + +#if BUILDFLAG(IS_ANDROID) + // Handler to rewrite chrome://newtab on Android. + handler->AddHandlerPair(&chrome::android::HandleAndroidNativePageURL, + BrowserURLHandler::null_handler()); +#else // BUILDFLAG(IS_ANDROID) + // Handler to rewrite chrome://newtab for InstantExtended. + handler->AddHandlerPair(&search::HandleNewTabURLRewrite, + &search::HandleNewTabURLReverseRewrite); +#endif // BUILDFLAG(IS_ANDROID) + + // chrome: & friends. + handler->AddHandlerPair(&ChromeContentBrowserClient::HandleWebUI, + &ChromeContentBrowserClient::HandleWebUIReverse); +} + +base::FilePath ChromeContentBrowserClient::GetDefaultDownloadDirectory() { + return DownloadPrefs::GetDefaultDownloadDirectory(); +} + +std::string ChromeContentBrowserClient::GetDefaultDownloadName() { + return l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME); +} + +base::FilePath ChromeContentBrowserClient::GetShaderDiskCacheDirectory() { + base::FilePath user_data_dir; + base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + DCHECK(!user_data_dir.empty()); + return user_data_dir.Append(FILE_PATH_LITERAL("ShaderCache")); +} + +base::FilePath ChromeContentBrowserClient::GetGrShaderDiskCacheDirectory() { + base::FilePath user_data_dir; + base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + DCHECK(!user_data_dir.empty()); + return user_data_dir.Append(FILE_PATH_LITERAL("GrShaderCache")); +} + +base::FilePath ChromeContentBrowserClient::GetGraphiteDawnDiskCacheDirectory() { + base::FilePath user_data_dir; + base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + return user_data_dir.Append(FILE_PATH_LITERAL("GraphiteDawnCache")); +} + +base::FilePath ChromeContentBrowserClient::GetNetLogDefaultDirectory() { + base::FilePath user_data_dir; + base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + DCHECK(!user_data_dir.empty()); + return user_data_dir; +} + +base::FilePath ChromeContentBrowserClient::GetFirstPartySetsDirectory() { + base::FilePath user_data_dir; + base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + DCHECK(!user_data_dir.empty()); + return user_data_dir; +} + +std::optional +ChromeContentBrowserClient::GetLocalTracesDirectory() { + base::FilePath user_data_dir; + if (!base::PathService::Get(chrome::DIR_LOCAL_TRACES, &user_data_dir)) { + return std::nullopt; + } + DCHECK(!user_data_dir.empty()); + return user_data_dir; +} + +void ChromeContentBrowserClient::DidCreatePpapiPlugin( + content::BrowserPpapiHost* browser_host) { +#if BUILDFLAG(ENABLE_PLUGINS) + ChromeContentBrowserClientPluginsPart::DidCreatePpapiPlugin(browser_host); +#endif +} + +content::BrowserPpapiHost* +ChromeContentBrowserClient::GetExternalBrowserPpapiHost(int plugin_process_id) { +#if BUILDFLAG(ENABLE_NACL) + content::BrowserChildProcessHostIterator iter(PROCESS_TYPE_NACL_LOADER); + while (!iter.Done()) { + nacl::NaClProcessHost* host = + static_cast(iter.GetDelegate()); + if (host->process() && host->process()->GetData().id == plugin_process_id) { + // Found the plugin. + return host->browser_ppapi_host(); + } + ++iter; + } +#endif + return nullptr; +} + +bool ChromeContentBrowserClient::AllowPepperSocketAPI( + content::BrowserContext* browser_context, + const GURL& url, + bool private_api, + const content::SocketPermissionRequest* params) { +#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientPluginsPart::AllowPepperSocketAPI( + browser_context, url, private_api, params); +#else + return false; +#endif +} + +bool ChromeContentBrowserClient::IsPepperVpnProviderAPIAllowed( + content::BrowserContext* browser_context, + const GURL& url) { +#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientPluginsPart::IsPepperVpnProviderAPIAllowed( + browser_context, url); +#else + return false; +#endif +} + +std::unique_ptr +ChromeContentBrowserClient::GetVpnServiceProxy( + content::BrowserContext* browser_context) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientExtensionsPart::GetVpnServiceProxy( + browser_context); +#else + return nullptr; +#endif +} + +std::unique_ptr +ChromeContentBrowserClient::CreateSelectFilePolicy(WebContents* web_contents) { + return std::make_unique(web_contents); +} + +void ChromeContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem( + std::vector* additional_allowed_schemes) { + ContentBrowserClient::GetAdditionalAllowedSchemesForFileSystem( + additional_allowed_schemes); + additional_allowed_schemes->push_back(content::kChromeDevToolsScheme); + additional_allowed_schemes->push_back(content::kChromeUIScheme); + additional_allowed_schemes->push_back(content::kChromeUIUntrustedScheme); + additional_allowed_schemes->push_back(chrome::kIsolatedAppScheme); + for (auto& extra_part : extra_parts_) { + extra_part->GetAdditionalAllowedSchemesForFileSystem( + additional_allowed_schemes); + } +} + +void ChromeContentBrowserClient::GetSchemesBypassingSecureContextCheckAllowlist( + std::set* schemes) { + *schemes = secure_origin_allowlist::GetSchemesBypassingSecureContextCheck(); +} + +void ChromeContentBrowserClient::GetURLRequestAutoMountHandlers( + std::vector* handlers) { + for (auto& part : extra_parts_) { + part->GetURLRequestAutoMountHandlers(handlers); + } +} + +void ChromeContentBrowserClient::GetAdditionalFileSystemBackends( + content::BrowserContext* browser_context, + const base::FilePath& storage_partition_path, + std::vector>* + additional_backends) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + storage::ExternalMountPoints* external_mount_points = + browser_context->GetMountPoints(); + DCHECK(external_mount_points); + auto backend = std::make_unique( + Profile::FromBrowserContext(browser_context), + ash::file_system_provider::BackendDelegate::MakeUnique(), + std::make_unique( + storage_partition_path), + std::make_unique(), + std::make_unique(), + std::make_unique( + Profile::FromBrowserContext(browser_context)), + std::make_unique( + Profile::FromBrowserContext(browser_context)), + external_mount_points, storage::ExternalMountPoints::GetSystemInstance()); + backend->AddSystemMountPoints(); + DCHECK(backend->CanHandleType(storage::kFileSystemTypeExternal)); + additional_backends->push_back(std::move(backend)); +#endif + + for (auto& part : extra_parts_) { + part->GetAdditionalFileSystemBackends( + browser_context, storage_partition_path, + GetQuarantineConnectionCallback(), additional_backends); + } +} + +#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) +void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess( + const base::CommandLine& command_line, + int child_process_id, + PosixFileDescriptorInfo* mappings) { +#if BUILDFLAG(IS_ANDROID) + base::MemoryMappedFile::Region region; + int fd = ui::GetMainAndroidPackFd(®ion); + mappings->ShareWithRegion(kAndroidUIResourcesPakDescriptor, fd, region); + + // For Android: Native resources for DFMs should only be used by the browser + // process. Their file descriptors and memory mapped file regions are not + // passed to child processes. + + fd = ui::GetCommonResourcesPackFd(®ion); + mappings->ShareWithRegion(kAndroidChrome100PercentPakDescriptor, fd, region); + + fd = ui::GetLocalePackFd(®ion); + mappings->ShareWithRegion(kAndroidLocalePakDescriptor, fd, region); + + // Optional secondary locale .pak file. + fd = ui::GetSecondaryLocalePackFd(®ion); + if (fd != -1) { + mappings->ShareWithRegion(kAndroidSecondaryLocalePakDescriptor, fd, region); + } + + base::FilePath app_data_path; + base::PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data_path); + DCHECK(!app_data_path.empty()); +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) + int crash_signal_fd = GetCrashSignalFD(command_line); + if (crash_signal_fd >= 0) { + mappings->Share(kCrashDumpSignal, crash_signal_fd); + } +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + // Map startup and post-login parameter files to child processes in Lacros. + // The FD numbers are passed via command line switches in + // |AppendExtraCommandLineSwitches|. + // + // NOTE: the Zygote process requires special handling. + // It doesn't need the post-login parameters, so it can be fully launched at + // login screen. Also, serializing startup data early in the initialization + // process requires temporarily initializing Mojo. That's handled in the + // |LaunchZygoteHelper| function in |content_main_runner_impl.cc|. Here, we + // deal with all other type of processes. + std::string process_type = + command_line.GetSwitchValueASCII(switches::kProcessType); + if (process_type != switches::kZygoteProcess) { + base::ScopedFD cros_startup_fd = + chromeos::BrowserInitParams::CreateStartupData(); + if (cros_startup_fd.is_valid()) { + constexpr int kStartupDataFD = + kCrosStartupDataDescriptor + base::GlobalDescriptors::kBaseDescriptor; + mappings->Transfer(kStartupDataFD, std::move(cros_startup_fd)); + } + + if (chromeos::IsLaunchedWithPostLoginParams()) { + base::ScopedFD cros_postlogin_fd = + chromeos::BrowserPostLoginParams::CreatePostLoginData(); + if (cros_postlogin_fd.is_valid()) { + constexpr int kPostLoginDataFD = + kCrosPostLoginDataDescriptor + + base::GlobalDescriptors::kBaseDescriptor; + mappings->Transfer(kPostLoginDataFD, std::move(cros_postlogin_fd)); + } + } + } +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) +} +#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +void ChromeContentBrowserClient::GetAdditionalMappedFilesForZygote( + base::CommandLine* command_line, + PosixFileDescriptorInfo* mappings) { + // Create the file descriptor for Cros startup data and pass it. + // This FD will be used to obtain BrowserInitParams in Zygote process. + // Note that this requires Mojo, but Mojo cannot be fully initialized this + // due to dependencies on base::FeatureList. So we also temporarily initialize + // Mojo and then shut it down immediately after preparing the FD. This is + // inexpensive, an the features which control Mojo behavior aren't relevant + // for this operation. + // + // TODO(crbug.com/40058840): This will need to be changed before + // MojoIpcz experimentation can happen on Lacros, as it results in + // inconsistent MojoIpcz feature status across Mojo initializations. + mojo::core::Init(); + base::ScopedFD cros_startup_fd = + chromeos::BrowserInitParams::CreateStartupData(); + mojo::core::ShutDown(); + + if (cros_startup_fd.is_valid()) { + constexpr int kStartupDataFD = + kCrosStartupDataDescriptor + base::GlobalDescriptors::kBaseDescriptor; + command_line->AppendSwitchASCII(chromeos::switches::kCrosStartupDataFD, + base::NumberToString(kStartupDataFD)); + mappings->Transfer(kStartupDataFD, std::move(cros_startup_fd)); + } +} +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + +#if BUILDFLAG(IS_WIN) +std::wstring ChromeContentBrowserClient::GetAppContainerSidForSandboxType( + sandbox::mojom::Sandbox sandbox_type, + AppContainerFlags flags) { + // TODO(wfh): Add support for more process types here. crbug.com/499523 + switch (sandbox_type) { + case sandbox::mojom::Sandbox::kRenderer: + if (flags & AppContainerFlags::kAppContainerFlagDisableAppContainer) + return std::wstring(); + return std::wstring(install_static::GetSandboxSidPrefix()) + L"129201922"; + case sandbox::mojom::Sandbox::kUtility: + return std::wstring(); + case sandbox::mojom::Sandbox::kGpu: + return std::wstring(); + case sandbox::mojom::Sandbox::kOnDeviceModelExecution: + return std::wstring(); +#if BUILDFLAG(ENABLE_PPAPI) + case sandbox::mojom::Sandbox::kPpapi: +#endif + case sandbox::mojom::Sandbox::kNoSandbox: + case sandbox::mojom::Sandbox::kNoSandboxAndElevatedPrivileges: + case sandbox::mojom::Sandbox::kXrCompositing: + case sandbox::mojom::Sandbox::kNetwork: + case sandbox::mojom::Sandbox::kCdm: +#if BUILDFLAG(ENABLE_OOP_PRINTING) + case sandbox::mojom::Sandbox::kPrintBackend: +#endif + case sandbox::mojom::Sandbox::kPrintCompositor: + case sandbox::mojom::Sandbox::kAudio: +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + case sandbox::mojom::Sandbox::kScreenAI: +#endif + case sandbox::mojom::Sandbox::kSpeechRecognition: + case sandbox::mojom::Sandbox::kPdfConversion: + case sandbox::mojom::Sandbox::kService: + case sandbox::mojom::Sandbox::kServiceWithJit: + case sandbox::mojom::Sandbox::kIconReader: + case sandbox::mojom::Sandbox::kMediaFoundationCdm: + case sandbox::mojom::Sandbox::kWindowsSystemProxyResolver: + // Should never reach here. + CHECK(0); + return std::wstring(); + } +} + +bool ChromeContentBrowserClient::IsAppContainerDisabled( + sandbox::mojom::Sandbox sandbox_type) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + constexpr auto kSandboxPolicyPrefMapping = + base::MakeFixedFlatMap({ + {sandbox::mojom::Sandbox::kRenderer, + prefs::kRendererAppContainerEnabled}, + {sandbox::mojom::Sandbox::kPrintCompositor, + prefs::kPrintingLPACSandboxEnabled}, + }); + auto iter = kSandboxPolicyPrefMapping.find(sandbox_type); + + if (iter == kSandboxPolicyPrefMapping.end()) { + return false; + } + + PrefService* local_state = g_browser_process->local_state(); + const PrefService::Preference* pref = + local_state->FindPreference(iter->second); + // App Container is disabled if managed pref is set to false. + if (pref && pref->IsManaged() && !pref->GetValue()->GetBool()) + return true; + + return false; +} + +std::wstring +ChromeContentBrowserClient::GetLPACCapabilityNameForNetworkService() { + // Use a different LPAC capability name for each Chrome channel so network + // service data between hannels is isolated. + version_info::Channel channel = chrome::GetChannel(); + switch (channel) { + case version_info::Channel::CANARY: + return std::wstring(L"lpacChromeCanaryNetworkSandbox"); + case version_info::Channel::BETA: + return std::wstring(L"lpacChromeBetaNetworkSandbox"); + case version_info::Channel::DEV: + return std::wstring(L"lpacChromeDevNetworkSandbox"); + case version_info::Channel::STABLE: + return std::wstring(L"lpacChromeStableNetworkSandbox"); + case version_info::Channel::UNKNOWN: + return std::wstring(L"lpacChromeNetworkSandbox"); + } +} + +// Note: Only use sparingly to add Chrome specific sandbox functionality here. +// Other code should reside in the content layer. Changes to this function +// should be reviewed by the security team. +bool ChromeContentBrowserClient::PreSpawnChild( + sandbox::TargetConfig* config, + sandbox::mojom::Sandbox sandbox_type, + ChildSpawnFlags flags) { + DCHECK(!config->IsConfigured()); +// Does not work under component build because all the component DLLs would need +// to be manually added and maintained. Does not work under ASAN build because +// ASAN has not yet fully initialized its instrumentation by the time the CIG +// intercepts run. +#if !defined(COMPONENT_BUILD) && !defined(ADDRESS_SANITIZER) + bool enforce_code_integrity = false; + + switch (sandbox_type) { + case sandbox::mojom::Sandbox::kRenderer: + enforce_code_integrity = + (flags & ChildSpawnFlags::kChildSpawnFlagRendererCodeIntegrity); + break; + case sandbox::mojom::Sandbox::kNetwork: + enforce_code_integrity = base::FeatureList::IsEnabled( + sandbox::policy::features::kNetworkServiceCodeIntegrity); + break; + case sandbox::mojom::Sandbox::kServiceWithJit: + enforce_code_integrity = true; + break; + case sandbox::mojom::Sandbox::kUtility: + case sandbox::mojom::Sandbox::kGpu: +#if BUILDFLAG(ENABLE_PPAPI) + case sandbox::mojom::Sandbox::kPpapi: +#endif + case sandbox::mojom::Sandbox::kNoSandbox: + case sandbox::mojom::Sandbox::kNoSandboxAndElevatedPrivileges: + case sandbox::mojom::Sandbox::kXrCompositing: + case sandbox::mojom::Sandbox::kCdm: +#if BUILDFLAG(ENABLE_PRINTING) + case sandbox::mojom::Sandbox::kPrintBackend: +#endif + case sandbox::mojom::Sandbox::kPrintCompositor: +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + case sandbox::mojom::Sandbox::kScreenAI: +#endif + case sandbox::mojom::Sandbox::kAudio: + case sandbox::mojom::Sandbox::kOnDeviceModelExecution: + case sandbox::mojom::Sandbox::kSpeechRecognition: + case sandbox::mojom::Sandbox::kPdfConversion: + case sandbox::mojom::Sandbox::kService: + case sandbox::mojom::Sandbox::kIconReader: + case sandbox::mojom::Sandbox::kMediaFoundationCdm: + case sandbox::mojom::Sandbox::kWindowsSystemProxyResolver: + break; + } + + if (!enforce_code_integrity) + return true; + + // Only enable signing mitigation if launching from chrome.exe. + base::FilePath exe_path; + if (!base::PathService::Get(base::FILE_EXE, &exe_path)) + return true; + if (chrome::kBrowserProcessExecutableName != exe_path.BaseName().value()) + return true; + + sandbox::MitigationFlags mitigations = config->GetProcessMitigations(); + mitigations |= sandbox::MITIGATION_FORCE_MS_SIGNED_BINS; + sandbox::ResultCode result = config->SetProcessMitigations(mitigations); + if (result != sandbox::SBOX_ALL_OK) + return false; + + // Allow loading Chrome's DLLs. + for (const auto* dll : {chrome::kBrowserResourcesDll, chrome::kElfDll}) { + result = config->AllowExtraDlls(GetModulePath(dll).value().c_str()); + if (result != sandbox::SBOX_ALL_OK) + return false; + } +#endif // !defined(COMPONENT_BUILD) && !defined(ADDRESS_SANITIZER) + return true; +} + +bool ChromeContentBrowserClient::IsRendererCodeIntegrityEnabled() { + // Emergency 'on switch' to re-enable the policy if force-disabling it causes + // issues. + if (base::FeatureList::IsEnabled( + sandbox::policy::features::kWinSboxForceRendererCodeIntegrity)) { + return true; + } + + PrefService* local_state = g_browser_process->local_state(); + + // If kWinSboxForceRendererCodeIntegrity is set to disabled, then code + // integrity defaults to enabled, unless specifically overridden by a policy + // controlled pref being set to false. + return !local_state->HasPrefPath(prefs::kRendererCodeIntegrityEnabled) || + local_state->GetBoolean(prefs::kRendererCodeIntegrityEnabled); +} + +bool ChromeContentBrowserClient::IsPdfFontProxyEnabled() { +#if BUILDFLAG(ENABLE_PDF) + return base::FeatureList::IsEnabled( + chrome_pdf::features::kWinPdfUseFontProxy); +#else + return false; +#endif +} + +// Note: Only use sparingly to add Chrome specific sandbox functionality here. +// Other code should reside in the content layer. Changes to this function +// should be reviewed by the security team. +bool ChromeContentBrowserClient::IsUtilityCetCompatible( + const std::string& utility_sub_type) { + if (utility_sub_type == chrome::mojom::UtilWin::Name_) + return false; + return true; +} + +void ChromeContentBrowserClient::SessionEnding( + std::optional control_type) { + chrome::SessionEnding(); +} + +bool ChromeContentBrowserClient::ShouldEnableAudioProcessHighPriority() { + return IsAudioProcessHighPriorityEnabled(); +} + +bool ChromeContentBrowserClient::ShouldUseSkiaFontManager( + const GURL& site_url) { + return IsTopChromeWebUIURL(site_url) && + base::FeatureList::IsEnabled(features::kSkiaFontService); +} + +#endif // BUILDFLAG(IS_WIN) + +void ChromeContentBrowserClient:: + RegisterMojoBinderPoliciesForSameOriginPrerendering( + content::MojoBinderPolicyMap& policy_map) { + // Changes to `policy_map` should be made in + // RegisterChromeMojoBinderPoliciesForSameOriginPrerendering() which requires + // security review. + RegisterChromeMojoBinderPoliciesForSameOriginPrerendering(policy_map); +} + +void ChromeContentBrowserClient::RegisterMojoBinderPoliciesForPreview( + content::MojoBinderPolicyMap& policy_map) { + // Changes to `policy_map` should be made in + // RegisterChromeMojoBinderPoliciesForPreview() which requires security + // review. + RegisterChromeMojoBinderPoliciesForPreview(policy_map); +} + +void ChromeContentBrowserClient::OpenURL( + content::SiteInstance* site_instance, + const content::OpenURLParams& params, + base::OnceCallback callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + content::BrowserContext* browser_context = site_instance->GetBrowserContext(); + +#if BUILDFLAG(IS_ANDROID) + ServiceTabLauncher::GetInstance()->LaunchTab(browser_context, params, + std::move(callback)); +#else + NavigateParams nav_params(Profile::FromBrowserContext(browser_context), + params.url, params.transition); + nav_params.FillNavigateParamsFromOpenURLParams(params); + + Navigate(&nav_params); + std::move(callback).Run(nav_params.navigated_or_inserted_contents); +#endif +} + +content::ControllerPresentationServiceDelegate* +ChromeContentBrowserClient::GetControllerPresentationServiceDelegate( + content::WebContents* web_contents) { + if (media_router::MediaRouterEnabled(web_contents->GetBrowserContext())) { + return media_router::PresentationServiceDelegateImpl:: + GetOrCreateForWebContents(web_contents); + } + return nullptr; +} + +content::ReceiverPresentationServiceDelegate* +ChromeContentBrowserClient::GetReceiverPresentationServiceDelegate( + content::WebContents* web_contents) { + if (media_router::MediaRouterEnabled(web_contents->GetBrowserContext())) { + // ReceiverPresentationServiceDelegateImpl exists only for WebContents + // created for offscreen presentations. The WebContents must belong to + // an incognito profile. + if (auto* impl = media_router::ReceiverPresentationServiceDelegateImpl:: + FromWebContents(web_contents)) { + DCHECK(web_contents->GetBrowserContext()->IsOffTheRecord()); + return impl; + } + } + return nullptr; +} + +void ChromeContentBrowserClient::AddPresentationObserver( + content::PresentationObserver* observer, + content::WebContents* web_contents) { + if (media_router::MediaRouterEnabled(web_contents->GetBrowserContext())) { + media_router::WebContentsPresentationManager::Get(web_contents) + ->AddObserver(observer); + } +} + +void ChromeContentBrowserClient::RemovePresentationObserver( + content::PresentationObserver* observer, + content::WebContents* web_contents) { + if (media_router::MediaRouterEnabled(web_contents->GetBrowserContext())) { + media_router::WebContentsPresentationManager::Get(web_contents) + ->RemoveObserver(observer); + } +} + +bool ChromeContentBrowserClient::AddPrivacySandboxAttestationsObserver( + content::PrivacySandboxAttestationsObserver* observer) { + return privacy_sandbox::PrivacySandboxAttestations::GetInstance() + ->AddObserver(observer); +} + +void ChromeContentBrowserClient::RemovePrivacySandboxAttestationsObserver( + content::PrivacySandboxAttestationsObserver* observer) { + privacy_sandbox::PrivacySandboxAttestations::GetInstance()->RemoveObserver( + observer); +} + +std::vector> +ChromeContentBrowserClient::CreateThrottlesForNavigation( + content::NavigationHandle* handle) { + std::vector> throttles; + + // MetricsNavigationThrottle requires that it runs before NavigationThrottles + // that may delay or cancel navigations, so only NavigationThrottles that + // don't delay or cancel navigations (e.g. throttles that are only observing + // callbacks without affecting navigation behavior) should be added before + // MetricsNavigationThrottle. + if (handle->IsInMainFrame()) { + throttles.push_back( + page_load_metrics::MetricsNavigationThrottle::Create(handle)); + } + +#if BUILDFLAG(IS_ANDROID) + // TODO(davidben): This is insufficient to integrate with prerender properly. + // https://crbug.com/370595 + prerender::NoStatePrefetchContents* no_state_prefetch_contents = + prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents( + handle->GetWebContents()); + if (!no_state_prefetch_contents) { + MaybeAddThrottle( + navigation_interception::InterceptNavigationDelegate:: + MaybeCreateThrottleFor( + handle, navigation_interception::SynchronyMode::kAsync), + &throttles); + } + throttles.push_back(InterceptOMADownloadNavigationThrottle::Create(handle)); + +#if BUILDFLAG(DFMIFY_DEV_UI) + // If the DevUI DFM is already installed, then this is a no-op, except for the + // side effect of ensuring that the DevUI DFM is loaded. + MaybeAddThrottle(dev_ui::DevUiLoaderThrottle::MaybeCreateThrottleFor(handle), + &throttles); +#endif // BUILDFLAG(DFMIFY_DEV_UI) + +#elif BUILDFLAG(ENABLE_EXTENSIONS) + // Redirect some navigations to apps that have registered matching URL + // handlers ('url_handlers' in the manifest). + MaybeAddThrottle( + PlatformAppNavigationRedirector::MaybeCreateThrottleFor(handle), + &throttles); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Check if we need to add merge session throttle. This throttle will postpone + // loading of main frames. + if (handle->IsInMainFrame()) { + // Add interstitial page while merge session process (cookie reconstruction + // from OAuth2 refresh token in ChromeOS login) is still in progress while + // we are attempting to load a google property. + if (ash::merge_session_throttling_utils::ShouldAttachNavigationThrottle() && + !ash::merge_session_throttling_utils::AreAllSessionMergedAlready() && + handle->GetURL().SchemeIsHTTPOrHTTPS()) { + throttles.push_back(ash::MergeSessionNavigationThrottle::Create(handle)); + } + } +#endif + +#if BUILDFLAG(IS_CHROMEOS) + auto disabled_app_throttle = + apps::ChromeOsDisabledAppsThrottle::MaybeCreate(handle); + if (disabled_app_throttle) { + throttles.push_back(std::move(disabled_app_throttle)); + } +#endif // BUILDFLAG(IS_CHROMEOS) + +#if !BUILDFLAG(IS_ANDROID) + std::unique_ptr + link_capturing_delegate; + +#if BUILDFLAG(IS_CHROMEOS) + link_capturing_delegate = + std::make_unique(); +#else + link_capturing_delegate = + std::make_unique(); +#endif + std::unique_ptr url_to_apps_throttle = + apps::LinkCapturingNavigationThrottle::MaybeCreate( + handle, std::move(link_capturing_delegate)); + if (url_to_apps_throttle) { + throttles.push_back(std::move(url_to_apps_throttle)); + } +#endif // !BUILDFLAG(IS_ANDROID) + + Profile* profile = Profile::FromBrowserContext( + handle->GetWebContents()->GetBrowserContext()); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (!ChromeContentBrowserClientExtensionsPart:: + AreExtensionsDisabledForProfile(profile)) { + throttles.push_back( + std::make_unique(handle)); + + MaybeAddThrottle(extensions::ExtensionsBrowserClient::Get() + ->GetUserScriptListener() + ->CreateNavigationThrottle(handle), + &throttles); + } +#endif + + MaybeAddThrottle( + SupervisedUserGoogleAuthNavigationThrottle::MaybeCreate(handle), + &throttles); + + MaybeAddThrottle( + SupervisedUserNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); + + if (auto* throttle_manager = + subresource_filter::ContentSubresourceFilterThrottleManager:: + FromNavigationHandle(*handle)) { + throttle_manager->MaybeAppendNavigationThrottles(handle, &throttles); + } + + if (base::FeatureList::IsEnabled(fingerprinting_protection_filter::features:: + kEnableFingerprintingProtectionFilter)) { + if (auto* throttle_manager = fingerprinting_protection_filter:: + ThrottleManager::FromNavigationHandle(*handle)) { + throttle_manager->MaybeAppendNavigationThrottles(handle, &throttles); + } + } + + MaybeAddThrottle( + LookalikeUrlNavigationThrottle::MaybeCreateNavigationThrottle(handle), + &throttles); + + MaybeAddThrottle(PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); +#if BUILDFLAG(ENABLE_PDF) + throttles.push_back(std::make_unique( + handle, std::make_unique())); +#endif // BUILDFLAG(ENABLE_PDF) + + MaybeAddThrottle(TabUnderNavigationThrottle::MaybeCreate(handle), &throttles); + + MaybeAddThrottle( + WellKnownChangePasswordNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); + + MaybeAddThrottle( + PasswordManagerNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); + + throttles.push_back(std::make_unique( + handle, handle->GetWebContents()->GetBrowserContext())); + + // Before setting up SSL error detection, configure SSLErrorHandler to invoke + // the relevant extension API whenever an SSL interstitial is shown. + SSLErrorHandler::SetClientCallbackOnInterstitialsShown( + base::BindRepeating(&MaybeTriggerSecurityInterstitialShownEvent)); + throttles.push_back(std::make_unique( + handle, + base::BindOnce(&HandleSSLErrorWrapper), base::BindOnce(&IsInHostedApp), + base::BindOnce( + &ShouldIgnoreSslInterstitialBecauseNavigationDefaultedToHttps))); + + throttles.push_back(std::make_unique(handle)); + + if (base::FeatureList::IsEnabled(omnibox::kDefaultTypedNavigationsToHttps)) { + MaybeAddThrottle( + TypedNavigationUpgradeThrottle::MaybeCreateThrottleFor(handle), + &throttles); + } + +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) + MaybeAddThrottle( + WebAppSettingsNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); + MaybeAddThrottle(profile_management::ProfileManagementNavigationThrottle:: + MaybeCreateThrottleFor(handle), + &throttles); + MaybeAddThrottle( + profile_management::OidcAuthResponseCaptureNavigationThrottle:: + MaybeCreateThrottleFor(handle), + &throttles); +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) + +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || \ + BUILDFLAG(IS_CHROMEOS_ASH) + MaybeAddThrottle(enterprise_connectors::DeviceTrustNavigationThrottle:: + MaybeCreateThrottleFor(handle), + &throttles); +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || + // BUILDFLAG(IS_CHROMEOS_ASH) + +#if !BUILDFLAG(IS_ANDROID) + MaybeAddThrottle(DevToolsWindow::MaybeCreateNavigationThrottle(handle), + &throttles); + + MaybeAddThrottle(NewTabPageNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); + + MaybeAddThrottle( + web_app::TabbedWebAppNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); + + MaybeAddThrottle( + web_app::WebUIWebAppNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); +#endif + + // g_browser_process->safe_browsing_service() may be null in unittests. + safe_browsing::SafeBrowsingUIManager* ui_manager = + g_browser_process->safe_browsing_service() + ? g_browser_process->safe_browsing_service()->ui_manager().get() + : nullptr; + MaybeAddThrottle( + safe_browsing::SafeBrowsingNavigationThrottle::MaybeCreateThrottleFor( + handle, ui_manager), + &throttles); + + if (base::FeatureList::IsEnabled(safe_browsing::kDelayedWarnings)) { + throttles.push_back( + std::make_unique( + handle)); + } + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + MaybeAddThrottle(browser_switcher::BrowserSwitcherNavigationThrottle:: + MaybeCreateThrottleFor(handle), + &throttles); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + MaybeAddThrottle( + chromeos::KioskSettingsNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); +#endif + +#if BUILDFLAG(IS_MAC) + MaybeAddThrottle(MaybeCreateAuthSessionThrottleFor(handle), &throttles); +#endif + + auto* performance_manager_registry = + performance_manager::PerformanceManagerRegistry::GetInstance(); + if (performance_manager_registry) { + MaybeAddThrottles( + performance_manager_registry->CreateThrottlesForNavigation(handle), + &throttles); + } + + if (profile && profile->GetPrefs()) { + MaybeAddThrottle( + security_interstitials::InsecureFormNavigationThrottle:: + MaybeCreateNavigationThrottle( + handle, std::make_unique(), + profile->GetPrefs()), + &throttles); + } + + if (IsErrorPageAutoReloadEnabled()) { + MaybeAddThrottle( + error_page::NetErrorAutoReloader::MaybeCreateThrottleFor(handle), + &throttles); + } + + MaybeAddThrottle( + payments::PaymentHandlerNavigationThrottle::MaybeCreateThrottleFor( + handle), + &throttles); + + MaybeAddThrottle( + prerender::NoStatePrefetchNavigationThrottle::MaybeCreateThrottleFor( + handle), + &throttles); + +#if defined(TOOLKIT_VIEWS) + if (profile && IsSideSearchEnabled(profile)) { + MaybeAddThrottle( + SideSearchSideContentsHelper::MaybeCreateThrottleFor(handle), + &throttles); + } +#endif + +#if BUILDFLAG(ENABLE_LENS_DESKTOP_GOOGLE_BRANDED_FEATURES) + if (lens::features::IsLensSidePanelEnabled()) { + MaybeAddThrottle( + lens::LensSidePanelNavigationHelper::MaybeCreateThrottleFor(handle), + &throttles); + } +#endif + +#if !BUILDFLAG(IS_ANDROID) + MaybeAddThrottle(ReadAnythingSidePanelNavigationThrottle::CreateFor(handle), + &throttles); + + if (lens::features::IsLensOverlayEnabled()) { + if (profile) { + if (ThemeService* theme_service = + ThemeServiceFactory::GetForProfile(profile)) { + MaybeAddThrottle( + lens::LensOverlaySidePanelNavigationThrottle::MaybeCreateFor( + handle, theme_service), + &throttles); + } + } + } +#endif + +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + MaybeAddThrottle( + offline_pages::OfflinePageNavigationThrottle::MaybeCreateThrottleFor( + handle), + &throttles); +#endif + + if (profile) { + MaybeAddThrottle( + HttpsUpgradesNavigationThrottle::MaybeCreateThrottleFor( + handle, std::make_unique(), + profile), + &throttles); + } + + MaybeAddThrottle(MaybeCreateNavigationAblationThrottle(handle), &throttles); + +#if !BUILDFLAG(IS_ANDROID) + MaybeAddThrottle(MaybeCreateAboutThisSiteThrottleFor(handle), &throttles); +#endif + + auto* privacy_sandbox_settings = + PrivacySandboxSettingsFactory::GetForProfile(profile); + if (privacy_sandbox_settings && + privacy_sandbox_settings->AreRelatedWebsiteSetsEnabled()) { + MaybeAddThrottle(first_party_sets::FirstPartySetsNavigationThrottle:: + MaybeCreateNavigationThrottle(handle), + &throttles); + } + +#if BUILDFLAG(IS_WIN) + // Don't perform platform authentication in incognito and guest profiles. + if (profile && !profile->IsOffTheRecord()) { + MaybeAddThrottle( + enterprise_auth::PlatformAuthNavigationThrottle::MaybeCreateThrottleFor( + handle), + &throttles); + } +#endif // BUILDFLAG(IS_WIN) + +#if BUILDFLAG(IS_CHROMEOS) + // TODO(b:296844164) Handle captive portal signin properly. + if (profile && profile->IsIncognitoProfile() && profile->IsOffTheRecord() && + !profile->GetOTRProfileID().IsCaptivePortal()) { + MaybeAddThrottle( + chromeos::IncognitoNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); + } + + MaybeAddThrottle(apps::AppInstallNavigationThrottle::MaybeCreate(handle), + &throttles); +#endif // BUILDFLAG(IS_CHROMEOS) + +#if !BUILDFLAG(IS_ANDROID) + MaybeAddThrottle(PreviewNavigationThrottle::MaybeCreateThrottleFor(handle), + &throttles); +#endif // !BUILDFLAG(IS_ANDROID) + + MaybeAddThrottle(MaybeCreateVisitedLinkNavigationThrottleFor(handle), + &throttles); + + MaybeAddThrottle( + data_sharing::DataSharingNavigationThrottle::MaybeCreateThrottleFor( + handle), + &throttles); + + return throttles; +} + +std::vector> +ChromeContentBrowserClient::CreateCommitDeferringConditionsForNavigation( + content::NavigationHandle* navigation_handle, + content::CommitDeferringCondition::NavigationType navigation_type) { + auto conditions = + std::vector>(); + +#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) + MaybeAddCondition( + safe_browsing::MaybeCreateCommitDeferringCondition(*navigation_handle), + &conditions); +#endif + + return conditions; +} + +std::unique_ptr +ChromeContentBrowserClient::GetNavigationUIData( + content::NavigationHandle* navigation_handle) { + return std::make_unique(navigation_handle); +} + +std::unique_ptr +ChromeContentBrowserClient::CreateScreenEnumerator() const { + return std::make_unique(); +} + +bool ChromeContentBrowserClient::EnforceSystemAudioEchoCancellation() { + // TODO(b/270042522): This is a short term solution to enforce the system + // audio cancellation and will be removed before Lacros is released. The + // short term solution will not work on Lacros. +#if BUILDFLAG(IS_CHROMEOS_ASH) && defined(USE_CRAS) + bool system_aec_enabled = false; + ash::CrosSettings::Get()->GetBoolean(ash::kDeviceSystemAecEnabled, + &system_aec_enabled); + return system_aec_enabled; +#else + return false; +#endif +} + +std::unique_ptr +ChromeContentBrowserClient::CreateDevToolsManagerDelegate() { +#if BUILDFLAG(IS_ANDROID) + return std::make_unique(); +#else + return std::make_unique(); +#endif +} + +void ChromeContentBrowserClient::UpdateDevToolsBackgroundServiceExpiration( + content::BrowserContext* browser_context, + int service, + base::Time expiration_time) { + Profile* profile = Profile::FromBrowserContext(browser_context); + DCHECK(profile); + + auto* pref_service = profile->GetPrefs(); + DCHECK(pref_service); + + ScopedDictPrefUpdate pref_update( + pref_service, prefs::kDevToolsBackgroundServicesExpirationDict); + base::Value::Dict& exp_dict = pref_update.Get(); + + // Convert |expiration_time| to minutes since that is the most granular + // option that returns an int. base::Value does not accept int64. + int expiration_time_minutes = + expiration_time.ToDeltaSinceWindowsEpoch().InMinutes(); + exp_dict.Set(base::NumberToString(service), expiration_time_minutes); +} + +base::flat_map +ChromeContentBrowserClient::GetDevToolsBackgroundServiceExpirations( + content::BrowserContext* browser_context) { + Profile* profile = Profile::FromBrowserContext(browser_context); + DCHECK(profile); + + auto* pref_service = profile->GetPrefs(); + DCHECK(pref_service); + + const auto& expiration_dict = + pref_service->GetDict(prefs::kDevToolsBackgroundServicesExpirationDict); + + base::flat_map expiration_times; + for (auto it : expiration_dict) { + // key. + int service = 0; + bool did_convert = base::StringToInt(it.first, &service); + DCHECK(did_convert); + + // value. + DCHECK(it.second.is_int()); + base::TimeDelta delta = base::Minutes(it.second.GetInt()); + base::Time expiration_time = base::Time::FromDeltaSinceWindowsEpoch(delta); + + expiration_times[service] = expiration_time; + } + + return expiration_times; +} + +std::optional +ChromeContentBrowserClient::GetSpareRendererDelayForSiteURL( + const GURL& site_url) { + if (!IsTopChromeWebUIURL(site_url)) { + return std::nullopt; + } + + // Experiments have shown that delaying 2s brings the most significant + // improvements to Top Chrome WebUIs. See crbug.com/41490050. + return base::Seconds(2); +} + +std::unique_ptr +ChromeContentBrowserClient::CreateTracingDelegate() { + return std::make_unique(); +} + +bool ChromeContentBrowserClient::IsSystemWideTracingEnabled() { + return ChromeTracingDelegate::IsSystemWideTracingEnabled(); +} + +bool ChromeContentBrowserClient::IsPluginAllowedToCallRequestOSFileHandle( + content::BrowserContext* browser_context, + const GURL& url) { +#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientPluginsPart:: + IsPluginAllowedToCallRequestOSFileHandle(browser_context, url); +#else + return false; +#endif +} + +bool ChromeContentBrowserClient::IsPluginAllowedToUseDevChannelAPIs( + content::BrowserContext* browser_context, + const GURL& url) { +#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientPluginsPart:: + IsPluginAllowedToUseDevChannelAPIs(browser_context, url); +#else + return false; +#endif +} + +void ChromeContentBrowserClient::InitOnUIThread() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + safe_browsing_service_ = g_browser_process->safe_browsing_service(); + + // Initialize `network_contexts_parent_directory_`. + base::FilePath user_data_dir; + base::PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + DCHECK(!user_data_dir.empty()); + network_contexts_parent_directory_.push_back(user_data_dir); + + base::FilePath cache_dir; + chrome::GetUserCacheDirectory(user_data_dir, &cache_dir); + DCHECK(!cache_dir.empty()); + // On some platforms, the cache is a child of the user_data_dir so only + // return the one path. + if (!user_data_dir.IsParent(cache_dir)) + network_contexts_parent_directory_.push_back(cache_dir); + + // If the cache location has been overridden by a switch or preference, + // include that as well. + if (auto* local_state = g_browser_process->local_state()) { + base::FilePath pref_cache_dir = + local_state->GetFilePath(prefs::kDiskCacheDir); + if (!pref_cache_dir.empty() && !user_data_dir.IsParent(cache_dir)) + network_contexts_parent_directory_.push_back(pref_cache_dir); + } +} + +void ChromeContentBrowserClient::MaybeCopyDisableWebRtcEncryptionSwitch( + base::CommandLine* to_command_line, + const base::CommandLine& from_command_line, + version_info::Channel channel) { +#if BUILDFLAG(IS_ANDROID) + const version_info::Channel kMaxDisableEncryptionChannel = + version_info::Channel::BETA; +#else + const version_info::Channel kMaxDisableEncryptionChannel = + version_info::Channel::DEV; +#endif + if (channel <= kMaxDisableEncryptionChannel) { + static const char* const kWebRtcDevSwitchNames[] = { + switches::kDisableWebRtcEncryption, + }; + to_command_line->CopySwitchesFrom(from_command_line, kWebRtcDevSwitchNames); + } +} + +#if BUILDFLAG(ENABLE_MEDIA_REMOTING) +void ChromeContentBrowserClient::CreateMediaRemoter( + content::RenderFrameHost* render_frame_host, + mojo::PendingRemote source, + mojo::PendingReceiver receiver) { + CastRemotingConnector::CreateMediaRemoter( + render_frame_host, std::move(source), std::move(receiver)); +} +#endif // BUILDFLAG(ENABLE_MEDIA_REMOTING) + +base::FilePath ChromeContentBrowserClient::GetLoggingFileName( + const base::CommandLine& command_line) { + return logging::GetLogFileName(command_line); +} + +#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) +std::unique_ptr +ChromeContentBrowserClient::MaybeCreateSafeBrowsingURLLoaderThrottle( + const network::ResourceRequest& request, + content::BrowserContext* browser_context, + const base::RepeatingCallback& wc_getter, + int frame_tree_node_id, + std::optional navigation_id, + Profile* profile) { + bool matches_enterprise_allowlist = safe_browsing::IsURLAllowlistedByPolicy( + request.url, *profile->GetPrefs()); + if (!matches_enterprise_allowlist) { +#if BUILDFLAG(SAFE_BROWSING_DB_LOCAL) + auto* connectors_service = + enterprise_connectors::ConnectorsServiceFactory::GetForBrowserContext( + browser_context); + bool has_valid_dm_token = + connectors_service && + connectors_service->GetDMTokenForRealTimeUrlCheck().has_value(); + bool is_enterprise_lookup_enabled = + safe_browsing::RealTimePolicyEngine::CanPerformEnterpriseFullURLLookup( + profile->GetPrefs(), has_valid_dm_token, profile->IsOffTheRecord()); +#else + bool is_enterprise_lookup_enabled = false; +#endif + bool is_consumer_lookup_enabled = + safe_browsing::RealTimePolicyEngine::CanPerformFullURLLookup( + profile->GetPrefs(), profile->IsOffTheRecord(), + g_browser_process->variations_service()); + + // |url_lookup_service| is used when real time url check is enabled. + safe_browsing::RealTimeUrlLookupServiceBase* url_lookup_service = + GetUrlLookupService(browser_context, is_enterprise_lookup_enabled, + is_consumer_lookup_enabled); + safe_browsing::HashRealTimeService* hash_realtime_service = + safe_browsing_service_ + ? safe_browsing_service_->GetHashRealTimeService(profile) + : nullptr; + safe_browsing::hash_realtime_utils::HashRealTimeSelection + hash_realtime_selection = + safe_browsing::hash_realtime_utils::DetermineHashRealTimeSelection( + profile->IsOffTheRecord(), profile->GetPrefs(), + safe_browsing::hash_realtime_utils::GetCountryCode( + g_browser_process->variations_service()), + /*log_usage_histograms=*/true); + safe_browsing::AsyncCheckTracker* async_check_tracker = + GetAsyncCheckTracker(wc_getter, is_enterprise_lookup_enabled, + is_consumer_lookup_enabled, + hash_realtime_selection, frame_tree_node_id); + + return safe_browsing::BrowserURLLoaderThrottle::Create( + base::BindRepeating( + &ChromeContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate, + base::Unretained(this), + safe_browsing::IsSafeBrowsingEnabled(*profile->GetPrefs()), + // Should check for enterprise when safe browsing is disabled. + /*should_check_on_sb_disabled=*/is_enterprise_lookup_enabled, + safe_browsing::GetURLAllowlistByPolicy(profile->GetPrefs())), + wc_getter, frame_tree_node_id, navigation_id, + url_lookup_service ? url_lookup_service->GetWeakPtr() : nullptr, + hash_realtime_service ? hash_realtime_service->GetWeakPtr() : nullptr, + hash_realtime_selection, + async_check_tracker ? async_check_tracker->GetWeakPtr() : nullptr); + } + return nullptr; +} +#endif + +#if BUILDFLAG(IS_ANDROID) +std::tuple +GetClientDataHeader(int frame_tree_node_id) { + std::string client_data_header; + bool is_custom_tab = false; + if (frame_tree_node_id != content::RenderFrameHost::kNoFrameTreeNodeId) { + auto* web_contents = WebContents::FromFrameTreeNodeId(frame_tree_node_id); + // Could be null if the FrameTreeNode's RenderFrameHost is shutting down. + if (web_contents) { + auto* client_data_header_observer = + customtabs::ClientDataHeaderWebContentsObserver::FromWebContents( + web_contents); + if (client_data_header_observer) { + client_data_header = client_data_header_observer->header(); + } + + auto* delegate = + TabAndroid::FromWebContents(web_contents) + ? static_cast( + web_contents->GetDelegate()) + : nullptr; + if (delegate) { + is_custom_tab = delegate->IsCustomTab(); + } + } + } + return {client_data_header, is_custom_tab}; +} +#endif + +std::unique_ptr CreateGoogleURLLoaderThrottle( +#if BUILDFLAG(IS_ANDROID) + const std::string& client_data_header, +#endif + Profile* profile) { +#if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + BoundSessionCookieRefreshService* bound_session_cookie_refresh_service = + BoundSessionCookieRefreshServiceFactory::GetForProfile(profile); + std::unique_ptr + bound_session_request_throttled_handler; + std::vector + bound_session_throttler_params; + + if (bound_session_cookie_refresh_service) { + bound_session_request_throttled_handler = + std::make_unique( + *bound_session_cookie_refresh_service); + bound_session_throttler_params = + bound_session_cookie_refresh_service->GetBoundSessionThrottlerParams(); + } +#endif + + chrome::mojom::DynamicParamsPtr dynamic_params = + chrome::mojom::DynamicParams::New( +#if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + std::move(bound_session_throttler_params), +#endif + profile->GetPrefs()->GetBoolean( + policy::policy_prefs::kForceGoogleSafeSearch), + profile->GetPrefs()->GetInteger( + policy::policy_prefs::kForceYouTubeRestrict), + profile->GetPrefs()->GetString(prefs::kAllowedDomainsForApps)); + return std::make_unique( +#if BUILDFLAG(IS_ANDROID) + client_data_header, +#endif +#if BUILDFLAG(ENABLE_BOUND_SESSION_CREDENTIALS) + std::move(bound_session_request_throttled_handler), +#endif + std::move(dynamic_params)); +} + +std::vector> +ChromeContentBrowserClient::CreateURLLoaderThrottles( + const network::ResourceRequest& request, + content::BrowserContext* browser_context, + const base::RepeatingCallback& wc_getter, + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id, + std::optional navigation_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + std::vector> result; + + DCHECK(browser_context); + Profile* profile = Profile::FromBrowserContext(browser_context); + DCHECK(profile); + + ChromeNavigationUIData* chrome_navigation_ui_data = + static_cast(navigation_ui_data); + +#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) + if (auto safe_browsing_throttle = MaybeCreateSafeBrowsingURLLoaderThrottle( + request, browser_context, wc_getter, frame_tree_node_id, + navigation_id, profile); + safe_browsing_throttle) { + result.push_back(std::move(safe_browsing_throttle)); + } +#endif + +#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) + result.push_back( + std::make_unique( + wc_getter.Run())); +#endif + +#if BUILDFLAG(ENABLE_REQUEST_HEADER_INTEGRITY) + result.push_back( + std::make_unique< + request_header_integrity::RequestHeaderIntegrityURLLoaderThrottle>()); +#endif + + if (chrome_navigation_ui_data && + chrome_navigation_ui_data->is_no_state_prefetching()) { + result.push_back( + std::make_unique( + GetPrerenderCanceler(wc_getter))); + } + +#if BUILDFLAG(IS_ANDROID) + auto [client_data_header, is_custom_tab] = + GetClientDataHeader(frame_tree_node_id); +#endif + + if (auto google_throttle = CreateGoogleURLLoaderThrottle( +#if BUILDFLAG(IS_ANDROID) + client_data_header, +#endif + profile); + google_throttle) { + result.push_back(std::move(google_throttle)); + } + + { + auto* factory = + ProtocolHandlerRegistryFactory::GetForBrowserContext(browser_context); + // null in unit tests. + if (factory) { + result.push_back( + std::make_unique(*factory)); + } + } + +#if BUILDFLAG(ENABLE_PLUGINS) + result.push_back(std::make_unique( + request.destination, frame_tree_node_id)); +#endif + +#if BUILDFLAG(IS_ANDROID) + auto delegate = std::make_unique( + profile, /*incognito_enabled=*/!is_custom_tab); +#else + auto delegate = + std::make_unique(profile); +#endif + + auto signin_throttle = + signin::URLLoaderThrottle::MaybeCreate(std::move(delegate), wc_getter); + if (signin_throttle) + result.push_back(std::move(signin_throttle)); + + return result; +} + +std::vector> +ChromeContentBrowserClient::CreateURLLoaderThrottlesForKeepAlive( + const network::ResourceRequest& request, + content::BrowserContext* browser_context, + const base::RepeatingCallback& wc_getter, + int frame_tree_node_id) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + std::vector> result; + + DCHECK(browser_context); + Profile* profile = Profile::FromBrowserContext(browser_context); + DCHECK(profile); + +#if BUILDFLAG(SAFE_BROWSING_AVAILABLE) + if (auto safe_browsing_throttle = MaybeCreateSafeBrowsingURLLoaderThrottle( + request, browser_context, wc_getter, frame_tree_node_id, + /*navigation_id=*/std::nullopt, profile); + safe_browsing_throttle) { + result.push_back(std::move(safe_browsing_throttle)); + } +#endif + +#if BUILDFLAG(IS_ANDROID) + auto [client_data_header, unused_is_custom_tab] = + GetClientDataHeader(frame_tree_node_id); +#endif + + if (auto google_throttle = CreateGoogleURLLoaderThrottle( +#if BUILDFLAG(IS_ANDROID) + client_data_header, +#endif + profile); + google_throttle) { + result.push_back(std::move(google_throttle)); + } + + return result; +} + +mojo::PendingRemote +ChromeContentBrowserClient::CreateNonNetworkNavigationURLLoaderFactory( + const std::string& scheme, + int frame_tree_node_id) { +#if BUILDFLAG(ENABLE_EXTENSIONS) || BUILDFLAG(IS_CHROMEOS_ASH) || \ + !BUILDFLAG(IS_ANDROID) + content::WebContents* web_contents = + content::WebContents::FromFrameTreeNodeId(frame_tree_node_id); + content::BrowserContext* browser_context = web_contents->GetBrowserContext(); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (scheme == extensions::kExtensionScheme) { + if (!ChromeContentBrowserClientExtensionsPart:: + AreExtensionsDisabledForProfile(browser_context)) { + return extensions::CreateExtensionNavigationURLLoaderFactory( + browser_context, + !!extensions::WebViewGuest::FromWebContents(web_contents)); + } + + return {}; + } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + + Profile* profile = Profile::FromBrowserContext(browser_context); + // KeyedServices could be disabled based on the profile type, e.g. System + // Profile doesn't construct services by default. + if (AreKeyedServicesDisabledForProfileByDefault(profile)) + return {}; + +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (scheme == content::kExternalFileScheme) { + return ash::ExternalFileURLLoaderFactory::Create( + profile, content::ChildProcessHost::kInvalidUniqueID); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#if !BUILDFLAG(IS_ANDROID) + if (scheme == chrome::kIsolatedAppScheme) { + if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled( + browser_context) && + !browser_context->ShutdownStarted()) { + return web_app::IsolatedWebAppURLLoaderFactory::CreateForFrame( + browser_context, /*app_origin=*/std::nullopt, frame_tree_node_id); + } + + return {}; + } +#endif // !BUILDFLAG(IS_ANDROID) +#endif // BUILDFLAG(ENABLE_EXTENSIONS) || BUILDFLAG(IS_CHROMEOS_ASH) || + // !BUILDFLAG(IS_ANDROID) + + return {}; +} + +void ChromeContentBrowserClient:: + RegisterNonNetworkWorkerMainResourceURLLoaderFactories( + content::BrowserContext* browser_context, + NonNetworkURLLoaderFactoryMap* factories) { + DCHECK(browser_context); + DCHECK(factories); + +#if !BUILDFLAG(IS_ANDROID) + if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled( + browser_context) && + !browser_context->ShutdownStarted()) { + factories->emplace(chrome::kIsolatedAppScheme, + web_app::IsolatedWebAppURLLoaderFactory::Create( + browser_context, /*app_origin=*/std::nullopt)); + } +#endif // !BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(ENABLE_EXTENSIONS) + DCHECK(!ChromeContentBrowserClientExtensionsPart:: + AreExtensionsDisabledForProfile(browser_context)); + + factories->emplace( + extensions::kExtensionScheme, + extensions::CreateExtensionWorkerMainResourceURLLoaderFactory( + browser_context)); +#endif // BUILDFLAG(ENABLE_EXTENSIONS) +} + +void ChromeContentBrowserClient:: + RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories( + content::BrowserContext* browser_context, + NonNetworkURLLoaderFactoryMap* factories) { + DCHECK(browser_context); + DCHECK(factories); + +#if !BUILDFLAG(IS_ANDROID) + if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled( + browser_context) && + !browser_context->ShutdownStarted()) { + factories->emplace(chrome::kIsolatedAppScheme, + web_app::IsolatedWebAppURLLoaderFactory::Create( + browser_context, /*app_origin=*/std::nullopt)); + } +#endif // !BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile( + browser_context)) { + return; + } + + factories->emplace( + extensions::kExtensionScheme, + extensions::CreateExtensionServiceWorkerScriptURLLoaderFactory( + browser_context)); +#endif // BUILDFLAG(ENABLE_EXTENSIONS) +} + +namespace { + +// The SpecialAccessFileURLLoaderFactory provided to the extension background +// pages. Checks with the ChildProcessSecurityPolicy to validate the file +// access. +class SpecialAccessFileURLLoaderFactory + : public network::SelfDeletingURLLoaderFactory { + public: + // Returns mojo::PendingRemote to a newly constructed + // SpecialAccessFileURLLoaderFactory. The factory is self-owned - it will + // delete itself once there are no more receivers (including the receiver + // associated with the returned mojo::PendingRemote and the receivers bound by + // the Clone method). + static mojo::PendingRemote Create( + int child_id) { + mojo::PendingRemote pending_remote; + + // The SpecialAccessFileURLLoaderFactory will delete itself when there are + // no more receivers - see the + // network::SelfDeletingURLLoaderFactory::OnDisconnect method. + new SpecialAccessFileURLLoaderFactory( + child_id, pending_remote.InitWithNewPipeAndPassReceiver()); + + return pending_remote; + } + + SpecialAccessFileURLLoaderFactory(const SpecialAccessFileURLLoaderFactory&) = + delete; + SpecialAccessFileURLLoaderFactory& operator=( + const SpecialAccessFileURLLoaderFactory&) = delete; + + private: + explicit SpecialAccessFileURLLoaderFactory( + int child_id, + mojo::PendingReceiver factory_receiver) + : network::SelfDeletingURLLoaderFactory(std::move(factory_receiver)), + child_id_(child_id) {} + + // network::mojom::URLLoaderFactory: + void CreateLoaderAndStart( + mojo::PendingReceiver loader, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& request, + mojo::PendingRemote client, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) + override { + if (!content::ChildProcessSecurityPolicy::GetInstance()->CanRequestURL( + child_id_, request.url)) { + mojo::Remote(std::move(client)) + ->OnComplete( + network::URLLoaderCompletionStatus(net::ERR_ACCESS_DENIED)); + return; + } + content::CreateFileURLLoaderBypassingSecurityChecks( + request, std::move(loader), std::move(client), + /*observer=*/nullptr, + /* allow_directory_listing */ true); + } + + int child_id_; +}; + +#if BUILDFLAG(IS_CHROMEOS) +bool IsSystemFeatureDisabled(policy::SystemFeature system_feature) { + return policy::SystemFeaturesDisableListPolicyHandler:: + IsSystemFeatureDisabled(system_feature, g_browser_process->local_state()); +} + +bool IsSystemFeatureURLDisabled(const GURL& url) { + if (!url.SchemeIs(content::kChromeUIScheme) && + !url.SchemeIs(content::kChromeUIUntrustedScheme)) { + return false; + } + + // chrome://os-settings/pwa.html shouldn't be replaced to let the settings app + // installation complete successfully. + if (url.DomainIs(chrome::kChromeUIOSSettingsHost) && + url.path() != "/pwa.html") { + return IsSystemFeatureDisabled(policy::SystemFeature::kOsSettings); + } + + if (url.DomainIs(chrome::kChromeUISettingsHost)) { + return IsSystemFeatureDisabled(policy::SystemFeature::kBrowserSettings); + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (url.DomainIs(chrome::kChromeUIUntrustedCroshHost)) { + return IsSystemFeatureDisabled(policy::SystemFeature::kCrosh); + } + + if (url.DomainIs(ash::kChromeUIScanningAppHost)) { + return IsSystemFeatureDisabled(policy::SystemFeature::kScanning); + } + + if (url.DomainIs(ash::kChromeUICameraAppHost)) { + return IsSystemFeatureDisabled(policy::SystemFeature::kCamera); + } + + if (url.DomainIs(ash::kChromeUIHelpAppHost)) { + return IsSystemFeatureDisabled(policy::SystemFeature::kExplore); + } + + if (url.DomainIs(ash::kChromeUIMediaAppHost)) { + return IsSystemFeatureDisabled(policy::SystemFeature::kGallery); + } + + if (url.DomainIs(chrome::kChromeUIUntrustedTerminalHost)) { + return IsSystemFeatureDisabled(policy::SystemFeature::kTerminal); + } + +#endif + + return false; +} +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) +void InitializeFileURLLoaderFactoryForExtension( + int render_process_id, + content::BrowserContext* browser_context, + const extensions::Extension* extension, + ChromeContentBrowserClient::NonNetworkURLLoaderFactoryMap* factories) { + // Extensions with the necessary permissions get access to file:// URLs that + // gets approval from ChildProcessSecurityPolicy. Keep this logic in sync with + // ExtensionWebContentsObserver::RenderFrameCreated. + Manifest::Type type = extension->GetType(); + if ((type == Manifest::TYPE_EXTENSION || + type == Manifest::TYPE_LEGACY_PACKAGED_APP) && + extensions::util::AllowFileAccess(extension->id(), browser_context)) { + factories->emplace( + url::kFileScheme, + SpecialAccessFileURLLoaderFactory::Create(render_process_id)); + } +} + +void AddChromeSchemeFactories( + int render_process_id, + content::RenderFrameHost* frame_host, + content::WebContents* web_contents, + const extensions::Extension* extension, + ChromeContentBrowserClient::NonNetworkURLLoaderFactoryMap* factories) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + InstantService* instant_service = + InstantServiceFactory::GetForProfile(profile); + // The test below matches when a remote 3P NTP is loaded. The effective + // URL is chrome-search://remote-ntp. This is to allow the use of the NTP + // public api and to embed most-visited tiles + // (chrome-search://most-visited/title.html). + // + // InstantService might be null for some irregular profiles, e.g. the System + // Profile. + if (instant_service && instant_service->IsInstantProcess(render_process_id)) { + factories->emplace( + chrome::kChromeSearchScheme, + content::CreateWebUIURLLoaderFactory( + frame_host, chrome::kChromeSearchScheme, + /*allowed_webui_hosts=*/base::flat_set())); + } + + extensions::ChromeExtensionWebContentsObserver* web_observer = + extensions::ChromeExtensionWebContentsObserver::FromWebContents( + web_contents); + + // There is nothing to do if no ChromeExtensionWebContentsObserver is attached + // to the |web_contents| or no enabled extension exists. + if (!web_observer || !extension) + return; + + std::vector allowed_webui_hosts; + // Support for chrome:// scheme if appropriate. + if ((extension->is_extension() || extension->is_platform_app()) && + Manifest::IsComponentLocation(extension->location())) { + // Components of chrome that are implemented as extensions or platform apps + // are allowed to use chrome://resources/ and chrome://theme/ URLs. + allowed_webui_hosts.emplace_back(content::kChromeUIResourcesHost); + allowed_webui_hosts.emplace_back(chrome::kChromeUIThemeHost); + // For testing purposes chrome://webui-test/ is also allowed. + allowed_webui_hosts.emplace_back(chrome::kChromeUIWebUITestHost); + } + if (extension->is_extension() || extension->is_legacy_packaged_app() || + (extension->is_platform_app() && + Manifest::IsComponentLocation(extension->location()))) { + // Extensions, legacy packaged apps, and component platform apps are allowed + // to use chrome://favicon/, chrome://extension-icon/ and chrome://app-icon + // URLs. Hosted apps are not allowed because they are served via web servers + // (and are generally never given access to Chrome APIs). + allowed_webui_hosts.emplace_back(chrome::kChromeUIExtensionIconHost); + allowed_webui_hosts.emplace_back(chrome::kChromeUIFaviconHost); + allowed_webui_hosts.emplace_back(chrome::kChromeUIAppIconHost); + } + if (!allowed_webui_hosts.empty()) { + factories->emplace(content::kChromeUIScheme, + content::CreateWebUIURLLoaderFactory( + frame_host, content::kChromeUIScheme, + std::move(allowed_webui_hosts))); + } +} +#endif // BUILDFLAG(ENABLE_EXTENSIONS) +} // namespace + +void ChromeContentBrowserClient:: + RegisterNonNetworkSubresourceURLLoaderFactories( + int render_process_id, + int render_frame_id, + const std::optional& request_initiator_origin, + NonNetworkURLLoaderFactoryMap* factories) { +#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ + !BUILDFLAG(IS_ANDROID) + content::RenderFrameHost* frame_host = + RenderFrameHost::FromID(render_process_id, render_frame_id); + WebContents* web_contents = WebContents::FromRenderFrameHost(frame_host); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(ENABLE_EXTENSIONS) || \ + // !BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (web_contents) { + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + factories->emplace( + content::kExternalFileScheme, + ash::ExternalFileURLLoaderFactory::Create(profile, render_process_id)); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if !BUILDFLAG(IS_ANDROID) + { + auto* rph = content::RenderProcessHost::FromID(render_process_id); + content::BrowserContext* browser_context = rph->GetBrowserContext(); + DCHECK(browser_context); + bool is_initiator_iwa = + request_initiator_origin.has_value() && + request_initiator_origin->scheme() == chrome::kIsolatedAppScheme; + if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled( + browser_context) && + !browser_context->ShutdownStarted() && is_initiator_iwa) { + if (frame_host != nullptr) { + factories->emplace( + chrome::kIsolatedAppScheme, + web_app::IsolatedWebAppURLLoaderFactory::CreateForFrame( + browser_context, request_initiator_origin, + frame_host->GetFrameTreeNodeId())); + } else { + factories->emplace(chrome::kIsolatedAppScheme, + web_app::IsolatedWebAppURLLoaderFactory::Create( + browser_context, request_initiator_origin)); + } + } + } +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + content::BrowserContext* browser_context = + content::RenderProcessHost::FromID(render_process_id) + ->GetBrowserContext(); + if (ChromeContentBrowserClientExtensionsPart::AreExtensionsDisabledForProfile( + browser_context)) + return; + + factories->emplace(extensions::kExtensionScheme, + extensions::CreateExtensionURLLoaderFactory( + render_process_id, render_frame_id)); + + const extensions::Extension* extension = nullptr; + if (request_initiator_origin != std::nullopt) { + extensions::ExtensionRegistry* registry = + extensions::ExtensionRegistry::Get( + Profile::FromBrowserContext(browser_context)); + DCHECK(registry); + extension = registry->enabled_extensions().GetExtensionOrAppByURL( + request_initiator_origin->GetURL()); + } + + // For service worker contexts, we only allow file access. The remainder of + // this code is used to allow extensions to access chrome:-scheme + // resources, which we are moving away from. + // TODO(crbug.com/40811448) Factories should not be created for unloaded + // extensions. + if (extension) { + InitializeFileURLLoaderFactoryForExtension( + render_process_id, browser_context, extension, factories); + } + + // This logic should match + // ChromeExtensionWebContentsObserver::RenderFrameCreated. + if (web_contents) { + AddChromeSchemeFactories(render_process_id, frame_host, web_contents, + extension, factories); + } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) +} + +void ChromeContentBrowserClient::WillCreateURLLoaderFactory( + content::BrowserContext* browser_context, + content::RenderFrameHost* frame, + int render_process_id, + URLLoaderFactoryType type, + const url::Origin& request_initiator, + const net::IsolationInfo& isolation_info, + std::optional navigation_id, + ukm::SourceIdObj ukm_source_id, + network::URLLoaderFactoryBuilder& factory_builder, + mojo::PendingRemote* + header_client, + bool* bypass_redirect_checks, + bool* disable_secure_dns, + network::mojom::URLLoaderFactoryOverridePtr* factory_override, + scoped_refptr navigation_response_task_runner) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + auto* web_request_api = + extensions::BrowserContextKeyedAPIFactory::Get( + browser_context); + + // NOTE: Some unit test environments do not initialize + // BrowserContextKeyedAPI factories for e.g. WebRequest. + if (web_request_api) { + bool use_proxy_for_web_request = + web_request_api->MaybeProxyURLLoaderFactory( + browser_context, frame, render_process_id, type, + std::move(navigation_id), ukm_source_id, factory_builder, + header_client, navigation_response_task_runner, request_initiator); + if (bypass_redirect_checks) + *bypass_redirect_checks = use_proxy_for_web_request; + } +#endif + + signin::ProxyingURLLoaderFactory::MaybeProxyRequest( + frame, type == URLLoaderFactoryType::kNavigation, request_initiator, + isolation_info, factory_builder); + +#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) + if (disable_secure_dns) { + WebContents* web_contents = WebContents::FromRenderFrameHost(frame); + *disable_secure_dns = + web_contents && + captive_portal::CaptivePortalTabHelper::FromWebContents(web_contents) && + captive_portal::CaptivePortalTabHelper::FromWebContents(web_contents) + ->is_captive_portal_window(); + } +#endif + + // WARNING: This must be the last interceptor in the chain as the proxying + // URLLoaderFactory installed by this needs to be the one actually sending + // packets over the network (to effectively target `bound_network`). + MaybeProxyNetworkBoundRequest(browser_context, + GetBoundNetworkFromRenderFrameHost(frame), + factory_builder, factory_override, + isolation_info); +} + +std::vector> +ChromeContentBrowserClient::WillCreateURLLoaderRequestInterceptors( + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id, + int64_t navigation_id, + bool force_no_https_upgrade, + scoped_refptr navigation_response_task_runner) { + std::vector> + interceptors; +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + interceptors.push_back( + std::make_unique( + navigation_ui_data, frame_tree_node_id)); +#endif + +#if BUILDFLAG(ENABLE_PDF) + { + std::unique_ptr pdf_interceptor = + pdf::PdfURLLoaderRequestInterceptor::MaybeCreateInterceptor( + frame_tree_node_id, std::make_unique()); + if (pdf_interceptor) + interceptors.push_back(std::move(pdf_interceptor)); + } +#endif + + interceptors.push_back(std::make_unique( + frame_tree_node_id, navigation_id, navigation_response_task_runner)); + + if (!force_no_https_upgrade) { + auto https_upgrades_interceptor = + HttpsUpgradesInterceptor::MaybeCreateInterceptor(frame_tree_node_id, + navigation_ui_data); + if (https_upgrades_interceptor) { + interceptors.push_back(std::move(https_upgrades_interceptor)); + } + } + + return interceptors; +} + +content::ContentBrowserClient::URLLoaderRequestHandler +ChromeContentBrowserClient:: + CreateURLLoaderHandlerForServiceWorkerNavigationPreload( + int frame_tree_node_id, + const network::ResourceRequest& resource_request) { + SearchPrefetchURLLoader::RequestHandler prefetch_handler = + SearchPrefetchURLLoaderInterceptor::MaybeCreateLoaderForRequest( + resource_request, frame_tree_node_id); + return prefetch_handler; +} + +bool ChromeContentBrowserClient::WillInterceptWebSocket( + content::RenderFrameHost* frame) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (!frame) { + return false; + } + const auto* web_request_api = + extensions::BrowserContextKeyedAPIFactory::Get( + frame->GetBrowserContext()); + + // NOTE: Some unit test environments do not initialize + // BrowserContextKeyedAPI factories for e.g. WebRequest. + if (!web_request_api) + return false; + + return (web_request_api->MayHaveProxies() || + web_request_api->MayHaveWebsocketProxiesForExtensionTelemetry() || + web_request_api->IsAvailableToWebViewEmbedderFrame(frame)); +#else + return false; +#endif +} + +void ChromeContentBrowserClient::CreateWebSocket( + content::RenderFrameHost* frame, + WebSocketFactory factory, + const GURL& url, + const net::SiteForCookies& site_for_cookies, + const std::optional& user_agent, + mojo::PendingRemote + handshake_client) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + // TODO(crbug.com/40195467): Request w/o a frame also should be proxied. + if (!frame) { + return; + } + auto* web_request_api = + extensions::BrowserContextKeyedAPIFactory::Get( + frame->GetBrowserContext()); + + DCHECK(web_request_api); + web_request_api->ProxyWebSocket(frame, std::move(factory), url, + site_for_cookies, user_agent, + std::move(handshake_client)); +#endif +} + +void ChromeContentBrowserClient::WillCreateWebTransport( + int process_id, + int frame_routing_id, + const GURL& url, + const url::Origin& initiator_origin, + mojo::PendingRemote + handshake_client, + WillCreateWebTransportCallback callback) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + DCHECK_CURRENTLY_ON(BrowserThread::UI); + // TODO(crbug.com/40195467): Add a unit test which calls + // ChromeContentBrowserClient::WillCreateWebTransport() with invalid process + // id and routing id. + auto* render_process_host = content::RenderProcessHost::FromID(process_id); + if (!render_process_host) { + std::move(callback).Run(std::move(handshake_client), std::nullopt); + return; + } + content::BrowserContext* browser_context = + render_process_host->GetBrowserContext(); + auto* web_request_api = + extensions::BrowserContextKeyedAPIFactory::Get( + browser_context); + // NOTE: Some unit test environments do not initialize BrowserContextKeyedAPI + // factories like WebRequestAPI. + if (!web_request_api) { + std::move(callback).Run(std::move(handshake_client), std::nullopt); + return; + } + web_request_api->ProxyWebTransport( + *render_process_host, frame_routing_id, url, initiator_origin, + std::move(handshake_client), std::move(callback)); +#else + std::move(callback).Run(std::move(handshake_client), std::nullopt); +#endif +} + +bool ChromeContentBrowserClient::WillCreateRestrictedCookieManager( + network::mojom::RestrictedCookieManagerRole role, + content::BrowserContext* browser_context, + const url::Origin& origin, + const net::IsolationInfo& isolation_info, + bool is_service_worker, + int process_id, + int routing_id, + mojo::PendingReceiver* receiver) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (origin.scheme() == extensions::kExtensionScheme) { + DCHECK_EQ(network::mojom::RestrictedCookieManagerRole::SCRIPT, role); + extensions::ChromeExtensionCookies::Get(browser_context) + ->CreateRestrictedCookieManager(origin, isolation_info, + std::move(*receiver)); + return true; + } +#endif + return false; +} + +void ChromeContentBrowserClient::OnNetworkServiceCreated( + network::mojom::NetworkService* network_service) { + PrefService* local_state; + if (g_browser_process) { + DCHECK(g_browser_process->local_state()); + local_state = g_browser_process->local_state(); + } else { + DCHECK(startup_data_.chrome_feature_list_creator()->local_state()); + local_state = startup_data_.chrome_feature_list_creator()->local_state(); + } + + // Create SystemNetworkContextManager if it has not been created yet. We need + // to set up global NetworkService state before anything else uses it and this + // is the first opportunity to initialize SystemNetworkContextManager with the + // NetworkService. + if (!SystemNetworkContextManager::HasInstance()) + SystemNetworkContextManager::CreateInstance(local_state); + + SystemNetworkContextManager::GetInstance()->OnNetworkServiceCreated( + network_service); + +#if !BUILDFLAG(IS_ANDROID) + if (task_manager::TaskManagerImpl::IsCreated() && + task_manager::TaskManagerImpl::GetInstance()->is_running()) { + network_service->EnableDataUseUpdates(true); + } +#endif +} + +void ChromeContentBrowserClient::ConfigureNetworkContextParams( + content::BrowserContext* context, + bool in_memory, + const base::FilePath& relative_partition_path, + network::mojom::NetworkContextParams* network_context_params, + cert_verifier::mojom::CertVerifierCreationParams* + cert_verifier_creation_params) { + ProfileNetworkContextService* service = + ProfileNetworkContextServiceFactory::GetForContext(context); + if (service) { + service->ConfigureNetworkContextParams(in_memory, relative_partition_path, + network_context_params, + cert_verifier_creation_params); + } else { + // Set default params. + network_context_params->user_agent = GetUserAgentBasedOnPolicy(context); + network_context_params->accept_language = GetApplicationLocale(); + } +} + +std::vector +ChromeContentBrowserClient::GetNetworkContextsParentDirectory() { + DCHECK(!network_contexts_parent_directory_.empty()); + return network_contexts_parent_directory_; +} + +base::Value::Dict ChromeContentBrowserClient::GetNetLogConstants() { + return net_log::GetPlatformConstantsForNetLog( + base::CommandLine::ForCurrentProcess()->GetCommandLineString(), + chrome::GetChannelName(chrome::WithExtendedStable(true))); +} + +bool ChromeContentBrowserClient::AllowRenderingMhtmlOverHttp( + content::NavigationUIData* navigation_ui_data) { +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + // It is OK to load the saved offline copy, in MHTML format. + ChromeNavigationUIData* chrome_navigation_ui_data = + static_cast(navigation_ui_data); + if (!chrome_navigation_ui_data) + return false; + offline_pages::OfflinePageNavigationUIData* offline_page_data = + chrome_navigation_ui_data->GetOfflinePageNavigationUIData(); + return offline_page_data && offline_page_data->is_offline_page(); +#else + return false; +#endif +} + +bool ChromeContentBrowserClient::ShouldForceDownloadResource( + content::BrowserContext* browser_context, + const GURL& url, + const std::string& mime_type) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + // Special-case user scripts to get downloaded instead of viewed. + if (extensions::UserScript::IsURLUserScript(url, mime_type)) { + return true; + } + +#if BUILDFLAG(IS_CHROMEOS) + // QuickOffice file interception is deprecated. If QuickOffice would + // have intercepted this file and this feature is disabled, download + // it instead. + if (browser_context) { + Profile* profile = Profile::FromBrowserContext(browser_context); + bool force_download = profile->GetPrefs()->GetBoolean( + quickoffice::kQuickOfficeForceFileDownloadEnabled); + + if (base::FeatureList::IsEnabled(features::kQuickOfficeForceFileDownload) && + force_download) { + std::string extension_id = + PluginUtils::GetExtensionIdForMimeType(browser_context, mime_type); + + if (extension_misc::IsQuickOfficeExtension(extension_id)) { + return true; + } + } + } +#endif // BUILDFLAG(IS_CHROMEOS) +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + return false; +} + +content::BluetoothDelegate* ChromeContentBrowserClient::GetBluetoothDelegate() { + if (!bluetooth_delegate_) { + bluetooth_delegate_ = std::make_unique( + std::make_unique()); + } + return bluetooth_delegate_.get(); +} + +content::UsbDelegate* ChromeContentBrowserClient::GetUsbDelegate() { + if (!usb_delegate_) + usb_delegate_ = std::make_unique(); + return usb_delegate_.get(); +} + +content::PrivateNetworkDeviceDelegate* +ChromeContentBrowserClient::GetPrivateNetworkDeviceDelegate() { + if (!private_network_device_delegate_) { + private_network_device_delegate_ = + std::make_unique(); + } + return private_network_device_delegate_.get(); +} + +bool ChromeContentBrowserClient::IsSecurityLevelAcceptableForWebAuthn( + content::RenderFrameHost* rfh, + const url::Origin& caller_origin) { + const Profile* profile = + Profile::FromBrowserContext(rfh->GetBrowserContext()); + if (profile->GetPrefs()->GetBoolean( + webauthn::pref_names::kAllowWithBrokenCerts)) { + return true; + } +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (caller_origin.scheme() == extensions::kExtensionScheme) { + return true; + } +#endif + if (net::IsLocalhost(caller_origin.GetURL())) { + return true; + } + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(rfh); + SecurityStateTabHelper::CreateForWebContents(web_contents); + SecurityStateTabHelper* helper = + SecurityStateTabHelper::FromWebContents(web_contents); + security_state::SecurityLevel security_level = helper->GetSecurityLevel(); + return security_level == security_state::SecurityLevel::SECURE || + security_level == + security_state::SecurityLevel::SECURE_WITH_POLICY_INSTALLED_CERT || + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kIgnoreCertificateErrors); +} + +#if !BUILDFLAG(IS_ANDROID) +void ChromeContentBrowserClient::CreateDeviceInfoService( + content::RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) { + DCHECK(render_frame_host); + DeviceServiceImpl::Create(render_frame_host, std::move(receiver)); +} + +void ChromeContentBrowserClient::CreateManagedConfigurationService( + content::RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) { + DCHECK(render_frame_host); + ManagedConfigurationServiceImpl::Create(render_frame_host, + std::move(receiver)); +} + +content::SerialDelegate* ChromeContentBrowserClient::GetSerialDelegate() { + if (!serial_delegate_) + serial_delegate_ = std::make_unique(); + return serial_delegate_.get(); +} + +content::HidDelegate* ChromeContentBrowserClient::GetHidDelegate() { + if (!hid_delegate_) + hid_delegate_ = std::make_unique(); + return hid_delegate_.get(); +} + +content::DirectSocketsDelegate* +ChromeContentBrowserClient::GetDirectSocketsDelegate() { + if (!direct_sockets_delegate_) { + direct_sockets_delegate_ = std::make_unique(); + } + return direct_sockets_delegate_.get(); +} + +content::WebAuthenticationDelegate* +ChromeContentBrowserClient::GetWebAuthenticationDelegate() { + if (!web_authentication_delegate_) { + web_authentication_delegate_ = + std::make_unique(); + } + return web_authentication_delegate_.get(); +} + +std::unique_ptr +ChromeContentBrowserClient::GetWebAuthenticationRequestDelegate( + content::RenderFrameHost* render_frame_host) { + return AuthenticatorRequestScheduler::CreateRequestDelegate( + render_frame_host); +} +#endif + +void ChromeContentBrowserClient::CreatePaymentCredential( + content::RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) { + payments::CreatePaymentCredential(render_frame_host, std::move(receiver)); +} + +std::unique_ptr +ChromeContentBrowserClient::CreateClientCertStore( + content::BrowserContext* browser_context) { + return ProfileNetworkContextServiceFactory::GetForContext(browser_context) + ->CreateClientCertStore(); +} + +std::unique_ptr +ChromeContentBrowserClient::CreateLoginDelegate( + const net::AuthChallengeInfo& auth_info, + content::WebContents* web_contents, + content::BrowserContext* browser_context, + const content::GlobalRequestID& request_id, + bool is_request_for_primary_main_frame, + const GURL& url, + scoped_refptr response_headers, + bool first_auth_attempt, + LoginAuthRequiredCallback auth_required_callback) { +#if BUILDFLAG(IS_CHROMEOS) + // Negotiate challenge is handled via GSSAPI library, which can not receive + // external credentials. However, on ChromeOS we can suggest the user to + // create a TGT using their credentials. Note that the credentials are NOT + // passed to the browser and everything happens on OS level, hence we return + // nullptr instead of LoginDelegate to fail authentication. (See b/260522530). + if (base::FeatureList::IsEnabled(net::features::kKerberosInBrowserRedirect) && + auth_info.scheme == + net::HttpAuth::SchemeToString(net::HttpAuth::AUTH_SCHEME_NEGOTIATE)) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + ash::KerberosInBrowserDialog::Show(); +#else + // Requests to show Kerberos ui via crosapi mojo call. + chromeos::LacrosService::Get() + ->GetRemote() + ->ShowKerberosInBrowserDialog(); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + return nullptr; + } +#endif // BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + auto* system_proxy_manager = ash::SystemProxyManager::Get(); + // For Managed Guest Session and Kiosk devices, the credentials configured + // via the policy SystemProxySettings may be used for proxy authentication. + // Note: |system_proxy_manager| may be missing in tests. + if (system_proxy_manager && system_proxy_manager->CanUsePolicyCredentials( + auth_info, first_auth_attempt)) { + return system_proxy_manager->CreateLoginDelegate( + std::move(auth_required_callback)); + } + + if (ash::HttpAuthDialog::IsEnabled()) { + return ash::HttpAuthDialog::Create(auth_info, web_contents, url, + std::move(auth_required_callback)); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + if (!http_auth_coordinator_) { + http_auth_coordinator_ = CreateHttpAuthCoordinator(); + } + // Once Lacros ships this logic will no longer need to be included in + // ash-chrome. + return http_auth_coordinator_->CreateLoginDelegate( + web_contents, browser_context, auth_info, request_id, + is_request_for_primary_main_frame, url, response_headers, + std::move(auth_required_callback)); +} + +bool ChromeContentBrowserClient::HandleExternalProtocol( + const GURL& url, + content::WebContents::Getter web_contents_getter, + int frame_tree_node_id, + content::NavigationUIData* navigation_data, + bool is_primary_main_frame, + bool is_in_fenced_frame_tree, + network::mojom::WebSandboxFlags sandbox_flags, + ui::PageTransition page_transition, + bool has_user_gesture, + const std::optional& initiating_origin, + content::RenderFrameHost* initiator_document, + mojo::PendingRemote* out_factory) { + CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + // External protocols are disabled for guests. An exception is made for the + // "mailto" protocol, so that pages that utilize it work properly in a + // WebView. + ChromeNavigationUIData* chrome_data = + static_cast(navigation_data); + if ((chrome_data && + chrome_data->GetExtensionNavigationUIData()->is_web_view()) && + !url.SchemeIs(url::kMailToScheme)) { + return false; + } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + +#if BUILDFLAG(IS_ANDROID) + // Main frame external protocols are handled by + // InterceptNavigationResourceThrottle. + if (is_primary_main_frame) + return false; +#endif // defined(ANDROID) + + auto weak_initiator_document = initiator_document + ? initiator_document->GetWeakDocumentPtr() + : content::WeakDocumentPtr(); + + // On Android, populate the `out_factory` param. + LaunchURL(weak_factory_.GetWeakPtr(), url, std::move(web_contents_getter), + page_transition, is_primary_main_frame, is_in_fenced_frame_tree, + sandbox_flags, has_user_gesture, initiating_origin, + std::move(weak_initiator_document), out_factory); + return true; +} + +std::unique_ptr +ChromeContentBrowserClient::CreateWindowForVideoPictureInPicture( + content::VideoPictureInPictureWindowController* controller) { + // Note: content::VideoOverlayWindow::Create() is defined by platform-specific + // implementation in chrome/browser/ui/views. This layering hack, which goes + // through //content and ContentBrowserClient, allows us to work around the + // dependency constraints that disallow directly calling + // chrome/browser/ui/views code either from here or from other code in + // chrome/browser. + return content::VideoOverlayWindow::Create(controller); +} + +void ChromeContentBrowserClient::RegisterRendererPreferenceWatcher( + content::BrowserContext* browser_context, + mojo::PendingRemote watcher) { + Profile* profile = Profile::FromBrowserContext(browser_context); + if (PrefWatcher* pref_watcher = PrefWatcher::Get(profile)) + pref_watcher->RegisterRendererPreferenceWatcher(std::move(watcher)); +} + +// Static; handles rewriting Web UI URLs. +bool ChromeContentBrowserClient::HandleWebUI( + GURL* url, + content::BrowserContext* browser_context) { + DCHECK(browser_context); + + // Rewrite chrome://help to chrome://settings/help. + if (url->SchemeIs(content::kChromeUIScheme) && + url->host() == chrome::kChromeUIHelpHost) { + *url = ReplaceURLHostAndPath(*url, chrome::kChromeUISettingsHost, + chrome::kChromeUIHelpHost); + } + +#if !BUILDFLAG(IS_ANDROID) + Profile* profile = Profile::FromBrowserContext(browser_context); + auto* tracking_protection_settings = + TrackingProtectionSettingsFactory::GetForProfile(profile); + if (tracking_protection_settings && + tracking_protection_settings->IsTrackingProtection3pcdEnabled()) { + // Redirect from cookies to trackingProtection in experiment. + if (url->SchemeIs(content::kChromeUIScheme) && + url->host() == chrome::kChromeUISettingsHost && + url->path() == chrome::kCookiesSubPagePath) { + GURL::Replacements replacements; + replacements.SetPathStr(chrome::kTrackingProtectionSubPagePath); + *url = url->ReplaceComponents(replacements); + UMA_HISTOGRAM_BOOLEAN("Settings.TrackingProtection.Redirect", true); + } else if (url->path() == chrome::kTrackingProtectionSubPagePath) { + UMA_HISTOGRAM_BOOLEAN("Settings.TrackingProtection.Redirect", false); + } + } else { + // Redirect from trackingProtection to cookies outside experiment. + if (url->SchemeIs(content::kChromeUIScheme) && + url->host() == chrome::kChromeUISettingsHost && + url->path() == chrome::kTrackingProtectionSubPagePath) { + GURL::Replacements replacements; + replacements.SetPathStr(chrome::kCookiesSubPagePath); + *url = url->ReplaceComponents(replacements); + } + } +#endif + +#if BUILDFLAG(IS_WIN) + // TODO(crbug.com/40647483): Remove when issue is resolved. + if (url->SchemeIs(content::kChromeUIScheme) && + url->host() == chrome::kChromeUIWelcomeWin10Host) { + *url = + ReplaceURLHostAndPath(*url, chrome::kChromeUIWelcomeHost, url->path()); + return true; + } +#endif // BUILDFLAG(IS_WIN) + + if (!ChromeWebUIControllerFactory::GetInstance()->UseWebUIForURL( + browser_context, *url) && + !content::WebUIConfigMap::GetInstance().GetConfig(browser_context, + *url)) { + return false; + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Special case : in ChromeOS in Guest mode bookmarks and history are + // disabled for security reasons. New tab page explains the reasons, so + // we redirect user to new tab page. + if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) { + if (url->SchemeIs(content::kChromeUIScheme) && + (url->DomainIs(chrome::kChromeUIBookmarksHost) || + url->DomainIs(chrome::kChromeUIHistoryHost))) { + // Rewrite with new tab URL + *url = GURL(chrome::kChromeUINewTabURL); + } + } +#endif + +#if BUILDFLAG(IS_CHROMEOS) + if (IsSystemFeatureURLDisabled(*url)) { + *url = GURL(chrome::kChromeUIAppDisabledURL); + return true; + } +#endif + + return true; +} + +#if BUILDFLAG(IS_CHROMEOS) +content::SmartCardDelegate* ChromeContentBrowserClient::GetSmartCardDelegate() { + if (!smart_card_delegate_) { + smart_card_delegate_ = std::make_unique(); + } + return smart_card_delegate_.get(); +} +#endif + +bool ChromeContentBrowserClient::ShowPaymentHandlerWindow( + content::BrowserContext* browser_context, + const GURL& url, + base::OnceCallback callback) { +#if BUILDFLAG(IS_ANDROID) + return false; +#else + payments::PaymentRequestDisplayManagerFactory::GetInstance() + ->GetForBrowserContext(browser_context) + ->ShowPaymentHandlerWindow(url, std::move(callback)); + return true; +#endif +} + +// static +bool ChromeContentBrowserClient::HandleWebUIReverse( + GURL* url, + content::BrowserContext* browser_context) { +#if BUILDFLAG(IS_WIN) + // TODO(crbug.com/40647483): Remove when issue is resolved. + // No need to actually reverse-rewrite the URL, but return true to update the + // displayed URL when rewriting chrome://welcome-win10 to chrome://welcome. + if (url->SchemeIs(content::kChromeUIScheme) && + url->host() == chrome::kChromeUIWelcomeHost) { + return true; + } +#endif // BUILDFLAG(IS_WIN) + +#if !BUILDFLAG(IS_ANDROID) + // TODO(crbug.com/40258836): Remove this after feature is launched. + // No need to actually reverse-rewrite the URL, but return true to update the + // displayed URL when rewriting chrome://settings/passwords to + // chrome://password-manager. + if (url->SchemeIs(content::kChromeUIScheme) && + url->DomainIs(password_manager::kChromeUIPasswordManagerHost)) { + return true; + } +#endif + + // No need to actually reverse-rewrite the URL, but return true to update the + // displayed URL when rewriting chrome://help to chrome://settings/help. + return url->SchemeIs(content::kChromeUIScheme) && + url->host() == chrome::kChromeUISettingsHost; +} + +const ui::NativeTheme* ChromeContentBrowserClient::GetWebTheme() const { + return ui::NativeTheme::GetInstanceForWeb(); +} + +void ChromeContentBrowserClient::AddExtraPart( + ChromeContentBrowserClientParts* part) { + extra_parts_.push_back(base::WrapUnique(part)); +} + +std::unique_ptr +ChromeContentBrowserClient::CreateHttpAuthCoordinator() { + return std::make_unique(); +} + +scoped_refptr +ChromeContentBrowserClient::GetSafeBrowsingUrlCheckerDelegate( + bool safe_browsing_enabled_for_profile, + bool should_check_on_sb_disabled, + const std::vector& allowlist_domains) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // Should not bypass safe browsing check if the check is for enterprise + // lookup. + if (!safe_browsing_enabled_for_profile && !should_check_on_sb_disabled) + return nullptr; + + // |safe_browsing_service_| may be unavailable in tests. + if (safe_browsing_service_ && !safe_browsing_url_checker_delegate_) { + safe_browsing_url_checker_delegate_ = + base::MakeRefCounted( + safe_browsing_service_->database_manager(), + safe_browsing_service_->ui_manager()); + } + + // Update allowlist domains. + if (safe_browsing_url_checker_delegate_) { + safe_browsing_url_checker_delegate_->SetPolicyAllowlistDomains( + allowlist_domains); + } + + return safe_browsing_url_checker_delegate_; +} + +safe_browsing::RealTimeUrlLookupServiceBase* +ChromeContentBrowserClient::GetUrlLookupService( + content::BrowserContext* browser_context, + bool is_enterprise_lookup_enabled, + bool is_consumer_lookup_enabled) { + // |safe_browsing_service_| may be unavailable in tests. + if (!safe_browsing_service_) { + return nullptr; + } + + Profile* profile = Profile::FromBrowserContext(browser_context); + +#if BUILDFLAG(SAFE_BROWSING_DB_LOCAL) + if (is_enterprise_lookup_enabled) { + return safe_browsing::ChromeEnterpriseRealTimeUrlLookupServiceFactory:: + GetForProfile(profile); + } +#endif + + if (is_consumer_lookup_enabled) { + return safe_browsing::RealTimeUrlLookupServiceFactory::GetForProfile( + profile); + } + return nullptr; +} + +safe_browsing::AsyncCheckTracker* +ChromeContentBrowserClient::GetAsyncCheckTracker( + const base::RepeatingCallback& wc_getter, + bool is_enterprise_lookup_enabled, + bool is_consumer_lookup_enabled, + safe_browsing::hash_realtime_utils::HashRealTimeSelection + hash_realtime_selection, + int frame_tree_node_id) { + content::WebContents* contents = wc_getter.Run(); + if (!contents || !safe_browsing_service_ || + !safe_browsing_service_->ui_manager()) { + return nullptr; + } + if (is_enterprise_lookup_enabled) { + // No async checks for enterprise real-time checks. URL filtering rules + // need to be applied before the navigation is completed. + return nullptr; + } + if (!is_consumer_lookup_enabled && + hash_realtime_selection == + safe_browsing::hash_realtime_utils::HashRealTimeSelection::kNone) { + return nullptr; + } + if (prerender::ChromeNoStatePrefetchContentsDelegate::FromWebContents( + contents) || + contents->IsPrerenderedFrame(frame_tree_node_id)) { + return nullptr; + } + if (!base::FeatureList::IsEnabled( + safe_browsing::kSafeBrowsingAsyncRealTimeCheck)) { + return nullptr; + } + return safe_browsing::AsyncCheckTracker::GetOrCreateForWebContents( + contents, safe_browsing_service_->ui_manager().get()); +} + +void ChromeContentBrowserClient::ReportLegacyTechEvent( + content::RenderFrameHost* render_frame_host, + const std::string type, + const GURL& url, + const GURL& frame_url, + const std::string& filename, + uint64_t line, + uint64_t column, + std::optional cookie_issue_details) { + WebContents* web_contents = + WebContents::FromRenderFrameHost(render_frame_host); + DCHECK(web_contents); + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + if (!profile) { + return; + } + enterprise_reporting::LegacyTechService* service = + enterprise_reporting::LegacyTechServiceFactory::GetForProfile(profile); + if (!service) { + return; + } + service->ReportEvent(type, url, frame_url, filename, line, column, + cookie_issue_details); +} + +bool ChromeContentBrowserClient::CanAcceptUntrustedExchangesIfNeeded() { + // We require --user-data-dir flag too so that no dangerous changes are made + // in the user's regular profile. + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kUserDataDir); +} + +void ChromeContentBrowserClient::OnNetworkServiceDataUseUpdate( + content::GlobalRenderFrameHostId render_frame_host_id, + int32_t network_traffic_annotation_id_hash, + int64_t recv_bytes, + int64_t sent_bytes) { +#if !BUILDFLAG(IS_ANDROID) + task_manager::TaskManagerInterface::UpdateAccumulatedStatsNetworkForRoute( + render_frame_host_id, recv_bytes, sent_bytes); +#endif +} + +base::FilePath +ChromeContentBrowserClient::GetSandboxedStorageServiceDataDirectory() { + if (!g_browser_process || !g_browser_process->profile_manager()) + return base::FilePath(); + return g_browser_process->profile_manager()->user_data_dir(); +} + +bool ChromeContentBrowserClient::ShouldSandboxAudioService() { + return IsAudioServiceSandboxEnabled(); +} + +bool ChromeContentBrowserClient::ShouldSandboxNetworkService() { + return SystemNetworkContextManager::IsNetworkSandboxEnabled(); +} + +bool ChromeContentBrowserClient::ShouldRunOutOfProcessSystemDnsResolution() { +// This enterprise policy is supported on Android, but the feature will not be +// launched there. +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) + // This is possibly called before `g_browser_process` is initialized. + PrefService* local_state; + if (g_browser_process) { + local_state = g_browser_process->local_state(); + } else { + local_state = startup_data_.chrome_feature_list_creator()->local_state(); + } + if (local_state && local_state->HasPrefPath( + prefs::kOutOfProcessSystemDnsResolutionEnabled)) { + return local_state->GetBoolean( + prefs::kOutOfProcessSystemDnsResolutionEnabled); + } +#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_ANDROID) + + return ContentBrowserClient::ShouldRunOutOfProcessSystemDnsResolution(); +} + +void ChromeContentBrowserClient::LogWebFeatureForCurrentPage( + content::RenderFrameHost* render_frame_host, + blink::mojom::WebFeature feature) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage( + render_frame_host, feature); +} + +void ChromeContentBrowserClient::LogWebDXFeatureForCurrentPage( + content::RenderFrameHost* render_frame_host, + blink::mojom::WebDXFeature feature) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + page_load_metrics::MetricsWebContentsObserver::RecordFeatureUsage( + render_frame_host, feature); +} + +std::string ChromeContentBrowserClient::GetProduct() { + return std::string(version_info::GetProductNameAndVersionForUserAgent()); +} + +std::string ChromeContentBrowserClient::GetUserAgent() { + return embedder_support::GetUserAgent(); +} + +std::string ChromeContentBrowserClient::GetUserAgentBasedOnPolicy( + content::BrowserContext* context) { + const PrefService* prefs = Profile::FromBrowserContext(context)->GetPrefs(); + embedder_support::UserAgentReductionEnterprisePolicyState + user_agent_reduction = + embedder_support::GetUserAgentReductionFromPrefs(prefs); + return embedder_support::GetUserAgent(user_agent_reduction); +} + +blink::UserAgentMetadata ChromeContentBrowserClient::GetUserAgentMetadata() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + return embedder_support::GetUserAgentMetadata( + g_browser_process->local_state()); +} + +std::optional ChromeContentBrowserClient::GetProductLogo() { + // This icon is available on Android, but adds 19KiB to the APK. Since it + // isn't used on Android we exclude it to avoid bloat. +#if !BUILDFLAG(IS_ANDROID) + return std::optional( + *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + IDR_PRODUCT_LOGO_256)); +#else + return std::nullopt; +#endif +} + +bool ChromeContentBrowserClient::IsBuiltinComponent( + content::BrowserContext* browser_context, + const url::Origin& origin) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeContentBrowserClientExtensionsPart::IsBuiltinComponent( + browser_context, origin); +#else + return false; +#endif +} + +bool ChromeContentBrowserClient::ShouldBlockRendererDebugURL( + const GURL& url, + content::BrowserContext* context, + content::RenderFrameHost* render_frame_host) { +#if !BUILDFLAG(IS_ANDROID) + // If devtools access is blocked for the page, debug URLs should also be + // blocked for the page. + Profile* profile = Profile::FromBrowserContext(context); + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(render_frame_host); + if (!DevToolsWindow::AllowDevToolsFor(profile, web_contents)) { + return true; + } +#endif + + // If the debug URL being visited is listed in the URLBlocklist policy it + // should be blocked. + PolicyBlocklistService* service = + PolicyBlocklistFactory::GetForBrowserContext(context); + using URLBlocklistState = policy::URLBlocklist::URLBlocklistState; + URLBlocklistState blocklist_state = service->GetURLBlocklistState(url); + return blocklist_state == URLBlocklistState::URL_IN_BLOCKLIST; +} + +#if BUILDFLAG(IS_ANDROID) +content::ContentBrowserClient::WideColorGamutHeuristic +ChromeContentBrowserClient::GetWideColorGamutHeuristic() { + if (viz::AlwaysUseWideColorGamut() || + features::IsDynamicColorGamutEnabled()) { + return WideColorGamutHeuristic::kUseDisplay; + } + + if (display::HasForceDisplayColorProfile() && + display::GetForcedDisplayColorProfile() == + gfx::ColorSpace::CreateDisplayP3D65()) { + return WideColorGamutHeuristic::kUseDisplay; + } + + return WideColorGamutHeuristic::kNone; +} +#endif + +base::flat_set +ChromeContentBrowserClient::GetPluginMimeTypesWithExternalHandlers( + content::BrowserContext* browser_context) { + base::flat_set mime_types; +#if BUILDFLAG(ENABLE_PLUGINS) + auto map = PluginUtils::GetMimeTypeToExtensionIdMap(browser_context); + for (const auto& pair : map) + mime_types.insert(pair.first); +#endif +#if BUILDFLAG(ENABLE_PDF) + mime_types.insert(pdf::kInternalPluginMimeType); +#endif + return mime_types; +} + +void ChromeContentBrowserClient::AugmentNavigationDownloadPolicy( + content::RenderFrameHost* frame_host, + bool user_gesture, + blink::NavigationDownloadPolicy* download_policy) { + const auto* throttle_manager = + subresource_filter::ContentSubresourceFilterThrottleManager::FromPage( + frame_host->GetPage()); + if (throttle_manager && + throttle_manager->IsRenderFrameHostTaggedAsAd(frame_host)) { + download_policy->SetAllowed(blink::NavigationDownloadType::kAdFrame); + if (!user_gesture) { + download_policy->SetDisallowed( + blink::NavigationDownloadType::kAdFrameNoGesture); + } + } +} + +bool ChromeContentBrowserClient::HandleTopicsWebApi( + const url::Origin& context_origin, + content::RenderFrameHost* main_frame, + browsing_topics::ApiCallerSource caller_source, + bool get_topics, + bool observe, + std::vector& topics) { + browsing_topics::BrowsingTopicsService* browsing_topics_service = + browsing_topics::BrowsingTopicsServiceFactory::GetForProfile( + Profile::FromBrowserContext( + content::WebContents::FromRenderFrameHost(main_frame) + ->GetBrowserContext())); + + if (!browsing_topics_service) + return {}; + + bool allowed = browsing_topics_service->HandleTopicsWebApi( + context_origin, main_frame, caller_source, get_topics, observe, topics); + + if (main_frame) { + ChromeBrowsingDataModelDelegate::BrowsingDataAccessed( + main_frame, context_origin, + ChromeBrowsingDataModelDelegate::StorageType::kTopics, !allowed); + } + + return allowed; +} + +int ChromeContentBrowserClient::NumVersionsInTopicsEpochs( + content::RenderFrameHost* main_frame) const { + browsing_topics::BrowsingTopicsService* browsing_topics_service = + browsing_topics::BrowsingTopicsServiceFactory::GetForProfile( + Profile::FromBrowserContext( + content::WebContents::FromRenderFrameHost(main_frame) + ->GetBrowserContext())); + + CHECK(browsing_topics_service); + return browsing_topics_service->NumVersionsInEpochs( + main_frame->GetLastCommittedOrigin()); +} + +bool ChromeContentBrowserClient::IsBluetoothScanningBlocked( + content::BrowserContext* browser_context, + const url::Origin& requesting_origin, + const url::Origin& embedding_origin) { + const HostContentSettingsMap* const content_settings = + HostContentSettingsMapFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + + if (content_settings->GetContentSetting( + requesting_origin.GetURL(), embedding_origin.GetURL(), + ContentSettingsType::BLUETOOTH_SCANNING) == CONTENT_SETTING_BLOCK) { + return true; + } + + return false; +} + +void ChromeContentBrowserClient::BlockBluetoothScanning( + content::BrowserContext* browser_context, + const url::Origin& requesting_origin, + const url::Origin& embedding_origin) { + HostContentSettingsMap* const content_settings = + HostContentSettingsMapFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + + content_settings->SetContentSettingDefaultScope( + requesting_origin.GetURL(), embedding_origin.GetURL(), + ContentSettingsType::BLUETOOTH_SCANNING, CONTENT_SETTING_BLOCK); +} + +void ChromeContentBrowserClient::GetMediaDeviceIDSalt( + content::RenderFrameHost* rfh, + const net::SiteForCookies& site_for_cookies, + const blink::StorageKey& storage_key, + base::OnceCallback callback) { + GURL url = rfh->GetLastCommittedURL(); + url::Origin top_frame_origin = rfh->GetMainFrame()->GetLastCommittedOrigin(); + content::BrowserContext* browser_context = rfh->GetBrowserContext(); + + // Persistent MediaDevice IDs are allowed if cookies are allowed or if the + // user is in the default state in 3PCD. + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + privacy_sandbox::TrackingProtectionSettings* tracking_protection = + TrackingProtectionSettingsFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + bool allowed = cookie_settings->IsFullCookieAccessAllowed( + url, site_for_cookies, top_frame_origin, + cookie_settings->SettingOverridesForStorage()) || + (tracking_protection->IsTrackingProtection3pcdEnabled() && + !tracking_protection->AreAllThirdPartyCookiesBlocked()); + ChromeBrowsingDataModelDelegate::BrowsingDataAccessed( + rfh, storage_key, + ChromeBrowsingDataModelDelegate::StorageType::kMediaDeviceSalt, !allowed); + media_device_salt::MediaDeviceSaltService* salt_service = + MediaDeviceSaltServiceFactory::GetInstance()->GetForBrowserContext( + browser_context); + if (!allowed || !salt_service) { + // Use ephemeral salt. + std::move(callback).Run(allowed, browser_context->UniqueId()); + return; + } + + salt_service->GetSalt(rfh->GetStorageKey(), + base::BindOnce(std::move(callback), allowed)); +} + +#if !BUILDFLAG(IS_ANDROID) +base::OnceClosure ChromeContentBrowserClient::FetchRemoteSms( + content::WebContents* web_contents, + const std::vector& origin_list, + base::OnceCallback>, + std::optional, + std::optional)> + callback) { + return ::FetchRemoteSms(web_contents, origin_list, std::move(callback)); +} +#endif + +bool ChromeContentBrowserClient::IsClipboardPasteAllowed( + content::RenderFrameHost* render_frame_host) { + DCHECK(render_frame_host); + + // Paste requires either (1) user activation, ... + if (WebContents::FromRenderFrameHost(render_frame_host) + ->HasRecentInteraction()) { + return true; + } + + // (2) granted web permission, ... + content::BrowserContext* browser_context = + render_frame_host->GetBrowserContext(); + content::PermissionController* permission_controller = + browser_context->GetPermissionController(); + blink::mojom::PermissionStatus status = + permission_controller->GetPermissionStatusForCurrentDocument( + blink::PermissionType::CLIPBOARD_READ_WRITE, render_frame_host); + if (status == blink::mojom::PermissionStatus::GRANTED) + return true; + +#if BUILDFLAG(ENABLE_EXTENSIONS) + // (3) origination directly from a Chrome extension, ... + Profile* profile = Profile::FromBrowserContext(browser_context); + DCHECK(profile); + const GURL& url = + render_frame_host->GetMainFrame()->GetLastCommittedOrigin().GetURL(); + auto* registry = extensions::ExtensionRegistry::Get(profile); + if (url.SchemeIs(extensions::kExtensionScheme)) { + return URLHasExtensionPermission(extensions::ProcessMap::Get(profile), + registry, url, + render_frame_host->GetProcess()->GetID(), + APIPermissionID::kClipboardRead); + } + + // or (4) origination from a process that at least might be running a + // content script from an extension with the clipboardRead permission. + // Note that we currently don't allow clipboard operations based just on user + // script injections. + extensions::ExtensionIdSet extension_ids = extensions:: + ScriptInjectionTracker::GetExtensionsThatRanContentScriptsInProcess( + *render_frame_host->GetProcess()); + for (const auto& extension_id : extension_ids) { + const Extension* extension = + registry->enabled_extensions().GetByID(extension_id); + if (extension && extension->permissions_data()->HasAPIPermission( + APIPermissionID::kClipboardRead)) { + return true; + } + } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + + return false; +} + +void ChromeContentBrowserClient::IsClipboardPasteAllowedByPolicy( + const content::ClipboardEndpoint& source, + const content::ClipboardEndpoint& destination, + const content::ClipboardMetadata& metadata, + ClipboardPasteData clipboard_paste_data, + IsClipboardPasteAllowedCallback callback) { +#if BUILDFLAG(ENTERPRISE_DATA_CONTROLS) + enterprise_data_protection::PasteAllowedRequest::StartPasteAllowedRequest( + source, destination, metadata, std::move(clipboard_paste_data), + std::move(callback)); +#else + std::move(callback).Run(std::move(clipboard_paste_data)); +#endif // BUILDFLAG(ENTERPRISE_DATA_CONTROLS) +} + +void ChromeContentBrowserClient::IsClipboardCopyAllowedByPolicy( + const content::ClipboardEndpoint& source, + const content::ClipboardMetadata& metadata, + const ClipboardPasteData& data, + IsClipboardCopyAllowedCallback callback) { +#if BUILDFLAG(ENTERPRISE_DATA_CONTROLS) + enterprise_data_protection::IsClipboardCopyAllowedByPolicy( + source, metadata, data, std::move(callback)); +#else + std::u16string replacement_data; + ClipboardRestrictionService* service = + ClipboardRestrictionServiceFactory::GetInstance()->GetForBrowserContext( + source.browser_context()); + if (service->IsUrlAllowedToCopy(*source.data_transfer_endpoint()->GetURL(), + metadata.size.value_or(0), + &replacement_data)) { + std::move(callback).Run(metadata.format_type, data, std::nullopt); + } else { + std::move(callback).Run(metadata.format_type, data, + std::move(replacement_data)); + } +#endif // BUILDFLAG(ENTERPRISE_DATA_CONTROLS) +} + +#if BUILDFLAG(ENABLE_VR) +content::XrIntegrationClient* +ChromeContentBrowserClient::GetXrIntegrationClient() { + if (!xr_integration_client_) + xr_integration_client_ = std::make_unique( + base::PassKey()); + return xr_integration_client_.get(); +} +#endif // BUILDFLAG(ENABLE_VR) + +void ChromeContentBrowserClient::BindBrowserControlInterface( + mojo::ScopedMessagePipeHandle pipe) { +#if BUILDFLAG(IS_CHROMEOS_LACROS) + chromeos::LacrosService::Get()->BindReceiver( + chrome::GetVersionString(chrome::WithExtendedStable(true))); +#endif +} + +bool ChromeContentBrowserClient:: + ShouldInheritCrossOriginEmbedderPolicyImplicitly(const GURL& url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return url.SchemeIs(extensions::kExtensionScheme); +#else + return false; +#endif +} + +bool ChromeContentBrowserClient:: + ShouldServiceWorkerInheritPolicyContainerFromCreator(const GURL& url) { + if (url.SchemeIsLocal()) { + return true; + } +#if BUILDFLAG(ENABLE_EXTENSIONS) + return url.SchemeIs(extensions::kExtensionScheme); +#else + return false; +#endif +} + +void ChromeContentBrowserClient:: + GrantAdditionalRequestPrivilegesToWorkerProcess(int child_id, + const GURL& script_url) { +#if !BUILDFLAG(IS_ANDROID) + // IWA Service Workers need to be explicitly granted access to their origin + // because isolated-app: isn't a web-safe scheme that can be accessed by + // default. + if (script_url.SchemeIs(chrome::kIsolatedAppScheme)) { + ChildProcessSecurityPolicy::GetInstance()->GrantRequestOrigin( + child_id, url::Origin::Create(script_url)); + } +#endif // !BUILDFLAG(IS_ANDROID) +} + +content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride +ChromeContentBrowserClient::ShouldOverridePrivateNetworkRequestPolicy( + content::BrowserContext* browser_context, + const url::Origin& origin) { + // The host content settings map might no be null for some irregular profiles, + // e.g. the System Profile. + if (HostContentSettingsMap* service = + HostContentSettingsMapFactory::GetForProfile(browser_context)) { + if (content_settings::ShouldAllowInsecurePrivateNetworkRequests(service, + origin)) { + return content::ContentBrowserClient:: + PrivateNetworkRequestPolicyOverride::kForceAllow; + } + } + +#if BUILDFLAG(IS_ANDROID) + if (base::FeatureList::IsEnabled( + kPrivateNetworkAccessRestrictionsForAutomotive) && + base::android::BuildInfo::GetInstance()->is_automotive()) { + return content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride:: + kBlockInsteadOfWarn; + } +#endif + + Profile* profile = Profile::FromBrowserContext(browser_context); + if (profile->GetPrefs()->GetBoolean( + prefs::kManagedPrivateNetworkAccessRestrictionsEnabled)) { + return content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride:: + kBlockInsteadOfWarn; + } + + return content::ContentBrowserClient::PrivateNetworkRequestPolicyOverride:: + kDefault; +} + +bool ChromeContentBrowserClient::IsJitDisabledForSite( + content::BrowserContext* browser_context, + const GURL& site_url) { + Profile* profile = Profile::FromBrowserContext(browser_context); + auto* map = HostContentSettingsMapFactory::GetForProfile(profile); + // Special case to determine if any policy is set. + if (map && site_url.is_empty()) { + return map->GetDefaultContentSetting(ContentSettingsType::JAVASCRIPT_JIT, + nullptr) == CONTENT_SETTING_BLOCK; + } + + // Only disable JIT for web schemes. + if (!site_url.SchemeIsHTTPOrHTTPS()) + return false; + + return (map && map->GetContentSetting(site_url, site_url, + ContentSettingsType::JAVASCRIPT_JIT) == + CONTENT_SETTING_BLOCK); +} + +ukm::UkmService* ChromeContentBrowserClient::GetUkmService() { + return g_browser_process->GetMetricsServicesManager()->GetUkmService(); +} + +blink::mojom::OriginTrialsSettingsPtr +ChromeContentBrowserClient::GetOriginTrialsSettings() { + return g_browser_process->GetOriginTrialsSettingsStorage()->GetSettings(); +} + +void ChromeContentBrowserClient::OnKeepaliveRequestStarted( + content::BrowserContext* context) { +#if !BUILDFLAG(IS_ANDROID) + DVLOG(1) << "OnKeepaliveRequestStarted: " << num_keepalive_requests_ + << " ==> " << num_keepalive_requests_ + 1; + ++num_keepalive_requests_; + DCHECK_GT(num_keepalive_requests_, 0u); + + if (!context) { + // We somehow failed to associate the request and the BrowserContext. Bail + // out. + return; + } + + const auto now = base::TimeTicks::Now(); + const auto timeout = GetKeepaliveTimerTimeout(context); + keepalive_deadline_ = std::max(keepalive_deadline_, now + timeout); + if (keepalive_deadline_ > now && !keepalive_timer_.IsRunning()) { + DVLOG(1) << "Starting a keepalive timer(" << timeout.InSecondsF() + << " seconds)"; + keepalive_timer_.Start( + FROM_HERE, keepalive_deadline_ - now, + base::BindOnce( + &ChromeContentBrowserClient::OnKeepaliveTimerFired, + weak_factory_.GetWeakPtr(), + std::make_unique( + KeepAliveOrigin::BROWSER, KeepAliveRestartOption::DISABLED))); + } +#endif // !BUILDFLAG(IS_ANDROID) +} + +void ChromeContentBrowserClient::OnKeepaliveRequestFinished() { +#if !BUILDFLAG(IS_ANDROID) + DCHECK_GT(num_keepalive_requests_, 0u); + DVLOG(1) << "OnKeepaliveRequestFinished: " << num_keepalive_requests_ + << " ==> " << num_keepalive_requests_ - 1; + --num_keepalive_requests_; + if (num_keepalive_requests_ == 0) { + DVLOG(1) << "Stopping the keepalive timer"; + keepalive_timer_.Stop(); + // This deletes the keep alive handle attached to the timer function and + // unblock the shutdown sequence. + } +#endif // !BUILDFLAG(IS_ANDROID) +} + +#if BUILDFLAG(IS_MAC) +bool ChromeContentBrowserClient::SetupEmbedderSandboxParameters( + sandbox::mojom::Sandbox sandbox_type, + sandbox::SandboxCompiler* compiler) { + if (sandbox_type == sandbox::mojom::Sandbox::kSpeechRecognition) { + base::FilePath soda_component_path = speech::GetSodaDirectory(); + CHECK(!soda_component_path.empty()); + CHECK(compiler->SetParameter(sandbox::policy::kParamSodaComponentPath, + soda_component_path.value())); + + base::FilePath soda_language_pack_path = + speech::GetSodaLanguagePacksDirectory(); + CHECK(!soda_language_pack_path.empty()); + CHECK(compiler->SetParameter(sandbox::policy::kParamSodaLanguagePackPath, + soda_language_pack_path.value())); + return true; +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + } else if (sandbox_type == sandbox::mojom::Sandbox::kScreenAI) { + // ScreenAI service needs read access to ScreenAI component binary path to + // load it. + base::FilePath screen_ai_binary_path = + screen_ai::ScreenAIInstallState::GetInstance() + ->get_component_binary_path(); + if (screen_ai_binary_path.empty()) { + VLOG(1) << "Screen AI component not found."; + return false; + } + return compiler->SetParameter(sandbox::policy::kParamScreenAiComponentPath, + screen_ai_binary_path.value()); +#endif + } + + return false; +} + +#endif // BUILDFLAG(IS_MAC) + +void ChromeContentBrowserClient::GetHyphenationDictionary( + base::OnceCallback callback) { +#if BUILDFLAG(USE_MINIKIN_HYPHENATION) && !BUILDFLAG(IS_ANDROID) + component_updater::HyphenationComponentInstallerPolicy:: + GetHyphenationDictionary(std::move(callback)); +#endif +} + +bool ChromeContentBrowserClient::HasErrorPage(int http_status_code) { + // Use an internal error page, if we have one for the status code. + return error_page::LocalizedError::HasStrings( + error_page::Error::kHttpErrorDomain, http_status_code); +} + +std::unique_ptr +ChromeContentBrowserClient::CreateIdentityRequestDialogController( + content::WebContents* web_contents) { + return std::make_unique(web_contents); +} + +std::unique_ptr +ChromeContentBrowserClient::CreateDigitalIdentityProvider() { +#if BUILDFLAG(IS_ANDROID) + return std::make_unique(); +#else + return std::make_unique(); +#endif +} + +bool ChromeContentBrowserClient::SuppressDifferentOriginSubframeJSDialogs( + content::BrowserContext* browser_context) { + Profile* profile = Profile::FromBrowserContext(browser_context); + if (!profile->GetPrefs()->GetBoolean( + prefs::kSuppressDifferentOriginSubframeJSDialogs)) { + return false; + } + return ContentBrowserClient::SuppressDifferentOriginSubframeJSDialogs( + browser_context); +} + +bool ChromeContentBrowserClient::IsFindInPageDisabledForOrigin( + const url::Origin& origin) { +#if BUILDFLAG(ENABLE_PDF) + // For PDF viewing with the PPAPI-free PDF Viewer, find-in-page should only + // display results from the PDF content, and not from the UI. + return IsPdfExtensionOrigin(origin); +#else + return false; +#endif +} + +std::unique_ptr +ChromeContentBrowserClient::CreateAnchorElementPreconnectDelegate( + content::RenderFrameHost& render_frame_host) { + return std::make_unique(render_frame_host); +} + +std::unique_ptr +ChromeContentBrowserClient::CreateSpeculationHostDelegate( + content::RenderFrameHost& render_frame_host) { + return std::make_unique(render_frame_host); +} + +std::unique_ptr +ChromeContentBrowserClient::CreatePrefetchServiceDelegate( + content::BrowserContext* browser_context) { + return std::make_unique(browser_context); +} + +std::unique_ptr +ChromeContentBrowserClient::CreatePrerenderWebContentsDelegate() { + return std::make_unique(); +} + +void ChromeContentBrowserClient::OnWebContentsCreated( + content::WebContents* web_contents) { + // NOTE: Please don't add additional code to this method - attaching universal + // WebContentsObservers goes through the separate function, to ensure that the + // (rare) additions of universal helpers are code reviewed by separate OWNERS. + AttachUniversalWebContentsObservers(web_contents); +} + +#if !BUILDFLAG(IS_ANDROID) +base::TimeDelta ChromeContentBrowserClient::GetKeepaliveTimerTimeout( + content::BrowserContext* context) { + Profile* profile = Profile::FromBrowserContext(context); + PrefService* prefs = profile->GetPrefs(); + if (!prefs) { + return base::TimeDelta(); + } + + const int seconds = + prefs->GetInteger(prefs::kFetchKeepaliveDurationOnShutdown); + // The preference is set only be the corresponding enterprise policy, and + // we have minimum/maximum values on it. + DCHECK_LE(0, seconds); + DCHECK_LE(seconds, 5); + return base::Seconds(seconds); +} + +void ChromeContentBrowserClient::OnKeepaliveTimerFired( + std::unique_ptr keep_alive_handle) { + const auto now = base::TimeTicks::Now(); + const auto then = keepalive_deadline_; + if (now < then) { + keepalive_timer_.Start( + FROM_HERE, then - now, + base::BindOnce(&ChromeContentBrowserClient::OnKeepaliveTimerFired, + weak_factory_.GetWeakPtr(), + std::move(keep_alive_handle))); + } +} +#endif + +bool ChromeContentBrowserClient::ShouldPreconnectNavigation( + content::RenderFrameHost* render_frame_host) { + content::BrowserContext* browser_context = + render_frame_host->GetBrowserContext(); +#if BUILDFLAG(ENABLE_EXTENSIONS) + // An extension could be blocking connections for privacy reasons, so skip + // optimization if there are any extensions with WebRequest permissions. + const auto* web_request_api = + extensions::BrowserContextKeyedAPIFactory::Get( + browser_context); + if (!web_request_api || web_request_api->MayHaveProxies() || + web_request_api->IsAvailableToWebViewEmbedderFrame(render_frame_host)) { + return false; + } +#endif + return prefetch::IsSomePreloadingEnabled( + *Profile::FromBrowserContext(browser_context)->GetPrefs()) == + content::PreloadingEligibility::kEligible; +} + +bool ChromeContentBrowserClient::ShouldDisableOriginAgentClusterDefault( + content::BrowserContext* browser_context) { + // The enterprise policy for kOriginAgentClusterDefaultEnabled defaults to + // true to defer to Chromium's decision. If it is set to false, it should + // override Chromium's decision and use site-keyed agent clusters by default + // instead. + return !Profile::FromBrowserContext(browser_context) + ->GetPrefs() + ->GetBoolean(prefs::kOriginAgentClusterDefaultEnabled); +} + +bool ChromeContentBrowserClient::WillProvidePublicFirstPartySets() { +#if BUILDFLAG(ENABLE_COMPONENT_UPDATER) + return !is_minimal_mode_ && + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableComponentUpdate); +#else + return false; +#endif // BUILDFLAG(ENABLE_COMPONENT_UPDATER) +} + +content::mojom::AlternativeErrorPageOverrideInfoPtr +ChromeContentBrowserClient::GetAlternativeErrorPageOverrideInfo( + const GURL& url, + content::RenderFrameHost* render_frame_host, + content::BrowserContext* browser_context, + int32_t error_code) { +#if !BUILDFLAG(IS_ANDROID) + if (content::IsolatedWebAppsPolicy::AreIsolatedWebAppsEnabled( + browser_context) && + url.SchemeIs(chrome::kIsolatedAppScheme)) { + content::mojom::AlternativeErrorPageOverrideInfoPtr + alternative_error_page_override_info = + web_app::MaybeGetIsolatedWebAppErrorPageInfo( + url, render_frame_host, browser_context, error_code); + if (alternative_error_page_override_info) { + alternative_error_page_override_info->alternative_error_page_params.Set( + error_page::kOverrideErrorPage, base::Value(true)); + return alternative_error_page_override_info; + } + } +#endif + + if (error_code == net::ERR_INTERNET_DISCONNECTED) { + content::mojom::AlternativeErrorPageOverrideInfoPtr + alternative_error_page_override_info = web_app::GetOfflinePageInfo( + url, render_frame_host, browser_context); + if (alternative_error_page_override_info) { + // Use the alternative error page dictionary to override the error page. + alternative_error_page_override_info->alternative_error_page_params.Set( + error_page::kOverrideErrorPage, base::Value(true)); + web_app::TrackOfflinePageVisibility(render_frame_host); + return alternative_error_page_override_info; + } + } + +#if BUILDFLAG(IS_CHROMEOS_ASH) + using PortalState = chromeos::network_config::mojom::PortalState; + auto portal_state = ash::network_health::NetworkHealthManager::GetInstance() + ->helper() + ->WiFiPortalState(); + if (portal_state != PortalState::kUnknown) { + auto alternative_error_page_override_info = + content::mojom::AlternativeErrorPageOverrideInfo::New(); + bool is_portal_state = portal_state == PortalState::kPortal || + portal_state == PortalState::kPortalSuspected; + // Use the alternative error page dictionary to provide additional + // suggestions in the default error page. + alternative_error_page_override_info->alternative_error_page_params.Set( + error_page::kOverrideErrorPage, base::Value(false)); + alternative_error_page_override_info->alternative_error_page_params.Set( + error_page::kIsPortalStateKey, base::Value(is_portal_state)); + return alternative_error_page_override_info; + } +#endif + + return nullptr; +} + +void ChromeContentBrowserClient::OnSharedStorageWorkletHostCreated( + content::RenderFrameHost* rfh) { + if (auto* observer = + page_load_metrics::MetricsWebContentsObserver::FromWebContents( + WebContents::FromRenderFrameHost(rfh))) { + observer->OnSharedStorageWorkletHostCreated(rfh); + } +} + +void ChromeContentBrowserClient::OnSharedStorageSelectURLCalled( + content::RenderFrameHost* main_rfh) { + if (auto* observer = + page_load_metrics::MetricsWebContentsObserver::FromWebContents( + WebContents::FromRenderFrameHost(main_rfh))) { + observer->OnSharedStorageSelectURLCalled(main_rfh); + } +} + +bool ChromeContentBrowserClient::ShouldSendOutermostOriginToRenderer( + const url::Origin& outermost_origin) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + // We only want to send the outermost origin if it is an extension scheme. + // We do not send the outermost origin to every renderer to avoid leaking + // additional information into the renderer about the embedder. For + // extensions though this is required for the way content injection API + // works. We do not want one extension injecting content into the context + // of another extension. + return outermost_origin.scheme() == extensions::kExtensionScheme; +#else + return false; +#endif +} + +bool ChromeContentBrowserClient::IsFileSystemURLNavigationAllowed( + content::BrowserContext* browser_context, + const GURL& url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + // filesystem: URLs for Chrome Apps are in the following format: + // `filesystem:chrome-extension:///...` + if (!url.SchemeIsFileSystem()) + return false; + // Once converted into an origin, we expect the following: + // scheme() is chrome-extension: (filesystem: is automatically discarded) + // host() is the extension-id + const url::Origin origin = url::Origin::Create(url); + if (origin.scheme() == extensions::kExtensionScheme) { + const Extension* extension = + extensions::ExtensionRegistry::Get(browser_context) + ->enabled_extensions() + .GetByID(origin.host()); + DCHECK(extension); + return extension->is_platform_app(); + } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + return false; +} + +bool ChromeContentBrowserClient::AreIsolatedWebAppsEnabled( + content::BrowserContext* browser_context) { +#if !BUILDFLAG(IS_ANDROID) + return ChromeContentBrowserClientIsolatedWebAppsPart:: + AreIsolatedWebAppsEnabled(browser_context); +#else // BUILDFLAG(IS_ANDROID) + return false; +#endif +} + +bool ChromeContentBrowserClient::IsThirdPartyStoragePartitioningAllowed( + content::BrowserContext* browser_context, + const url::Origin& top_level_origin) { + const HostContentSettingsMap* const content_settings = + HostContentSettingsMapFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + if (!content_settings) { + // We fail permissive as this function is used to check whether partitioning + // should be blocked, but isn't the final word on if it's allowed. + return true; + } + return content_settings->GetContentSetting( + top_level_origin.GetURL(), top_level_origin.GetURL(), + ContentSettingsType::THIRD_PARTY_STORAGE_PARTITIONING) == + CONTENT_SETTING_ALLOW; +} + +bool ChromeContentBrowserClient::AreDeprecatedAutomaticBeaconCredentialsAllowed( + content::BrowserContext* browser_context, + const GURL& destination_url, + const url::Origin& top_frame_origin) { + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile( + Profile::FromBrowserContext(browser_context)); + return cookie_settings->IsFullCookieAccessAllowed( + destination_url, net::SiteForCookies(), top_frame_origin, + cookie_settings->SettingOverridesForStorage()); +} + +bool ChromeContentBrowserClient:: + IsTransientActivationRequiredForShowFileOrDirectoryPicker( + content::WebContents* web_contents) { +#if !BUILDFLAG(IS_ANDROID) + return IsFileOrDirectoryPickerWithoutGestureAllowed(web_contents); +#else // !BUILDFLAG(IS_ANDROID) + return true; +#endif // !BUILDFLAG(IS_ANDROID) +} + +bool ChromeContentBrowserClient::IsTransientActivationRequiredForHtmlFullscreen( + content::RenderFrameHost* render_frame_host) { + // TODO(crbug.com/40941384): Remove this code and solely rely on permissions. + if (base::FeatureList::IsEnabled( + features::kAutomaticFullscreenContentSetting) && + !base::FeatureList::IsEnabled( + blink::features::kAutomaticFullscreenPermissionsQuery)) { + const GURL& url = render_frame_host->GetLastCommittedURL(); + const HostContentSettingsMap* const content_settings = + HostContentSettingsMapFactory::GetForProfile( + render_frame_host->GetBrowserContext()); + if (content_settings && + content_settings->GetContentSetting( + url, url, ContentSettingsType::AUTOMATIC_FULLSCREEN) == + CONTENT_SETTING_ALLOW) { + return false; + } + } + + return true; +} + +#if BUILDFLAG(IS_MAC) +std::string ChromeContentBrowserClient::GetChildProcessSuffix(int child_flags) { + if (child_flags == chrome::kChildProcessHelperAlerts) { + return chrome::kMacHelperSuffixAlerts; + } + NOTREACHED_IN_MIGRATION() << "Unsupported child process flags!"; + return {}; +} +#endif // BUILDFLAG(IS_MAC) + +bool ChromeContentBrowserClient::ShouldUseFirstPartyStorageKey( + const url::Origin& origin) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return origin.scheme() == extensions::kExtensionScheme; +#else + return false; +#endif // BUILDFLAG(ENABLE_EXTENSIONS) +} + +std::unique_ptr +ChromeContentBrowserClient::CreateResponsivenessCalculatorDelegate() { +#if !BUILDFLAG(IS_ANDROID) + return ChromeResponsivenessCalculatorDelegate::Create(); +#else + return nullptr; +#endif +} + +// static +bool ChromeContentBrowserClient::DoesGaiaOriginRequireDedicatedProcess() { +#if !BUILDFLAG(IS_ANDROID) + return true; +#else + // Sign-in process isolation is not strictly needed on Android, see + // https://crbug.com/739418. On Android, it's more optional but it does + // improve security generally and specifically it allows the exposure of + // certain optional privileged APIs. + + // Kill switch that falls back to the legacy behavior. + if (!base::FeatureList::IsEnabled(kAllowGaiaOriginIsolationOnAndroid)) { + return false; + } + + if (site_isolation::SiteIsolationPolicy:: + ShouldDisableSiteIsolationDueToMemoryThreshold( + content::SiteIsolationMode::kPartialSiteIsolation)) { + // Insufficient memory to isolate Gaia's origin. + return false; + } + + return true; +#endif // !BUILDFLAG(IS_ANDROID) +} + +bool ChromeContentBrowserClient::CanBackForwardCachedPageReceiveCookieChanges( + content::BrowserContext& browser_context, + const GURL& url, + const net::SiteForCookies& site_for_cookies, + const std::optional& top_frame_origin, + const net::CookieSettingOverrides overrides) { + scoped_refptr cookie_settings = + CookieSettingsFactory::GetForProfile( + Profile::FromBrowserContext(&browser_context)); + CHECK(cookie_settings); + return cookie_settings->IsFullCookieAccessAllowed( + url, site_for_cookies, top_frame_origin, overrides); +} + +void ChromeContentBrowserClient::GetCloudIdentifiers( + const storage::FileSystemURL& url, + content::FileSystemAccessPermissionContext::HandleType handle_type, + GetCloudIdentifiersCallback callback) { +#if BUILDFLAG(IS_CHROMEOS) + cloud_identifier::GetCloudIdentifierFromAsh(url, handle_type, + std::move(callback)); +#else // BUILDFLAG(IS_CHROMEOS) + return ContentBrowserClient::GetCloudIdentifiers(url, handle_type, + std::move(callback)); +#endif // BUILDFLAG(IS_CHROMEOS) +} + +bool ChromeContentBrowserClient:: + ShouldAllowBackForwardCacheForCacheControlNoStorePage( + content::BrowserContext* browser_context) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); +#if BUILDFLAG(IS_CHROMEOS) + // Do not store CCNS page into BFCache in the kiosk session. + if (chromeos::IsKioskSession()) { + return false; + } +#endif + + if (chrome::IsRunningInAppMode()) { + return false; + } + + const PrefService::Preference* pref = + Profile::FromBrowserContext(browser_context) + ->GetPrefs() + ->FindPreference( + policy::policy_prefs:: + kAllowBackForwardCacheForCacheControlNoStorePageEnabled); + if (pref && pref->IsManaged() && pref->GetValue()->is_bool()) { + return pref->GetValue()->GetBool(); + } + // If the pref is not found or not managed, BFCaching CCNS page should be + // enabled by default. + return true; +} + +void ChromeContentBrowserClient::SetIsMinimalMode(bool minimal) { + is_minimal_mode_ = minimal; +} + +bool ChromeContentBrowserClient:: + UseOutermostMainFrameOrEmbedderForSubCaptureTargets() const { +#if BUILDFLAG(PLATFORM_CFM) + return true; +#else + return false; +#endif +} + +#if !BUILDFLAG(IS_ANDROID) +void ChromeContentBrowserClient::BindVideoEffectsManager( + const std::string& device_id, + content::BrowserContext* browser_context, + mojo::PendingReceiver + video_effects_manager) { + media_effects::BindVideoEffectsManager(device_id, browser_context, + std::move(video_effects_manager)); +} + +void ChromeContentBrowserClient::BindVideoEffectsProcessor( + const std::string& device_id, + content::BrowserContext* browser_context, + mojo::PendingReceiver + video_effects_processor) { + media_effects::BindVideoEffectsProcessor(device_id, browser_context, + std::move(video_effects_processor)); +} +#endif // !BUILDFLAG(IS_ANDROID) + +void ChromeContentBrowserClient::PreferenceRankAudioDeviceInfos( + content::BrowserContext* browser_context, + blink::WebMediaDeviceInfoArray& infos) { + if (!user_prefs::UserPrefs::IsInitialized(browser_context)) { + return; + } + auto* prefs = user_prefs::UserPrefs::Get(browser_context); + CHECK(prefs); + media_prefs::PreferenceRankAudioDeviceInfos(*prefs, infos); +} + +void ChromeContentBrowserClient::PreferenceRankVideoDeviceInfos( + content::BrowserContext* browser_context, + blink::WebMediaDeviceInfoArray& infos) { + if (!user_prefs::UserPrefs::IsInitialized(browser_context)) { + return; + } + auto* prefs = user_prefs::UserPrefs::Get(browser_context); + CHECK(prefs); + media_prefs::PreferenceRankVideoDeviceInfos(*prefs, infos); +} + +network::mojom::IpProtectionProxyBypassPolicy +ChromeContentBrowserClient::GetIpProtectionProxyBypassPolicy() { + return network::mojom::IpProtectionProxyBypassPolicy:: + kFirstPartyToTopLevelFrame; +} + +void ChromeContentBrowserClient::MaybePrewarmHttpDiskCache( + content::BrowserContext& browser_context, + const std::optional& initiator_origin, + const GURL& navigation_url) { + Profile* profile = Profile::FromBrowserContext(&browser_context); + CHECK(profile); + + // `loading_predictor` can be nullptr if the profile `IsOffTheRecord`. + if (predictors::LoadingPredictor* loading_predictor = + predictors::LoadingPredictorFactory::GetForProfile(profile)) { + loading_predictor->MaybePrewarmResources(initiator_origin, navigation_url); + } +} + +#if BUILDFLAG(IS_CHROMEOS) +void ChromeContentBrowserClient::NotifyMultiCaptureStateChanged( + content::GlobalRenderFrameHostId capturer_rfh_id, + const std::string& label, + MultiCaptureChanged state) { + switch (state) { + case MultiCaptureChanged::kStarted: { + content::WebContents* const web_contents = + WebContents::FromRenderFrameHost( + RenderFrameHost::FromID(capturer_rfh_id)); + if (!web_contents) { + return; + } + NotifyMultiCaptureStarted( + label, web_contents, + web_app::WebAppTabHelper::GetAppId(web_contents)); + } break; + case MultiCaptureChanged::kStopped: + NotifyMultiCaptureStopped(label); + break; + } +} +#endif // BUILDFLAG(IS_CHROMEOS) + +std::unique_ptr +ChromeContentBrowserClient::CreateDipsDelegate() { + return std::make_unique(); +} + +bool ChromeContentBrowserClient::ShouldSuppressAXLoadComplete( + RenderFrameHost* rfh) { + CHECK(rfh); + WebContents* web_contents = WebContents::FromRenderFrameHost(rfh); + + const GURL& url = web_contents->GetVisibleURL(); + return url == GURL(chrome::kChromeUINewTabURL) || + url == GURL(chrome::kChromeUINewTabPageURL); +} + +void ChromeContentBrowserClient::BindAIManager( + content::BrowserContext* browser_context, + mojo::PendingReceiver receiver) { + auto* ai_manager = + AIManagerKeyedServiceFactory::GetAIManagerKeyedService(browser_context); + ai_manager->AddReceiver(std::move(receiver)); +} + +#if !BUILDFLAG(IS_ANDROID) +void ChromeContentBrowserClient::QueryInstalledWebAppsByManifestId( + const GURL& frame_url, + const GURL& manifest_id, + content::BrowserContext* browser_context, + base::OnceCallback)> + callback) { + Profile* profile = Profile::FromBrowserContext(browser_context); + web_app::WebAppProvider* const provider = + web_app::WebAppProvider::GetForLocalAppsUnchecked(profile); + + webapps::AppId app_id = web_app::GenerateAppIdFromManifestId(manifest_id); + + if (app_id.empty()) { + return std::move(callback).Run(std::nullopt); + } + + // arg_for_shutdown must be explicitly defined, otherwise + // ScheduleCallbackWithResult cannot infer the optional type the nullopt + // is associated with. + std::optional arg_for_shutdown = + std::nullopt; + web_app::AppLockDescription lock_description(app_id); + + provider->scheduler().ScheduleCallbackWithResult( + "QueryInstalledWebAppsByManifestId", std::move(lock_description), + base::BindOnce( + [](webapps::AppId app_id, webapps::ManifestId manifest_id, + GURL frame_url, web_app::AppLock& lock, + base::Value::Dict& debug_value) + -> std::optional { + debug_value.Set("input", base::Value::Dict() + .Set("manifest_id", manifest_id.spec()) + .Set("frame_url", frame_url.spec())); + + if (!lock.registrar().IsInstallState( + app_id, {web_app::proto::INSTALLED_WITHOUT_OS_INTEGRATION, + web_app::proto::INSTALLED_WITH_OS_INTEGRATION})) { + debug_value.Set("did_find_application", false); + return std::nullopt; + } + + if (!lock.registrar().IsUrlInAppScope(frame_url, app_id)) { + debug_value.Set("did_find_application", false); + return std::nullopt; + } + + blink::mojom::RelatedApplication application; + application.platform = "webapp"; + application.id = lock.registrar().GetAppManifestId(app_id).spec(); + // Note: This url is the manifest_url for purely legacy reasons + // where Android used to implement the unique identifier using the + // manifest url. + if (lock.registrar().GetAppManifestUrl(app_id).is_valid()) { + application.url = + lock.registrar().GetAppManifestUrl(app_id).spec(); + } + + debug_value.Set("did_find_application", true); + debug_value.Set( + "application", + base::Value::Dict() + .Set("app_id", application.id.value_or("")) + .Set("manifest_url", application.url.value_or(""))); + return application; + }, + std::move(app_id), std::move(manifest_id), std::move(frame_url)), + std::move(callback), std::move(arg_for_shutdown)); +} +#endif // !BUILDFLAG(IS_ANDROID) + +void ChromeContentBrowserClient::SetSamplingProfiler( + std::unique_ptr sampling_profiler) { + sampling_profiler_ = std::move(sampling_profiler); +} diff --git a/tools/under-control/src/chrome/browser/prefs/browser_prefs.cc b/tools/under-control/src/chrome/browser/prefs/browser_prefs.cc new file mode 100755 index 000000000..8cf6b5d7d --- /dev/null +++ b/tools/under-control/src/chrome/browser/prefs/browser_prefs.cc @@ -0,0 +1,2722 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/prefs/browser_prefs.h" + +#include +#include +#include +#include + +#include "ash/constants/ash_constants.h" +#include "base/time/time.h" +#include "base/trace_event/trace_event.h" +#include "build/branding_buildflags.h" +#include "build/build_config.h" +#include "build/chromecast_buildflags.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/about_flags.h" +#include "chrome/browser/accessibility/accessibility_labels_service.h" +#include "chrome/browser/accessibility/invert_bubble_prefs.h" +#include "chrome/browser/accessibility/page_colors.h" +#include "chrome/browser/accessibility/prefers_default_scrollbar_styles_prefs.h" +#include "chrome/browser/browser_process_impl.h" +#include "chrome/browser/chrome_content_browser_client.h" +#include "chrome/browser/chromeos/enterprise/cloud_storage/policy_utils.h" +#include "chrome/browser/chromeos/upload_office_to_cloud/upload_office_to_cloud.h" +#include "chrome/browser/component_updater/component_updater_prefs.h" +#include "chrome/browser/devtools/devtools_window.h" +#include "chrome/browser/download/download_prefs.h" +#include "chrome/browser/engagement/important_sites_util.h" +#include "chrome/browser/enterprise/reporting/prefs.h" +#include "chrome/browser/enterprise/util/managed_browser_utils.h" +#include "chrome/browser/external_protocol/external_protocol_handler.h" +#include "chrome/browser/first_run/first_run.h" +#include "chrome/browser/gpu/gpu_mode_manager.h" +#include "chrome/browser/lifetime/browser_shutdown.h" +#include "chrome/browser/login_detection/login_detection_prefs.h" +#include "chrome/browser/media/media_engagement_service.h" +#include "chrome/browser/media/media_storage_id_salt.h" +#include "chrome/browser/media/prefs/capture_device_ranking.h" +#include "chrome/browser/media/router/discovery/access_code/access_code_cast_feature.h" +#include "chrome/browser/media/router/media_router_feature.h" +#include "chrome/browser/media/webrtc/capture_policy_utils.h" +#include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" +#include "chrome/browser/media/webrtc/permission_bubble_media_access_handler.h" +#include "chrome/browser/memory/enterprise_memory_limit_pref_observer.h" +#include "chrome/browser/metrics/chrome_metrics_service_client.h" +#include "chrome/browser/net/net_error_tab_helper.h" +#include "chrome/browser/net/profile_network_context_service.h" +#include "chrome/browser/net/secure_dns_util.h" +#include "chrome/browser/net/system_network_context_manager.h" +#include "chrome/browser/notifications/notification_display_service_impl.h" +#include "chrome/browser/notifications/notifier_state_tracker.h" +#include "chrome/browser/notifications/platform_notification_service_impl.h" +#include "chrome/browser/permissions/quiet_notification_permission_ui_state.h" +#include "chrome/browser/prefs/chrome_pref_service_factory.h" +#include "chrome/browser/prefs/incognito_mode_prefs.h" +#include "chrome/browser/prefs/session_startup_pref.h" +#include "chrome/browser/preloading/prefetch/prefetch_service/prefetch_origin_decider.h" +#include "chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service.h" +#include "chrome/browser/preloading/preloading_prefs.h" +#include "chrome/browser/printing/print_preview_sticky_settings.h" +#include "chrome/browser/profiles/chrome_version_service.h" +#include "chrome/browser/profiles/profile_attributes_entry.h" +#include "chrome/browser/profiles/profile_attributes_storage.h" +#include "chrome/browser/profiles/profile_impl.h" +#include "chrome/browser/profiles/profiles_state.h" +#include "chrome/browser/push_messaging/push_messaging_app_identifier.h" +#include "chrome/browser/push_messaging/push_messaging_service_impl.h" +#include "chrome/browser/rlz/chrome_rlz_tracker_delegate.h" +#include "chrome/browser/search/search.h" +#include "chrome/browser/sharing/sharing_sync_preference.h" +#include "chrome/browser/sharing_hub/sharing_hub_features.h" +#include "chrome/browser/ssl/ssl_config_service_manager.h" +#include "chrome/browser/task_manager/task_manager_interface.h" +#include "chrome/browser/tracing/chrome_tracing_delegate.h" +#include "chrome/browser/ui/browser_ui_prefs.h" +#include "chrome/browser/ui/hats/hats_service_desktop.h" +#include "chrome/browser/ui/network_profile_bubble.h" +#include "chrome/browser/ui/performance_controls/performance_controls_metrics.h" +#include "chrome/browser/ui/prefs/prefs_tab_helper.h" +#include "chrome/browser/ui/safety_hub/safety_hub_prefs.h" +#include "chrome/browser/ui/search_engines/keyword_editor_controller.h" +#include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_bubble.h" +#include "chrome/browser/ui/tabs/organization/prefs.h" +#include "chrome/browser/ui/tabs/pinned_tab_codec.h" +#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_pref_names.h" +#include "chrome/browser/ui/tabs/tab_strip_prefs.h" +#include "chrome/browser/ui/toolbar/chrome_labs/chrome_labs_prefs.h" +#include "chrome/browser/ui/toolbar/chrome_location_bar_model_delegate.h" +#include "chrome/browser/ui/toolbar/toolbar_pref_names.h" +#include "chrome/browser/ui/views/side_panel/side_panel_prefs.h" +#include "chrome/browser/ui/webui/accessibility/accessibility_ui.h" +#include "chrome/browser/ui/webui/bookmarks/bookmark_prefs.h" +#include "chrome/browser/ui/webui/flags/flags_ui.h" +#include "chrome/browser/ui/webui/ntp/new_tab_ui.h" +#include "chrome/browser/ui/webui/policy/policy_ui.h" +#include "chrome/browser/ui/webui/print_preview/policy_settings.h" +#include "components/privacy_sandbox/tpcd_pref_names.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ui/webui/settings/reset_settings_handler.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/updates/announcement_notification/announcement_notification_service.h" +#include "chrome/browser/user_education/browser_feature_promo_storage_service.h" +#include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h" +#include "chrome/browser/webauthn/webauthn_pref_names.h" +#include "chrome/common/buildflags.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/secure_origin_allowlist.h" +#include "components/autofill/core/common/autofill_prefs.h" +#include "components/blocked_content/safe_browsing_triggered_popup_blocker.h" +#include "components/breadcrumbs/core/breadcrumbs_status.h" +#include "components/browser_sync/sync_to_signin_migration.h" +#include "components/browsing_data/core/pref_names.h" +#include "components/certificate_transparency/pref_names.h" +#include "components/commerce/core/pref_names.h" +#include "components/content_settings/core/browser/host_content_settings_map.h" +#include "components/content_settings/core/common/pref_names.h" +#include "components/custom_handlers/protocol_handler_registry.h" +#include "components/dom_distiller/core/distilled_page_prefs.h" +#include "components/domain_reliability/domain_reliability_prefs.h" +#include "components/embedder_support/origin_trials/origin_trial_prefs.h" +#include "components/enterprise/browser/identifiers/identifiers_prefs.h" +#include "components/enterprise/buildflags/buildflags.h" +#include "components/enterprise/connectors/connectors_prefs.h" +#include "components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_constants.h" +#include "components/flags_ui/pref_service_flags_storage.h" +#include "components/history_clusters/core/history_clusters_prefs.h" +#include "components/image_fetcher/core/cache/image_cache.h" +#include "components/invalidation/impl/fcm_invalidation_service.h" +#include "components/invalidation/impl/invalidator_registrar_with_memory.h" +#include "components/invalidation/impl/per_user_topic_subscription_manager.h" +#include "components/language/content/browser/geo_language_provider.h" +#include "components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator.h" +#include "components/language/core/browser/language_prefs.h" +#include "components/lens/buildflags.h" +#include "components/lookalikes/core/lookalike_url_util.h" +#include "components/media_device_salt/media_device_id_salt.h" +#include "components/metrics/demographics/user_demographics.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/network_time/network_time_tracker.h" +#include "components/ntp_tiles/most_visited_sites.h" +#include "components/offline_pages/buildflags/buildflags.h" +#include "components/omnibox/browser/document_provider.h" +#include "components/omnibox/browser/omnibox_prefs.h" +#include "components/omnibox/browser/zero_suggest_provider.h" +#include "components/optimization_guide/core/model_execution/model_execution_prefs.h" +#include "components/optimization_guide/core/optimization_guide_prefs.h" +#include "components/password_manager/core/browser/password_manager.h" +#include "components/payments/core/payment_prefs.h" +#include "components/performance_manager/public/user_tuning/prefs.h" +#include "components/permissions/permission_hats_trigger_helper.h" +#include "components/permissions/pref_names.h" +#include "components/policy/core/browser/browser_policy_connector.h" +#include "components/policy/core/browser/url_blocklist_manager.h" +#include "components/policy/core/common/local_test_policy_provider.h" +#include "components/policy/core/common/management/management_service.h" +#include "components/policy/core/common/policy_pref_names.h" +#include "components/policy/core/common/policy_statistics_collector.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/pref_registry.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/privacy_sandbox/privacy_sandbox_prefs.h" +#include "components/proxy_config/pref_proxy_config_tracker_impl.h" +#include "components/safe_browsing/content/common/file_type_policies_prefs.h" +#include "components/safe_browsing/core/common/safe_browsing_prefs.h" +#include "components/saved_tab_groups/pref_names.h" +#include "components/search_engines/template_url_prepopulate_data.h" +#include "components/security_interstitials/content/insecure_form_blocking_page.h" +#include "components/security_interstitials/content/stateful_ssl_host_state_delegate.h" +#include "components/segmentation_platform/embedder/default_model/device_switcher_result_dispatcher.h" +#include "components/segmentation_platform/public/segmentation_platform_service.h" +#include "components/sessions/core/session_id_generator.h" +#include "components/signin/public/base/signin_pref_names.h" +#include "components/signin/public/base/signin_prefs.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/site_engagement/content/site_engagement_service.h" +#include "components/subresource_filter/content/shared/browser/ruleset_service.h" +#include "components/subresource_filter/core/common/constants.h" +#include "components/supervised_user/core/browser/supervised_user_preferences.h" +#include "components/sync/base/pref_names.h" +#include "components/sync/service/glue/sync_transport_data_prefs.h" +#include "components/sync/service/sync_prefs.h" +#include "components/sync_device_info/device_info_prefs.h" +#include "components/sync_preferences/pref_service_syncable.h" +#include "components/sync_sessions/session_sync_prefs.h" +#include "components/tpcd/metadata/browser/prefs.h" +#include "components/tracing/common/pref_names.h" +#include "components/translate/core/browser/translate_prefs.h" +#include "components/update_client/update_client.h" +#include "components/variations/service/variations_service.h" +#include "content/public/browser/render_process_host.h" +#include "extensions/buildflags/buildflags.h" +#include "net/http/http_server_properties_manager.h" +#include "pdf/buildflags.h" +#include "ppapi/buildflags/buildflags.h" +#include "printing/buildflags/buildflags.h" +#include "rlz/buildflags/buildflags.h" +#include "services/screen_ai/buildflags/buildflags.h" + +#if BUILDFLAG(ENABLE_BACKGROUND_MODE) +#include "chrome/browser/background/background_mode_manager.h" +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "chrome/browser/accessibility/animation_policy_prefs.h" +#include "chrome/browser/apps/platform_apps/shortcut_manager.h" +#include "chrome/browser/extensions/activity_log/activity_log.h" +#include "chrome/browser/extensions/api/commands/command_service.h" +#include "chrome/browser/extensions/api/tabs/tabs_api.h" +#include "chrome/browser/extensions/extension_web_ui.h" +#include "chrome/browser/extensions/preinstalled_apps.h" +#include "chrome/browser/ui/extensions/settings_api_bubble_helpers.h" +#include "chrome/browser/ui/webui/extensions/extensions_ui.h" +#include "extensions/browser/api/audio/audio_api.h" +#include "extensions/browser/api/runtime/runtime_api.h" +#include "extensions/browser/extension_prefs.h" +#include "extensions/browser/permissions_manager.h" +#include "extensions/browser/pref_names.h" +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/crosapi/browser_data_migrator.h" +#include "chrome/browser/ash/device_name/device_name_store.h" +#include "chrome/browser/ash/extensions/extensions_permissions_tracker.h" +#include "chrome/browser/ash/kerberos/kerberos_credentials_manager.h" +#include "chrome/browser/ash/net/system_proxy_manager.h" +#include "chrome/browser/ash/platform_keys/key_permissions/key_permissions_manager_impl.h" +#include "chrome/browser/ash/policy/networking/euicc_status_uploader.h" +#include "chrome/browser/ash/policy/remote_commands/crd/crd_admin_session_controller.h" +#include "chrome/browser/ash/settings/hardware_data_usage_controller.h" +#include "chrome/browser/ash/settings/stats_reporting_controller.h" +#include "chrome/browser/ash/system_web_apps/apps/media_app/media_app_guest_ui_config.h" +#include "chrome/browser/component_updater/metadata_table_chromeos.h" +#include "chrome/browser/extensions/api/shared_storage/shared_storage_private_api.h" +#include "chrome/browser/ui/ash/projector/projector_app_client_impl.h" +#include "chrome/browser/ui/webui/ash/edu_coexistence/edu_coexistence_login_handler.h" +#include "chrome/browser/ui/webui/signin/ash/inline_login_handler_impl.h" +#include "chromeos/ash/components/carrier_lock/carrier_lock_manager.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + +#if BUILDFLAG(ENABLE_PDF) +#include "chrome/browser/pdf/pdf_pref_names.h" +#endif // BUILDFLAG(ENABLE_PDF) + +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) +#include "chrome/browser/screen_ai/pref_names.h" +#endif + +#include "components/feed/buildflags.h" +#if BUILDFLAG(ENABLE_FEED_V2) +#include "components/feed/core/common/pref_names.h" // nogncheck +#include "components/feed/core/shared_prefs/pref_names.h" // nogncheck +#include "components/feed/core/v2/ios_shared_prefs.h" // nogncheck +#endif + +#if BUILDFLAG(IS_ANDROID) +#include "chrome/browser/accessibility/accessibility_prefs/android/accessibility_prefs_controller.h" +#include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h" +#include "chrome/browser/android/ntp/recent_tabs_page_prefs.h" +#include "chrome/browser/android/oom_intervention/oom_intervention_decider.h" +#include "chrome/browser/android/preferences/browser_prefs_android.h" +#include "chrome/browser/android/preferences/shared_preferences_migrator_android.h" +#include "chrome/browser/android/usage_stats/usage_stats_bridge.h" +#include "chrome/browser/first_run/android/first_run_prefs.h" +#include "chrome/browser/lens/android/lens_prefs.h" +#include "chrome/browser/media/android/cdm/media_drm_origin_id_manager.h" +#include "chrome/browser/notifications/notification_channels_provider_android.h" +#include "chrome/browser/password_manager/android/password_manager_android_util.h" +#include "chrome/browser/readaloud/android/prefs.h" +#include "chrome/browser/ssl/known_interception_disclosure_infobar_delegate.h" +#include "components/cdm/browser/media_drm_storage_impl.h" // nogncheck crbug.com/1125897 +#include "components/ntp_tiles/popular_sites_impl.h" +#include "components/permissions/contexts/geolocation_permission_context_android.h" +#include "components/query_tiles/tile_service_prefs.h" +#include "components/webapps/browser/android/install_prompt_prefs.h" +#else // BUILDFLAG(IS_ANDROID) +#include "chrome/browser/cart/cart_service.h" +#include "chrome/browser/companion/core/promo_handler.h" +#include "chrome/browser/device_api/device_service_impl.h" +#include "chrome/browser/gcm/gcm_product_util.h" +#include "chrome/browser/hid/hid_policy_allowed_devices.h" +#include "chrome/browser/intranet_redirect_detector.h" +#include "chrome/browser/media/unified_autoplay_config.h" +#include "chrome/browser/metrics/tab_stats/tab_stats_tracker.h" +#include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" +#include "chrome/browser/new_tab_page/modules/file_suggestion/drive_service.h" +#include "chrome/browser/new_tab_page/modules/safe_browsing/safe_browsing_handler.h" +#include "chrome/browser/new_tab_page/modules/v2/calendar/google_calendar_page_handler.h" +#include "chrome/browser/new_tab_page/modules/v2/most_relevant_tab_resumption/most_relevant_tab_resumption_page_handler.h" +#include "chrome/browser/new_tab_page/modules/v2/tab_resumption/tab_resumption_page_handler.h" +#include "chrome/browser/new_tab_page/promos/promo_service.h" +#include "chrome/browser/policy/developer_tools_policy_handler.h" +#include "chrome/browser/search/background/ntp_custom_background_service.h" +#include "chrome/browser/search_engine_choice/search_engine_choice_dialog_service.h" +#include "chrome/browser/serial/serial_policy_allowed_ports.h" +#include "chrome/browser/signin/signin_promo.h" +#include "chrome/browser/ui/commerce/commerce_ui_tab_helper.h" +#include "chrome/browser/ui/startup/startup_browser_creator.h" +#include "chrome/browser/ui/webui/cr_components/theme_color_picker/theme_color_picker_handler.h" +#include "chrome/browser/ui/webui/history/foreign_session_handler.h" +#include "chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h" +#include "chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.h" +#include "chrome/browser/ui/webui/settings/settings_ui.h" +#include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.h" +#include "chrome/browser/ui/webui/tab_search/tab_search_prefs.h" +#include "chrome/browser/upgrade_detector/upgrade_detector.h" +#include "components/headless/policy/headless_mode_prefs.h" +#include "components/lens/lens_overlay_permission_utils.h" +#include "components/live_caption/live_caption_controller.h" +#include "components/live_caption/live_translate_controller.h" +#include "components/ntp_tiles/custom_links_manager_impl.h" +#include "components/user_notes/user_notes_prefs.h" +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) +#include "chrome/browser/ui/webui/whats_new/whats_new_ui.h" +#endif + +#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +#include "chrome/browser/promos/promos_utils.h" +#endif // !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + +#if BUILDFLAG(IS_CHROMEOS) +#include "chrome/browser/chromeos/extensions/echo_private/echo_private_api.h" +#include "chrome/browser/chromeos/extensions/login_screen/login/login_api_prefs.h" +#include "chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl.h" +#include "chrome/browser/chromeos/quickoffice/quickoffice_prefs.h" +#include "chrome/browser/chromeos/reporting/metric_reporting_prefs.h" +#include "chrome/browser/extensions/api/document_scan/document_scan_api_handler.h" +#include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" +#include "chrome/browser/memory/oom_kills_monitor.h" +#include "chrome/browser/policy/annotations/blocklist_handler.h" +#include "chrome/browser/policy/networking/policy_cert_service.h" +#include "chrome/browser/policy/system_features_disable_list_policy_handler.h" +#include "chrome/browser/ui/webui/certificates_handler.h" +#include "chromeos/ui/wm/fullscreen/pref_names.h" +#if BUILDFLAG(USE_CUPS) +#include "chrome/browser/extensions/api/printing/printing_api_handler.h" +#endif // BUILDFLAG(USE_CUPS) +#endif // BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "ash/components/arc/arc_prefs.h" +#include "ash/constants/ash_pref_names.h" +#include "ash/public/cpp/ash_prefs.h" +#include "chrome/browser/apps/app_discovery_service/almanac_fetcher.h" +#include "chrome/browser/apps/app_preload_service/app_preload_service.h" +#include "chrome/browser/apps/app_service/metrics/app_platform_metrics_service.h" +#include "chrome/browser/apps/app_service/webapk/webapk_prefs.h" +#include "chrome/browser/ash/account_manager/account_apps_availability.h" +#include "chrome/browser/ash/account_manager/account_manager_edu_coexistence_controller.h" +#include "chrome/browser/ash/app_list/app_list_syncable_service.h" +#include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h" +#include "chrome/browser/ash/app_mode/kiosk_chrome_app_manager.h" +#include "chrome/browser/ash/app_mode/kiosk_cryptohome_remover.h" +#include "chrome/browser/ash/app_mode/kiosk_system_session.h" +#include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h" +#include "chrome/browser/ash/app_restore/full_restore_prefs.h" +#include "chrome/browser/ash/apps/apk_web_app_service.h" +#include "chrome/browser/ash/arc/boot_phase_monitor/arc_boot_phase_monitor_bridge.h" +#include "chrome/browser/ash/arc/policy/arc_policy_bridge.h" +#include "chrome/browser/ash/arc/session/arc_session_manager.h" +#include "chrome/browser/ash/bluetooth/debug_logs_manager.h" +#include "chrome/browser/ash/bluetooth/hats_bluetooth_revamp_trigger_impl.h" +#include "chrome/browser/ash/borealis/borealis_prefs.h" +#include "chrome/browser/ash/bruschetta/bruschetta_pref_names.h" +#include "chrome/browser/ash/cert_provisioning/cert_provisioning_common.h" +#include "chrome/browser/ash/child_accounts/family_user_chrome_activity_metrics.h" +#include "chrome/browser/ash/child_accounts/family_user_metrics_service.h" +#include "chrome/browser/ash/child_accounts/family_user_session_metrics.h" +#include "chrome/browser/ash/child_accounts/parent_access_code/parent_access_service.h" +#include "chrome/browser/ash/child_accounts/screen_time_controller.h" +#include "chrome/browser/ash/child_accounts/time_limits/app_activity_registry.h" +#include "chrome/browser/ash/child_accounts/time_limits/app_time_controller.h" +#include "chrome/browser/ash/crosapi/browser_util.h" +#include "chrome/browser/ash/crostini/crostini_pref_names.h" +#include "chrome/browser/ash/cryptauth/client_app_metadata_provider_service.h" +#include "chrome/browser/ash/cryptauth/cryptauth_device_id_provider_impl.h" +#include "chrome/browser/ash/customization/customization_document.h" +#include "chrome/browser/ash/file_manager/file_manager_pref_names.h" +#include "chrome/browser/ash/file_manager/file_tasks.h" +#include "chrome/browser/ash/file_system_provider/registry.h" +#include "chrome/browser/ash/first_run/first_run.h" +#include "chrome/browser/ash/floating_workspace/floating_workspace_util.h" +#include "chrome/browser/ash/guest_os/guest_id.h" +#include "chrome/browser/ash/guest_os/guest_os_pref_names.h" +#include "chrome/browser/ash/guest_os/guest_os_terminal.h" +#include "chrome/browser/ash/lock_screen_apps/state_controller.h" +#include "chrome/browser/ash/login/demo_mode/demo_mode_resources_remover.h" +#include "chrome/browser/ash/login/demo_mode/demo_session.h" +#include "chrome/browser/ash/login/demo_mode/demo_setup_controller.h" +#include "chrome/browser/ash/login/quick_unlock/fingerprint_storage.h" +#include "chrome/browser/ash/login/quick_unlock/pin_storage_prefs.h" +#include "chrome/browser/ash/login/quick_unlock/quick_unlock_utils.h" +#include "chrome/browser/ash/login/reporting/login_logout_reporter.h" +#include "chrome/browser/ash/login/saml/saml_profile_prefs.h" +#include "chrome/browser/ash/login/screens/enable_adb_sideloading_screen.h" +#include "chrome/browser/ash/login/screens/reset_screen.h" +#include "chrome/browser/ash/login/security_token_session_controller.h" +#include "chrome/browser/ash/login/session/chrome_session_manager.h" +#include "chrome/browser/ash/login/session/user_session_manager.h" +#include "chrome/browser/ash/login/signin/signin_error_notifier.h" +#include "chrome/browser/ash/login/signin/token_handle_fetcher.h" +#include "chrome/browser/ash/login/startup_utils.h" +#include "chrome/browser/ash/login/users/avatar/user_image_manager_impl.h" +#include "chrome/browser/ash/login/users/avatar/user_image_prefs.h" +#include "chrome/browser/ash/login/users/avatar/user_image_sync_observer.h" +#include "chrome/browser/ash/net/ash_proxy_monitor.h" +#include "chrome/browser/ash/net/network_throttling_observer.h" +#include "chrome/browser/ash/plugin_vm/plugin_vm_pref_names.h" +#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h" +#include "chrome/browser/ash/policy/core/device_cloud_policy_manager_ash.h" +#include "chrome/browser/ash/policy/core/dm_token_storage.h" +#include "chrome/browser/ash/policy/enrollment/auto_enrollment_client_impl.h" +#include "chrome/browser/ash/policy/enrollment/enrollment_requisition_manager.h" +#include "chrome/browser/ash/policy/external_data/handlers/device_wallpaper_image_external_data_handler.h" +#include "chrome/browser/ash/policy/handlers/adb_sideloading_allowance_mode_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/minimum_version_policy_handler.h" +#include "chrome/browser/ash/policy/handlers/tpm_auto_update_mode_policy_handler.h" +#include "chrome/browser/ash/policy/reporting/app_install_event_log_manager_wrapper.h" +#include "chrome/browser/ash/policy/reporting/arc_app_install_event_logger.h" +#include "chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_prefs.h" +#include "chrome/browser/ash/policy/scheduled_task_handler/reboot_notifications_scheduler.h" +#include "chrome/browser/ash/policy/status_collector/device_status_collector.h" +#include "chrome/browser/ash/policy/status_collector/status_collector.h" +#include "chrome/browser/ash/power/auto_screen_brightness/metrics_reporter.h" +#include "chrome/browser/ash/power/power_metrics_reporter.h" +#include "chrome/browser/ash/preferences.h" +#include "chrome/browser/ash/printing/cups_printers_manager.h" +#include "chrome/browser/ash/printing/enterprise/enterprise_printers_provider.h" +#include "chrome/browser/ash/release_notes/release_notes_storage.h" +#include "chrome/browser/ash/scanning/chrome_scanning_app_delegate.h" +#include "chrome/browser/ash/scheduler_configuration_manager.h" +#include "chrome/browser/ash/settings/device_settings_cache.h" +#include "chrome/browser/ash/system/automatic_reboot_manager.h" +#include "chrome/browser/ash/system/input_device_settings.h" +#include "chrome/browser/ash/system_web_apps/apps/help_app/help_app_notification_controller.h" +#include "chrome/browser/device_identity/chromeos/device_oauth2_token_store_chromeos.h" +#include "chrome/browser/extensions/extension_assets_manager_chromeos.h" +#include "chrome/browser/media/protected_media_identifier_permission_context.h" +#include "chrome/browser/metrics/chromeos_metrics_provider.h" +#include "chrome/browser/ui/ash/shelf/chrome_shelf_prefs.h" +#include "chrome/browser/ui/webui/ash/login/enable_debugging_screen_handler.h" +#include "chrome/browser/ui/webui/ash/settings/os_settings_ui.h" +#include "chrome/browser/ui/webui/settings/reset_settings_handler.h" +#include "chrome/browser/upgrade_detector/upgrade_detector_chromeos.h" +#include "chromeos/ash/components/audio/audio_devices_pref_handler_impl.h" +#include "chromeos/ash/components/local_search_service/search_metrics_reporter.h" +#include "chromeos/ash/components/network/cellular_esim_profile_handler_impl.h" +#include "chromeos/ash/components/network/cellular_metrics_logger.h" +#include "chromeos/ash/components/network/fast_transition_observer.h" +#include "chromeos/ash/components/network/managed_cellular_pref_handler.h" +#include "chromeos/ash/components/network/network_metadata_store.h" +#include "chromeos/ash/components/network/proxy/proxy_config_handler.h" +#include "chromeos/ash/components/report/report_controller.h" +#include "chromeos/ash/components/standalone_browser/migrator_util.h" +#include "chromeos/ash/components/timezone/timezone_resolver.h" +#include "chromeos/ash/services/assistant/public/cpp/assistant_prefs.h" +#include "chromeos/ash/services/auth_factor_config/auth_factor_config.h" +#include "chromeos/ash/services/bluetooth_config/bluetooth_power_controller_impl.h" +#include "chromeos/ash/services/bluetooth_config/device_name_manager_impl.h" +#include "chromeos/ash/services/device_sync/public/cpp/device_sync_prefs.h" +#include "chromeos/ash/services/multidevice_setup/multidevice_setup_service.h" +#include "chromeos/components/quick_answers/public/cpp/quick_answers_prefs.h" +#include "components/account_manager_core/chromeos/account_manager.h" +#include "components/onc/onc_pref_names.h" +#include "components/quirks/quirks_manager.h" +#include "components/user_manager/user_manager_base.h" +#include "extensions/browser/api/lock_screen_data/lock_screen_item_storage.h" +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_MAC) +#include "chrome/browser/media/webrtc/system_media_capture_permissions_stats_mac.h" +#include "chrome/browser/ui/cocoa/apps/quit_with_apps_controller_mac.h" +#include "chrome/browser/ui/cocoa/confirm_quit.h" +#include "chrome/browser/web_applications/os_integration/mac/app_shim_registry.h" +#endif + +#if BUILDFLAG(IS_WIN) +#include "chrome/browser/font_prewarmer_tab_helper.h" +#include "chrome/browser/media/cdm_pref_service_helper.h" +#include "chrome/browser/media/media_foundation_service_monitor.h" +#include "chrome/browser/os_crypt/app_bound_encryption_provider_win.h" +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) +#include "chrome/browser/win/conflicts/incompatible_applications_updater.h" +#include "chrome/browser/win/conflicts/module_database.h" +#include "chrome/browser/win/conflicts/third_party_conflicts_manager.h" +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) +#endif // BUILDFLAG(IS_WIN) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) +#include "chrome/browser/enterprise/platform_auth/platform_auth_policy_observer.h" +#include "components/os_crypt/sync/os_crypt.h" +#endif + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS_ASH) +#include "components/device_signals/core/browser/pref_names.h" // nogncheck due to crbug.com/1125897 +#endif + +// TODO(crbug.com/40118868): Revisit the macro expression once build flag switch +// of lacros-chrome is complete. +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \ + (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) +#include "chrome/browser/browser_switcher/browser_switcher_prefs.h" +#endif + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) +#include "chrome/browser/enterprise/signin/enterprise_signin_prefs.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/apps/app_service/metrics/website_metrics_service_lacros.h" +#include "chrome/browser/lacros/account_manager/account_cache.h" +#include "chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h" +#include "chrome/browser/lacros/lacros_prefs.h" +#include "chrome/browser/lacros/net/proxy_config_service_lacros.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(ENABLE_DICE_SUPPORT) +#include "chrome/browser/ui/startup/first_run_service.h" +#endif + +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) +#include "chrome/browser/downgrade/downgrade_prefs.h" +#endif + +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/device_identity/device_oauth2_token_store_desktop.h" +#include "chrome/browser/ui/startup/default_browser_prompt/default_browser_prompt.h" +#endif + +#if defined(TOOLKIT_VIEWS) +#include "chrome/browser/ui/browser_view_prefs.h" +#include "chrome/browser/ui/side_search/side_search_prefs.h" +#endif + +#if BUILDFLAG(ENABLE_SESSION_SERVICE) +#include "chrome/browser/sessions/session_data_service.h" +#include "chrome/browser/sessions/session_service_log.h" +#endif + +#if BUILDFLAG(IS_LINUX) +#include "ui/color/system_theme.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/wallpaper_handlers/wallpaper_prefs.h" +#endif + +#if BUILDFLAG(ENTERPRISE_DATA_CONTROLS) +#include "components/enterprise/data_controls/core/prefs.h" +#endif + +namespace { + +// Please keep the list of deprecated prefs in chronological order. i.e. Add to +// the bottom of the list, not here at the top. + +// Deprecated 08/2023. +const char kDriveFsBulkPinningMaxQueueSize[] = + "drivefs.bulk_pinning.max_queue_size"; + +// Deprecated 09/2023. +const char kPrivacySandboxM1Unrestricted[] = "privacy_sandbox.m1.unrestricted"; +#if BUILDFLAG(IS_WIN) +const char kSwReporter[] = "software_reporter"; +const char kChromeCleaner[] = "chrome_cleaner"; +const char kSettingsResetPrompt[] = "settings_reset_prompt"; +#endif +// A boolean specifying whether the new download bubble UI is enabled. If it is +// set to false, the old download shelf UI will be shown instead. +const char kDownloadBubbleEnabled[] = "download_bubble_enabled"; + +// Deprecated 09/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) +const char kGestureEducationNotificationShown[] = + "ash.gesture_education.notification_shown"; + +// Note that this very name is used outside ChromeOS Ash, where it isn't +// deprecated. +const char kSyncInitialSyncFeatureSetupCompleteOnAsh[] = + "sync.has_setup_completed"; +#endif + +// Deprecated 09/2023. +const char kPrivacySandboxManuallyControlled[] = + "privacy_sandbox.manually_controlled"; + +// Deprecated 09/2023. +#if BUILDFLAG(IS_ANDROID) +const char kSettingsMigratedToUPM[] = "profile.settings_migrated_to_upm"; +#endif + +// Deprecated 10/2023. +const char kSyncRequested[] = "sync.requested"; +const char kDownloadLastCompleteTime[] = "download.last_complete_time"; + +// Deprecated 10/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) +const char kLastSuccessfulDomainPref[] = "android_sms.last_successful_domain"; +const char kShouldAttemptReenable[] = "android_sms.should_attempt_reenable"; +const char kAudioVolumePercent[] = "settings.audio.volume_percent"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 10/2023. +#if BUILDFLAG(IS_CHROMEOS) +const char kSupportedLinksAppPrefsKey[] = "supported_links_infobar.apps"; +#endif // BUILDFLAG(IS_CHROMEOS) + +// Deprecated 10/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kNightLightCachedLatitude[] = "ash.night_light.cached_latitude"; +constexpr char kNightLightCachedLongitude[] = + "ash.night_light.cached_longitude"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 11/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kUserGeolocationAllowed[] = "ash.user.geolocation_allowed"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 11/2023. +const char kPrivacySandboxAntiAbuseInitialized[] = + "privacy_sandbox.anti_abuse_initialized"; + +// Deprecated 11/2023. +constexpr char kWebRTCAllowLegacyTLSProtocols[] = + "webrtc.allow_legacy_tls_protocols"; + +// Deprecated 11/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kSystemTrayExpanded[] = "ash.system_tray.expanded"; +#endif + +// Deprecated 11/2023. +constexpr char kPasswordChangeSuccessTrackerFlows[] = + "password_manager.password_change_success_tracker.flows"; +constexpr char kPasswordChangeSuccessTrackerVersion[] = + "password_manager.password_change_success_tracker.version"; + +// Deprecated 11/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kImageSearchPrivacyNotice[] = + "ash.launcher.image_search_privacy_notice"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 11/2023. +constexpr char kWebAndAppActivityEnabledForShopping[] = + "web_and_app_activity_enabled_for_shopping"; + +// Deprecated 12/2023. +#if BUILDFLAG(IS_ANDROID) +const char kTemplatesRandomOrder[] = "content_creation.notes.random_order"; +#endif + +// Deprecated 12/2023. +#if BUILDFLAG(IS_ANDROID) +const char kDesktopSitePeripheralSettingEnabled[] = + "desktop_site.peripheral_setting"; +const char kDesktopSiteDisplaySettingEnabled[] = "desktop_site.display_setting"; +#endif + +// Deprecated 12/2023. +constexpr char kDownloadDuplicateFilePromptEnabled[] = + "download_duplicate_file_prompt_enabled"; + +// Deprecated 12/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kIsolatedWebAppsEnabled[] = "ash.isolated_web_apps_enabled"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 12/2023. +const char kPrivacyBudgetReportedReidBlocks[] = + "privacy_budget.reported_reid_blocks"; + +// Deprecated from profile prefs 12/2023. +const char kModelQualityLoggingClientId[] = + "optimization_guide.model_quality_logging_client_id"; + +// Deprecated 12/2023. +const char kSync_ExplicitBrowserSignin[] = "sync.explicit_browser_signin"; + +// Deprecated 01/2024. +const char kPrivacySandboxPageViewed[] = "privacy_sandbox.page_viewed"; + +// Deprecated 01/2024. +const char kPrivacySandboxApisEnabledV2[] = "privacy_sandbox.apis_enabled_v2"; +const char kPrivacySandboxManuallyControlledV2[] = + "privacy_sandbox.manually_controlled_v2"; + +// Deprecated 01/2024. +#if BUILDFLAG(ENABLE_COMPOSE) +constexpr char kPrefHasAcceptedComposeConsent[] = + "compose_has_accepted_consent"; +constexpr char kAutofillAssistanceEnabled[] = "autofill_assistance.enabled"; +#endif + +// Deprecated 01/2024. +const char kSyncedLastTimePasswordCheckCompleted[] = + "profile.credentials_last_password_checkup_time"; + +// Deprecated 01/2024. +const char kDownloadBubbleIphSuppression[] = "suppress_download_bubble_iph"; + +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 01/2024. +const char kPersistedSystemExtensions[] = "system_extensions.persisted"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 01/2024. +const char kPPAPISharedImagesForVideoDecoderAllowed[] = + "policy.ppapi_shared_images_for_video_decoder_allowed"; + +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 01/2024. +const char kBorealisVmTokenHash[] = "borealis.vm_token_hash"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 01/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kExtendedFkeysModifier[] = + "ash.settings.extended_fkeys_modifier"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 01/2024. +constexpr char kNtpShownPage[] = "ntp.shown_page"; +constexpr char kNtpAppPageNames[] = "ntp.app_page_names"; + +// Deprecated 01/2024. +#if BUILDFLAG(IS_WIN) +const char kSearchResultsPagePrimaryFontsPref[] = + "cached_fonts.search_results_page.primary"; +const char kSearchResultsPageFallbackFontsPref[] = + "cached_fonts.search_results_page.fallback"; +#endif // BUILDFLAG(IS_WIN) + +// Deprecated 01/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kUpdateNotificationLastShownMilestone[] = + "update_notification_last_shown_milestone"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 02/2024. +#if BUILDFLAG(IS_ANDROID) +constexpr char kSavePasswordsSuspendedByError[] = + "profile.save_passwords_suspended_by_error"; +#endif +constexpr char kSafeBrowsingDeepScanPromptSeen[] = + "safebrowsing.deep_scan_prompt_seen"; +constexpr char kSafeBrowsingEsbEnabledTimestamp[] = + "safebrowsing.esb_enabled_timestamp"; + +#if BUILDFLAG(IS_MAC) +constexpr char kScreenTimeEnabled[] = "policy.screen_time"; +#endif + +// Deprecated 02/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr std::array + kWelcomeTourTimeBucketsOfFirstInteractions = { + "ash.welcome_tour.interaction_time.ExploreApp.first_time_bucket", + "ash.welcome_tour.interaction_time.FilesApp.first_time_bucket", + "ash.welcome_tour.interaction_time.Launcher.first_time_bucket", + "ash.welcome_tour.interaction_time.QuickSettings.first_time_bucket", + "ash.welcome_tour.interaction_time.Search.first_time_bucket", + "ash.welcome_tour.interaction_time.SettingsApp.first_time_bucket", +}; + +// Deprecated 02/2024. +constexpr char kDiscoverTabSuggestionChipTimesLeftToShow[] = + "times_left_to_show_discover_tab_suggestion_chip"; +#endif + +// Deprecated 02/2024 +constexpr char kSearchEnginesChoiceProfile[] = "search_engines.choice_profile"; + +// Deprecated 02/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kHatsUnlockSurveyCycleEndTs[] = + "hats_unlock_cycle_end_timestamp"; +constexpr char kHatsUnlockDeviceIsSelected[] = "hats_unlock_device_is_selected"; +constexpr char kHatsSmartLockSurveyCycleEndTs[] = + "hats_smartlock_cycle_end_timestamp"; +constexpr char kHatsSmartLockDeviceIsSelected[] = + "hats_smartlock_device_is_selected"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 02/2024 +constexpr char kResetCheckDefaultBrowser[] = + "browser.should_reset_check_default_browser"; + +#if BUILDFLAG(IS_WIN) +// Deprecated 02/2024 +constexpr char kOsCryptAppBoundFixedDataPrefName[] = + "os_crypt.app_bound_fixed_data"; +// Deprecated 03/2024 +constexpr char kOsCryptAppBoundFixedData2PrefName[] = + "os_crypt.app_bound_fixed_data2"; +// Deprecated 06/2024 +constexpr char kOsCryptAppBoundFixedData3PrefName[] = + "os_crypt.app_bound_fixed_data3"; +#endif // BUILDFLAG(IS_WIN) + +// Deprecated 02/2024. +constexpr char kOfferReaderMode[] = "dom_distiller.offer_reader_mode"; + +// Deprecated 03/2024. +constexpr char kPlusAddressLastFetchedTime[] = "plus_address.last_fetched_time"; + +// Deprecated 03/2024. +constexpr char kPrivacySandboxApisEnabled[] = "privacy_sandbox.apis_enabled"; + +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 03/2024 +constexpr char kOobeGuestAcceptedTos[] = "oobe.guest_accepted_tos"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 04/2024 +constexpr char kLastUploadedEuiccStatusPrefLegacy[] = + "esim.last_upload_euicc_status"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 03/2024. +constexpr char kShowInternalAccessibilityTree[] = + "accessibility.show_internal_accessibility_tree"; + +// Deprecated 03/2024. +// A `kDefaultSearchProviderChoicePending` pref persists (migrated to a new +// pref name to reset the data), so the variable name has been changed here. +constexpr char kDefaultSearchProviderChoicePendingDeprecated[] = + "default_search_provider.choice_pending"; + +// Deprecated 03/2024. +constexpr char kTrackingProtectionSentimentSurveyGroup[] = + "tracking_protection.tracking_protection_sentiment_survey_group"; +constexpr char kTrackingProtectionSentimentSurveyStartTime[] = + "tracking_protection.tracking_protection_sentiment_survey_start_time"; +constexpr char kTrackingProtectionSentimentSurveyEndTime[] = + "tracking_protection.tracking_protection_sentiment_survey_end_time"; + +// Deprecated 03/2024 +constexpr char kPreferencesMigratedToBasic[] = + "browser.clear_data.preferences_migrated_to_basic"; + +// Deprecated 04/2024. +inline constexpr char kOmniboxInstantKeywordUsed[] = + "omnibox.instant_keyword_used"; + +// Deprecated 04/2024. +inline constexpr char kWebAppPreinstalledAppWindowExperiment[] = + "web_apps.preinstalled_app_window_experiment"; + +// Deprecated 04/2024. +inline constexpr char kDIPSTimerLastUpdate[] = "dips_timer_last_update"; + +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 04/2024 +constexpr char kMetricsUserInheritOwnerConsent[] = + "metrics.user_inherit_owner_consent"; +constexpr char kGlanceablesEnabled[] = "ash.glanceables_enabled"; + +// Deprecated 05/2024. +// A preference to keep track of the device registered time. +constexpr char kDeviceRegisteredTime[] = "DeviceRegisteredTime"; +constexpr char kArcKioskDictionaryName[] = "arc-kiosk"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if !BUILDFLAG(IS_ANDROID) +// Deprecated 05/2024 +inline constexpr char kSearchEnginesStudyGroup[] = + "search_engines.client_side_study_group"; +#endif + +#if !BUILDFLAG(IS_ANDROID) +// Deprecated 05/2024 +// Pref name for the whether whats new refresh page has been shown +// successfully. +inline constexpr char kHasShownRefreshWhatsNew[] = + "browser.has_shown_refresh_2023_whats_new"; +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 05/2024 +// A boolean pref which determines if you can pause mouse keys with a +// keyboard shortcut. +inline constexpr char kAccessibilityMouseKeysShortcutToPauseEnabled[] = + "settings.a11y.mouse_keys.ctrl_to_pause_enabled"; +// A boolean pref which determines if mouse keys is automatically disabled in +// text fields. +inline constexpr char kAccessibilityMouseKeysDisableInTextFields[] = + "settings.a11y.mouse_keys.disable_in_text_fields"; +// A boolean pref which determines whether screen magnifier should center +// the text input focus. +inline constexpr char kAccessibilityScreenMagnifierCenterFocus[] = + "settings.a11y.screen_magnifier_center_focus"; +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 05/2024. +constexpr char kBlockTruncatedCookies[] = "profile.cookie_block_truncated"; + +// Deprecated 05/2024 +inline constexpr char kDefaultSearchProviderChoiceLocationPrefName[] = + "default_search_provider_data.choice_location"; + +// Deprecated 05/2024. +inline constexpr char kSyncCachedTrustedVaultAutoUpgradeDebugInfo[] = + "sync.cached_trusted_vault_auto_upgrade_debug_info"; + +// Deprecated 05/2024. +inline constexpr char kAutologinEnabled[] = "autologin.enabled"; +inline constexpr char kReverseAutologinRejectedEmailList[] = + "reverse_autologin.rejected_email_list"; + +// Deprecated 06/2024. +inline constexpr char kTrackingProtectionOnboardingNoticeFirstRequested[] = + "tracking_protection.tracking_protection_onboarding_notice_first_requested"; +inline constexpr char kTrackingProtectionOnboardingNoticeLastRequested[] = + "tracking_protection.tracking_protection_onboarding_notice_last_requested"; + +// Deprecated 06/2024. +#if !BUILDFLAG(IS_ANDROID) +inline constexpr char kAccessibilityReadAnythingOmniboxIconLabelShownCount[] = + "settings.a11y.read_anything.omnibox_icon_label_shown_count"; +#endif + +// Deprecated 06/2024. +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) +inline constexpr char kAccessibilityPdfOcrAlwaysActive[] = + "settings.a11y.pdf_ocr_always_active"; +#endif + +// Deprecated 06/2024. +inline constexpr char kTrackingProtectionOffboarded[] = + "tracking_protection.tracking_protection_offboarded"; +inline constexpr char kTrackingProtectionOffboardedSince[] = + "tracking_protection.tracking_protection_offboarded_since"; +inline constexpr char kTrackingProtectionOffboardingAckAction[] = + "tracking_protection.tracking_protection_offboarding_ack_action"; + +#if BUILDFLAG(IS_CHROMEOS_ASH) +// Deprecated 06/2024. +constexpr std::array + kHoldingSpaceWallpaperNudgeTimesOfFirstInteraction = { + "ash.holding_space.wallpaper_nudge.interaction_time." + "DroppedFileOnHoldingSpace.first_time", + "ash.holding_space.wallpaper_nudge.interaction_time." + "DroppedFileOnWallpaper.first_time", + "ash.holding_space.wallpaper_nudge.interaction_time." + "DraggedFileOverWallpaper.first_time", + "ash.holding_space.wallpaper_nudge.interaction_time.OpenedHoldingSpace." + "first_time", + "ash.holding_space.wallpaper_nudge.interaction_time." + "PinnedFileFromAnySource.first_time", + "ash.holding_space.wallpaper_nudge.interaction_time." + "PinnedFileFromContextMenu.first_time", + "ash.holding_space.wallpaper_nudge.interaction_time." + "PinnedFileFromFilesApp.first_time", + "ash.holding_space.wallpaper_nudge.interaction_time." + "PinnedFileFromHoldingSpaceDrop.first_time", + "ash.holding_space.wallpaper_nudge.interaction_time." + "PinnedFileFromPinButton.first_time", + "ash.holding_space.wallpaper_nudge.interaction_time." + "PinnedFileFromWallpaperDrop.first_time", + "ash.holding_space.wallpaper_nudge.interaction_time.UsedOtherItem." + "first_time", + "ash.holding_space.wallpaper_nudge.interaction_time.UsedPinnedItem." + "first_time", +}; + +// Deprecated 06/2024. +constexpr char kHoldingSpaceWallpaperNudgeLastTimeNudgeShownCounterfactual[] = + "ash.holding_space.wallpaper_nudge.last_shown_time_counterfactual"; +constexpr char kHoldingSpaceWallpaperNudgeLastTimeNudgeShown[] = + "ash.holding_space.wallpaper_nudge.last_shown_time"; +constexpr char kHoldingSpaceWallpaperNudgeNudgeShownCountCounterfactual[] = + "ash.holding_space.wallpaper_nudge.shown_count_counterfactual"; +constexpr char kHoldingSpaceWallpaperNudgeNudgeShownCount[] = + "ash.holding_space.wallpaper_nudge.shown_count"; +constexpr char kHoldingSpaceWallpaperNudgeUserEligibleForNudge[] = + "ash.holding_space.wallpaper_nudge.user_eligible"; +constexpr char kHoldingSpaceWallpaperNudgeUserFirstEligibleSessionTime[] = + "ash.holding_space.wallpaper_nudge.first_eligible_session_time"; + +// Deprecated 06/2024. +constexpr char kLocalUserFilesMigrationEnabled[] = + "filebrowser.local_user_files_migration_enabled"; + +// Deprecated 06/2024. +constexpr char kBirchUseRecentTabs[] = "ash.birch.use_recent_tabs"; +constexpr char kBirchUseLastActive[] = "ash.birch.use_last_active"; +constexpr char kBirchUseMostVisited[] = "ash.birch.use_most_visited"; +constexpr char kBirchUseSelfShare[] = "ash.birch.use_self_share"; +#endif + +// Deprecated 06/2024 +constexpr char kDefaultSearchProviderChoicePending[] = + "default_search_provider.engine_choice_pending"; + +// Deprecated 07/2024 +#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(ENABLE_DICE_SUPPORT) +inline constexpr char kFirstRunStudyGroup[] = "browser.first_run_study_group"; +#endif + +#if !BUILDFLAG(IS_ANDROID) +// Deprecated 07/2024 +constexpr char kNtpRecipesDismissedTasks[] = "NewTabPage.DismissedRecipeTasks"; +constexpr char kNtpModulesFirstShownTime[] = "NewTabPage.ModulesFirstShownTime"; +constexpr char kNtpModulesFreVisible[] = "NewTabPage.ModulesFreVisible"; +constexpr char kNtpModulesShownCount[] = "NewTabPage.ModulesShownCount"; +constexpr char kNtpPhotosLastDismissedTimePrefName[] = + "NewTabPage.Photos.LastDimissedTime"; +constexpr char kNtpPhotosOptInAcknowledgedPrefName[] = + "NewTabPage.Photos.OptInAcknowledged"; +constexpr char kNtpPhotosLastMemoryOpenTimePrefName[] = + "NewTabPage.Photos.LastMemoryOpenTime"; +constexpr char kNtpPhotosSoftOptOutCountPrefName[] = + "NewTabPage.Photos.SoftOptOutCount"; +constexpr char kNtpPhotosLastSoftOptedOutTimePrefName[] = + "NewTabPage.Photos.LastSoftOptedoutTime"; +#endif + +// Deprecated 07/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kAppDeduplicationServiceLastGetTimestamp[] = + "apps.app_deduplication_service.last_get_data_from_server_timestamp"; +#endif + +// Deprecated 07/2024 +#if BUILDFLAG(IS_CHROMEOS_ASH) +constexpr char kShowTunaScreenEnabled[] = "ash.tuna_screen_oobe_enabled"; +#endif + +// Register local state used only for migration (clearing or moving to a new +// key). +void RegisterLocalStatePrefsForMigration(PrefRegistrySimple* registry) { + // Deprecated 09/2023. +#if BUILDFLAG(IS_WIN) + registry->RegisterDictionaryPref(kSwReporter); + registry->RegisterDictionaryPref(kChromeCleaner); +#endif + + // Deprecated 09/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterBooleanPref(kGestureEducationNotificationShown, true); +#endif + + // Deprecated 11/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterBooleanPref(kIsolatedWebAppsEnabled, false); +#endif + + // Deprecated 12/2023. + registry->RegisterStringPref(kPrivacyBudgetReportedReidBlocks, std::string()); + + // Deprecated 01/2024. + registry->RegisterBooleanPref(kPPAPISharedImagesForVideoDecoderAllowed, true); + + // Deprecated 01/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterIntegerPref(kExtendedFkeysModifier, 0); +#endif + + // Deprecated 02/2024 +#if BUILDFLAG(IS_MAC) + registry->RegisterBooleanPref(kScreenTimeEnabled, true); +#endif + + // Deprecated 02/2024. + registry->RegisterFilePathPref(kSearchEnginesChoiceProfile, base::FilePath()); + +#if BUILDFLAG(IS_WIN) + // Deprecated 02/2024. + registry->RegisterStringPref(kOsCryptAppBoundFixedDataPrefName, + std::string()); + // Deprecated 03/2024. + registry->RegisterStringPref(kOsCryptAppBoundFixedData2PrefName, + std::string()); + // Deprecated 06/2024. + registry->RegisterStringPref(kOsCryptAppBoundFixedData3PrefName, + std::string()); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Deprecated 03/2024. + registry->RegisterBooleanPref(kOobeGuestAcceptedTos, false); + + // Deprecated 05/2024. + registry->RegisterTimePref(kDeviceRegisteredTime, base::Time()); + registry->RegisterDictionaryPref(kArcKioskDictionaryName); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 04/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterDictionaryPref(kLastUploadedEuiccStatusPrefLegacy); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if !BUILDFLAG(IS_ANDROID) + // Deprecated 05/2024. + registry->RegisterStringPref(kSearchEnginesStudyGroup, std::string()); +#endif + +#if !BUILDFLAG(IS_ANDROID) + // Deprecated 05/2024. + registry->RegisterBooleanPref(kHasShownRefreshWhatsNew, false); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Deprecated 06/2024. + registry->RegisterBooleanPref(kLocalUserFilesMigrationEnabled, false); +#endif +#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(ENABLE_DICE_SUPPORT) + // Deprecated 07/2024. + registry->RegisterStringPref(kFirstRunStudyGroup, std::string()); +#endif +} + +// Register prefs used only for migration (clearing or moving to a new key). +void RegisterProfilePrefsForMigration( + user_prefs::PrefRegistrySyncable* registry) { + chrome_browser_net::secure_dns::RegisterProbesSettingBackupPref(registry); + + // Deprecated 08/2023. + registry->RegisterIntegerPref(kDriveFsBulkPinningMaxQueueSize, 0); + + // Deprecated 09/2023. + registry->RegisterBooleanPref(kPrivacySandboxM1Unrestricted, false); +#if BUILDFLAG(IS_WIN) + registry->RegisterDictionaryPref(kSwReporter); + registry->RegisterDictionaryPref(kSettingsResetPrompt); + registry->RegisterDictionaryPref(kChromeCleaner); +#endif + registry->RegisterBooleanPref(kDownloadBubbleEnabled, true); + registry->RegisterBooleanPref(kPrivacySandboxManuallyControlled, false); +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterBooleanPref(kSyncInitialSyncFeatureSetupCompleteOnAsh, + false); +#endif +#if BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref(kSettingsMigratedToUPM, false); +#endif + registry->RegisterBooleanPref(kSyncRequested, false); + + // Deprecated 10/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterStringPref(kLastSuccessfulDomainPref, std::string()); + registry->RegisterBooleanPref(kShouldAttemptReenable, true); + registry->RegisterDoublePref(kAudioVolumePercent, 0); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterTimePref(kDownloadLastCompleteTime, base::Time()); + +// Deprecated 10/2023. +#if BUILDFLAG(IS_CHROMEOS) + registry->RegisterDictionaryPref(kSupportedLinksAppPrefsKey); +#endif // BUILDFLAG(IS_CHROMEOS) + +// Deprecated 10/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterDoublePref(kNightLightCachedLatitude, 0.0); + registry->RegisterDoublePref(kNightLightCachedLongitude, 0.0); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Deprecated 11/2023. + registry->RegisterBooleanPref(kPrivacySandboxAntiAbuseInitialized, false); + + // Deprecated 11/2023. + registry->RegisterBooleanPref(kWebRTCAllowLegacyTLSProtocols, false); + +// Deprecated 11/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterBooleanPref(kSystemTrayExpanded, true); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Deprecated 11/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterBooleanPref(kUserGeolocationAllowed, true); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Deprecated 11/2023. + registry->RegisterListPref(kPasswordChangeSuccessTrackerFlows); + registry->RegisterIntegerPref(kPasswordChangeSuccessTrackerVersion, 0); + + // Deprecated 11/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterDictionaryPref(kImageSearchPrivacyNotice); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Deprecated 11/2023. + registry->RegisterBooleanPref(kWebAndAppActivityEnabledForShopping, true); + + // Deprecated 12/2023. +#if BUILDFLAG(IS_ANDROID) + registry->RegisterListPref(kTemplatesRandomOrder); +#endif + +// Deprecated 12/2023. +#if BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref(kDesktopSitePeripheralSettingEnabled, false); + registry->RegisterBooleanPref(kDesktopSiteDisplaySettingEnabled, false); +#endif + + // Deprecated 12/2023. + registry->RegisterBooleanPref(kDownloadDuplicateFilePromptEnabled, true); + + // Deprecated 12/2023. + registry->RegisterInt64Pref(kModelQualityLoggingClientId, true); + registry->RegisterBooleanPref(kSync_ExplicitBrowserSignin, false); + + // Deprecated 01/2024. + registry->RegisterBooleanPref(kPrivacySandboxPageViewed, false); + + // Deprecated 01/2024. + registry->RegisterBooleanPref(kPrivacySandboxApisEnabledV2, false); + registry->RegisterBooleanPref(kPrivacySandboxManuallyControlledV2, false); + +// Deprecated 01/2024. +#if BUILDFLAG(ENABLE_COMPOSE) + registry->RegisterBooleanPref(kPrefHasAcceptedComposeConsent, false); + registry->RegisterBooleanPref(kAutofillAssistanceEnabled, false); +#endif + + // Deprecated 01/2024. + registry->RegisterTimePref(kSyncedLastTimePasswordCheckCompleted, + base::Time()); + + // Deprecated 01/2024. + registry->RegisterBooleanPref(kDownloadBubbleIphSuppression, false); + +// Deprecated 01/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterDictionaryPref(kPersistedSystemExtensions); + registry->RegisterStringPref(kBorealisVmTokenHash, ""); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Deprecated 01/2024. + registry->RegisterIntegerPref(kNtpShownPage, 0); + registry->RegisterListPref(kNtpAppPageNames); + + // Deprecated 01/2024. +#if BUILDFLAG(IS_WIN) + registry->RegisterListPref(kSearchResultsPagePrimaryFontsPref); + registry->RegisterListPref(kSearchResultsPageFallbackFontsPref); +#endif + + // Deprecated 01/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterIntegerPref(kUpdateNotificationLastShownMilestone, -10); +#endif + + // Deprecated 02/2024. +#if BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref(kSavePasswordsSuspendedByError, false); +#endif + registry->RegisterBooleanPref(kSafeBrowsingDeepScanPromptSeen, false); + registry->RegisterTimePref(kSafeBrowsingEsbEnabledTimestamp, base::Time()); + +// Deprecated 02/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + for (const char* pref : kWelcomeTourTimeBucketsOfFirstInteractions) { + registry->RegisterIntegerPref(pref, -1); + } + + // Deprecated 02/2024. + registry->RegisterIntegerPref(kDiscoverTabSuggestionChipTimesLeftToShow, 0); +#endif + + // Deprecated 02/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterInt64Pref(kHatsSmartLockSurveyCycleEndTs, 0); + registry->RegisterBooleanPref(kHatsSmartLockDeviceIsSelected, false); + registry->RegisterInt64Pref(kHatsUnlockSurveyCycleEndTs, 0); + registry->RegisterBooleanPref(kHatsUnlockDeviceIsSelected, false); +#endif + + // Deprecated 02/2024 + registry->RegisterBooleanPref(kResetCheckDefaultBrowser, false); + + // Deprecated 02/2024. + registry->RegisterBooleanPref(kOfferReaderMode, false); + + // Deprecated 03/2024. + registry->RegisterTimePref(kPlusAddressLastFetchedTime, base::Time()); + + // Deprecated 03/2024. + registry->RegisterBooleanPref(kPrivacySandboxApisEnabled, true); + + // Deprecated 03/2024. + registry->RegisterBooleanPref(kShowInternalAccessibilityTree, false); + + // Deprecated 03/2024. + registry->RegisterBooleanPref(kDefaultSearchProviderChoicePendingDeprecated, + false); + + // Deprecated 03/2024 + registry->RegisterIntegerPref(kTrackingProtectionSentimentSurveyGroup, 0); + registry->RegisterTimePref(kTrackingProtectionSentimentSurveyStartTime, + base::Time()); + registry->RegisterTimePref(kTrackingProtectionSentimentSurveyEndTime, + base::Time()); + + // Deprecated 03/2024. + registry->RegisterBooleanPref(kPreferencesMigratedToBasic, false); + + // Deprecated 04/2024. + registry->RegisterBooleanPref(kOmniboxInstantKeywordUsed, false); + + // Deprecated 04/2024. + registry->RegisterDictionaryPref(kWebAppPreinstalledAppWindowExperiment); + + // Deprecated 04/2024. + registry->RegisterTimePref(kDIPSTimerLastUpdate, base::Time()); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Deprecated 04/2024. + registry->RegisterBooleanPref(kMetricsUserInheritOwnerConsent, true); + registry->RegisterBooleanPref(kGlanceablesEnabled, true); + + // Deprecated 05/2024. + registry->RegisterBooleanPref(kAccessibilityMouseKeysShortcutToPauseEnabled, + true); + registry->RegisterBooleanPref(kAccessibilityMouseKeysDisableInTextFields, + true); + registry->RegisterBooleanPref(kAccessibilityScreenMagnifierCenterFocus, true); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Deprecated 05/2024. + registry->RegisterBooleanPref(kBlockTruncatedCookies, true); + + // Deprecated 05/2024 + registry->RegisterIntegerPref( + kDefaultSearchProviderChoiceLocationPrefName, + static_cast(search_engines::ChoiceMadeLocation::kOther)); + + // Deprecated 05/2024. + registry->RegisterStringPref(kSyncCachedTrustedVaultAutoUpgradeDebugInfo, ""); + + // Deprecated 05/2024. + registry->RegisterBooleanPref(kAutologinEnabled, true); + registry->RegisterListPref(kReverseAutologinRejectedEmailList); + + // Deprecated 06/2024. + registry->RegisterTimePref(kTrackingProtectionOnboardingNoticeFirstRequested, + base::Time()); + registry->RegisterTimePref(kTrackingProtectionOnboardingNoticeLastRequested, + base::Time()); + +// Deprecated 06/2024. +#if !BUILDFLAG(IS_ANDROID) + registry->RegisterIntegerPref( + kAccessibilityReadAnythingOmniboxIconLabelShownCount, 0); +#endif + +// Deprecated 06/2024. +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + registry->RegisterBooleanPref(kAccessibilityPdfOcrAlwaysActive, true); +#endif + + // Deprecated 06/2024. + registry->RegisterBooleanPref(kTrackingProtectionOffboarded, false); + registry->RegisterTimePref(kTrackingProtectionOffboardedSince, base::Time()); + registry->RegisterIntegerPref(kTrackingProtectionOffboardingAckAction, 0); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Deprecated 06/2024. + for (const char* pref : kHoldingSpaceWallpaperNudgeTimesOfFirstInteraction) { + registry->RegisterTimePref(pref, base::Time()); + } + + // Deprecated 06/2024. + registry->RegisterBooleanPref(kHoldingSpaceWallpaperNudgeUserEligibleForNudge, + false); + registry->RegisterTimePref( + kHoldingSpaceWallpaperNudgeLastTimeNudgeShownCounterfactual, + base::Time()); + registry->RegisterTimePref(kHoldingSpaceWallpaperNudgeLastTimeNudgeShown, + base::Time()); + registry->RegisterTimePref( + kHoldingSpaceWallpaperNudgeUserFirstEligibleSessionTime, base::Time()); + registry->RegisterUint64Pref( + kHoldingSpaceWallpaperNudgeNudgeShownCountCounterfactual, 0u); + registry->RegisterUint64Pref(kHoldingSpaceWallpaperNudgeNudgeShownCount, 0u); + + // Deprecated 06/2024 + registry->RegisterBooleanPref(kBirchUseRecentTabs, true); + registry->RegisterBooleanPref(kBirchUseLastActive, true); + registry->RegisterBooleanPref(kBirchUseMostVisited, true); + registry->RegisterBooleanPref(kBirchUseSelfShare, true); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Deprecated 06/2024. + registry->RegisterBooleanPref(kDefaultSearchProviderChoicePending, false); + +#if !BUILDFLAG(IS_ANDROID) + // Deprecated 07/2024 + registry->RegisterListPref(kNtpRecipesDismissedTasks); + registry->RegisterBooleanPref(kNtpModulesFreVisible, true); + registry->RegisterIntegerPref(kNtpModulesShownCount, 0); + registry->RegisterTimePref(kNtpModulesFirstShownTime, base::Time()); + registry->RegisterTimePref(kNtpPhotosLastDismissedTimePrefName, base::Time()); + registry->RegisterBooleanPref(kNtpPhotosOptInAcknowledgedPrefName, false); + registry->RegisterTimePref(kNtpPhotosLastMemoryOpenTimePrefName, + base::Time()); + registry->RegisterTimePref(kNtpPhotosLastSoftOptedOutTimePrefName, + base::Time()); + registry->RegisterIntegerPref(kNtpPhotosSoftOptOutCountPrefName, 0); +#endif + + // Deprecated 07/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + registry->RegisterTimePref(kAppDeduplicationServiceLastGetTimestamp, + base::Time()); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Deprecated 07/2024. + registry->RegisterBooleanPref(kShowTunaScreenEnabled, true); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) +} + +void ClearSyncRequestedPrefAndMaybeMigrate(PrefService* profile_prefs) { +#if BUILDFLAG(IS_CHROMEOS_ASH) + // On Ash specifically, if `kSyncRequested` was set to false explicitly, the + // value needs to be migrated to syncer::internal::kSyncDisabledViaDashboard. + if (profile_prefs->GetUserPrefValue(kSyncRequested) != nullptr && + !profile_prefs->GetUserPrefValue(kSyncRequested)->GetBool()) { + profile_prefs->SetBoolean( + syncer::prefs::internal::kSyncDisabledViaDashboard, true); + } +#endif + profile_prefs->ClearPref(kSyncRequested); +} + +} // namespace + +std::string GetCountry() { + if (!g_browser_process || !g_browser_process->variations_service()) { + // This should only happen in tests. Ideally this would be guarded by + // CHECK_IS_TEST, but that is not set on Android, so no specific guard. + return std::string(); + } + return std::string( + g_browser_process->variations_service()->GetStoredPermanentCountry()); +} + +void RegisterLocalState(PrefRegistrySimple* registry) { + // Call outs to individual subsystems that register Local State (browser-wide) + // prefs en masse. See RegisterProfilePrefs for per-profile prefs. Please + // keep this list alphabetized. +#if BUILDFLAG(IS_ANDROID) + accessibility::AccessibilityPrefsController::RegisterLocalStatePrefs( + registry); +#endif + autofill::prefs::RegisterLocalStatePrefs(registry); + breadcrumbs::RegisterPrefs(registry); + browser_shutdown::RegisterPrefs(registry); + BrowserProcessImpl::RegisterPrefs(registry); + ChromeContentBrowserClient::RegisterLocalStatePrefs(registry); + chrome_labs_prefs::RegisterLocalStatePrefs(registry); + ChromeMetricsServiceClient::RegisterPrefs(registry); + chrome::enterprise_util::RegisterLocalStatePrefs(registry); + component_updater::RegisterPrefs(registry); + domain_reliability::RegisterPrefs(registry); + embedder_support::OriginTrialPrefs::RegisterPrefs(registry); + enterprise_reporting::RegisterLocalStatePrefs(registry); + ExternalProtocolHandler::RegisterPrefs(registry); + flags_ui::PrefServiceFlagsStorage::RegisterPrefs(registry); + GpuModeManager::RegisterPrefs(registry); + signin::IdentityManager::RegisterLocalStatePrefs(registry); + invalidation::FCMInvalidationService::RegisterPrefs(registry); + invalidation::InvalidatorRegistrarWithMemory::RegisterPrefs(registry); + invalidation::PerUserTopicSubscriptionManager::RegisterPrefs(registry); + language::GeoLanguageProvider::RegisterLocalStatePrefs(registry); + language::UlpLanguageCodeLocator::RegisterLocalStatePrefs(registry); + memory::EnterpriseMemoryLimitPrefObserver::RegisterPrefs(registry); + metrics::RegisterDemographicsLocalStatePrefs(registry); + network_time::NetworkTimeTracker::RegisterPrefs(registry); + optimization_guide::prefs::RegisterLocalStatePrefs(registry); + optimization_guide::model_execution::prefs::RegisterLocalStatePrefs(registry); + password_manager::PasswordManager::RegisterLocalPrefs(registry); + policy::BrowserPolicyConnector::RegisterPrefs(registry); + policy::LocalTestPolicyProvider::RegisterLocalStatePrefs(registry); + policy::ManagementService::RegisterLocalStatePrefs(registry); + policy::PolicyStatisticsCollector::RegisterPrefs(registry); + PrefProxyConfigTrackerImpl::RegisterPrefs(registry); + ProfileAttributesEntry::RegisterLocalStatePrefs(registry); + ProfileAttributesStorage::RegisterPrefs(registry); + ProfileNetworkContextService::RegisterLocalStatePrefs(registry); + profiles::RegisterPrefs(registry); +#if BUILDFLAG(IS_ANDROID) + PushMessagingServiceImpl::RegisterPrefs(registry); +#endif + RegisterScreenshotPrefs(registry); + safe_browsing::RegisterLocalStatePrefs(registry); + secure_origin_allowlist::RegisterPrefs(registry); + segmentation_platform::SegmentationPlatformService::RegisterLocalStatePrefs( + registry); +#if !BUILDFLAG(IS_ANDROID) + SerialPolicyAllowedPorts::RegisterPrefs(registry); + HidPolicyAllowedDevices::RegisterLocalStatePrefs(registry); +#endif + sessions::SessionIdGenerator::RegisterPrefs(registry); + SSLConfigServiceManager::RegisterPrefs(registry); + subresource_filter::IndexedRulesetVersion::RegisterPrefs( + registry, subresource_filter::kSafeBrowsingRulesetConfig.filter_tag); + subresource_filter::IndexedRulesetVersion::RegisterPrefs( + registry, + fingerprinting_protection_filter::kFingerprintingProtectionRulesetConfig + .filter_tag); + SystemNetworkContextManager::RegisterPrefs(registry); + tpcd::experiment::RegisterLocalStatePrefs(registry); + tpcd::metadata::RegisterLocalStatePrefs(registry); + tracing::RegisterPrefs(registry); + update_client::RegisterPrefs(registry); + variations::VariationsService::RegisterPrefs(registry); + + // Individual preferences. If you have multiple preferences that should + // clearly be grouped together, please group them together into a helper + // function called above. Please keep this list alphabetized. + registry->RegisterBooleanPref( + policy::policy_prefs::kIntensiveWakeUpThrottlingEnabled, false); + registry->RegisterBooleanPref( + policy::policy_prefs::kUserAgentClientHintsGREASEUpdateEnabled, true); +#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + registry->RegisterBooleanPref(prefs::kFeatureNotificationsEnabled, true); +#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) +#if BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref(policy::policy_prefs::kBackForwardCacheEnabled, + true); + registry->RegisterBooleanPref(policy::policy_prefs::kReadAloudEnabled, true); +#endif // BUILDFLAG(IS_ANDROID) + + // Below this point is for platform-specific and compile-time conditional + // calls. Please follow the helper-function-first-then-direct-calls pattern + // established above, and keep things alphabetized. + +#if BUILDFLAG(ENABLE_BACKGROUND_MODE) + BackgroundModeManager::RegisterPrefs(registry); +#endif + +#if BUILDFLAG(IS_ANDROID) + ::android::RegisterPrefs(registry); + + registry->RegisterIntegerPref(first_run::kTosDialogBehavior, 0); + registry->RegisterBooleanPref(lens::kLensCameraAssistedSearchEnabled, true); +#else // BUILDFLAG(IS_ANDROID) + enterprise_connectors::RegisterLocalStatePrefs(registry); + gcm::RegisterPrefs(registry); + headless::RegisterPrefs(registry); + IntranetRedirectDetector::RegisterPrefs(registry); + media_router::RegisterLocalStatePrefs(registry); + metrics::TabStatsTracker::RegisterPrefs(registry); + performance_manager::user_tuning::prefs::RegisterLocalStatePrefs(registry); + PerformanceInterventionMetricsReporter::RegisterLocalStatePrefs(registry); + RegisterBrowserPrefs(registry); + speech::SodaInstaller::RegisterLocalStatePrefs(registry); + StartupBrowserCreator::RegisterLocalStatePrefs(registry); + task_manager::TaskManagerInterface::RegisterPrefs(registry); + UpgradeDetector::RegisterPrefs(registry); + registry->RegisterIntegerPref(prefs::kLastWhatsNewVersion, 0); +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + WhatsNewUI::RegisterLocalStatePrefs(registry); +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(ENABLE_DICE_SUPPORT) + FirstRunService::RegisterLocalStatePrefs(registry); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + arc::prefs::RegisterLocalStatePrefs(registry); + ChromeOSMetricsProvider::RegisterPrefs(registry); + ash::AudioDevicesPrefHandlerImpl::RegisterPrefs(registry); + ash::carrier_lock::CarrierLockManager::RegisterLocalPrefs(registry); + ash::cert_provisioning::RegisterLocalStatePrefs(registry); + ash::CellularESimProfileHandlerImpl::RegisterLocalStatePrefs(registry); + ash::ManagedCellularPrefHandler::RegisterLocalStatePrefs(registry); + ash::ChromeSessionManager::RegisterPrefs(registry); + user_manager::UserManagerBase::RegisterPrefs(registry); + crosapi::browser_util::RegisterLocalStatePrefs(registry); + ash::CupsPrintersManager::RegisterLocalStatePrefs(registry); + ash::BrowserDataMigratorImpl::RegisterLocalStatePrefs(registry); + ash::bluetooth_config::BluetoothPowerControllerImpl::RegisterLocalStatePrefs( + registry); + ash::bluetooth_config::DeviceNameManagerImpl::RegisterLocalStatePrefs( + registry); + ash::DemoModeResourcesRemover::RegisterLocalStatePrefs(registry); + ash::DemoSession::RegisterLocalStatePrefs(registry); + ash::DemoSetupController::RegisterLocalStatePrefs(registry); + ash::DeviceNameStore::RegisterLocalStatePrefs(registry); + chromeos::DeviceOAuth2TokenStoreChromeOS::RegisterPrefs(registry); + ash::device_settings_cache::RegisterPrefs(registry); + ash::EnableAdbSideloadingScreen::RegisterPrefs(registry); + ash::report::ReportController::RegisterPrefs(registry); + ash::EnableDebuggingScreenHandler::RegisterPrefs(registry); + ash::FastTransitionObserver::RegisterPrefs(registry); + ash::HWDataUsageController::RegisterLocalStatePrefs(registry); + ash::KerberosCredentialsManager::RegisterLocalStatePrefs(registry); + ash::KioskChromeAppManager::RegisterLocalStatePrefs(registry); + ash::KioskSystemSession::RegisterLocalStatePrefs(registry); + ash::KioskCryptohomeRemover::RegisterPrefs(registry); + ash::language_prefs::RegisterPrefs(registry); + ash::local_search_service::SearchMetricsReporter::RegisterLocalStatePrefs( + registry); + ash::login::SecurityTokenSessionController::RegisterLocalStatePrefs(registry); + ash::reporting::LoginLogoutReporter::RegisterPrefs(registry); + ash::reporting::RegisterLocalStatePrefs(registry); + ash::NetworkMetadataStore::RegisterPrefs(registry); + ash::NetworkThrottlingObserver::RegisterPrefs(registry); + ash::PowerMetricsReporter::RegisterLocalStatePrefs(registry); + ash::platform_keys::KeyPermissionsManagerImpl::RegisterLocalStatePrefs( + registry); + ash::power::auto_screen_brightness::MetricsReporter::RegisterLocalStatePrefs( + registry); + ash::Preferences::RegisterPrefs(registry); + ash::ResetScreen::RegisterPrefs(registry); + ash::SchedulerConfigurationManager::RegisterLocalStatePrefs(registry); + ash::ServicesCustomizationDocument::RegisterPrefs(registry); + ash::standalone_browser::migrator_util::RegisterLocalStatePrefs(registry); + ash::StartupUtils::RegisterPrefs(registry); + ash::StatsReportingController::RegisterLocalStatePrefs(registry); + ash::system::AutomaticRebootManager::RegisterPrefs(registry); + ash::TimeZoneResolver::RegisterPrefs(registry); + ash::UserImageManagerImpl::RegisterPrefs(registry); + ash::UserSessionManager::RegisterPrefs(registry); + ash::WebKioskAppManager::RegisterPrefs(registry); + component_updater::MetadataTable::RegisterPrefs(registry); + ash::CryptAuthDeviceIdProviderImpl::RegisterLocalPrefs(registry); + extensions::ExtensionAssetsManagerChromeOS::RegisterPrefs(registry); + extensions::ExtensionsPermissionsTracker::RegisterLocalStatePrefs(registry); + extensions::lock_screen_data::LockScreenItemStorage::RegisterLocalState( + registry); + extensions::login_api::RegisterLocalStatePrefs(registry); + ::onc::RegisterPrefs(registry); + policy::AdbSideloadingAllowanceModePolicyHandler::RegisterPrefs(registry); + // TODO(b/265923216): Replace with EnrollmentStateFetcher::RegisterPrefs. + policy::AutoEnrollmentClientImpl::RegisterPrefs(registry); + policy::BrowserPolicyConnectorAsh::RegisterPrefs(registry); + policy::CrdAdminSessionController::RegisterLocalStatePrefs(registry); + policy::DeviceCloudPolicyManagerAsh::RegisterPrefs(registry); + policy::DeviceStatusCollector::RegisterPrefs(registry); + policy::DeviceWallpaperImageExternalDataHandler::RegisterPrefs(registry); + policy::DMTokenStorage::RegisterPrefs(registry); + policy::EnrollmentRequisitionManager::RegisterPrefs(registry); + policy::MinimumVersionPolicyHandler::RegisterPrefs(registry); + policy::EuiccStatusUploader::RegisterLocalStatePrefs(registry); + policy::TPMAutoUpdateModePolicyHandler::RegisterPrefs(registry); + quirks::QuirksManager::RegisterPrefs(registry); + UpgradeDetectorChromeos::RegisterPrefs(registry); + RegisterNearbySharingLocalPrefs(registry); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS) + chromeos::echo_offer::RegisterPrefs(registry); + memory::OOMKillsMonitor::RegisterPrefs(registry); + policy::SystemFeaturesDisableListPolicyHandler::RegisterPrefs(registry); + policy::DlpRulesManagerImpl::RegisterPrefs(registry); +#endif // BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(IS_MAC) + confirm_quit::RegisterLocalState(registry); + QuitWithAppsController::RegisterPrefs(registry); + system_media_permissions::RegisterSystemMediaPermissionStatesPrefs(registry); + AppShimRegistry::Get()->RegisterLocalPrefs(registry); +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + AccountCache::RegisterLocalStatePrefs(registry); + lacros_prefs::RegisterLocalStatePrefs(registry); + KioskSessionServiceLacros::RegisterLocalStatePrefs(registry); +#endif + +#if BUILDFLAG(IS_WIN) + OSCrypt::RegisterLocalPrefs(registry); + registry->RegisterBooleanPref(prefs::kRendererCodeIntegrityEnabled, true); + registry->RegisterBooleanPref(prefs::kRendererAppContainerEnabled, true); + registry->RegisterBooleanPref(prefs::kBlockBrowserLegacyExtensionPoints, + true); + registry->RegisterIntegerPref(prefs::kDynamicCodeSettings, /*Default=*/0); + registry->RegisterBooleanPref(prefs::kApplicationBoundEncryptionEnabled, + true); + registry->RegisterBooleanPref(prefs::kPrintingLPACSandboxEnabled, true); + registry->RegisterBooleanPref( + policy::policy_prefs::kNativeWindowOcclusionEnabled, true); + MediaFoundationServiceMonitor::RegisterPrefs(registry); + os_crypt_async::AppBoundEncryptionProviderWin::RegisterLocalPrefs(registry); +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + IncompatibleApplicationsUpdater::RegisterLocalStatePrefs(registry); + ModuleDatabase::RegisterLocalStatePrefs(registry); + ThirdPartyConflictsManager::RegisterLocalStatePrefs(registry); +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) +#endif // BUILDFLAG(IS_WIN) + +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) + downgrade::RegisterPrefs(registry); +#endif + +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) + RegisterDefaultBrowserPromptPrefs(registry); +#endif + +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH) + DeviceOAuth2TokenStoreDesktop::RegisterPrefs(registry); +#endif + +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + screen_ai::RegisterLocalStatePrefs(registry); +#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) + PlatformAuthPolicyObserver::RegisterPrefs(registry); +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) + + // Platform-specific and compile-time conditional individual preferences. + // If you have multiple preferences that should clearly be grouped together, + // please group them together into a helper function called above. Please + // keep this list alphabetized. + +#if BUILDFLAG(ENABLE_OOP_PRINTING) + registry->RegisterBooleanPref(prefs::kOopPrintDriversAllowedByPolicy, true); +#endif + +#if BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + // TODO(b/328668317): Default pref should be set to true once this is + // launched. + registry->RegisterBooleanPref(prefs::kOsUpdateHandlerEnabled, false); +#endif // BUILDFLAG(IS_WIN) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + +#if BUILDFLAG(ENABLE_PDF) + registry->RegisterBooleanPref(prefs::kPdfViewerOutOfProcessIframeEnabled, + true); +#endif // BUILDFLAG(ENABLE_PDF) + +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) || \ + BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref(prefs::kChromeForTestingAllowed, true); +#endif + +#if BUILDFLAG(IS_WIN) + registry->RegisterBooleanPref(prefs::kUiAutomationProviderEnabled, false); +#endif + + registry->RegisterBooleanPref(prefs::kQRCodeGeneratorEnabled, true); + + // This is intentionally last. + RegisterLocalStatePrefsForMigration(registry); +} + +// Register prefs applicable to all profiles. +void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry, + const std::string& locale) { + TRACE_EVENT0("browser", "chrome::RegisterProfilePrefs"); + // User prefs. Please keep this list alphabetized. + AccessibilityLabelsService::RegisterProfilePrefs(registry); + AccessibilityUIMessageHandler::RegisterProfilePrefs(registry); + AnnouncementNotificationService::RegisterProfilePrefs(registry); + autofill::prefs::RegisterProfilePrefs(registry); + browsing_data::prefs::RegisterBrowserUserPrefs(registry); + capture_policy::RegisterProfilePrefs(registry); + certificate_transparency::prefs::RegisterPrefs(registry); + ChromeContentBrowserClient::RegisterProfilePrefs(registry); + chrome_labs_prefs::RegisterProfilePrefs(registry); + ChromeLocationBarModelDelegate::RegisterProfilePrefs(registry); + content_settings::CookieSettings::RegisterProfilePrefs(registry); + StatefulSSLHostStateDelegate::RegisterProfilePrefs(registry); + ChromeVersionService::RegisterProfilePrefs(registry); + chrome_browser_net::NetErrorTabHelper::RegisterProfilePrefs(registry); + chrome_prefs::RegisterProfilePrefs(registry); + commerce::RegisterPrefs(registry); + DocumentProvider::RegisterProfilePrefs(registry); + enterprise::RegisterIdentifiersProfilePrefs(registry); + enterprise_reporting::RegisterProfilePrefs(registry); + dom_distiller::DistilledPagePrefs::RegisterProfilePrefs(registry); + DownloadPrefs::RegisterProfilePrefs(registry); + permissions::PermissionHatsTriggerHelper::RegisterProfilePrefs(registry); + history_clusters::prefs::RegisterProfilePrefs(registry); + HostContentSettingsMap::RegisterProfilePrefs(registry); + image_fetcher::ImageCache::RegisterProfilePrefs(registry); + site_engagement::ImportantSitesUtil::RegisterProfilePrefs(registry); + IncognitoModePrefs::RegisterProfilePrefs(registry); + invalidation::PerUserTopicSubscriptionManager::RegisterProfilePrefs(registry); + invalidation::InvalidatorRegistrarWithMemory::RegisterProfilePrefs(registry); + language::LanguagePrefs::RegisterProfilePrefs(registry); + login_detection::prefs::RegisterProfilePrefs(registry); + lookalikes::RegisterProfilePrefs(registry); + media_prefs::RegisterUserPrefs(registry); + MediaCaptureDevicesDispatcher::RegisterProfilePrefs(registry); + media_device_salt::MediaDeviceIDSalt::RegisterProfilePrefs(registry); + MediaEngagementService::RegisterProfilePrefs(registry); + MediaStorageIdSalt::RegisterProfilePrefs(registry); + metrics::RegisterDemographicsProfilePrefs(registry); + NotificationDisplayServiceImpl::RegisterProfilePrefs(registry); + NotifierStateTracker::RegisterProfilePrefs(registry); + ntp_tiles::MostVisitedSites::RegisterProfilePrefs(registry); + optimization_guide::prefs::RegisterProfilePrefs(registry); + optimization_guide::model_execution::prefs::RegisterProfilePrefs(registry); + PageColors::RegisterProfilePrefs(registry); + password_manager::PasswordManager::RegisterProfilePrefs(registry); + payments::RegisterProfilePrefs(registry); + performance_manager::user_tuning::prefs::RegisterProfilePrefs(registry); + permissions::RegisterProfilePrefs(registry); + PermissionBubbleMediaAccessHandler::RegisterProfilePrefs(registry); + PlatformNotificationServiceImpl::RegisterProfilePrefs(registry); + policy::URLBlocklistManager::RegisterProfilePrefs(registry); + PolicyUI::RegisterProfilePrefs(registry); + PrefProxyConfigTrackerImpl::RegisterProfilePrefs(registry); + prefetch::RegisterPredictionOptionsProfilePrefs(registry); + PrefetchOriginDecider::RegisterPrefs(registry); + PrefsTabHelper::RegisterProfilePrefs(registry, locale); + privacy_sandbox::RegisterProfilePrefs(registry); + Profile::RegisterProfilePrefs(registry); + ProfileImpl::RegisterProfilePrefs(registry); + ProfileNetworkContextService::RegisterProfilePrefs(registry); + custom_handlers::ProtocolHandlerRegistry::RegisterProfilePrefs(registry); + PushMessagingAppIdentifier::RegisterProfilePrefs(registry); + QuietNotificationPermissionUiState::RegisterProfilePrefs(registry); + RegisterBrowserUserPrefs(registry); + RegisterPrefersDefaultScrollbarStylesPrefs(registry); + RegisterSafetyHubProfilePrefs(registry); +#if BUILDFLAG(IS_CHROMEOS_ASH) + settings::ResetSettingsHandler::RegisterProfilePrefs(registry); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + safe_browsing::file_type::RegisterProfilePrefs(registry); + safe_browsing::RegisterProfilePrefs(registry); + SearchPrefetchService::RegisterProfilePrefs(registry); + blocked_content::SafeBrowsingTriggeredPopupBlocker::RegisterProfilePrefs( + registry); + security_interstitials::InsecureFormBlockingPage::RegisterProfilePrefs( + registry); + segmentation_platform::SegmentationPlatformService::RegisterProfilePrefs( + registry); + segmentation_platform::DeviceSwitcherResultDispatcher::RegisterProfilePrefs( + registry); + SessionStartupPref::RegisterProfilePrefs(registry); + SharingSyncPreference::RegisterProfilePrefs(registry); + SigninPrefs::RegisterProfilePrefs(registry); + site_engagement::SiteEngagementService::RegisterProfilePrefs(registry); + supervised_user::RegisterProfilePrefs(registry); + sync_sessions::SessionSyncPrefs::RegisterProfilePrefs(registry); + syncer::DeviceInfoPrefs::RegisterProfilePrefs(registry); + syncer::SyncPrefs::RegisterProfilePrefs(registry); + syncer::SyncTransportDataPrefs::RegisterProfilePrefs(registry); + TemplateURLPrepopulateData::RegisterProfilePrefs(registry); + tab_groups::prefs::RegisterProfilePrefs(registry); + tpcd::experiment::RegisterProfilePrefs(registry); + translate::TranslatePrefs::RegisterProfilePrefs(registry); + omnibox::RegisterProfilePrefs(registry); + ZeroSuggestProvider::RegisterProfilePrefs(registry); + +#if !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + promos_utils::RegisterProfilePrefs(registry); +#endif // !BUILDFLAG(IS_ANDROID) && BUILDFLAG(GOOGLE_CHROME_BRANDING) + +#if BUILDFLAG(ENABLE_SESSION_SERVICE) + RegisterSessionServiceLogProfilePrefs(registry); + SessionDataService::RegisterProfilePrefs(registry); +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + ExtensionWebUI::RegisterProfilePrefs(registry); + RegisterAnimationPolicyPrefs(registry); + extensions::ActivityLog::RegisterProfilePrefs(registry); + extensions::AudioAPI::RegisterUserPrefs(registry); + extensions::ExtensionPrefs::RegisterProfilePrefs(registry); + extensions::ExtensionsUI::RegisterProfilePrefs(registry); +#if BUILDFLAG(IS_CHROMEOS_ASH) + extensions::shared_storage::RegisterProfilePrefs(registry); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + extensions::PermissionsManager::RegisterProfilePrefs(registry); + extensions::RuntimeAPI::RegisterPrefs(registry); + // TODO(devlin): This would be more inline with the other calls here if it + // were nested in either a class or separate namespace with a simple + // Register[Profile]Prefs() name. + extensions::RegisterSettingsOverriddenUiPrefs(registry); + update_client::RegisterProfilePrefs(registry); +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + +#if BUILDFLAG(ENABLE_PDF) + registry->RegisterListPref(prefs::kPdfLocalFileAccessAllowedForDomains, + base::Value::List()); + registry->RegisterBooleanPref(prefs::kPdfUseSkiaRendererEnabled, true); +#endif // BUILDFLAG(ENABLE_PDF) + +#if BUILDFLAG(ENABLE_PRINT_PREVIEW) + printing::PolicySettings::RegisterProfilePrefs(registry); + printing::PrintPreviewStickySettings::RegisterProfilePrefs(registry); +#endif + +#if BUILDFLAG(ENABLE_RLZ) + ChromeRLZTrackerDelegate::RegisterProfilePrefs(registry); +#endif + +#if BUILDFLAG(ENABLE_FEED_V2) + feed::prefs::RegisterFeedSharedProfilePrefs(registry); + feed::RegisterProfilePrefs(registry); +#endif + +#if BUILDFLAG(IS_ANDROID) + cdm::MediaDrmStorageImpl::RegisterProfilePrefs(registry); + KnownInterceptionDisclosureInfoBarDelegate::RegisterProfilePrefs(registry); + MediaDrmOriginIdManager::RegisterProfilePrefs(registry); + NotificationChannelsProviderAndroid::RegisterProfilePrefs(registry); + ntp_tiles::PopularSitesImpl::RegisterProfilePrefs(registry); + OomInterventionDecider::RegisterProfilePrefs(registry); + PartnerBookmarksShim::RegisterProfilePrefs(registry); + permissions::GeolocationPermissionContextAndroid::RegisterProfilePrefs( + registry); + query_tiles::RegisterPrefs(registry); + readaloud::RegisterProfilePrefs(registry); + RecentTabsPagePrefs::RegisterProfilePrefs(registry); + usage_stats::UsageStatsBridge::RegisterProfilePrefs(registry); + variations::VariationsService::RegisterProfilePrefs(registry); + webapps::InstallPromptPrefs::RegisterProfilePrefs(registry); +#else // BUILDFLAG(IS_ANDROID) + bookmarks_webui::RegisterProfilePrefs(registry); + browser_sync::ForeignSessionHandler::RegisterProfilePrefs(registry); + BrowserFeaturePromoStorageService::RegisterProfilePrefs(registry); + captions::LiveTranslateController::RegisterProfilePrefs(registry); + CartService::RegisterProfilePrefs(registry); + ChromeAuthenticatorRequestDelegate::RegisterProfilePrefs(registry); + commerce::CommerceUiTabHelper::RegisterProfilePrefs(registry); + companion::PromoHandler::RegisterProfilePrefs(registry); + DeviceServiceImpl::RegisterProfilePrefs(registry); + DevToolsWindow::RegisterProfilePrefs(registry); + DriveService::RegisterProfilePrefs(registry); + enterprise_connectors::RegisterProfilePrefs(registry); + extensions::CommandService::RegisterProfilePrefs(registry); + extensions::TabsCaptureVisibleTabFunction::RegisterProfilePrefs(registry); + first_run::RegisterProfilePrefs(registry); + gcm::RegisterProfilePrefs(registry); + GoogleCalendarPageHandler::RegisterProfilePrefs(registry); + HatsServiceDesktop::RegisterProfilePrefs(registry); + lens::prefs::RegisterProfilePrefs(registry); + NtpCustomBackgroundService::RegisterProfilePrefs(registry); + media_router::RegisterAccessCodeProfilePrefs(registry); + media_router::RegisterProfilePrefs(registry); + NewTabPageHandler::RegisterProfilePrefs(registry); + NewTabPageUI::RegisterProfilePrefs(registry); + ntp::SafeBrowsingHandler::RegisterProfilePrefs(registry); + ntp_tiles::CustomLinksManagerImpl::RegisterProfilePrefs(registry); + PinnedTabCodec::RegisterProfilePrefs(registry); + policy::DeveloperToolsPolicyHandler::RegisterProfilePrefs(registry); + PromoService::RegisterProfilePrefs(registry); + RegisterReadAnythingProfilePrefs(registry); + settings::SettingsUI::RegisterProfilePrefs(registry); + send_tab_to_self::RegisterProfilePrefs(registry); + signin::RegisterProfilePrefs(registry); + StartupBrowserCreator::RegisterProfilePrefs(registry); + TabResumptionPageHandler::RegisterProfilePrefs(registry); + MostRelevantTabResumptionPageHandler::RegisterProfilePrefs(registry); + tab_groups::saved_tab_groups::prefs::RegisterProfilePrefs(registry); + tab_organization_prefs::RegisterProfilePrefs(registry); + tab_search_prefs::RegisterProfilePrefs(registry); + ThemeColorPickerHandler::RegisterProfilePrefs(registry); + toolbar::RegisterProfilePrefs(registry); + UnifiedAutoplayConfig::RegisterProfilePrefs(registry); + user_notes::RegisterProfilePrefs(registry); + +#if !BUILDFLAG(IS_CHROMEOS_LACROS) + captions::LiveCaptionController::RegisterProfilePrefs(registry); +#endif // !BUILDFLAG(IS_CHROMEOS_LACROS) +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_CHROMEOS) + extensions::DocumentScanAPIHandler::RegisterProfilePrefs(registry); + extensions::login_api::RegisterProfilePrefs(registry); + extensions::platform_keys::RegisterProfilePrefs(registry); + certificate_manager::CertificatesHandler::RegisterProfilePrefs(registry); + chromeos::cloud_storage::RegisterProfilePrefs(registry); + chromeos::cloud_upload::RegisterProfilePrefs(registry); + policy::NetworkAnnotationBlocklistHandler::RegisterPrefs(registry); + policy::PolicyCertService::RegisterProfilePrefs(registry); + quickoffice::RegisterProfilePrefs(registry); + registry->RegisterBooleanPref(prefs::kDeskAPIThirdPartyAccessEnabled, false); + registry->RegisterBooleanPref(prefs::kDeskAPIDeskSaveAndShareEnabled, false); + registry->RegisterListPref(prefs::kDeskAPIThirdPartyAllowlist); + registry->RegisterBooleanPref(prefs::kInsightsExtensionEnabled, false); + registry->RegisterBooleanPref(prefs::kEssentialSearchEnabled, false); + registry->RegisterBooleanPref(prefs::kLastEssentialSearchValue, false); + // By default showing Sync Consent is set to true. It can changed by policy. + registry->RegisterBooleanPref(prefs::kEnableSyncConsent, true); + registry->RegisterListPref( + chromeos::prefs::kKeepFullscreenWithoutNotificationUrlAllowList, + PrefRegistry::PUBLIC); + registry->RegisterBooleanPref(policy::policy_prefs::kFloatingWorkspaceEnabled, + false); + ::reporting::RegisterProfilePrefs(registry); + registry->RegisterBooleanPref(prefs::kFloatingSsoEnabled, false); + registry->RegisterListPref(prefs::kFloatingSsoDomainBlocklist); + registry->RegisterListPref(prefs::kFloatingSsoDomainBlocklistExceptions); +#if BUILDFLAG(USE_CUPS) + extensions::PrintingAPIHandler::RegisterProfilePrefs(registry); +#endif // BUILDFLAG(USE_CUPS) +#endif // BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + app_list::AppListSyncableService::RegisterProfilePrefs(registry); + apps::AlmanacFetcher::RegisterProfilePrefs(registry); + apps::AppPlatformMetricsService::RegisterProfilePrefs(registry); + apps::AppPreloadService::RegisterProfilePrefs(registry); + apps::webapk_prefs::RegisterProfilePrefs(registry); + arc::prefs::RegisterProfilePrefs(registry); + ArcAppListPrefs::RegisterProfilePrefs(registry); + arc::ArcBootPhaseMonitorBridge::RegisterProfilePrefs(registry); + ash::AccountAppsAvailability::RegisterPrefs(registry); + account_manager::AccountManager::RegisterPrefs(registry); + ash::ApkWebAppService::RegisterProfilePrefs(registry); + ash::app_time::AppActivityRegistry::RegisterProfilePrefs(registry); + ash::app_time::AppTimeController::RegisterProfilePrefs(registry); + ash::AshProxyMonitor::RegisterProfilePrefs(registry); + ash::assistant::prefs::RegisterProfilePrefs(registry); + ash::auth::AuthFactorConfig::RegisterPrefs(registry); + ash::bluetooth::DebugLogsManager::RegisterPrefs(registry); + ash::bluetooth_config::BluetoothPowerControllerImpl::RegisterProfilePrefs( + registry); + ash::HatsBluetoothRevampTriggerImpl::RegisterProfilePrefs(registry); + user_manager::UserManagerBase::RegisterProfilePrefs(registry); + ash::ClientAppMetadataProviderService::RegisterProfilePrefs(registry); + ash::CupsPrintersManager::RegisterProfilePrefs(registry); + ash::device_sync::RegisterProfilePrefs(registry); + ash::FamilyUserChromeActivityMetrics::RegisterProfilePrefs(registry); + ash::FamilyUserMetricsService::RegisterProfilePrefs(registry); + ash::FamilyUserSessionMetrics::RegisterProfilePrefs(registry); + ash::InlineLoginHandlerImpl::RegisterProfilePrefs(registry); + ash::first_run::RegisterProfilePrefs(registry); + ash::file_system_provider::RegisterProfilePrefs(registry); + ash::full_restore::RegisterProfilePrefs(registry); + ash::KerberosCredentialsManager::RegisterProfilePrefs(registry); + ash::multidevice_setup::MultiDeviceSetupService::RegisterProfilePrefs( + registry); + ash::NetworkMetadataStore::RegisterPrefs(registry); + ash::ReleaseNotesStorage::RegisterProfilePrefs(registry); + ash::HelpAppNotificationController::RegisterProfilePrefs(registry); + ash::quick_unlock::FingerprintStorage::RegisterProfilePrefs(registry); + ash::quick_unlock::PinStoragePrefs::RegisterProfilePrefs(registry); + ash::Preferences::RegisterProfilePrefs(registry); + ash::EnterprisePrintersProvider::RegisterProfilePrefs(registry); + ash::parent_access::ParentAccessService::RegisterProfilePrefs(registry); + quick_answers::prefs::RegisterProfilePrefs(registry); + ash::quick_unlock::RegisterProfilePrefs(registry); + ash::RegisterSamlProfilePrefs(registry); + ash::ScreenTimeController::RegisterProfilePrefs(registry); + ash::EduCoexistenceConsentInvalidationController::RegisterProfilePrefs( + registry); + ash::EduCoexistenceLoginHandler::RegisterProfilePrefs(registry); + ash::SigninErrorNotifier::RegisterPrefs(registry); + ash::ServicesCustomizationDocument::RegisterProfilePrefs(registry); + ash::settings::OSSettingsUI::RegisterProfilePrefs(registry); + ash::StartupUtils::RegisterOobeProfilePrefs(registry); + ash::user_image::prefs::RegisterProfilePrefs(registry); + ash::UserImageSyncObserver::RegisterProfilePrefs(registry); + ChromeMetricsServiceClient::RegisterProfilePrefs(registry); + crostini::prefs::RegisterProfilePrefs(registry); + flags_ui::PrefServiceFlagsStorage::RegisterProfilePrefs(registry); + guest_os::prefs::RegisterProfilePrefs(registry); + lock_screen_apps::StateController::RegisterProfilePrefs(registry); + plugin_vm::prefs::RegisterProfilePrefs(registry); + policy::ArcAppInstallEventLogger::RegisterProfilePrefs(registry); + policy::AppInstallEventLogManagerWrapper::RegisterProfilePrefs(registry); + policy::StatusCollector::RegisterProfilePrefs(registry); + ash::SystemProxyManager::RegisterProfilePrefs(registry); + ChromeShelfPrefs::RegisterProfilePrefs(registry); + ::onc::RegisterProfilePrefs(registry); + ash::cert_provisioning::RegisterProfilePrefs(registry); + borealis::prefs::RegisterProfilePrefs(registry); + ash::ChromeScanningAppDelegate::RegisterProfilePrefs(registry); + ProjectorAppClientImpl::RegisterProfilePrefs(registry); + ash::floating_workspace_util::RegisterProfilePrefs(registry); + policy::RebootNotificationsScheduler::RegisterProfilePrefs(registry); + ash::KioskChromeAppManager::RegisterProfilePrefs(registry); + file_manager::file_tasks::RegisterProfilePrefs(registry); + file_manager::prefs::RegisterProfilePrefs(registry); + bruschetta::prefs::RegisterProfilePrefs(registry); + wallpaper_handlers::prefs::RegisterProfilePrefs(registry); + ash::reporting::RegisterProfilePrefs(registry); + ChromeMediaAppGuestUIDelegate::RegisterProfilePrefs(registry); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + lacros_prefs::RegisterProfilePrefs(registry); + chromeos::ProxyConfigServiceLacros::RegisterProfilePrefs(registry); + lacros_prefs::RegisterExtensionControlledAshPrefs(registry); + KioskSessionServiceLacros::RegisterProfilePrefs(registry); + apps::WebsiteMetricsServiceLacros::RegisterProfilePrefs(registry); +#endif + +#if BUILDFLAG(IS_WIN) + CdmPrefServiceHelper::RegisterProfilePrefs(registry); + FontPrewarmerTabHelper::RegisterProfilePrefs(registry); + NetworkProfileBubble::RegisterProfilePrefs(registry); +#endif + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS_ASH) + device_signals::RegisterProfilePrefs(registry); +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || + // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) + browser_switcher::BrowserSwitcherPrefs::RegisterProfilePrefs(registry); + enterprise_signin::RegisterProfilePrefs(registry); +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) && !BUILDFLAG(IS_CHROMEOS_ASH) + preinstalled_apps::RegisterProfilePrefs(registry); +#endif + +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) + sharing_hub::RegisterProfilePrefs(registry); +#endif + +#if defined(TOOLKIT_VIEWS) + accessibility_prefs::RegisterInvertBubbleUserPrefs(registry); + side_search_prefs::RegisterProfilePrefs(registry); + RegisterBrowserViewProfilePrefs(registry); +#endif + +#if BUILDFLAG(ENABLE_LENS_DESKTOP) + registry->RegisterBooleanPref( + prefs::kLensRegionSearchEnabled, true, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); + registry->RegisterBooleanPref(prefs::kLensDesktopNTPSearchEnabled, true); +#endif + +#if !BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref( + webauthn::pref_names::kRemoteProxiedRequestsAllowed, false); + + registry->RegisterStringPref( + webauthn::pref_names::kLastUsedPairingFromSyncPublicKey, ""); + + registry->RegisterIntegerPref( + webauthn::pref_names::kEnclaveFailedPINAttemptsCount, 0); + + side_panel_prefs::RegisterProfilePrefs(registry); + + tabs::RegisterProfilePrefs(registry); +#endif // !BUILDFLAG(IS_ANDROID) + + registry->RegisterBooleanPref(webauthn::pref_names::kAllowWithBrokenCerts, + false); + + registry->RegisterBooleanPref(prefs::kPrivacyGuideViewed, false); + + RegisterProfilePrefsForMigration(registry); + +#if !BUILDFLAG(IS_ANDROID) + registry->RegisterIntegerPref(prefs::kMemorySaverChipExpandedCount, 0); + registry->RegisterTimePref(prefs::kLastMemorySaverChipExpandedTimestamp, + base::Time()); +#endif + +#if BUILDFLAG(IS_ANDROID) + registry->RegisterBooleanPref(prefs::kVirtualKeyboardResizesLayoutByDefault, + false); +#endif + +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + registry->RegisterBooleanPref( + prefs::kAccessibilityMainNodeAnnotationsEnabled, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); +#endif // BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + + registry->RegisterBooleanPref( + prefs::kManagedPrivateNetworkAccessRestrictionsEnabled, false); + +#if BUILDFLAG(ENTERPRISE_DATA_CONTROLS) + data_controls::RegisterProfilePrefs(registry); +#endif // BUILDFLAG(ENTERPRISE_DATA_CONTROLS) + +#if BUILDFLAG(IS_WIN) + registry->RegisterBooleanPref(prefs::kNativeHostsExecutablesLaunchDirectly, + false); +#endif // BUILDFLAG(IS_WIN) + +#if BUILDFLAG(ENABLE_COMPOSE) + registry->RegisterBooleanPref(prefs::kPrefHasCompletedComposeFRE, false); + registry->RegisterBooleanPref(prefs::kEnableProactiveNudge, true); + registry->RegisterDictionaryPref(prefs::kProactiveNudgeDisabledSitesWithTime); +#endif + +#if !BUILDFLAG(IS_ANDROID) + registry->RegisterIntegerPref(prefs::kChromeDataRegionSetting, 0); +#endif + + registry->RegisterIntegerPref(prefs::kLensOverlayStartCount, 0); + + registry->RegisterDictionaryPref(prefs::kReportingEndpoints); +} + +void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { + RegisterUserProfilePrefs(registry, g_browser_process->GetApplicationLocale()); +} + +void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry, + const std::string& locale) { + RegisterProfilePrefs(registry, locale); + +#if BUILDFLAG(IS_ANDROID) + ::android::RegisterUserProfilePrefs(registry); +#endif +#if BUILDFLAG(IS_CHROMEOS_ASH) + ash::RegisterUserProfilePrefs(registry, locale); + ash::TokenHandleFetcher::RegisterPrefs(registry); +#endif +} + +void RegisterScreenshotPrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kDisableScreenshots, false); +} + +#if BUILDFLAG(IS_CHROMEOS_ASH) +void RegisterSigninProfilePrefs(user_prefs::PrefRegistrySyncable* registry, + std::string_view country) { + RegisterProfilePrefs(registry, g_browser_process->GetApplicationLocale()); + ash::RegisterSigninProfilePrefs(registry, country); +} + +#endif + +// This method should be periodically pruned of year+ old migrations. +// See chrome/browser/prefs/README.md for details. +void MigrateObsoleteLocalStatePrefs(PrefService* local_state) { + // IMPORTANT NOTE: This code is *not* run on iOS Chrome. If a pref is migrated + // or cleared here, and that pref is also used in iOS Chrome, it may also need + // to be migrated or cleared specifically for iOS as well. This could be by + // doing the migration in feature code that's called by all platforms instead + // of here, or by calling migration code in the appropriate place for iOS + // specifically, e.g. ios/chrome/browser/shared/model/prefs/browser_prefs.mm. + + // BEGIN_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS + // Please don't delete the preceding line. It is used by PRESUBMIT.py. + + // Added 09/2023. +#if BUILDFLAG(IS_WIN) + local_state->ClearPref(kSwReporter); + local_state->ClearPref(kChromeCleaner); +#endif + +// Added 09/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + local_state->ClearPref(kGestureEducationNotificationShown); +#endif + +// Added 11/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + local_state->ClearPref(kIsolatedWebAppsEnabled); +#endif + + // Added 12/2023. + local_state->ClearPref(kPrivacyBudgetReportedReidBlocks); + + // Added 01/2024. + local_state->ClearPref(kPPAPISharedImagesForVideoDecoderAllowed); + +// Added 01/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + local_state->ClearPref(kExtendedFkeysModifier); +#endif + +// Added 02/2024 +#if BUILDFLAG(IS_MAC) + local_state->ClearPref(kScreenTimeEnabled); +#endif + + // Added 02/2024 + local_state->ClearPref(kSearchEnginesChoiceProfile); + +#if BUILDFLAG(IS_WIN) + // Deprecated 02/2024. + local_state->ClearPref(kOsCryptAppBoundFixedDataPrefName); + // Deprecated 03/2024. + local_state->ClearPref(kOsCryptAppBoundFixedData2PrefName); + // Deprecated 06/2024. + local_state->ClearPref(kOsCryptAppBoundFixedData3PrefName); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 03/2024. + local_state->ClearPref(kOobeGuestAcceptedTos); + + // Added 05/2024. + local_state->ClearPref(kDeviceRegisteredTime); + local_state->ClearPref(kArcKioskDictionaryName); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +// Added 04/2024 . +#if BUILDFLAG(IS_CHROMEOS_ASH) + local_state->ClearPref(kLastUploadedEuiccStatusPrefLegacy); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if !BUILDFLAG(IS_ANDROID) + // Added 05/2024. + local_state->ClearPref(kSearchEnginesStudyGroup); +#endif + +#if !BUILDFLAG(IS_ANDROID) + // Added 05/2024. + local_state->ClearPref(kHasShownRefreshWhatsNew); +#endif + +// Added 06/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + local_state->ClearPref(kLocalUserFilesMigrationEnabled); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_LACROS) || BUILDFLAG(ENABLE_DICE_SUPPORT) + // Added 07/2024. + local_state->ClearPref(kFirstRunStudyGroup); +#endif + + // Please don't delete the following line. It is used by PRESUBMIT.py. + // END_MIGRATE_OBSOLETE_LOCAL_STATE_PREFS + + // IMPORTANT NOTE: This code is *not* run on iOS Chrome. If a pref is migrated + // or cleared here, and that pref is also used in iOS Chrome, it may also need + // to be migrated or cleared specifically for iOS as well. This could be by + // doing the migration in feature code that's called by all platforms instead + // of here, or by calling migration code in the appropriate place for iOS + // specifically, e.g. ios/chrome/browser/shared/model/prefs/browser_prefs.mm. +} + +// This method should be periodically pruned of year+ old migrations. +// See chrome/browser/prefs/README.md for details. +void MigrateObsoleteProfilePrefs(PrefService* profile_prefs, + const base::FilePath& profile_path) { + // IMPORTANT NOTE: This code is *not* run on iOS Chrome. If a pref is migrated + // or cleared here, and that pref is also used in iOS Chrome, it may also need + // to be migrated or cleared specifically for iOS as well. This could be by + // doing the migration in feature code that's called by all platforms instead + // of here, or by calling migration code in the appropriate place for iOS + // specifically, e.g. ios/chrome/browser/shared/model/prefs/browser_prefs.mm. + + // BEGIN_MIGRATE_OBSOLETE_PROFILE_PREFS + // Please don't delete the preceding line. It is used by PRESUBMIT.py. + + // Check MigrateDeprecatedAutofillPrefs() to see if this is safe to remove. + autofill::prefs::MigrateDeprecatedAutofillPrefs(profile_prefs); + + // Added 3/2020. + // TODO(crbug.com/40122991): Remove this once the privacy settings redesign + // is fully launched. + chrome_browser_net::secure_dns::MigrateProbesSettingToOrFromBackup( + profile_prefs); + + // Once this migration is complete, the tracked preference + // `kGoogleServicesLastSyncingAccountIdDeprecated` can be removed. + if (profile_prefs->HasPrefPath( + prefs::kGoogleServicesLastSyncingAccountIdDeprecated)) { + std::string account_id = profile_prefs->GetString( + prefs::kGoogleServicesLastSyncingAccountIdDeprecated); + profile_prefs->ClearPref( + prefs::kGoogleServicesLastSyncingAccountIdDeprecated); + bool is_email = account_id.find('@') != std::string::npos; + if (!is_email && !account_id.empty()) { + profile_prefs->SetString(prefs::kGoogleServicesLastSyncingGaiaId, + account_id); + } + } + + // TODO(326079444): After experiment is over, update the deprecated date and + // allow this to be cleaned up. +#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS) + MigrateDefaultBrowserLastDeclinedPref(profile_prefs); +#endif + + // Added 08/2023. + invalidation::InvalidatorRegistrarWithMemory::ClearDeprecatedPrefs( + profile_prefs); + invalidation::PerUserTopicSubscriptionManager::ClearDeprecatedPrefs( + profile_prefs); + invalidation::FCMInvalidationService::ClearDeprecatedPrefs(profile_prefs); + + // Added 08/2023. + profile_prefs->ClearPref(kDriveFsBulkPinningMaxQueueSize); + + // Added 09/2023. + profile_prefs->ClearPref(kPrivacySandboxM1Unrestricted); +#if BUILDFLAG(IS_WIN) + profile_prefs->ClearPref(kSwReporter); + profile_prefs->ClearPref(kSettingsResetPrompt); + profile_prefs->ClearPref(kChromeCleaner); +#endif + profile_prefs->ClearPref(kDownloadBubbleEnabled); + profile_prefs->ClearPref(kPrivacySandboxManuallyControlled); +#if BUILDFLAG(IS_CHROMEOS_ASH) + profile_prefs->ClearPref(kSyncInitialSyncFeatureSetupCompleteOnAsh); +#endif +#if BUILDFLAG(IS_ANDROID) + profile_prefs->ClearPref(kSettingsMigratedToUPM); +#endif + + // Added 10/2023. + ClearSyncRequestedPrefAndMaybeMigrate(profile_prefs); + +// Added 10/2023. +#if BUILDFLAG(IS_CHROMEOS_ASH) + profile_prefs->ClearPref(kLastSuccessfulDomainPref); + profile_prefs->ClearPref(kShouldAttemptReenable); + profile_prefs->ClearPref(kAudioVolumePercent); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Added 10/2023. +#if BUILDFLAG(IS_CHROMEOS) + profile_prefs->ClearPref(kSupportedLinksAppPrefsKey); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 10/2023. + profile_prefs->ClearPref(kNightLightCachedLatitude); + profile_prefs->ClearPref(kNightLightCachedLongitude); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Added 11/2023. + profile_prefs->ClearPref(kPrivacySandboxAntiAbuseInitialized); + + // Added 11/2023. + profile_prefs->ClearPref(kWebRTCAllowLegacyTLSProtocols); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 11/2023. + profile_prefs->ClearPref(kSystemTrayExpanded); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 11/2023. + profile_prefs->ClearPref(kUserGeolocationAllowed); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if !BUILDFLAG(IS_ANDROID) + // Added 11/2023. + password_manager::features_util::MigrateOptInPrefToSyncSelectedTypes( + profile_prefs); +#endif // !BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_ANDROID) + // Added 11/2023, but DO NOT REMOVE after the usual year! + // TODO(crbug.com/40268177): The pref kPasswordsUseUPMLocalAndSeparateStores + // and this call (to compute said pref) should be removed once + // kUnifiedPasswordManagerLocalPasswordsAndroidWithMigration is launched and + // enough clients have migrated. UsesSplitStoresAndUPMForLocal() should be + // updated to check the GmsCoreVersion directly instead of the pref, or might + // be removed entirely, depending how the outdated GmsCore case is handled. + password_manager_android_util::SetUsesSplitStoresAndUPMForLocal(profile_prefs, + profile_path); +#endif + + // Added 11/2023. + profile_prefs->ClearPref(kPasswordChangeSuccessTrackerFlows); + profile_prefs->ClearPref(kPasswordChangeSuccessTrackerVersion); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 11/2023. + profile_prefs->ClearPref(kImageSearchPrivacyNotice); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Added 11/2023. + profile_prefs->ClearPref(kWebAndAppActivityEnabledForShopping); + +#if !BUILDFLAG(IS_ANDROID) + // Added 12/2023. + password_manager::features_util::MigrateDeclinedSaveOptInToExplicitOptOut( + profile_prefs); +#endif // !BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_ANDROID) + // Added 12/2023. + profile_prefs->ClearPref(kTemplatesRandomOrder); +#endif + +#if BUILDFLAG(IS_ANDROID) + // Added 12/2023. + profile_prefs->ClearPref(kDesktopSitePeripheralSettingEnabled); + profile_prefs->ClearPref(kDesktopSiteDisplaySettingEnabled); +#endif + + // Added 12/2023. + profile_prefs->ClearPref(kDownloadDuplicateFilePromptEnabled); + + // Added 12/2023. + profile_prefs->ClearPref(kModelQualityLoggingClientId); + + // Added 12/2023. + // Moving the `kExplicitBrowserSignin` from sync/ to signin/. + // If the sync (old) pref still exists, copy it to signin (new), + // and clear the sync part of the pref. + if (profile_prefs->HasPrefPath(kSync_ExplicitBrowserSignin)) { + profile_prefs->SetBoolean( + prefs::kExplicitBrowserSignin, + profile_prefs->GetBoolean(kSync_ExplicitBrowserSignin)); + profile_prefs->ClearPref(kSync_ExplicitBrowserSignin); + } + + // Added 01/2024. + profile_prefs->ClearPref(kPrivacySandboxPageViewed); + + // Added 01/2024. + profile_prefs->ClearPref(kPrivacySandboxApisEnabledV2); + profile_prefs->ClearPref(kPrivacySandboxManuallyControlledV2); + + // Added 01/2024. +#if BUILDFLAG(ENABLE_COMPOSE) + profile_prefs->ClearPref(kPrefHasAcceptedComposeConsent); + profile_prefs->ClearPref(kAutofillAssistanceEnabled); +#endif + + // Added 01/2024. + profile_prefs->ClearPref(kSyncedLastTimePasswordCheckCompleted); + + // Added 01/2024. + profile_prefs->ClearPref(kDownloadBubbleIphSuppression); + + // Added 01/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + profile_prefs->ClearPref(kPersistedSystemExtensions); + profile_prefs->ClearPref(kBorealisVmTokenHash); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if !BUILDFLAG(IS_ANDROID) + // Added 1/2024. + performance_manager::user_tuning::prefs::MigrateTabDiscardingExceptionsPref( + profile_prefs); +#endif + + // Added 01/2024. + profile_prefs->ClearPref(kNtpShownPage); + profile_prefs->ClearPref(kNtpAppPageNames); + + // Added 01/2024. +#if BUILDFLAG(IS_WIN) + profile_prefs->ClearPref(kSearchResultsPagePrimaryFontsPref); + profile_prefs->ClearPref(kSearchResultsPageFallbackFontsPref); +#endif + + // Added 01/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + profile_prefs->ClearPref(kUpdateNotificationLastShownMilestone); +#endif + + // Added 01/2024. +#if BUILDFLAG(IS_ANDROID) + profile_prefs->ClearPref(kSavePasswordsSuspendedByError); +#endif + + // Added 02/2024 + profile_prefs->ClearPref(kSafeBrowsingDeepScanPromptSeen); + profile_prefs->ClearPref(kSafeBrowsingEsbEnabledTimestamp); + + // Added 02/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + for (const char* pref : kWelcomeTourTimeBucketsOfFirstInteractions) { + profile_prefs->ClearPref(pref); + } + + // Added 02/2024. + profile_prefs->ClearPref(kDiscoverTabSuggestionChipTimesLeftToShow); +#endif + + // Added 02/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + profile_prefs->ClearPref(kHatsSmartLockSurveyCycleEndTs); + profile_prefs->ClearPref(kHatsSmartLockDeviceIsSelected); + profile_prefs->ClearPref(kHatsUnlockSurveyCycleEndTs); + profile_prefs->ClearPref(kHatsUnlockDeviceIsSelected); +#endif + + // Added 02/2024 + profile_prefs->ClearPref(kResetCheckDefaultBrowser); + + // Added 02/2024 + profile_prefs->ClearPref(kOfferReaderMode); + + // Added 03/2024. + profile_prefs->ClearPref(kPlusAddressLastFetchedTime); + + // Added 03/2024. + profile_prefs->ClearPref(kPrivacySandboxApisEnabled); + + // Added 03/2024. + profile_prefs->ClearPref(kDefaultSearchProviderChoicePendingDeprecated); + + // Added 02/2024, but DO NOT REMOVE after the usual year! + // TODO(crbug.com/40282890): Remove ~one year after full launch. + browser_sync::MaybeMigrateSyncingUserToSignedIn(profile_path, profile_prefs); + + // Added 03/2024. + profile_prefs->ClearPref(kShowInternalAccessibilityTree); + + // Added 03/2024. + profile_prefs->ClearPref(kTrackingProtectionSentimentSurveyGroup); + profile_prefs->ClearPref(kTrackingProtectionSentimentSurveyStartTime); + profile_prefs->ClearPref(kTrackingProtectionSentimentSurveyEndTime); + + // Added 03/2024 + profile_prefs->ClearPref(kPreferencesMigratedToBasic); + + // Added 04/2024. + profile_prefs->ClearPref(kOmniboxInstantKeywordUsed); + + // Added 04/2024. + profile_prefs->ClearPref(kWebAppPreinstalledAppWindowExperiment); + + // Added 04/2024. + profile_prefs->ClearPref(kDIPSTimerLastUpdate); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 04/2024. + profile_prefs->ClearPref(kMetricsUserInheritOwnerConsent); + profile_prefs->ClearPref(kGlanceablesEnabled); + + // Added 05/2024. + profile_prefs->ClearPref(kAccessibilityMouseKeysShortcutToPauseEnabled); + profile_prefs->ClearPref(kAccessibilityMouseKeysDisableInTextFields); + profile_prefs->ClearPref(kAccessibilityScreenMagnifierCenterFocus); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + // Added 05/2024. + profile_prefs->ClearPref(kBlockTruncatedCookies); + + // Added 05/2024 + profile_prefs->ClearPref(kDefaultSearchProviderChoiceLocationPrefName); + + // Added 05/2024. + profile_prefs->ClearPref(kSyncCachedTrustedVaultAutoUpgradeDebugInfo); + + // Added 05/2024. + profile_prefs->ClearPref(kAutologinEnabled); + profile_prefs->ClearPref(kReverseAutologinRejectedEmailList); + + // Added 06/2024. + profile_prefs->ClearPref(kTrackingProtectionOnboardingNoticeFirstRequested); + profile_prefs->ClearPref(kTrackingProtectionOnboardingNoticeLastRequested); + + // Added 06/2024. +#if !BUILDFLAG(IS_ANDROID) + profile_prefs->ClearPref( + kAccessibilityReadAnythingOmniboxIconLabelShownCount); +#endif + +// Added 06/2024. +#if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE) + profile_prefs->ClearPref(kAccessibilityPdfOcrAlwaysActive); +#endif + + // Added 06/2024. + profile_prefs->ClearPref(kTrackingProtectionOffboarded); + profile_prefs->ClearPref(kTrackingProtectionOffboardedSince); + profile_prefs->ClearPref(kTrackingProtectionOffboardingAckAction); + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 06/2024. + for (const char* pref : kHoldingSpaceWallpaperNudgeTimesOfFirstInteraction) { + profile_prefs->ClearPref(pref); + } + + // Added 06/2024. + profile_prefs->ClearPref(kHoldingSpaceWallpaperNudgeUserEligibleForNudge); + profile_prefs->ClearPref( + kHoldingSpaceWallpaperNudgeLastTimeNudgeShownCounterfactual); + profile_prefs->ClearPref(kHoldingSpaceWallpaperNudgeLastTimeNudgeShown); + profile_prefs->ClearPref( + kHoldingSpaceWallpaperNudgeUserFirstEligibleSessionTime); + profile_prefs->ClearPref( + kHoldingSpaceWallpaperNudgeNudgeShownCountCounterfactual); + profile_prefs->ClearPref(kHoldingSpaceWallpaperNudgeNudgeShownCount); + + // Added 06/2024. + profile_prefs->ClearPref(kBirchUseRecentTabs); + profile_prefs->ClearPref(kBirchUseLastActive); + profile_prefs->ClearPref(kBirchUseMostVisited); + profile_prefs->ClearPref(kBirchUseSelfShare); +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +#if !BUILDFLAG(IS_ANDROID) + // Added 06/2024. + syncer::SyncPrefs::MaybeMigrateAutofillToPerAccountPref(profile_prefs); +#endif // !BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_ANDROID) + // Added 06/2024 + feed::prefs::MigrateObsoleteFeedExperimentPref_Jun_2024(profile_prefs); +#endif // BUILDFLAG(IS_ANDROID) + + // Added 06/2024. + profile_prefs->ClearPref(kDefaultSearchProviderChoicePending); + +#if !BUILDFLAG(IS_ANDROID) + // Added 07/2024. + profile_prefs->ClearPref(kNtpRecipesDismissedTasks); + profile_prefs->ClearPref(kNtpModulesFirstShownTime); + profile_prefs->ClearPref(kNtpModulesFreVisible); + profile_prefs->ClearPref(kNtpModulesShownCount); + profile_prefs->ClearPref(kNtpPhotosLastDismissedTimePrefName); + profile_prefs->ClearPref(kNtpPhotosOptInAcknowledgedPrefName); + profile_prefs->ClearPref(kNtpPhotosLastMemoryOpenTimePrefName); + profile_prefs->ClearPref(kNtpPhotosLastSoftOptedOutTimePrefName); + profile_prefs->ClearPref(kNtpPhotosSoftOptOutCountPrefName); +#endif + + // Added 07/2024. +#if BUILDFLAG(IS_CHROMEOS_ASH) + profile_prefs->ClearPref(kAppDeduplicationServiceLastGetTimestamp); +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Added 07/2024. + profile_prefs->ClearPref(kShowTunaScreenEnabled); +#endif + + // Please don't delete the following line. It is used by PRESUBMIT.py. + // END_MIGRATE_OBSOLETE_PROFILE_PREFS + + // IMPORTANT NOTE: This code is *not* run on iOS Chrome. If a pref is migrated + // or cleared here, and that pref is also used in iOS Chrome, it may also need + // to be migrated or cleared specifically for iOS as well. This could be by + // doing the migration in feature code that's called by all platforms instead + // of here, or by calling migration code in the appropriate place for iOS + // specifically, e.g. ios/chrome/browser/shared/model/prefs/browser_prefs.mm. +} diff --git a/tools/under-control/src/chrome/browser/ui/tab_helpers.cc b/tools/under-control/src/chrome/browser/ui/tab_helpers.cc new file mode 100755 index 000000000..21e3a2abf --- /dev/null +++ b/tools/under-control/src/chrome/browser/ui/tab_helpers.cc @@ -0,0 +1,840 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/tab_helpers.h" + +#include +#include + +#include "base/command_line.h" +#include "base/feature_list.h" +#include "base/time/default_tick_clock.h" +#include "base/trace_event/trace_event.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/browser/bookmarks/bookmark_model_factory.h" +#include "chrome/browser/breadcrumbs/breadcrumb_manager_tab_helper.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/buildflags.h" +#include "chrome/browser/captive_portal/captive_portal_service_factory.h" +#include "chrome/browser/chained_back_navigation_tracker.h" +#include "chrome/browser/chrome_content_browser_client.h" +#include "chrome/browser/commerce/shopping_service_factory.h" +#include "chrome/browser/complex_tasks/task_tab_helper.h" +#include "chrome/browser/content_settings/host_content_settings_map_factory.h" +#include "chrome/browser/content_settings/mixed_content_settings_tab_helper.h" +#include "chrome/browser/content_settings/page_specific_content_settings_delegate.h" +#include "chrome/browser/content_settings/sound_content_setting_observer.h" +#include "chrome/browser/dips/dips_bounce_detector.h" +#include "chrome/browser/dips/dips_service.h" +#include "chrome/browser/enterprise/data_protection/data_protection_navigation_controller.h" +#include "chrome/browser/external_protocol/external_protocol_observer.h" +#include "chrome/browser/favicon/favicon_utils.h" +#include "chrome/browser/file_system_access/file_system_access_features.h" +#include "chrome/browser/file_system_access/file_system_access_permission_request_manager.h" +#include "chrome/browser/file_system_access/file_system_access_tab_helper.h" +#include "chrome/browser/fingerprinting_protection/chrome_fingerprinting_protection_web_contents_helper_factory.h" +#include "chrome/browser/history/history_tab_helper.h" +#include "chrome/browser/history/top_sites_factory.h" +#include "chrome/browser/history_clusters/history_clusters_tab_helper.h" +#include "chrome/browser/history_embeddings/history_embeddings_tab_helper.h" +#include "chrome/browser/image_fetcher/image_fetcher_service_factory.h" +#include "chrome/browser/login_detection/login_detection_tab_helper.h" +#include "chrome/browser/lookalikes/safety_tip_web_contents_observer.h" +#include "chrome/browser/media/media_engagement_service.h" +#include "chrome/browser/metrics/desktop_session_duration/desktop_session_duration_observer.h" +#include "chrome/browser/navigation_predictor/navigation_predictor_preconnect_client.h" +#include "chrome/browser/net/net_error_tab_helper.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" +#include "chrome/browser/optimization_guide/optimization_guide_web_contents_observer.h" +#include "chrome/browser/page_content_annotations/page_content_annotations_service_factory.h" +#include "chrome/browser/page_content_annotations/page_content_annotations_web_contents_observer.h" +#include "chrome/browser/page_info/about_this_site_tab_helper.h" +#include "chrome/browser/page_info/page_info_features.h" +#include "chrome/browser/page_load_metrics/page_load_metrics_initialize.h" +#include "chrome/browser/password_manager/chrome_password_manager_client.h" +#include "chrome/browser/permissions/one_time_permissions_tracker_helper.h" +#include "chrome/browser/predictors/loading_predictor_factory.h" +#include "chrome/browser/predictors/loading_predictor_tab_helper.h" +#include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_manager_factory.h" +#include "chrome/browser/preloading/prefetch/no_state_prefetch/no_state_prefetch_tab_helper.h" +#include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_key.h" +#include "chrome/browser/resource_coordinator/tab_helper.h" +#include "chrome/browser/safe_browsing/chrome_password_reuse_detection_manager_client.h" +#include "chrome/browser/safe_browsing/chrome_safe_browsing_tab_observer_delegate.h" +#include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager_factory.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/browser/safe_browsing/tailored_security/tailored_security_service_factory.h" +#include "chrome/browser/safe_browsing/tailored_security/tailored_security_url_observer.h" +#include "chrome/browser/safe_browsing/trigger_creator.h" +#include "chrome/browser/sessions/session_tab_helper_factory.h" +#include "chrome/browser/ssl/chrome_security_blocking_page_factory.h" +#include "chrome/browser/ssl/connection_help_tab_helper.h" +#include "chrome/browser/ssl/https_only_mode_tab_helper.h" +#include "chrome/browser/ssl/security_state_tab_helper.h" +#include "chrome/browser/storage_access_api/storage_access_api_service_factory.h" +#include "chrome/browser/storage_access_api/storage_access_api_service_impl.h" +#include "chrome/browser/storage_access_api/storage_access_api_tab_helper.h" +#include "chrome/browser/subresource_filter/chrome_content_subresource_filter_web_contents_helper_factory.h" +#include "chrome/browser/supervised_user/supervised_user_navigation_observer.h" +#include "chrome/browser/sync/sessions/sync_sessions_router_tab_helper.h" +#include "chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.h" +#include "chrome/browser/tab_contents/navigation_metrics_recorder.h" +#include "chrome/browser/tpcd/heuristics/opener_heuristic_tab_helper.h" +#include "chrome/browser/tpcd/heuristics/redirect_heuristic_tab_helper.h" +#include "chrome/browser/tpcd/http_error_observer/http_error_tab_helper.h" +#include "chrome/browser/tpcd/metadata/devtools_observer.h" +#include "chrome/browser/tpcd/support/validity_service.h" +#include "chrome/browser/translate/chrome_translate_client.h" +#include "chrome/browser/trusted_vault/trusted_vault_encryption_keys_tab_helper.h" +#include "chrome/browser/ui/autofill/autofill_client_provider.h" +#include "chrome/browser/ui/autofill/autofill_client_provider_factory.h" +#include "chrome/browser/ui/find_bar/find_bar_state.h" +#include "chrome/browser/ui/focus_tab_after_navigation_helper.h" +#include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" +#include "chrome/browser/ui/performance_controls/memory_saver_chip_tab_helper.h" +#include "chrome/browser/ui/performance_controls/tab_resource_usage_tab_helper.h" +#include "chrome/browser/ui/prefs/prefs_tab_helper.h" +#include "chrome/browser/ui/privacy_sandbox/privacy_sandbox_prompt_helper.h" +#include "chrome/browser/ui/recently_audible_helper.h" +#include "chrome/browser/ui/safety_hub/unused_site_permissions_service.h" +#include "chrome/browser/ui/safety_hub/unused_site_permissions_service_factory.h" +#include "chrome/browser/ui/search_engines/search_engine_tab_helper.h" +#include "chrome/browser/ui/tab_contents/core_tab_helper.h" +#include "chrome/browser/ui/tab_dialogs.h" +#include "chrome/browser/ui/tab_ui_helper.h" +#include "chrome/browser/ui/thumbnails/thumbnail_tab_helper.h" +#include "chrome/browser/ui/views/side_panel/companion/companion_utils.h" +#include "chrome/browser/v8_compile_hints/v8_compile_hints_tab_helper.h" +#include "chrome/browser/vr/vr_tab_helper.h" +#include "chrome/common/buildflags.h" +#include "chrome/common/chrome_features.h" +#include "chrome/common/chrome_isolated_world_ids.h" +#include "chrome/common/chrome_switches.h" +#include "components/autofill/content/browser/content_autofill_client.h" +#include "components/autofill/content/browser/content_autofill_driver_factory.h" +#include "components/autofill/core/browser/browser_autofill_manager.h" +#include "components/blocked_content/popup_blocker_tab_helper.h" +#include "components/blocked_content/popup_opener_tab_helper.h" +#include "components/breadcrumbs/core/breadcrumbs_status.h" +#include "components/browsing_topics/browsing_topics_redirect_observer.h" +#include "components/captive_portal/core/buildflags.h" +#include "components/client_hints/browser/client_hints_web_contents_observer.h" +#include "components/commerce/content/browser/commerce_tab_helper.h" +#include "components/commerce/core/commerce_feature_list.h" +#include "components/compose/buildflags.h" +#include "components/content_settings/browser/page_specific_content_settings.h" +#include "components/dom_distiller/core/dom_distiller_features.h" +#include "components/download/content/factory/navigation_monitor_factory.h" +#include "components/download/content/public/download_navigation_observer.h" +#include "components/enterprise/buildflags/buildflags.h" +#include "components/feed/buildflags.h" +#include "components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.h" +#include "components/history/content/browser/web_contents_top_sites_observer.h" +#include "components/history/core/browser/top_sites.h" +#include "components/infobars/content/content_infobar_manager.h" +#include "components/javascript_dialogs/tab_modal_dialog_manager.h" +#include "components/metrics/content/metrics_services_web_contents_observer.h" +#include "components/metrics_services_manager/metrics_services_manager.h" +#include "components/no_state_prefetch/browser/no_state_prefetch_manager.h" +#include "components/offline_pages/buildflags/buildflags.h" +#include "components/optimization_guide/core/optimization_guide_features.h" +#include "components/page_info/core/features.h" +#include "components/password_manager/core/browser/password_manager.h" +#include "components/performance_manager/embedder/performance_manager_registry.h" +#include "components/performance_manager/public/features.h" +#include "components/permissions/features.h" +#include "components/permissions/permission_recovery_success_rate_tracker.h" +#include "components/permissions/permission_request_manager.h" +#include "components/safe_browsing/content/browser/async_check_tracker.h" +#include "components/safe_browsing/content/browser/safe_browsing_navigation_observer.h" +#include "components/safe_browsing/content/browser/safe_browsing_tab_observer.h" +#include "components/safe_browsing/core/common/features.h" +#include "components/search/ntp_features.h" +#include "components/site_engagement/content/site_engagement_helper.h" +#include "components/site_engagement/content/site_engagement_service.h" +#include "components/tracing/common/tracing_switches.h" +#include "components/ukm/content/source_url_recorder.h" +#include "components/user_notes/user_notes_features.h" +#include "components/webapps/browser/installable/installable_manager.h" +#include "components/webapps/browser/installable/ml_installability_promoter.h" +#include "content/public/browser/web_contents.h" +#include "extensions/buildflags/buildflags.h" +#include "media/base/media_switches.h" +#include "pdf/buildflags.h" +#include "ppapi/buildflags/buildflags.h" +#include "printing/buildflags/buildflags.h" +#include "rlz/buildflags/buildflags.h" +#include "ui/accessibility/accessibility_features.h" + +#if BUILDFLAG(IS_ANDROID) +#include "base/functional/bind.h" +#include "base/memory/ptr_util.h" +#include "chrome/browser/android/oom_intervention/oom_intervention_tab_helper.h" +#include "chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android.h" +#include "chrome/browser/android/policy/policy_auditor_bridge.h" +#include "chrome/browser/banners/android/chrome_app_banner_manager_android.h" +#include "chrome/browser/content_settings/request_desktop_site_web_contents_observer_android.h" +#include "chrome/browser/dips/dips_navigation_flow_detector.h" +#include "chrome/browser/facilitated_payments/ui/chrome_facilitated_payments_client.h" +#include "chrome/browser/fast_checkout/fast_checkout_tab_helper.h" +#include "chrome/browser/flags/android/chrome_feature_list.h" +#include "chrome/browser/plugins/plugin_observer_android.h" +#include "chrome/browser/ui/android/context_menu_helper.h" +#include "chrome/browser/ui/javascript_dialogs/javascript_tab_modal_dialog_manager_delegate_android.h" +#include "components/facilitated_payments/core/features/features.h" +#include "components/webapps/browser/android/app_banner_manager_android.h" +#include "content/public/common/content_features.h" +#else +#include "chrome/browser/banners/app_banner_manager_desktop.h" +#include "chrome/browser/companion/core/features.h" +#include "chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h" +#include "chrome/browser/preloading/prefetch/zero_suggest_prefetch/zero_suggest_prefetch_tab_helper.h" +#include "chrome/browser/tab_contents/form_interaction_tab_helper.h" +#include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" +#include "chrome/browser/ui/commerce/commerce_ui_tab_helper.h" +#include "chrome/browser/ui/intent_picker_tab_helper.h" +#include "chrome/browser/ui/javascript_dialogs/javascript_tab_modal_dialog_manager_delegate_desktop.h" +#include "chrome/browser/ui/sad_tab_helper.h" +#include "chrome/browser/ui/search/search_tab_helper.h" +#include "chrome/browser/ui/search_engine_choice/search_engine_choice_tab_helper.h" +#include "chrome/browser/ui/views/side_panel/companion/companion_tab_helper.h" +#include "chrome/browser/ui/views/side_panel/companion/exps_registration_success_observer.h" +#include "chrome/browser/ui/views/side_panel/history_clusters/history_clusters_tab_helper.h" +#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_tab_helper.h" +#include "chrome/browser/ui/sync/browser_synced_tab_delegate.h" +#include "chrome/browser/ui/ui_features.h" +#include "chrome/browser/ui/uma_browsing_activity_observer.h" +#include "components/commerce/content/browser/hint/commerce_hint_tab_helper.h" +#include "components/image_fetcher/core/image_fetcher_service.h" +#include "components/omnibox/browser/omnibox_field_trial.h" +#include "components/web_modal/web_contents_modal_dialog_manager.h" +#include "components/zoom/zoom_controller.h" +#include "third_party/blink/public/common/features.h" +#endif // BUILDFLAG(IS_ANDROID) + +#if defined(TOOLKIT_VIEWS) +#include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h" +#include "chrome/browser/ui/side_search/side_search_utils.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) +#include "chrome/browser/ash/boot_times_recorder_tab_helper.h" +#include "chrome/browser/ash/growth/campaigns_manager_session_tab_helper.h" +#include "chrome/browser/ui/ash/google_one_offer_iph_tab_helper.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#include "chrome/browser/lacros/web_contents_can_go_back_observer.h" +#endif + +#if BUILDFLAG(IS_CHROMEOS) +#include "chrome/browser/chromeos/container_app/container_app_tab_helper.h" +#include "chrome/browser/chromeos/cros_apps/cros_apps_tab_helper.h" +#include "chrome/browser/chromeos/mahi/mahi_tab_helper.h" +#include "chrome/browser/chromeos/policy/dlp/dlp_content_tab_helper.h" +#include "chrome/browser/chromeos/printing/print_preview/printing_init_cros.h" +#endif + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) +#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/hats/hats_helper.h" +#include "chrome/browser/ui/shared_highlighting/shared_highlighting_promo.h" +#endif + +#if BUILDFLAG(IS_WIN) +#include "chrome/browser/font_prewarmer_tab_helper.h" +#endif + +#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) +#include "components/captive_portal/content/captive_portal_tab_helper.h" +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "chrome/browser/extensions/api/web_navigation/web_navigation_api.h" +#include "chrome/browser/extensions/navigation_extension_enabler.h" +#include "chrome/browser/extensions/tab_helper.h" +#include "chrome/browser/ui/extensions/extension_side_panel_utils.h" +#include "chrome/browser/ui/web_applications/web_app_metrics.h" +#include "chrome/browser/ui/web_applications/web_app_metrics_tab_helper.h" +#include "chrome/browser/web_applications/policy/pre_redirection_url_observer.h" +#include "chrome/browser/web_applications/web_app_tab_helper.h" +#include "chrome/browser/web_applications/web_app_utils.h" +#include "extensions/browser/view_type_utils.h" +#include "extensions/common/extension_features.h" +#include "extensions/common/mojom/view_type.mojom.h" +#endif + +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) +#include "chrome/browser/offline_pages/android/auto_fetch_page_load_watcher.h" +#include "chrome/browser/offline_pages/offline_page_tab_helper.h" +#include "chrome/browser/offline_pages/recent_tab_helper.h" +#endif + +#if BUILDFLAG(ENABLE_PLUGINS) +#include "chrome/browser/plugins/plugin_observer.h" +#include "chrome/browser/ui/hung_plugin_tab_helper.h" +#endif + +#if BUILDFLAG(ENABLE_PRINTING) +#include "chrome/browser/printing/printing_init.h" +#endif + + +#if !BUILDFLAG(IS_ANDROID) +#include "chrome/browser/privacy_sandbox/tracking_protection_notice_service.h" +#endif + +#if BUILDFLAG(ENABLE_COMPOSE) +#include "chrome/browser/compose/chrome_compose_client.h" +#include "chrome/browser/compose/compose_enabling.h" +#include "components/compose/buildflags.h" +#include "components/compose/core/browser/compose_features.h" +#endif + +#if BUILDFLAG(ENABLE_RLZ) +#include "chrome/browser/rlz/chrome_rlz_tracker_web_contents_observer.h" +#endif + +using content::WebContents; + +namespace { + +const char kTabContentsAttachedTabHelpersUserDataKey[] = + "TabContentsAttachedTabHelpers"; + +} // namespace + +// static +// WARNING: Do not use this class for desktop chrome. Use TabFeatures instead. +// See +// https://chromium.googlesource.com/chromium/src/+/main/docs/chrome_browser_design_principles.md +void TabHelpers::AttachTabHelpers(WebContents* web_contents) { + // If already adopted, nothing to be done. + base::SupportsUserData::Data* adoption_tag = + web_contents->GetUserData(&kTabContentsAttachedTabHelpersUserDataKey); + if (adoption_tag) { + return; + } + + // Mark as adopted. + web_contents->SetUserData(&kTabContentsAttachedTabHelpersUserDataKey, + std::make_unique()); + + // Create all the tab helpers. + + // SessionTabHelper comes first because it sets up the tab ID, and other + // helpers may rely on that. + CreateSessionServiceTabHelper(web_contents); + +#if !BUILDFLAG(IS_ANDROID) + // ZoomController comes before common tab helpers since ChromeAutofillClient + // may want to register as a ZoomObserver with it. + zoom::ZoomController::CreateForWebContents(web_contents); +#endif + + // infobars::ContentInfoBarManager comes before common tab helpers since + // ChromeSubresourceFilterClient has it as a dependency. + infobars::ContentInfoBarManager::CreateForWebContents(web_contents); + + // `PageSpecificContentSettings` (PSCS) needs to come before + // `DIPSWebContentsObserver` for this latter to be correctly added to the PSCS + // observer list. + content_settings::PageSpecificContentSettings::CreateForWebContents( + web_contents, + std::make_unique( + web_contents)); + + // RedirectChainDetector comes before common tab helpers since + // DIPSWebContentsObserver has it as a dependency. + RedirectChainDetector::CreateForWebContents(web_contents); + + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + + // --- Section 1: Common tab helpers --- + if (page_info::IsAboutThisSiteAsyncFetchingEnabled() +#if defined(TOOLKIT_VIEWS) + || page_info::IsPersistentSidePanelEntryFeatureEnabled() +#endif + ) { + if (auto* optimization_guide_decider = + OptimizationGuideKeyedServiceFactory::GetForProfile(profile)) { + AboutThisSiteTabHelper::CreateForWebContents(web_contents, + optimization_guide_decider); + } + } + autofill::AutofillClientProvider& autofill_client_provider = + autofill::AutofillClientProviderFactory::GetForProfile(profile); + autofill_client_provider.CreateClientForWebContents(web_contents); + if (breadcrumbs::IsEnabled(g_browser_process->local_state())) { + BreadcrumbManagerTabHelper::CreateForWebContents(web_contents); + } + browsing_topics::BrowsingTopicsRedirectObserver::MaybeCreateForWebContents( + web_contents); + chrome::ChainedBackNavigationTracker::CreateForWebContents(web_contents); + chrome_browser_net::NetErrorTabHelper::CreateForWebContents(web_contents); + if (!autofill_client_provider.uses_platform_autofill()) { + ChromePasswordManagerClient::CreateForWebContents(web_contents); + } + ChromePasswordReuseDetectionManagerClient::CreateForWebContents(web_contents); + CreateSubresourceFilterWebContentsHelper(web_contents); +#if BUILDFLAG(ENABLE_RLZ) + ChromeRLZTrackerWebContentsObserver::CreateForWebContentsIfNeeded( + web_contents); +#endif + ChromeTranslateClient::CreateForWebContents(web_contents); + client_hints::ClientHintsWebContentsObserver::CreateForWebContents( + web_contents); + commerce::CommerceTabHelper::CreateForWebContents( + web_contents, profile->IsOffTheRecord(), + commerce::ShoppingServiceFactory::GetForBrowserContext(profile), + ISOLATED_WORLD_ID_CHROME_INTERNAL); + ConnectionHelpTabHelper::CreateForWebContents(web_contents); + CoreTabHelper::CreateForWebContents(web_contents); + DIPSWebContentsObserver::MaybeCreateForWebContents(web_contents); + ExternalProtocolObserver::CreateForWebContents(web_contents); + favicon::CreateContentFaviconDriverForWebContents(web_contents); + FileSystemAccessPermissionRequestManager::CreateForWebContents(web_contents); + FileSystemAccessTabHelper::CreateForWebContents(web_contents); + FindBarState::ConfigureWebContents(web_contents); + if (base::FeatureList::IsEnabled(fingerprinting_protection_filter::features:: + kEnableFingerprintingProtectionFilter)) { + // TODO(https://crbug.com/40280666): Move this to TabFeatures. + CreateFingerprintingProtectionWebContentsHelper( + web_contents, profile->GetPrefs(), + TrackingProtectionSettingsFactory::GetForProfile(profile)); + } + download::DownloadNavigationObserver::CreateForWebContents( + web_contents, + download::NavigationMonitorFactory::GetForKey(profile->GetProfileKey())); + history::WebContentsTopSitesObserver::CreateForWebContents( + web_contents, TopSitesFactory::GetForProfile(profile).get()); + HistoryTabHelper::CreateForWebContents(web_contents); + HistoryClustersTabHelper::CreateForWebContents(web_contents); + HistoryEmbeddingsTabHelper::CreateForWebContents(web_contents); + HttpsOnlyModeTabHelper::CreateForWebContents(web_contents); + webapps::InstallableManager::CreateForWebContents(web_contents); + login_detection::LoginDetectionTabHelper::MaybeCreateForWebContents( + web_contents); + if (MediaEngagementService::IsEnabled()) { + MediaEngagementService::CreateWebContentsObserver(web_contents); + } + if (auto* metrics_services_manager = + g_browser_process->GetMetricsServicesManager()) { + metrics::MetricsServicesWebContentsObserver::CreateForWebContents( + web_contents, metrics_services_manager->GetOnDidStartLoadingCb(), + metrics_services_manager->GetOnDidStopLoadingCb(), + metrics_services_manager->GetOnRendererUnresponsiveCb()); + } + MixedContentSettingsTabHelper::CreateForWebContents(web_contents); + NavigationMetricsRecorder::CreateForWebContents(web_contents); + NavigationPredictorPreconnectClient::CreateForWebContents(web_contents); + OpenerHeuristicTabHelper::CreateForWebContents(web_contents); + if (optimization_guide::features::IsOptimizationHintsEnabled()) { + OptimizationGuideWebContentsObserver::CreateForWebContents(web_contents); + } + page_content_annotations::PageContentAnnotationsService* + page_content_annotations_service = + PageContentAnnotationsServiceFactory::GetForProfile(profile); + if (page_content_annotations_service) { + page_content_annotations::PageContentAnnotationsWebContentsObserver:: + CreateForWebContents(web_contents); + +#if BUILDFLAG(IS_ANDROID) + // If enabled, save sensitivity data for each non-incognito non-custom + // android tab + // TODO(crbug.com/40276584): Consider moving check conditions or the + // registration logic to sensitivity_persisted_tab_data_android.* + if (!profile->IsOffTheRecord()) { + if (auto* tab = TabAndroid::FromWebContents(web_contents); + (tab && !tab->IsCustomTab())) { + SensitivityPersistedTabDataAndroid::From( + tab, + base::BindOnce( + [](page_content_annotations::PageContentAnnotationsService* + page_content_annotations_service, + PersistedTabDataAndroid* persisted_tab_data) { + auto* sensitivity_persisted_tab_data_android = + static_cast( + persisted_tab_data); + sensitivity_persisted_tab_data_android->RegisterPCAService( + page_content_annotations_service); + }, + page_content_annotations_service)); + } + } +#endif // BUILDFLAG(IS_ANDROID) + } + chrome::InitializePageLoadMetricsForWebContents(web_contents); + if (auto* pm_registry = + performance_manager::PerformanceManagerRegistry::GetInstance()) { + pm_registry->SetPageType(web_contents, performance_manager::PageType::kTab); + } + permissions::PermissionRequestManager::CreateForWebContents(web_contents); + permissions::PermissionRecoverySuccessRateTracker::CreateForWebContents( + web_contents); + // The PopupBlockerTabHelper has an implicit dependency on + // ChromeSubresourceFilterClient being available in its constructor. + blocked_content::PopupBlockerTabHelper::CreateForWebContents(web_contents); + blocked_content::PopupOpenerTabHelper::CreateForWebContents( + web_contents, base::DefaultTickClock::GetInstance(), + HostContentSettingsMapFactory::GetForProfile(profile)); + if (predictors::LoadingPredictorFactory::GetForProfile(profile)) { + predictors::LoadingPredictorTabHelper::CreateForWebContents(web_contents); + } + PrefsTabHelper::CreateForWebContents(web_contents); + prerender::NoStatePrefetchTabHelper::CreateForWebContents(web_contents); + RecentlyAudibleHelper::CreateForWebContents(web_contents); + RedirectHeuristicTabHelper::CreateForWebContents(web_contents); +#if BUILDFLAG(IS_ANDROID) + RequestDesktopSiteWebContentsObserverAndroid::CreateForWebContents( + web_contents); +#endif // BUILDFLAG(IS_ANDROID) + // TODO(siggi): Remove this once the Resource Coordinator refactoring is done. + // See https://crbug.com/910288. + resource_coordinator::ResourceCoordinatorTabHelper::CreateForWebContents( + web_contents); + safe_browsing::SafeBrowsingNavigationObserver::MaybeCreateForWebContents( + web_contents, HostContentSettingsMapFactory::GetForProfile(profile), + safe_browsing::SafeBrowsingNavigationObserverManagerFactory:: + GetForBrowserContext(profile), + profile->GetPrefs(), g_browser_process->safe_browsing_service()); + if (base::FeatureList::IsEnabled( + safe_browsing::kTailoredSecurityIntegration)) { + safe_browsing::TailoredSecurityUrlObserver::CreateForWebContents( + web_contents, + safe_browsing::TailoredSecurityServiceFactory::GetForProfile(profile)); + } + if (base::FeatureList::IsEnabled( + safe_browsing::kSafeBrowsingAsyncRealTimeCheck) && + g_browser_process->safe_browsing_service()) { + safe_browsing::AsyncCheckTracker::CreateForWebContents( + web_contents, g_browser_process->safe_browsing_service()->ui_manager()); + } + // SafeBrowsingTabObserver creates a ClientSideDetectionHost, which observes + // events from PermissionRequestManager and AsyncCheckTracker in its + // constructor. Therefore, PermissionRequestManager and AsyncCheckTracker need + // to be created before SafeBrowsingTabObserver is created. + safe_browsing::SafeBrowsingTabObserver::CreateForWebContents( + web_contents, + std::make_unique()); + safe_browsing::TriggerCreator::MaybeCreateTriggersForWebContents( + profile, web_contents); + SafetyTipWebContentsObserver::CreateForWebContents(web_contents); + SearchEngineTabHelper::CreateForWebContents(web_contents); + SecurityStateTabHelper::CreateForWebContents(web_contents); + if (site_engagement::SiteEngagementService::IsEnabled()) { + site_engagement::SiteEngagementService::Helper::CreateForWebContents( + web_contents, + prerender::NoStatePrefetchManagerFactory::GetForBrowserContext( + profile)); + } + SoundContentSettingObserver::CreateForWebContents(web_contents); + StorageAccessAPITabHelper::CreateForWebContents( + web_contents, StorageAccessAPIServiceFactory::GetForBrowserContext( + web_contents->GetBrowserContext())); + // Do not create for Incognito mode. + if (!profile->IsOffTheRecord()) { + SupervisedUserNavigationObserver::CreateForWebContents(web_contents); + } + HttpErrorTabHelper::CreateForWebContents(web_contents); + sync_sessions::SyncSessionsRouterTabHelper::CreateForWebContents( + web_contents, + sync_sessions::SyncSessionsWebContentsRouterFactory::GetForProfile( + profile)); + TabUIHelper::CreateForWebContents(web_contents); + tasks::TaskTabHelper::CreateForWebContents(web_contents); + tpcd::metadata::TpcdMetadataDevtoolsObserver::CreateForWebContents( + web_contents); + tpcd::trial::ValidityService::MaybeCreateForWebContents(web_contents); + TrustedVaultEncryptionKeysTabHelper::CreateForWebContents(web_contents); +#if BUILDFLAG(IS_ANDROID) + if (base::FeatureList::IsEnabled(features::kSafetyHub)) { + auto* service = UnusedSitePermissionsServiceFactory::GetForProfile(profile); + if (service) { + UnusedSitePermissionsService::TabHelper::CreateForWebContents( + web_contents, service); + } + } +#else // BUILDFLAG(IS_ANDROID) + auto* service = UnusedSitePermissionsServiceFactory::GetForProfile(profile); + if (service) { + UnusedSitePermissionsService::TabHelper::CreateForWebContents(web_contents, + service); + } +#endif // BUILDFLAG(IS_ANDROID) + ukm::InitializeSourceUrlRecorderForWebContents(web_contents); + v8_compile_hints::V8CompileHintsTabHelper::MaybeCreateForWebContents( + web_contents); + vr::VrTabHelper::CreateForWebContents(web_contents); + OneTimePermissionsTrackerHelper::CreateForWebContents(web_contents); + + // NO! Do not just add your tab helper here. This is a large alphabetized + // block; please insert your tab helper above in alphabetical order. + + // --- Section 2: Platform-specific tab helpers --- + +#if BUILDFLAG(IS_ANDROID) + DipsNavigationFlowDetector::MaybeCreateForWebContents(web_contents); + webapps::MLInstallabilityPromoter::CreateForWebContents(web_contents); + { + // Remove after fixing https://crbug/905919 + TRACE_EVENT0("browser", "AppBannerManagerAndroid::CreateForWebContents"); + webapps::AppBannerManagerAndroid::CreateForWebContents( + web_contents, std::make_unique( + *web_contents)); + } + ContextMenuHelper::CreateForWebContents(web_contents); + FastCheckoutTabHelper::CreateForWebContents(web_contents); + + javascript_dialogs::TabModalDialogManager::CreateForWebContents( + web_contents, + std::make_unique( + web_contents)); + if (OomInterventionTabHelper::IsEnabled()) { + OomInterventionTabHelper::CreateForWebContents(web_contents); + } + PolicyAuditorBridge::CreateForWebContents(web_contents); + PluginObserverAndroid::CreateForWebContents(web_contents); + + if (base::FeatureList::IsEnabled( + payments::facilitated::kEnablePixDetection)) { + if (auto* optimization_guide_decider = + OptimizationGuideKeyedServiceFactory::GetForProfile(profile)) { + ChromeFacilitatedPaymentsClient::CreateForWebContents( + web_contents, optimization_guide_decider); + } + } +#else // BUILDFLAG(IS_ANDROID) + if (web_app::AreWebAppsUserInstallable(profile)) { + webapps::MLInstallabilityPromoter::CreateForWebContents(web_contents); + webapps::AppBannerManagerDesktop::CreateForWebContents(web_contents); + } + if (base::FeatureList::IsEnabled( + blink::features::kMediaSessionEnterPictureInPicture)) { + AutoPictureInPictureTabHelper::CreateForWebContents(web_contents); + } + BookmarkTabHelper::CreateForWebContents(web_contents); + BrowserSyncedTabDelegate::CreateForWebContents(web_contents); + FocusTabAfterNavigationHelper::CreateForWebContents(web_contents); + FormInteractionTabHelper::CreateForWebContents(web_contents); + FramebustBlockTabHelper::CreateForWebContents(web_contents); + IntentPickerTabHelper::CreateForWebContents(web_contents); +#if BUILDFLAG(ENTERPRISE_WATERMARK) + enterprise_data_protection::DataProtectionNavigationController:: + MaybeCreateForWebContents(web_contents); +#endif + javascript_dialogs::TabModalDialogManager::CreateForWebContents( + web_contents, + std::make_unique( + web_contents)); + ManagePasswordsUIController::CreateForWebContents(web_contents); + if (PrivacySandboxPromptHelper::ProfileRequiresPrompt(profile)) { + PrivacySandboxPromptHelper::CreateForWebContents(web_contents); + } + + if (SearchEngineChoiceTabHelper::IsHelperNeeded()) { + SearchEngineChoiceTabHelper::CreateForWebContents(web_contents); + } + + SadTabHelper::CreateForWebContents(web_contents); + SearchTabHelper::CreateForWebContents(web_contents); + TabDialogs::CreateForWebContents(web_contents); + if (privacy_sandbox::TrackingProtectionNoticeService::TabHelper:: + IsHelperNeeded(profile)) { + privacy_sandbox::TrackingProtectionNoticeService::TabHelper:: + CreateForWebContents(web_contents); + } + MemorySaverChipTabHelper::CreateForWebContents(web_contents); + TabResourceUsageTabHelper::CreateForWebContents(web_contents); + if (base::FeatureList::IsEnabled(features::kTabHoverCardImages) || + base::FeatureList::IsEnabled(features::kWebUITabStrip)) { + ThumbnailTabHelper::CreateForWebContents(web_contents); + } + chrome::UMABrowsingActivityObserver::TabHelper::CreateForWebContents( + web_contents); + web_modal::WebContentsModalDialogManager::CreateForWebContents(web_contents); + if (OmniboxFieldTrial::IsZeroSuggestPrefetchingEnabled()) { + ZeroSuggestPrefetchTabHelper::CreateForWebContents(web_contents); + } + if (commerce::isContextualConsentEnabled()) { + commerce_hint::CommerceHintTabHelper::CreateForWebContents(web_contents); + } + if (base::FeatureList::IsEnabled(ntp_features::kNtpHistoryClustersModule)) { + side_panel::HistoryClustersTabHelper::CreateForWebContents(web_contents); + } + if (companion::IsCompanionFeatureEnabled()) { + companion::CompanionTabHelper::CreateForWebContents(web_contents); + } + if (features::IsReadAnythingLocalSidePanelEnabled()) { + ReadAnythingTabHelper::CreateForWebContents(web_contents); + } + if (base::FeatureList::IsEnabled( + companion::features::internal:: + kCompanionEnabledByObservingExpsNavigations)) { + companion::ExpsRegistrationSuccessObserver::CreateForWebContents( + web_contents); + } +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(ENABLE_COMPOSE) + // We need to create the ChromeComposeClient to listen for the feature + // being turned on, even if it is not enabled yet. + if (!profile->IsOffTheRecord()) { + ChromeComposeClient::CreateForWebContents(web_contents); + } +#endif + +#if BUILDFLAG(IS_CHROMEOS_ASH) + GoogleOneOfferIphTabHelper::CreateForWebContents(web_contents); + // Do not create for Incognito mode. + if (!profile->IsOffTheRecord()) { + CampaignsManagerSessionTabHelper::CreateForWebContents(web_contents); + } + ash::BootTimesRecorderTabHelper::MaybeCreateForWebContents(web_contents); +#endif + +#if BUILDFLAG(IS_CHROMEOS_LACROS) + WebContentsCanGoBackObserver::CreateForWebContents(web_contents); +#endif + +#if BUILDFLAG(IS_CHROMEOS) + ContainerAppTabHelper::MaybeCreateForWebContents(web_contents); + CrosAppsTabHelper::MaybeCreateForWebContents(web_contents); + mahi::MahiTabHelper::MaybeCreateForWebContents(web_contents); + policy::DlpContentTabHelper::MaybeCreateForWebContents(web_contents); +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + webapps::PreRedirectionURLObserver::CreateForWebContents(web_contents); +#endif + +// TODO(crbug.com/40118868): Revisit the macro expression once build flag switch +// of lacros-chrome is complete. +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \ + (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)) + metrics::DesktopSessionDurationObserver::CreateForWebContents(web_contents); +#endif + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ + BUILDFLAG(IS_CHROMEOS) + if (base::FeatureList::IsEnabled( + features::kHappinessTrackingSurveysForDesktopDemo) || + base::FeatureList::IsEnabled(features::kTrustSafetySentimentSurvey) || + base::FeatureList::IsEnabled(features::kTrustSafetySentimentSurveyV2) || + base::FeatureList::IsEnabled(performance_manager::features:: + kPerformanceControlsPerformanceSurvey) || + base::FeatureList::IsEnabled( + performance_manager::features:: + kPerformanceControlsBatteryPerformanceSurvey) || + base::FeatureList::IsEnabled( + performance_manager::features:: + kPerformanceControlsMemorySaverOptOutSurvey) || + base::FeatureList::IsEnabled( + performance_manager::features:: + kPerformanceControlsBatterySaverOptOutSurvey)) { + HatsHelper::CreateForWebContents(web_contents); + } + SharedHighlightingPromo::CreateForWebContents(web_contents); + + if (!profile->IsIncognitoProfile()) { + // TODO(crbug.com/40863325): Consider using the in-memory cache instead. + commerce::CommerceUiTabHelper::CreateForWebContents( + web_contents, + commerce::ShoppingServiceFactory::GetForBrowserContext(profile), + BookmarkModelFactory::GetForBrowserContext(profile), + ImageFetcherServiceFactory::GetForKey(profile->GetProfileKey()) + ->GetImageFetcher(image_fetcher::ImageFetcherConfig::kNetworkOnly)); + } +#endif + +#if BUILDFLAG(IS_WIN) + FontPrewarmerTabHelper::CreateForWebContents(web_contents); +#endif + +#if defined(TOOLKIT_VIEWS) + if (IsSideSearchEnabled(profile)) { + SideSearchTabContentsHelper::CreateForWebContents(web_contents); + } +#endif + + // --- Section 3: Feature tab helpers behind BUILDFLAGs --- + // NOT for "if enabled"; put those in section 1. + +#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) + captive_portal::CaptivePortalTabHelper::CreateForWebContents( + web_contents, CaptivePortalServiceFactory::GetForProfile(profile), + base::BindRepeating( + &ChromeSecurityBlockingPageFactory::OpenLoginTabForWebContents, + web_contents, false)); +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) + extensions::SetViewType(web_contents, + extensions::mojom::ViewType::kTabContents); + + extensions::TabHelper::CreateForWebContents(web_contents); + extensions::NavigationExtensionEnabler::CreateForWebContents(web_contents); + + if (base::FeatureList::IsEnabled( + extensions_features::kExtensionSidePanelIntegration)) { + extensions::side_panel_util::CreateSidePanelManagerForWebContents( + profile, web_contents); + } + + extensions::WebNavigationTabObserver::CreateForWebContents(web_contents); + if (web_app::AreWebAppsEnabled(profile)) { + web_app::WebAppTabHelper::CreateForWebContents(web_contents); + } + // Note WebAppMetricsTabHelper must be created after AppBannerManager. + if (web_app::WebAppMetricsTabHelper::IsEnabled(web_contents)) { + web_app::WebAppMetricsTabHelper::CreateForWebContents(web_contents); + } +#endif + +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + offline_pages::OfflinePageTabHelper::CreateForWebContents(web_contents); + offline_pages::RecentTabHelper::CreateForWebContents(web_contents); + offline_pages::AutoFetchPageLoadWatcher::CreateForWebContents(web_contents); +#endif + +#if BUILDFLAG(ENABLE_PLUGINS) + HungPluginTabHelper::CreateForWebContents(web_contents); + PluginObserver::CreateForWebContents(web_contents); +#endif + +// Only enable ChromeOS print preview if `kPrintPreviewCrosPrimary` is enabled +// and is a ChromeOS build. Otherwise instantiate browser print preview. +#if BUILDFLAG(ENABLE_PRINTING) && BUILDFLAG(IS_CHROMEOS) + if (base::FeatureList::IsEnabled(::features::kPrintPreviewCrosPrimary)) { + chromeos::printing::InitializePrintingForWebContents(web_contents); + } else { + printing::InitializePrintingForWebContents(web_contents); + } +#elif BUILDFLAG(ENABLE_PRINTING) + printing::InitializePrintingForWebContents(web_contents); +#endif + + // --- Section 4: The warning --- + + // NONO NO NONONO ! + // NO NO NO NO NO ! + // NO NO NO NO NO ! + // NO NO NO NO NO ! + // NO NONO NONONO ! + + // Do NOT just drop your tab helpers here! There are three sections above (1. + // All platforms, 2. Some platforms, 3. Behind BUILDFLAGs). Each is in rough + // alphabetical order. PLEASE PLEASE PLEASE add your flag to the correct + // section in the correct order. + + // This is common code for all of us. PLEASE DO YOUR PART to keep it tidy and + // organized. +} diff --git a/tools/under-control/src/chrome/browser/ui/webui/chrome_content_browser_client_webui_part.cc b/tools/under-control/src/chrome/browser/ui/webui/chrome_content_browser_client_webui_part.cc new file mode 100755 index 000000000..bb8b59404 --- /dev/null +++ b/tools/under-control/src/chrome/browser/ui/webui/chrome_content_browser_client_webui_part.cc @@ -0,0 +1,120 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/webui/chrome_content_browser_client_webui_part.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/webui_url_constants.h" +#include "components/prefs/pref_service.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/browser/web_contents.h" +#include "extensions/common/constants.h" +#include "third_party/blink/public/common/web_preferences/web_preferences.h" + +namespace { + +// Returns whether any prefs were changed. +bool CopyFontPrefs(const blink::web_pref::WebPreferences& source, + blink::web_pref::WebPreferences* destination) { + bool changed = false; + changed |= destination->default_font_size != source.default_font_size; + changed |= + destination->default_fixed_font_size != source.default_fixed_font_size; + changed |= destination->minimum_font_size != source.minimum_font_size; + changed |= destination->minimum_logical_font_size != + source.minimum_logical_font_size; + + if (!changed) { + return false; + } + + destination->default_font_size = source.default_font_size; + destination->default_fixed_font_size = source.default_fixed_font_size; + destination->minimum_font_size = source.minimum_font_size; + destination->minimum_logical_font_size = source.minimum_logical_font_size; + + return true; +} + +// Returns the visible URL or GURL() if unavailable. +GURL GetVisibleURL(content::WebContents* web_contents) { + if (!web_contents) { + return GURL(); + } + + content::NavigationEntry* entry = + web_contents->GetController().GetVisibleEntry(); + return entry ? entry->GetURL() : GURL(); +} + +} // namespace + +ChromeContentBrowserClientWebUiPart::ChromeContentBrowserClientWebUiPart() = + default; +ChromeContentBrowserClientWebUiPart::~ChromeContentBrowserClientWebUiPart() = + default; + +void ChromeContentBrowserClientWebUiPart::OverrideWebkitPrefs( + content::WebContents* web_contents, + blink::web_pref::WebPreferences* web_prefs) { + // This logic is invoked at startup, and anytime the default prefs change. + GURL url = GetVisibleURL(web_contents); + + if (!url.SchemeIs(content::kChromeUIScheme)) { + return; + } + + // Use default font sizes for WebUi. + blink::web_pref::WebPreferences default_prefs; + CopyFontPrefs(/*source=*/default_prefs, /*destination=*/web_prefs); + +#if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) + // Set some non-font prefs for webui tabstrip. The tabstrip renderer is never + // navigated to or from, so we don't need to replicate this logic in + // OverrideWebPreferencesAfterNavigation. + if (url.host_piece() == chrome::kChromeUITabStripHost) { + web_prefs->touch_drag_drop_enabled = true; + web_prefs->touch_dragend_context_menu = true; + } +#endif +} + +bool ChromeContentBrowserClientWebUiPart::OverrideWebPreferencesAfterNavigation( + content::WebContents* web_contents, + blink::web_pref::WebPreferences* web_prefs) { + // This logic is invoked once on each navigation. + + GURL url = GetVisibleURL(web_contents); + if (!url.is_valid()) { + return false; + } + + // Extensions are handled by ChromeContentBrowserClientExtensionsPart. + const GURL& site_url = + web_contents->GetPrimaryMainFrame()->GetSiteInstance()->GetSiteURL(); + if (site_url.SchemeIs(extensions::kExtensionScheme)) { + return false; + } + + blink::web_pref::WebPreferences web_prefs_source; + if (url.SchemeIs(content::kChromeUIScheme)) { + // Use default prefs for WebUi. Not further modifications necessary for + // web_prefs_source. + } else { + // Use profile prefs for normal websites. + Profile* profile = + Profile::FromBrowserContext(web_contents->GetBrowserContext()); + PrefService* prefs = profile->GetPrefs(); + web_prefs_source.default_font_size = + prefs->GetInteger(prefs::kWebKitDefaultFontSize); + web_prefs_source.default_fixed_font_size = + prefs->GetInteger(prefs::kWebKitDefaultFixedFontSize); + web_prefs_source.minimum_font_size = + prefs->GetInteger(prefs::kWebKitMinimumFontSize); + web_prefs_source.minimum_logical_font_size = + prefs->GetInteger(prefs::kWebKitMinimumLogicalFontSize); + } + return CopyFontPrefs(web_prefs_source, web_prefs); +} diff --git a/tools/under-control/src/chrome/common/extensions/api/accessibility_service_private.idl b/tools/under-control/src/chrome/common/extensions/api/accessibility_service_private.idl new file mode 100755 index 000000000..45c454a52 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/accessibility_service_private.idl @@ -0,0 +1,30 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// API which provides support for ChromeOS Accessibility features in the +// browser. + +[platforms=("chromeos", "lacros"), + implemented_in="chrome/browser/chromeos/extensions/accessibility_service_private.h"] + +namespace accessibilityServicePrivate { + callback VoidCallback = void(); + + interface Functions { + // Called when Select to Speak in ChromeOS should speak the current + // text selection; fired when the context menu option was clicked in + // a selection context. + static void speakSelectedText( + optional VoidCallback callback); + }; + + interface Events { + // Called when Select to Speak in ChromeOS wants a clipboard copy + // event to be performed on the active and focused tab with the + // given URL. This is fired when Select to Speak is trying to speak + // with search+s but cannot find a selection and the focused node + // is in a Google Docs page. + static void clipboardCopyInActiveGoogleDoc(DOMString url); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/appview_tag.idl b/tools/under-control/src/chrome/common/extensions/api/appview_tag.idl new file mode 100755 index 000000000..18f00d138 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/appview_tag.idl @@ -0,0 +1,49 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the appview tag to embed other Chrome Apps within your +// Chrome App. (see Usage). +[documentation_title=" Tag", + documentation_namespace="", + documented_in="tags/appview"] +namespace appviewTag { + // This object specifies details and operations to perform on the embedding + // request. The app to be embedded can make a decision on whether or not to + // allow the embedding and what to embed based on the embedder making the + // request. + dictionary EmbedRequest { + // The ID of the app that sent the embedding request. + DOMString embedderId; + + // Optional developer specified data that the app to be embedded can use + // when making an embedding decision. + object data; + + // Allows the embedding request. + // + // |url| : Specifies the content to be embedded. + static void allow(DOMString url); + + // Prevents the embedding request. + static void deny(); + }; + + // An optional function that's called after the embedding request is + // completed. + // + // |success| : True if the embedding request succeded. + callback EmbeddingCallback = void (boolean success); + + interface Functions { + // Requests another app to be embedded. + // + // |app| : The extension id of the app to be embedded. + // |data| : Optional developer specified data that the app to be embedded + // can use when making an embedding decision. + // |callback| : An optional function that's called after the embedding + // request is completed. + static void connect(DOMString app, optional any data, + optional EmbeddingCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/autofill_private.idl b/tools/under-control/src/chrome/common/extensions/api/autofill_private.idl new file mode 100755 index 000000000..cfb8ceead --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/autofill_private.idl @@ -0,0 +1,426 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.autofillPrivate API to add, remove, or update +// autofill data from the settings UI. +namespace autofillPrivate { + // Subset of properties from the user account (signin component, AccountInfo). + dictionary AccountInfo { + DOMString email; + boolean isSyncEnabledForAutofillProfiles; + boolean isEligibleForAddressAccountStorage; + + // Controls whether the Autofill Sync toggle should be available (duplicated + // from the Sync Settings page) on the Autofill Settings page. + // TODO(crbug.com/40943238): Remove when toggle becomes available on the Sync + // page for non-syncing users. + boolean isAutofillSyncToggleAvailable; + + // Represents the UserSelectableType::kAutofill state (enabled or not). + // TODO(crbug.com/40943238): Remove when toggle becomes available on the Sync + // page for non-syncing users. + boolean isAutofillSyncToggleEnabled; + }; + + // A copy of FieldType from + // chrome/common/extensions/api/autofill_private.idl + enum FieldType { + NO_SERVER_DATA, + UNKNOWN_TYPE, + EMPTY_TYPE, + NAME_FIRST, + NAME_MIDDLE, + NAME_LAST, + NAME_MIDDLE_INITIAL, + NAME_FULL, + NAME_SUFFIX, + EMAIL_ADDRESS, + PHONE_HOME_NUMBER, + PHONE_HOME_CITY_CODE, + PHONE_HOME_COUNTRY_CODE, + PHONE_HOME_CITY_AND_NUMBER, + PHONE_HOME_WHOLE_NUMBER, + ADDRESS_HOME_LINE1, + ADDRESS_HOME_LINE2, + ADDRESS_HOME_APT_NUM, + ADDRESS_HOME_CITY, + ADDRESS_HOME_STATE, + ADDRESS_HOME_ZIP, + ADDRESS_HOME_COUNTRY, + CREDIT_CARD_NAME_FULL, + CREDIT_CARD_NUMBER, + CREDIT_CARD_EXP_MONTH, + CREDIT_CARD_EXP_2_DIGIT_YEAR, + CREDIT_CARD_EXP_4_DIGIT_YEAR, + CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR, + CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR, + CREDIT_CARD_TYPE, + CREDIT_CARD_VERIFICATION_CODE, + COMPANY_NAME, + FIELD_WITH_DEFAULT_VALUE, + MERCHANT_EMAIL_SIGNUP, + MERCHANT_PROMO_CODE, + PASSWORD, + ACCOUNT_CREATION_PASSWORD, + ADDRESS_HOME_STREET_ADDRESS, + ADDRESS_HOME_SORTING_CODE, + ADDRESS_HOME_DEPENDENT_LOCALITY, + ADDRESS_HOME_LINE3, + NOT_ACCOUNT_CREATION_PASSWORD, + USERNAME, + USERNAME_AND_EMAIL_ADDRESS, + NEW_PASSWORD, + PROBABLY_NEW_PASSWORD, + NOT_NEW_PASSWORD, + CREDIT_CARD_NAME_FIRST, + CREDIT_CARD_NAME_LAST, + PHONE_HOME_EXTENSION, + CONFIRMATION_PASSWORD, + AMBIGUOUS_TYPE, + SEARCH_TERM, + PRICE, + NOT_PASSWORD, + SINGLE_USERNAME, + NOT_USERNAME, + UPI_VPA, + ADDRESS_HOME_STREET_NAME, + ADDRESS_HOME_HOUSE_NUMBER, + ADDRESS_HOME_SUBPREMISE, + ADDRESS_HOME_OTHER_SUBUNIT, + NAME_LAST_FIRST, + NAME_LAST_CONJUNCTION, + NAME_LAST_SECOND, + NAME_HONORIFIC_PREFIX, + ADDRESS_HOME_ADDRESS, + ADDRESS_HOME_ADDRESS_WITH_NAME, + ADDRESS_HOME_FLOOR, + PHONE_HOME_CITY_CODE_WITH_TRUNK_PREFIX, + PHONE_HOME_CITY_AND_NUMBER_WITHOUT_TRUNK_PREFIX, + PHONE_HOME_NUMBER_PREFIX, + PHONE_HOME_NUMBER_SUFFIX, + IBAN_VALUE, + CREDIT_CARD_STANDALONE_VERIFICATION_CODE, + NUMERIC_QUANTITY, + ONE_TIME_CODE, + DELIVERY_INSTRUCTIONS, + ADDRESS_HOME_OVERFLOW, + ADDRESS_HOME_LANDMARK, + ADDRESS_HOME_OVERFLOW_AND_LANDMARK, + ADDRESS_HOME_ADMIN_LEVEL2, + ADDRESS_HOME_STREET_LOCATION, + ADDRESS_HOME_BETWEEN_STREETS, + ADDRESS_HOME_BETWEEN_STREETS_OR_LANDMARK, + ADDRESS_HOME_STREET_LOCATION_AND_LOCALITY, + ADDRESS_HOME_STREET_LOCATION_AND_LANDMARK, + ADDRESS_HOME_DEPENDENT_LOCALITY_AND_LANDMARK, + ADDRESS_HOME_BETWEEN_STREETS_1, + ADDRESS_HOME_BETWEEN_STREETS_2, + SINGLE_USERNAME_FORGOT_PASSWORD, + ADDRESS_HOME_APT, + ADDRESS_HOME_APT_TYPE, + ADDRESS_HOME_HOUSE_NUMBER_AND_APT, + SINGLE_USERNAME_WITH_INTERMEDIATE_VALUES, + MAX_VALID_FIELD_TYPE + }; + + // The address source origin. Describes where the address is stored. + enum AddressSource { + // The address is stored in the Chrome infrastructure (locally and + // possibly synced between devices). + LOCAL_OR_SYNCABLE, + // The address is stored in a third party service that is tied + // to user's account. + ACCOUNT + }; + + // Metadata about an autofill entry (address or credit card) which is used to + // render a summary list of all entries. + dictionary AutofillMetadata { + // Short summary of the address/credit card which is displayed in the UI; an + // undefined value means that this entry has just been created on the client + // and has not yet been given a summary. + DOMString summaryLabel; + + // Short, secondary summary of the address/credit card which is displayed + // in the UI; an undefined value means that this entry has just been created + // on the client and has not yet been given a summary. + DOMString? summarySublabel; + + // For addresses. Describes where the address is stored. + AddressSource? source; + + // For credit cards, whether the entry is locally owned by Chrome (as opposed to + // being synced down from the server). Non-local entries may not be editable. + boolean? isLocal; + + // For credit cards, whether this is a full copy of the card + boolean? isCached; + + // For credit cards, whether this is migratable (both the card number and + // expiration date valid and does not have the duplicated server card). + boolean? isMigratable; + + // For credit cards. Indicates whether a card is eligible for virtual cards + // enrollment. + boolean? isVirtualCardEnrollmentEligible; + + // For credit cards. Indicates whether a card has been enrolled in virtual + // cards if it is eligible. + boolean? isVirtualCardEnrolled; + }; + + // Represents single entry of the autofill profile, containing field type and + // the corresponding field value. + dictionary AddressField { + FieldType type; + DOMString value; + }; + + // An address entry which can be saved in the autofill section of the + // settings UI. + dictionary AddressEntry { + // Globally unique identifier for this entry. + DOMString? guid; + + // Fields have to be stored in the array with every field style stored only + // once. + AddressField[] fields; + + DOMString? languageCode; + + AutofillMetadata? metadata; + }; + + // An entry representing a country and its code. + dictionary CountryEntry { + // The internationalized name of the country. + DOMString? name; + + // A two-character string representing the country. + DOMString? countryCode; + }; + + // A component to be shown in an address editor. Different countries have + // different components to their addresses. + dictionary AddressComponent { + // The field type. + FieldType field; + + // The name of the field. + DOMString fieldName; + + // A hint for the UI regarding whether the input is likely to be long. + boolean isLongField; + + // Whether this component is required or not. + boolean isRequired; + + // A placeholder for the text field to be used when the user has not yet + // input a value for the field. + DOMString? placeholder; + }; + + // A row of address components. Each component in a row should be shown in the + // same row in the UI. For example, city, state, and zip code are all included + // on the same line for US addresses. + dictionary AddressComponentRow { + AddressComponent[] row; + }; + + // The address components for a given country code. Each entry in |components| + // constitutes a row in the UI, while each inner array contains the list of + // components to use in that row. For example, city, state, and zip code are + // all included on the same line for US addresses. This dictionary also + // includes the associated language code. + dictionary AddressComponents { + // The components. + AddressComponentRow[] components; + + // The language code. + DOMString languageCode; + }; + + // A credit card entry which can be saved in the autofill section of the + // settings UI. + dictionary CreditCardEntry { + // Globally unique identifier for this entry. + DOMString? guid; + + // The card's instrument ID from the GPay server, if applicable. + DOMString? instrumentId; + + // Name of the person who owns the credit card. + DOMString? name; + + // Credit card number. + DOMString? cardNumber; + + // Month as 2-character string ("01" = January, "12" = December). + DOMString? expirationMonth; + + // Year as a 4-character string (as in "2015"). + DOMString? expirationYear; + + // Credit card's nickname. + DOMString? nickname; + + // Credit card's network. + DOMString? network; + + // Credit card's image source. + DOMString? imageSrc; + + // Credit card's masked cvc. + DOMString? cvc; + + // Credit card's product terms URL. + DOMString? productTermsUrl; + + AutofillMetadata? metadata; + }; + + // An IBAN entry which can be saved in the autofill section of the + // settings UI. + dictionary IbanEntry { + // Globally unique identifier for this entry. + DOMString? guid; + + // IBAN value. + DOMString? value; + + // IBAN's nickname. + DOMString? nickname; + + AutofillMetadata? metadata; + }; + + callback GetAccountInfoCallback = void(optional AccountInfo accountInfo); + callback GetCountryListCallback = void(CountryEntry[] countries); + callback GetAddressComponentsCallback = void(AddressComponents components); + callback GetAddressListCallback = void(AddressEntry[] entries); + callback GetCreditCardListCallback = void(CreditCardEntry[] entries); + callback GetIbanListCallback = void(IbanEntry[] entries); + callback IsValidIbanCallback = void(boolean isValid); + callback GetCreditCardCallback = void(optional CreditCardEntry card); + callback CheckForDeviceAuthCallback = void(boolean isDeviceAuthAvailable); + + interface Functions { + // Gets currently signed-in user profile info, no value is returned if + // the user is not signed-in. + // |callback|: Callback which will be called with the info. + static void getAccountInfo( + GetAccountInfoCallback callback); + + // Saves the given address. If |address| has an empty string as its ID, it + // will be assigned a new one and added as a new entry. + // |address|: The address entry to save. + static void saveAddress(AddressEntry address); + + // Gets the list of all countries. + // |forAccountAddressProfile|: whether the address profile opened in the + // editor originates in the user's profile. + // |callback|: Callback which will be called with the countries. + static void getCountryList( + boolean forAccountAddressProfile, + GetCountryListCallback callback); + + // Gets the address components for a given country code. + // |countryCode|: A two-character string representing the address' country + // whose components should be returned. See autofill_country.cc for a + // list of valid codes. + // |callback|: Callback which will be called with components. + static void getAddressComponents( + DOMString countryCode, + GetAddressComponentsCallback callback); + + // Gets the list of addresses. + // |callback|: Callback which will be called with the list of addresses. + static void getAddressList( + GetAddressListCallback callback); + + // Saves the given credit card. If |card| has an empty string as its + // ID, it will be assigned a new one and added as a new entry. + // |card|: The card entry to save. + static void saveCreditCard(CreditCardEntry card); + + // Saves the given IBAN. If `iban` has an empty string as its ID, it will be + // assigned a new one and added as a new entry. + // |iban|: The IBAN entry to save. + static void saveIban(IbanEntry iban); + + // Removes the entry (address or credit card) with the given ID. + // |guid|: ID of the entry to remove. + static void removeEntry(DOMString guid); + + // Gets the list of credit cards. + // |callback|: Callback which will be called with the list of credit cards. + static void getCreditCardList( + GetCreditCardListCallback callback); + + // Gets the list of IBANs. + // `callback`: Callback which will be called with the list of IBANs. + static void getIbanList( + GetIbanListCallback callback); + + // Returns true if the given `ibanValue` is a valid IBAN. + // `callback`: Callback which will be called with the result of IBAN + // validation. + static void isValidIban( + DOMString ibanValue, IsValidIbanCallback callback); + + // Triggers local credit cards migration. + static void migrateCreditCards(); + + // Logs that the server cards edit link was clicked. + static void logServerCardLinkClicked(); + + // Enrolls a credit card into virtual cards. + // |cardId|: The server side id of the credit card to be enrolled. Note it + // refers to the legacy server id of credit cards, not the instrument ids. + static void addVirtualCard(DOMString cardId); + + // Unenrolls a credit card from virtual cards. + // |cardId|: The server side id of the credit card to be unenrolled. Note + // it refers to the legacy server id of credit cards, not the instrument + // ids. + static void removeVirtualCard(DOMString cardId); + + // Authenticates the user via device authentication and if successful, it + // will then flip the mandatory auth toggle. + static void authenticateUserAndFlipMandatoryAuthToggle(); + + // Returns the local card based on the `guid` provided. The user could + // also be challenged with a reauth if that is enabled. For a successful + // auth, the local card is returned otherwise return a null object. + static void getLocalCard( + DOMString guid, GetCreditCardCallback callback); + + // Returns true if there is authentication available on this device + // (biometric or screen lock), false otherwise. + static void checkIfDeviceAuthAvailable( + CheckForDeviceAuthCallback callback); + + // Bulk delete all the CVCs (server and local) from the local webdata + // database. For server CVCs, this will also clear them from the Chrome + // sync server and thus other devices. + static void bulkDeleteAllCvcs(); + + // Sets the Sync Autofill toggle value, which corresponds to + // `syncer::UserSelectableType::kAutofill` in `SyncUserSettings`. + static void setAutofillSyncToggleEnabled(boolean enabled); + }; + + interface Events { + // Fired when the personal data has changed, meaning that an entry has + // been added, removed, or changed. + // `addressEntries`: the updated list of addresses. + // `creditCardEntries`: the updated list of credit cards. + // `ibans`: the updated list of IBANs. + // `accountInfo`: account info if the user is signed-in or no value if not. + static void onPersonalDataChanged(AddressEntry[] addressEntries, + CreditCardEntry[] creditCardEntries, + IbanEntry[] ibans, + optional AccountInfo accountInfo); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/autotest_private.idl b/tools/under-control/src/chrome/common/extensions/api/autotest_private.idl new file mode 100755 index 000000000..f30dcd10f --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/autotest_private.idl @@ -0,0 +1,1678 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// API for integration testing. To be used on test images with a test component +// extension. +[platforms=("chromeos"), + implemented_in="chrome/browser/ash/extensions/autotest_private/autotest_private_api.h"] +namespace autotestPrivate { + + enum ShelfAlignmentType { + // BottomLocked not supported by shelf_prefs. + Bottom, Left, Right + }; + + // A mapping of ash::ShelfItemType. + enum ShelfItemType { + PinnedApp, + BrowserShortcut, + App, + UnpinnedBrowserShortcut, + Dialog + }; + + // A mapping of ash::ShelfItemStatus. + enum ShelfItemStatus { + Closed, + Running, + Attention + }; + + // A mapping of apps::mojom::Type + enum AppType { + Arc, + BuiltIn, + Crostini, + Extension, + Web, + MacOS, + PluginVm, + StandaloneBrowser, + Remote, + Borealis, + Bruschetta + }; + + // A mapping of apps::mojom::InstallSource + enum AppInstallSource { + Unknown, + System, + Policy, + Oem, + Default, + Sync, + User, + SubApp, + Kiosk, + CommandLine + }; + + // A mapping of apps::mojom::Readiness + enum AppReadiness { + Ready, + DisabledByBlacklist, + DisabledByPolicy, + DisabledByUser, + Terminated, + UninstalledByUser, + Removed, + UninstalledByMigration, + DisabledByLocalSettings + }; + + // A mapping of arc::mojom::WakefulnessMode + enum WakefulnessMode { + Unknown, + Asleep, + Awake, + Dreaming, + Dozing + }; + callback WakefulnessModeCallback = void (WakefulnessMode mode); + + // A subset of Window State types in ash::WindowStateType. We may add more + // into the set in the future. + enum WindowStateType { + Normal, + Minimized, + Maximized, + Fullscreen, + PrimarySnapped, + SecondarySnapped, + Pinned, + TrustedPinned, + PIP, + Floated + }; + + // A subset of WM event types in ash::WMEventType. We may add more in the + // set in the future. + enum WMEventType { + WMEventNormal, + WMEventMaximize, + WMEventMinimize, + WMEventFullscreen, + WMEventSnapPrimary, + WMEventSnapSecondary, + WMEventFloat + }; + + // Display orientation type. + enum RotationType { + // RotateAny is the auto-rotation status (not locked to a rotation) for + // tablet mode. Not working in clamshell mode. + RotateAny, + Rotate0, + Rotate90, + Rotate180, + Rotate270 + }; + + enum LauncherStateType { + Closed, + FullscreenAllApps, + FullscreenSearch + }; + + enum OverviewStateType { + Shown, + Hidden + }; + + enum MouseButton { + Left, + Middle, + Right, + Back, + Forward + }; + + // A paramter used in setArcAppWindowState() function. + dictionary WindowStateChangeDict { + // The WM event to change the ARC window state. + WMEventType eventType; + + // If the initial state is already same as the expected state, should we + // treat this case as a failure? Default value is false. + boolean? failIfNoChange; + }; + + dictionary LoginStatusDict { + // Are we logged in? + boolean isLoggedIn; + // Is the logged-in user the owner? + boolean isOwner; + // Is the screen locked? + boolean isScreenLocked; + // Is the wallpaper blur layer still animating in? + boolean isLockscreenWallpaperAnimating; + // Is the screen ready for password? + boolean isReadyForPassword; + // Are the avatar images loaded for all users? + boolean areAllUserImagesLoaded; + + // Is the logged-in user a regular user? Set only if `isLoggedIn`. + boolean? isRegularUser; + // Are we logged into the guest account? Set only if `isLoggedIn`. + boolean? isGuest; + // Are we logged into kiosk-app mode? Set only if `isLoggedIn`. + boolean? isKiosk; + + // User email. Set only if `isLoggedIn`. + DOMString? email; + // User display email. Set only if `isLoggedIn`. + DOMString? displayEmail; + // User display name. Set only if `isLoggedIn`. + DOMString? displayName; + // User image: 'file', 'profile' or a number. Set only if `isLoggedIn`. + DOMString? userImage; + // Whether the user has a valid oauth2 token. Only set for gaia user. + boolean? hasValidOauth2Token; + }; + callback LoginStatusCallback = void (LoginStatusDict status); + + // |all_policies| will be the full list of policies as returned by the + // DictionaryPolicyConversions.ToValue function. + callback AllEnterprisePoliciesCallback = void (any all_policies); + + dictionary ExtensionInfoDict { + DOMString id; + DOMString version; + DOMString name; + DOMString publicKey; + DOMString description; + DOMString backgroundUrl; + DOMString optionsUrl; + + DOMString[] hostPermissions; + DOMString[] effectiveHostPermissions; + DOMString[] apiPermissions; + + boolean isComponent; + boolean isInternal; + boolean isUserInstalled; + boolean isEnabled; + boolean allowedInIncognito; + boolean hasPageAction; + }; + dictionary ExtensionsInfoArray { + ExtensionInfoDict[] extensions; + }; + callback ExtensionsInfoCallback = void (ExtensionsInfoArray info); + + dictionary Notification { + DOMString id; + DOMString type; + DOMString title; + DOMString message; + long priority; + long progress; + }; + callback NotificationArrayCallback = void (Notification[] notifications); + + dictionary Printer { + DOMString printerName; + DOMString? printerId; + DOMString? printerType; + DOMString? printerDesc; + DOMString? printerMakeAndModel; + DOMString? printerUri; + DOMString? printerPpd; + }; + callback PrinterArrayCallback = void (Printer[] printers); + + callback ArcStartTimeCallback = void (double startTicks); + + dictionary ArcState { + // Whether the ARC is provisioned. + boolean provisioned; + // Whether ARC Terms of Service needs to be shown. + boolean tosNeeded; + // ARC pre-start time (mini-ARC) or 0 if not pre-started. + double preStartTime; + // ARC start time or 0 if not started. + double startTime; + }; + callback ArcStateCallback = void (ArcState result); + + dictionary PlayStoreState { + // Whether the Play Store allowed for the current user. + boolean allowed; + // Whether the Play Store currently enabled. + boolean? enabled; + // Whether the Play Store managed by policy. + boolean? managed; + }; + callback PlayStoreStateCallback = void (PlayStoreState result); + + dictionary AssistantQueryResponse { + // Text response returned from server. + DOMString? text; + // HTML response returned from server. + DOMString? htmlResponse; + // Open URL response returned from server. + DOMString? openUrl; + // Open Android app response returned from server. + DOMString? openAppResponse; + }; + dictionary AssistantQueryStatus { + // Indicates whether this might be a voice interaction. + boolean isMicOpen; + // Query text sent to Assistant. In the event of a voice interaction, + // this field will be same as the speech recognition final result. + DOMString queryText; + // Response for the current query. + AssistantQueryResponse queryResponse; + }; + callback AssistantQueryStatusCallback = void (AssistantQueryStatus status); + + callback IsAppShownCallback = void (boolean appShown); + + callback IsArcProvisionedCallback = void (boolean arcProvisioned); + + callback IsArcPackageListInitialRefreshedCallback = void (boolean refreshed); + + // A mapping of crosapi::BrowserManager::State + enum LacrosState { + NotInitialized, + Reloading, + Mounting, + Unavailable, + Stopped, + PreparingForLaunch, + PreLaunched, + Starting, + Running, + WaitingForMojoDisconnected, + WaitingForProcessTerminated + }; + + // A mapping of crosapi::browser_util::LacrosMode + enum LacrosMode { + Disabled, + Only + }; + + dictionary LacrosInfo { + // The state of lacros. + LacrosState state; + // True iff keepalive is enabled for lacros. + boolean isKeepAlive; + // Path to lacros-chrome directory. Note that this may change over time if + // omaha is used. This also may be empty if lacros is not running. + DOMString lacrosPath; + // Specifies the mode Lacros is currently running. + // For a full list of supported mode, see LacrosMode enum definition. + // DEPRECATED: please use isEnabled. + // TODO(crbug.com/40286020): Remove this field after tests are fixed. + LacrosMode mode; + // True iff Lacros is enabled for the current user session's primary user. + boolean isEnabled; + }; + + callback GetLacrosInfoCallback = void (LacrosInfo info); + + dictionary ArcAppDict { + DOMString name; + DOMString packageName; + DOMString activity; + DOMString intentUri; + DOMString iconResourceId; + double lastLaunchTime; + double installTime; + boolean sticky; + boolean notificationsEnabled; + boolean ready; + boolean suspended; + boolean showInLauncher; + boolean shortcut; + boolean launchable; + }; + callback GetArcAppCallback = void (ArcAppDict package); + + dictionary ArcAppKillsDict { + double oom; + double lmkdForeground; + double lmkdPerceptible; + double lmkdCached; + double pressureForeground; + double pressurePerceptible; + double pressureCached; + }; + callback GetArcAppKillsCallback = void (ArcAppKillsDict counts); + + dictionary ArcPackageDict { + DOMString packageName; + long packageVersion; + DOMString lastBackupAndroidId; + double lastBackupTime; + boolean shouldSync; + boolean vpnProvider; + }; + callback GetArcPackageCallback = void (ArcPackageDict package); + + dictionary Location { + double x; + double y; + }; + + dictionary Bounds { + double left; + double top; + double width; + double height; + }; + + dictionary ArcAppTracingInfo { + boolean success; + double fps; + double perceivedFps; + double commitDeviation; + double presentDeviation; + double renderQuality; + double janksPerMinute; + double janksPercentage; + }; + + callback TakeScreenshotCallback = void (DOMString base64Png); + + callback GetPrimaryDisplayScaleFactorCallback = void (double scaleFactor); + + callback IsTabletModeEnabledCallback = void (boolean enabled); + + callback SetTabletModeEnabledCallback = void(boolean enabled); + + callback SetShelfIconPinCallback = void(DOMString[] results); + + callback SetOverviewModeStateCallback = void(boolean finished); + + enum ThemeStyle { + TonalSpot, + Vibrant, + Expressive, + Spritz, + Rainbow, + FruitSalad + }; + + callback SendArcOverlayColorCallback = void (boolean result); + + callback ArcAppTracingCallback = void(ArcAppTracingInfo info); + + callback WaitForDisplayRotationCallback = void (boolean success); + + callback InstallPWAForCurrentURLCallback = void (DOMString appId); + + dictionary App { + DOMString appId; + DOMString name; + DOMString shortName; + DOMString publisherId; + AppType? type; + AppInstallSource? installSource; + AppReadiness? readiness; + DOMString[] additionalSearchTerms; + boolean? showInLauncher; + boolean? showInSearch; + }; + + dictionary SystemWebApp { + // App's internal name. This isn't user-visible and should only be used + // for logging. + DOMString internalName; + + // App's install URL. This is a placeholder for installation pipeline, + // not used for anything else. + DOMString url; + + // App's visible name. This is defined in the Web App manifest, and shown + // in Shelf and Launcher. This matches App's name attribute (see above). + DOMString name; + + // App's default start_url. This is the default URL that the App will be + // launched to. + DOMString startUrl; + }; + + callback GetAllInstalledAppsCallback = void (App[] apps); + + dictionary ShelfItem { + DOMString appId; + DOMString launchId; + DOMString title; + ShelfItemType? type; + ShelfItemStatus status; + boolean showsTooltip; + boolean pinnedByPolicy; + boolean pinStateForcedByType; + boolean hasNotification; + }; + + // A mapping of ash::AppType. + enum AppWindowType { + Browser, + ChromeApp, + ArcApp, + CrostiniApp, + SystemApp, + ExtensionApp, + Lacros + }; + + // A mapping of HotseatState in ash/public/cpp/shelf_types.h. + enum HotseatState { + Hidden, + ShownClamShell, + ShownHomeLauncher, + Extended + }; + + // The frame mode of a window. None if the window is framesless. + enum FrameMode { + Normal, + Immersive + }; + + dictionary OverviewInfo { + // Bounds in screen of an OverviewItem. + Bounds bounds; + // Whether an OverviewItem is being dragged in overview. + boolean isDragged; + }; + + // Used to update an app's shelf pin state. + dictionary ShelfIconPinUpdateParam { + // The identifier of the target app. + DOMString appId; + + // The target pin state for the app. + boolean pinned; + }; + + dictionary AppWindowInfo { + // The identifier of the window. This shouldn't change across the time. + long id; + + // The name of the window object -- typically internal class name of the + // window (like 'BrowserFrame'). + DOMString name; + + AppWindowType windowType; + WindowStateType stateType; + + // The bounds of the window, in the coordinate of the root window (i.e. + // relative to the display where this window resides). + Bounds boundsInRoot; + + // The identifier of the display where this window resides. + DOMString displayId; + + boolean isVisible; + boolean canFocus; + + // The title of the window; this can be seen in the window caption, or in + // the overview mode. Typically, this provides the title of the webpage or + // the title supplied by the application. + DOMString title; + + // Whether some animation is ongoing on the window or not. + boolean isAnimating; + + // The final bounds of the window when the animation completes. This should + // be same as |boundsInRoot| when |isAnimating| is false. + Bounds targetBounds; + + // Whether or not the window is going to be visible after the animation + // completes. This should be same as |isVisible| when |isAnimating| is + // false. + boolean targetVisibility; + + // WM Releated states + boolean isActive; + boolean hasFocus; + boolean onActiveDesk; + boolean hasCapture; + boolean canResize; + + // Stacking order of the window in relation to its siblings. 0 indicates + // that the window is topmost. -1 if stacking info is not available + long stackingOrder; + + // Window frame info + FrameMode frameMode; + boolean isFrameVisible; + long captionHeight; + // The bitset of the enabled caption buttons. See + // ui/views/window/caption_button_types.h. + long captionButtonEnabledStatus; + // The bitset of the caption buttons which are visible on the frame. + long captionButtonVisibleStatus; + + DOMString? arcPackageName; + + OverviewInfo? overviewInfo; + + // The identifier of the app associated with the window that was launched + // from full restore. This should be same as |appId| when the window was + // restored from full restore, otherwise null. + DOMString? fullRestoreWindowAppId; + + // The identifier of the app associated with the window. + DOMString? appId; + }; + + dictionary Accelerator { + DOMString keyCode; + boolean shift; + boolean control; + boolean alt; + boolean search; + boolean pressed; + }; + + // Mapped to ScrollableShelfState in ash/public/cpp/shelf_ui_info.h. + // [deprecated="Use ShelfState"] + dictionary ScrollableShelfState { + double? scrollDistance; + }; + + // Mapped to ShelfState in ash/public/cpp/shelf_ui_info.h. + dictionary ShelfState { + double? scrollDistance; + }; + + // Mapped to ScrollableShelfInfo in ash/public/cpp/shelf_ui_info.h. + // |targetMainAxisOffset| is set when ShelfState used in query + // specifies the scroll distance. + dictionary ScrollableShelfInfo { + double mainAxisOffset; + double pageOffset; + double? targetMainAxisOffset; + Bounds leftArrowBounds; + Bounds rightArrowBounds; + boolean isAnimating; + boolean iconsUnderAnimation; + boolean isOverflow; + Bounds[] iconsBoundsInScreen; + boolean isShelfWidgetAnimating; + }; + + // Mapped to HotseatSwipeDescriptor in ash/public/cpp/shelf_ui_info.h. + dictionary HotseatSwipeDescriptor { + Location swipeStartLocation; + Location swipeEndLocation; + }; + + // Mapped to HotseatInfo in ash/public/cpp/shelf_ui_info.h. + dictionary HotseatInfo { + HotseatSwipeDescriptor swipeUp; + HotseatState state; + boolean isAnimating; + // Whether the shelf is hidden with auto-hide enabled. + boolean isAutoHidden; + }; + + // The ui information of shelf components, including hotseat and + // scrollable shelf. + dictionary ShelfUIInfo { + HotseatInfo hotseatInfo; + ScrollableShelfInfo scrollableShelfInfo; + }; + + // Information about all desks. + dictionary DesksInfo { + long activeDeskIndex; + long numDesks; + boolean isAnimating; + DOMString[] deskContainers; + }; + + // Information about launcher's search box. + dictionary LauncherSearchBoxState { + DOMString ghostText; + }; + + callback GetShelfItemsCallback = void (ShelfItem[] items); + + callback GetDefaultPinnedAppIdsCallback = void (DOMString[] items); + + callback GetShelfAutoHideBehaviorCallback = void (DOMString behavior); + + callback GetLauncherSearchBoxStateCallback = void ( + LauncherSearchBoxState state); + + callback GetShelfAlignmentCallback = void (ShelfAlignmentType alignment); + + callback WindowStateCallback = void (WindowStateType currentType); + + callback VoidCallback = void (); + + callback DOMStringCallback = void (DOMString data); + + callback GetAppWindowListCallback = void (AppWindowInfo[] window_list); + + callback AcceleratorCallback = void (boolean success); + + callback DesksCallback = void (boolean success); + + callback GetDeskCountCallback = void (long count); + + callback GetDesksInfoCallback = void (DesksInfo desks); + + callback GetScrollableShelfInfoForStateCallback = void ( + ScrollableShelfInfo info); + + callback GetShelfUIInfoForStateCallback = void (ShelfUIInfo info); + + // Frame counting record for one frame sink/compositor. + dictionary FrameCountingPerSinkData { + // Type of the frame sink. This corresponds to CompositorFrameSinkType. + DOMString sinkType; + // Whether the frame sink is the root. + boolean isRoot; + // Debug label of the frame sink. + DOMString debugLabel; + + // Number of presented frames grouped using `bucketSizeInSeconds` arg in + // startFrameCounting call. It would be fps if the `bucketSizeInSeconds` is + // 1s. + long[] presentedFrames; + }; + + callback StopFrameCountingCallback = void (FrameCountingPerSinkData[] data); + + // Result of calling setWindowBounds, which returns the actual bounds and + // display the window was set to. This may be different than the requested + // bounds and display, for example if the window is showing an ARC app and + // Android modifies the bounds request. Further, this result may never be + // returned in some situations (e.g. Android ignoring a bounds request), + // causing a timeout. + dictionary SetWindowBoundsResult { + // Bounds of the window. + Bounds bounds; + // Display ID of the display the window is on. + DOMString displayId; + }; + callback WindowBoundsCallback = void (SetWindowBoundsResult result); + + // Collected DisplaySmoothness data between startSmoothnessTracking and + // stopSmoothnessTracking calls. + dictionary DisplaySmoothnessData { + // Number of frames expected to be shown for this animation. + long framesExpected; + // Number of frames actually shown for this animation. + long framesProduced; + // Number of janks during this animation. A jank is counted when the current + // frame latency is larger than previous ones. + long jankCount; + // Display throughput percentage at fixed intervals. + long[] throughput; + // The durations of the janks during this animation in millisecond. + double[] jankDurations; + }; + + // Callback invoked to report the smoothness after StopSmoothnessTracking is + // called. + callback StopSmoothnessTrackingCallback = void + (DisplaySmoothnessData data); + + // Collected ui::ThroughputTracker data for one animation. It is based on + // cc::FrameSequenceMetrics::ThroughputData. + dictionary ThroughputTrackerAnimationData { + // Animation start time in milliseconds, relative to when + // `startThroughputTrackerDataCollection` is called. + long startOffsetMs; + // Animation stop time in milliseconds, relative to when + // `startThroughputTrackerDataCollection` is called. + long stopOffsetMs; + // Number of frames expected to be shown for this animation. + long framesExpected; + // Number of frames actually shown for this animation. + long framesProduced; + // Number of janks during this animation. A jank is counted when the current + // frame latency is larger than previous ones. + long jankCount; + }; + + // Callback invoked to report the collection ui::ThroughputTracker data + // after stopThroughputTrackerDataCollection is called. + callback StopThroughputTrackerDataCollectionCallback = void + (ThroughputTrackerAnimationData[] data); + + // Callback invoked to report the currently collected ui::ThroughputTracker + // animation data. Note that the data reported is removed to avoid reporting + // duplicated data. + callback GetThroughtputTrackerDataCallback = void + (ThroughputTrackerAnimationData[] data); + + // Callback invoked to report the number of system web apps that should be + // installed. + callback GetRegisteredSystemWebAppsCallback = void + (SystemWebApp[] systemWebApps); + + callback IsSystemWebAppOpenCallback = void (boolean isOpen); + + // Callback invoked to return the smoothness percentage after + // getDisplaySmoothness is called. + callback GetDisplaySmoothnessCallback = void (long smoothness); + + // Options for resetting the holding space. + dictionary ResetHoldingSpaceOptions { + // Whether to call `ash::holding_space_prefs::MarkTimeOfFirstAdd()` after + // reset. Used to show the holding space tray in tests, since it's otherwise + // hidden after OOBE. + boolean markTimeOfFirstAdd; + }; + + callback CouldAllowCrostiniCallback = void (boolean canBeAllowed); + + // Collected ash::LoginEventRecorder data. + dictionary LoginEventRecorderData { + // Event name + DOMString name; + // Number of frames actually shown for this animation. + double microsecnods_since_unix_epoch; + }; + + // Callback invoked to report the collection ui::LoginEventRecorder data + // after getLoginEventRecorderLoginEvents is called. + callback GetLoginEventRecorderLoginEventsCallback = void + (LoginEventRecorderData[] data); + + // Request parameters for getAccessToken. + dictionary GetAccessTokenParams { + // An email associated with the account to get a token for. + DOMString email; + // A list of OAuth scopes to request. + DOMString[] scopes; + // An optional timeout in milliseconds for the request. + // Default: 90 seconds + long? timeoutMs; + }; + + // Response data for getAccessToken. + dictionary GetAccessTokenData { + // The access token + DOMString accessToken; + // The time the access token will expire as a unix timestamp in + // milliseconds. + DOMString expirationTimeUnixMs; + }; + + // Reponse callback for getAccessToken. + callback GetAccessTokenCallback = void(GetAccessTokenData data); + + // Callback invoked to report whether the current input method is ready to + // accept key events from the test. + callback IsInputMethodReadyForTestingCallback = void + (boolean isReady); + + // Response data for makeFuseboxTempDir. + dictionary MakeFuseboxTempDirData { + DOMString fuseboxFilePath; + DOMString underlyingFilePath; + }; + + // Callback invoked when the temporary directory was made. + callback MakeFuseboxTempDirCallback = void(MakeFuseboxTempDirData data); + + // Callback invoked when the temporary directory was removed. + callback RemoveFuseboxTempDirCallback = void(); + + callback IsFeatureEnabledCallback = void(boolean enabled); + + // Response data for getCurrentInputMethodDescriptor. + // Add more fields from ash/input_method/InputMethodDescriptor as needed. + dictionary GetCurrentInputMethodDescriptorData { + DOMString keyboardLayout; + }; + + // Response callback for current input method keyboard layout. + callback GetCurrentInputMethodDescriptorCallback = void + (GetCurrentInputMethodDescriptorData data); + + // Response callback to report if a field trial exists and has been activated. + callback IsFieldTrialActiveCallback = void(boolean active); + + // Request data containing the mock responses from + // overrideOrcaResponseForTesting. + dictionary OrcaResponseArray { + DOMString[] responses; + }; + + callback OverrideOrcaResponseForTestingCallback = void(boolean success); + + interface Functions { + // Must be called to allow autotestPrivateAPI events to be fired. + static void initializeEvents(); + + // Logout of a user session. + static void logout(); + + // Restart the browser. + static void restart(); + + // Shutdown the browser. + // |force|: if set, ignore ongoing downloads and onunbeforeunload handlers. + static void shutdown(boolean force); + + // Get login status. + static void loginStatus(LoginStatusCallback callback); + + // Waits for the post login animation to be complete and then triggers the + // callback. + static void waitForLoginAnimationEnd(VoidCallback callback); + + // Locks the screen. + static void lockScreen(); + + // Get info about installed extensions. + static void getExtensionsInfo( + ExtensionsInfoCallback callback); + + // Get state of the policies. + // Will contain device policies and policies from the active profile. + // The policy values are formatted as they would be for exporting in + // chrome://policy. + static void getAllEnterprisePolicies( + AllEnterprisePoliciesCallback callback); + + // Refreshes the Enterprise Policies. + static void refreshEnterprisePolicies( + VoidCallback callback); + + // Refreshes the remote commands. + static void refreshRemoteCommands(VoidCallback callback); + + // Simulates a memory access bug for asan testing. + static void simulateAsanMemoryBug(); + + // Set the touchpad pointer sensitivity setting. + // |value|: the pointer sensitivity setting index. + static void setTouchpadSensitivity(long value); + + // Turn on/off tap-to-click for the touchpad. + // |enabled|: if set, enable tap-to-click. + static void setTapToClick(boolean enabled); + + // Turn on/off three finger click for the touchpad. + // |enabled|: if set, enable three finger click. + static void setThreeFingerClick(boolean enabled); + + // Turn on/off tap dragging for the touchpad. + // |enabled|: if set, enable tap dragging. + static void setTapDragging(boolean enabled); + + // Turn on/off Australian scrolling for devices other than wheel mouse. + // |enabled|: if set, enable Australian scrolling. + static void setNaturalScroll(boolean enabled); + + // Set the mouse pointer sensitivity setting. + // |value|: the pointer sensitivity setting index. + static void setMouseSensitivity(long value); + + // Swap the primary mouse button for left click. + // |right|: if set, swap the primary mouse button. + static void setPrimaryButtonRight(boolean right); + + // Turn on/off reverse scrolling for mice. + // |enabled|: if set, enable reverse scrolling. + static void setMouseReverseScroll(boolean enabled); + + // Get visible notifications on the system. + static void getVisibleNotifications( + NotificationArrayCallback callback); + + // Remove all notifications. + static void removeAllNotifications( + VoidCallback callback); + + // Get ARC start time in ticks. + static void getArcStartTime( + ArcStartTimeCallback callback); + + // Get state of the ARC session. + static void getArcState( + ArcStateCallback callback); + + // Get state of the Play Store. + static void getPlayStoreState( + PlayStoreStateCallback callback); + + // Get list of available printers + static void getPrinterList( + PrinterArrayCallback callback); + + // Returns true if requested app is shown in Chrome. + static void isAppShown( + DOMString appId, + IsAppShownCallback callback); + + // Returns true if ARC is provisioned. + // [deprecated="Use getArcState()"] + static void isArcProvisioned( + IsArcProvisionedCallback callback); + + // Gets various information about the state of lacros on the system. + static void getLacrosInfo( + GetLacrosInfoCallback callback); + + // Gets information about the requested ARC app. + static void getArcApp( + DOMString appId, + GetArcAppCallback callback); + + // Gets counts of how many ARC apps have been killed, by priority. + static void getArcAppKills( + GetArcAppKillsCallback callback); + + // Gets information about requested ARC package. + static void getArcPackage( + DOMString packageName, + GetArcPackageCallback callback); + + // Waits for system web apps to complete the installation. + static void waitForSystemWebAppsInstall( + VoidCallback callback); + + // Gets all the default pinned shelf app IDs, these may not be installed. + static void getDefaultPinnedAppIds( + GetDefaultPinnedAppIdsCallback callback); + + // Returns the number of system web apps that should be installed. + static void getRegisteredSystemWebApps( + GetRegisteredSystemWebAppsCallback callback); + + // Returns whether the system web app is currently open or not. + static void isSystemWebAppOpen( + DOMString appId, + IsSystemWebAppOpenCallback callback); + + // Launches an application from the launcher with the given appId. + static void launchApp( + DOMString appId, + VoidCallback callback); + + // Launches an system web app from the launcher with the given app name and + // url. + static void launchSystemWebApp( + DOMString appName, + DOMString url, + VoidCallback callback); + + // Launches Files app directly to absolutePath, if the path does not + // exist, it will launch to the default opening location (i.e. MyFiles). + // If the supplied path is a file (and it exists) it will open Files app + // to the parent folder instead. + static void launchFilesAppToPath( + DOMString absolutePath, + VoidCallback callback); + + // Closes an application the given appId in case it was running. + static void closeApp( + DOMString appId, + VoidCallback callback); + + // Update printer. Printer with empty ID is considered new. + static void updatePrinter(Printer printer); + + // Remove printer. + static void removePrinter(DOMString printerId); + + // Start ARC directly, note this differs from |setPlayStoreEnabled|. It is + // used to restart ARC in tests. + // |callback|: Called when the operation has completed. + static void startArc(VoidCallback callback); + + // Stop ARC directly, note this differs from |setPlayStoreEnabled|. It is + // used to restart ARC in tests. Note, this preserves ARC data. + // |callback|: Called when the operation has completed. + static void stopArc(VoidCallback callback); + + // Enable/disable the Play Store. + // |enabled|: if set, enable the Play Store. + // |callback|: Called when the operation has completed. + static void setPlayStoreEnabled( + boolean enabled, + VoidCallback callback); + + // Get text from ui::Clipboard. + // |callback|: Called with result. + static void getClipboardTextData( + DOMStringCallback callback); + + // Set text in ui::Clipbaord. + // |callback|: Called when operation is complete. + static void setClipboardTextData( + DOMString data, + VoidCallback callback); + + // Run the crostini installer GUI to install the default crostini + // vm / container and create sshfs mount. The installer launches the + // crostini terminal app on completion. The installer expects that + // crostini is not already installed. + // |callback|: Called when the operation has completed. + static void runCrostiniInstaller(VoidCallback callback); + + // Run the crostini uninstaller GUI to remove the default crostini + // vm / container. The callback is invoked upon completion. + static void runCrostiniUninstaller( + VoidCallback callback); + + // Enable/disable Crostini in preferences. + // |enabled|: Enable Crostini. + // |callback|: Called when the operation has completed. + static void setCrostiniEnabled( + boolean enabled, + VoidCallback callback); + + // Export the crostini container. + // |path|: The path in Downloads to save the export. + // |callback|: Called when the operation has completed. + static void exportCrostini( + DOMString path, + VoidCallback callback); + + // Import the crostini container. + // |path|: The path in Downloads to read the import. + // |callback|: Called when the operation has completed. + static void importCrostini( + DOMString path, + VoidCallback callback); + + // Returns whether crostini could ever be allowed. + // |callback|: Called with a boolean indicating if crostini can ever be + // allowed in the current profile. + static void couldAllowCrostini( + CouldAllowCrostiniCallback callback); + + // Sets mock Plugin VM policy. + // |imageUrl|: URL to the image to install. + // |imageHash|: Hash for the provided image. + // |licenseKey|: License key for Plugin VM. + static void setPluginVMPolicy(DOMString imageUrl, + DOMString imageHash, + DOMString licenseKey); + + // Shows the Plugin VM installer. Does not start installation. + static void showPluginVMInstaller(); + + // Installs Borealis without showing the normal installer UI. + // |callback|: Called when the operation has completed. + static void installBorealis(VoidCallback callback); + + // Register a component with ComponentManagerAsh. + // |name|: The name of the component. + // |path|: Path to the component. + static void registerComponent(DOMString name, DOMString path); + + // Takes a screenshot and returns the data in base64 encoded PNG format. + static void takeScreenshot( + TakeScreenshotCallback callback); + + // Tasks a screenshot for a display. + // |display_id|: the display id of the display. + // |callback|: called when the operation has completed. + static void takeScreenshotForDisplay( + DOMString display_id, + TakeScreenshotCallback callback); + + // Triggers an on-demand update of smart dim component and checks whether + // it's successfully loaded by smart dim ml_agent. + // |callback|: Called when the operation has completed. + static void loadSmartDimComponent(VoidCallback callback); + + // Enables/disables the Google Assistant. + // |callback|: Called when the operation has completed. + static void setAssistantEnabled( + boolean enabled, + long timeout_ms, + VoidCallback callback); + + // Bring up the Assistant service, and wait for the ready signal. + // |callback|: Called when the operation has completed. + static void enableAssistantAndWaitForReady( + VoidCallback callback); + + // Sends a text query via Google Assistant. + // |callback|: Called when response has been received. + static void sendAssistantTextQuery( + DOMString query, + long timeout_ms, + AssistantQueryStatusCallback callback); + + // Invokes |callback| once the current text/voice interaction is completed. + // Responds with the the query status if any valid response was caught + // before the timeout. This API should be called before sending the query. + // To use it for testing a voice query via OKG in Autotest, for example, + // you can do: + // + // // Enable hotword setting for Assistant. + // assistant_util.enable_hotword(); + // + // // Call this API with your callback function. + // chrome.autotestPrivate.waitForAssistantQueryStatus(timeout_s, + // function(status) {...}); + // + // then start Assistant via OKG and send voice query before timeout. + // + // TODO(meilinw@): disable warmer welcome to avoid an unintended early + // return of this API when launching Assistant via hotkey. + // TODO(meilinw@): update the comment above to use Tast instead after + // adding API to enable hotword in Tast. + static void waitForAssistantQueryStatus( + long timeout_s, + AssistantQueryStatusCallback callback); + + // Whether the local list of installed ARC packages has been refreshed for + // the first time after user login. + static void isArcPackageListInitialRefreshed( + IsArcPackageListInitialRefreshedCallback callback); + + // Set value for the specified user pref in the pref tree. + static void setAllowedPref( + DOMString pref_name, + any value, + VoidCallback callback); + + // Clears value for the specified user pref in the pref tree. + static void clearAllowedPref( + DOMString pref_name, + VoidCallback callback); + + // DEPRECATED: use SetAllowedPref instead, see crbug/1262034 + // Set value for the specified user pref in the pref tree. + static void setWhitelistedPref( + DOMString pref_name, + any value, + VoidCallback callback); + + // Enable/disable a Crostini app's "scaled" property. + // |appId|: The Crostini application ID. + // |scaled|: The app is "scaled" when shown, which means it uses low display + // density. + // |callback|: Called when the operation has completed. + static void setCrostiniAppScaled( + DOMString appId, + boolean scaled, + VoidCallback callback); + + // Get the primary display scale factor. + // |callback| is invoked with the scale factor. + static void getPrimaryDisplayScaleFactor( + GetPrimaryDisplayScaleFactorCallback callback); + + // Get the tablet mode enabled status. + // |callback| is invoked with the tablet mode enablement status. + static void isTabletModeEnabled( + IsTabletModeEnabledCallback callback); + + // Enable/disable tablet mode. After calling this function, it won't be + // possible to physically switch to/from tablet mode since that + // functionality will be disabled. + // |enabled|: if set, enable tablet mode. + // |callback|: Called when the operation has completed. + static void setTabletModeEnabled( + boolean enabled, + SetTabletModeEnabledCallback callback); + + // Get the list of all installed applications + static void getAllInstalledApps( + GetAllInstalledAppsCallback callback); + + // Get the list of all shelf items + static void getShelfItems( + GetShelfItemsCallback callback); + + // Get the launcher search box search state. + static void getLauncherSearchBoxState( + GetLauncherSearchBoxStateCallback callback); + + // Get the shelf auto hide behavior. + // |displayId|: display that contains the shelf. + // |callback| is invoked with the shelf auto hide behavior. Possible + // behavior values are: "always", "never" or "hidden". + static void getShelfAutoHideBehavior( + DOMString displayId, + GetShelfAutoHideBehaviorCallback callback); + + // Set the shelf auto hide behavior. + // |displayId|: display that contains the shelf. + // |behavior|: an enum of "always", "never" or "hidden". + // |callback|: Called when the operation has completed. + static void setShelfAutoHideBehavior( + DOMString displayId, + DOMString behavior, + VoidCallback callback); + + // Get the shelf alignment. + // |displayId|: display that contains the shelf. + // |callback| is invoked with the shelf alignment type. + static void getShelfAlignment( + DOMString displayId, + GetShelfAlignmentCallback callback); + + // Set the shelf alignment. + // |displayId|: display that contains the shelf. + // |alignment|: the type of alignment to set. + // |callback|: Called when the operation has completed. + static void setShelfAlignment( + DOMString displayId, + ShelfAlignmentType alignment, + VoidCallback callback); + + // Create a pin on shelf for the app specified by |appId|. + // Deprecated. Use setShelfIconPin() instead. + static void pinShelfIcon( + DOMString appId, + VoidCallback callback); + + // Update pin states of the shelf apps based on |updateParams|. Return a + // list of app ids whose pin state changed. Pin states will not be changed + // if the method fails. + static void setShelfIconPin( + ShelfIconPinUpdateParam[] updateParams, + optional SetShelfIconPinCallback callback); + + // Enter or exit the overview mode. + // |start|: whether entering to or exiting from the overview mode. + // |callback|: called after the overview mode switch finishes. + static void setOverviewModeState( + boolean start, + SetOverviewModeStateCallback callback); + + // Show virtual keyboard of the current input method if it's available. + static void showVirtualKeyboardIfEnabled(); + + // Sends the overlay color and theme to Android and changes the Android system color and theme to these values. + // |color|: the int color of the system ui. + // |theme|: the theme of the system ui. + // |callback|: callback to deliver sendArcOverlayColor result. + static void sendArcOverlayColor( + long color, ThemeStyle theme, SendArcOverlayColorCallback callback); + + // Start ARC performance tracing for the active ARC app window. + // |callback|: Called when the operation has completed. + static void arcAppTracingStart(VoidCallback callback); + + // Stop ARC performance tracing if it was started and analyze results. + // |callback|: callback to deliver tracing results. + static void arcAppTracingStopAndAnalyze( + ArcAppTracingCallback callback); + + // Swap the windows in the split view. + // |callback|: Called when the operation has completed. + static void swapWindowsInSplitView( + VoidCallback callback); + + // Set ARC app window focused. + // |packageName|: the package name of the ARC app window. + // |callback|: called when the operation has completed. + static void setArcAppWindowFocus( + DOMString packageName, + VoidCallback callback); + + // Invokes the callback when the display rotation animation is finished, or + // invokes it immediately if it is not animating. The callback argument + // is true if the display's rotation is same as |rotation|, or false otherwise. + // |displayId|: display that contains the shelf. + // |rotation|: the target rotation. + // |callback|: called when the operation has completed. + static void waitForDisplayRotation( + DOMString displayId, + RotationType rotation, + WaitForDisplayRotationCallback callback); + + // Get information on all application windows. Callback will be called + // with the list of |AppWindowInfo| dictionary. + // |callback|: called with window list. + static void getAppWindowList( + GetAppWindowListCallback callback); + + // Send WM event to change the app window's window state. + // |id|: the id of the window + // |change|: WM event type to send to the app window. + // |wait|: whether the method should wait for the window state to change before returning. + // |callback|: called when the window state is changed if |wait| is true. + // Otherwise, called right after the WM event is sent. + static void setAppWindowState( + long id, + WindowStateChangeDict change, + optional boolean wait, + WindowStateCallback callback); + + // Activate app window given by "id". + // |id|: the id of the window + // |callback|: called when the window is requested to activate. + static void activateAppWindow( + long id, + VoidCallback callback); + + // Closes an app window given by "id". + // |id|: the id of the window + // |callback|: called when the window is requested to close. + static void closeAppWindow( + long id, + VoidCallback callback); + + // Installs the Progressive Web App (PWA) that is in the current URL. + // |timeout_ms|: Timeout in milliseconds for the operation to complete. + // |callback|: called when the operation has completed. Passes the app Id + // of the recently installed PWA as argument. + static void installPWAForCurrentURL( + long timeout_ms, + InstallPWAForCurrentURLCallback callback); + + // Activates shortcut. + // |accelerator|: the accelerator to activate. + // |callback|: called when the operation has completed. + static void activateAccelerator( + Accelerator accelerator, + AcceleratorCallback callback); + + // Wwait until the launcher is transitionto the |launcherState|, if it's not + // in that state. + // |launcherState|: the target launcher state. + // |callback|: called when the operation has completed. + static void waitForLauncherState( + LauncherStateType launcherState, + VoidCallback callback); + + // Wait until overview has transitioned to |overviewState|, if it is not in + // that state. + // |overviewState|: the target overview state. + // |callback|: called when overview has reached |overviewState|. + static void waitForOverviewState( + OverviewStateType overviewState, + VoidCallback callback); + + // Creates a new desk if the maximum number of desks has not been reached. + // |callback|: called to indicate success or failure. + static void createNewDesk(DesksCallback callback); + + // Activates the desk at the given |index| triggering the activate-desk + // animation. + // |index|: the zero-based index of the desk desired to be activated. + // |callback|: called indicating success when the animation completes, or + // failure when the desk at |index| is already the active desk. + static void activateDeskAtIndex( + long index, + DesksCallback callback); + + // Removes the currently active desk and triggers the remove-desk animation. + // |callback|: called indicating success when the animation completes, or + // failure if the currently active desk is the last available desk which + // cannot be removed. + static void removeActiveDesk(DesksCallback callback); + + // Activates the desk at the given |index| by chaining multiple + // activate-desk animations. + // |index|: the zero-based index of the desk desired to be activated. + // |callback|: called indicating success when the animation completes, or + // failure when the desk at |index| is already the active desk. + static void activateAdjacentDesksToTargetIndex( + long index, + DesksCallback callback); + + // Fetches the number of open desks in the `DesksController` at the time of + // call. + // `callback`: callback that is passed the number of open desks. + static void getDeskCount( + GetDeskCountCallback callback); + + // Fetches info about the open desks at the time of the call. + // `callback`: callback that is passed desks information. + static void getDesksInfo( + GetDesksInfoCallback callback); + + // Create mouse events to cause a mouse click. + // |button|: the mouse button for the click event. + // |callback|: called after the mouse click finishes. + static void mouseClick( + MouseButton button, + VoidCallback callback); + + // Create a mouse event to cause mouse pressing. The mouse button stays + // in the pressed state. + // |button|: the mouse button to be pressed. + // |callback|: called after the mouse pressed event is handled. + static void mousePress( + MouseButton button, + VoidCallback callback); + + // Create a mouse event to release a mouse button. This does nothing and + // returns immediately if the specified button is not pressed. + // |button|: the mouse button to be released. + // |callback|: called after the mouse is released. + static void mouseRelease( + MouseButton button, + VoidCallback callback); + + // Create mouse events to move a mouse cursor to the location. This can + // cause a dragging if a button is pressed. It starts from the last mouse + // location. + // |location|: the target location (in screen coordinate). + // |duration_in_ms|: the duration (in milliseconds) for the mouse movement. + // The mouse will move linearly. 0 means moving immediately. + // |callback|: called after the mouse move finishes. + static void mouseMove( + Location location, + double duration_in_ms, + VoidCallback callback); + + // Enable/disable metrics reporting in preferences. + // |enabled|: Enable metrics reporting. + // |callback|: Called when the operation has completed. + static void setMetricsEnabled( + boolean enabled, + VoidCallback callback); + + // Sends ARC touch mode enabled or disabled. + // |enable|: whether enabled touch mode. + // |callback|: called when action performed. + static void setArcTouchMode( + boolean enabled, + VoidCallback callback); + + // Fetches ui information of scrollable shelf view for the given shelf + // state. This function does not change scrollable shelf. + // [deprecated="Use getShelfUIInfoForState()"] + static void getScrollableShelfInfoForState( + ScrollableShelfState state, + GetScrollableShelfInfoForStateCallback callback); + + // Fetches UI information of shelf (including scrollable shelf and hotseat) + // for the given shelf state. This function does not change any shelf + // component. + static void getShelfUIInfoForState( + ShelfState state, + GetShelfUIInfoForStateCallback callback); + + // Sends a WM event to change a window's bounds and/or the display it is on. + // |id|: the id of the window. + // |bounds|: bounds the window should be set to. + // |displayId|: id of display to move the window to. + // |callback|: called when the window bounds are changed. + static void setWindowBounds( + long id, + Bounds bounds, + DOMString displayId, + WindowBoundsCallback callback); + + // Starts smoothness tracking for a display. If the display id is not + // specified, the primary display is used. Otherwise, the display specified + // by the display id is used. If `throughputIntervalMs` is not specified, + // default 5 seconds interval is used to collect throughput data. + static void startSmoothnessTracking( + optional DOMString displayId, + optional long throughputIntervalMs, + VoidCallback callback); + + // Stops smoothness tracking for a display and report the smoothness. If + // the display id is not specified, the primary display is used. Otherwise, + // the display specified by the display id is used. + static void stopSmoothnessTracking( + optional DOMString displayId, + StopSmoothnessTrackingCallback callback); + + // When neccesary, disables showing the dialog when Switch Access is disabled. + static void disableSwitchAccessDialog(); + + // Waits for the completion of photo transition animation in ambient mode. + // |numCompletions|: number of completions of the animation. + // |timeout|: the timeout in seconds. + // |callback|: Called when the operation has completed. + static void waitForAmbientPhotoAnimation( + long numCompletions, + long timeout, + VoidCallback callback); + + // Waits for ambient video to successfully start playback. + // |timeout|: the timeout in seconds. + // |callback|: Called when the operation has completed. + static void waitForAmbientVideo( + long timeout, + VoidCallback callback); + + // Disables the automation feature. Note that the event handlers and caches + // of automation nodes still remain in the test extension and so the next + // automation.getDesktop will miss initialization. The caller should ensure + // invalidation of those information (i.e. reloading the entire background + // page). + static void disableAutomation(VoidCallback callback); + + // Starts to ui::ThroughputTracker data collection for tracked animations. + static void startThroughputTrackerDataCollection( + VoidCallback callback); + + // Stops ui::ThroughputTracker data collection and reports the collected + // data since the start or the last GetThroughtputTrackerData call. + static void stopThroughputTrackerDataCollection( + StopThroughputTrackerDataCollectionCallback callback); + + // Reports the currently collected animation data. + static void getThroughputTrackerData( + GetThroughtputTrackerDataCallback callback); + + // Gets the smoothness of a display. If the display id is not specified, + // the primary display is used. + static void getDisplaySmoothness( + optional DOMString displayId, + GetDisplaySmoothnessCallback callback); + + // Resets the holding space by removing all items and clearing the prefs. + static void resetHoldingSpace( + optional ResetHoldingSpaceOptions options, + VoidCallback callback); + + // Starts collection of ui::LoginEventRecorder data. + static void startLoginEventRecorderDataCollection( + VoidCallback callback); + + // Stops ui::LoginEventRecorder data collection and reports all the + // collected data. + static void getLoginEventRecorderLoginEvents( + GetLoginEventRecorderLoginEventsCallback callback); + + // Adds login event to test LoginEventRecorderDataCollection API. + static void addLoginEventForTesting( + VoidCallback callback); + + // Force auto theme mode in dark mode or light mode for testing. + static void forceAutoThemeMode(boolean darkModeEnabled, VoidCallback callback); + + // Fetches an access token from Chrome. + static void getAccessToken( + GetAccessTokenParams accessTokenParams, + GetAccessTokenCallback callback); + + // Returns whether the current input method is ready to accept key events. + static void isInputMethodReadyForTesting( + IsInputMethodReadyForTestingCallback callback); + + // Creates a temporary directory visible under the Fusebox mount point. + static void makeFuseboxTempDir( + MakeFuseboxTempDirCallback callback); + + // Removes a temporary directory visible under the Fusebox mount point. The + // fuseboxFilePath argument was returned by the MakeFuseboxTempDirCallback. + static void removeFuseboxTempDir( + DOMString fuseboxFilePath, + RemoveFuseboxTempDirCallback callback); + + // Remove the specified component extension. + static void removeComponentExtension( + DOMString extensionId, VoidCallback callback); + + // Starts frame counting in viz. `bucketSizeInSeconds` decides the bucket + // size of the frame count records. If it is X seconds, each record is + // the number of presented frames in X seconds. + static void startFrameCounting( + long bucketSizeInSeconds, + VoidCallback callback); + + // Ends frame counting in viz and return the collected data. + static void stopFrameCounting( + StopFrameCountingCallback callback); + + // Install a bruschetta VM. + static void installBruschetta( + DOMString vm_name, VoidCallback callback); + + // Delete a bruschetta VM. + static void removeBruschetta( + DOMString vm_name, VoidCallback callback); + + // Returns whether a base::Feature is enabled. The state may change because + // a Chrome uprev into ChromeOS changed the default feature state. + static void isFeatureEnabled( + DOMString feature_name, IsFeatureEnabledCallback callback); + + // Returns keyboard layout used for current input method. + static void getCurrentInputMethodDescriptor( + GetCurrentInputMethodDescriptorCallback callback); + + // Overrides the response from Orca Provider and returns the boolean value + // that indicates if the overriding is successful or not. + static void overrideOrcaResponseForTesting( + OrcaResponseArray array, + OverrideOrcaResponseForTestingCallback callback); + + // ARC set interactive enable/disable state. + // |enabled|: Enable ARC interactive. + // |callback|: Called when the operation sent to ARC by mojo. + static void setArcInteractiveState( + boolean enabled, VoidCallback callback); + + // Returns whether a field trial exists and has been activated. + static void isFieldTrialActive( + DOMString trial_name, + DOMString group_name, + IsFieldTrialActiveCallback callback); + + // ARC get wakefulness mode. + static void getArcWakefulnessMode( + WakefulnessModeCallback callback); + + // Sets the default device language. + // A restart is required for this change to take effect. + // |value|: the locale of the language. + static void setDeviceLanguage(DOMString locale, VoidCallback callback); + }; + + interface Events { + // Fired when the data in ui::Clipboard is changed. + static void onClipboardDataChanged(); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/braille_display_private.idl b/tools/under-control/src/chrome/common/extensions/api/braille_display_private.idl new file mode 100755 index 000000000..68938d47a --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/braille_display_private.idl @@ -0,0 +1,93 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Braille display access private API. +namespace brailleDisplayPrivate { + // Braille display keyboard command. + enum KeyCommand { + line_up, + line_down, + pan_left, + pan_right, + top, + bottom, + routing, + secondary_routing, + dots, + chord, + standard_key + }; + + // A keyboard event. This is not a standard keyboard event because + // braille display keyboards look significantly different from standard + // keyboards. + dictionary KeyEvent { + KeyCommand command; + // 0-based display position for commands that involve a routing key. + long? displayPosition; + // Braille dot keys that were pressed, stored in the low-order bits. + // Dot 1 is stored in bit 0, dot2 in bit 1, etc. + long? brailleDots; + // DOM keyboard event code. This is present when command is standard_key + // and the braille display event represents a non-alphanumeric key such + // as an arrow key or function key. + // The value is as defined by the |code| property in + // http://www.w3.org/TR/uievents/#keyboard-event-interface + DOMString? standardKeyCode; + // DOM keyboard event character value. This is present if the + // braille key event corresponds to a character. + DOMString? standardKeyChar; + // Whether the space key was pressed. + boolean? spaceKey; + // Whether the alt key was pressed. + boolean? altKey; + // Whether the shift key was pressed. + boolean? shiftKey; + // Whether the ctrl key was pressed. + boolean? ctrlKey; + }; + + // The current braille display state. + dictionary DisplayState { + // Whether a braille display is currently available. + boolean available; + // Number of rows of braille cells on the currently connected display. + long? textRowCount; + // Number of columns of braille cells on the currently connected display. + long? textColumnCount; + // The number of dots in a braille cell on the currently connected display. + long? cellSize; + }; + + callback DisplayStateCallback = void(DisplayState result); + + interface Functions { + // Gets the current display state. + static void getDisplayState( + DisplayStateCallback callback); + + // Write the given dot patterns to the display. The buffer contains one + // byte for each braille cell on the display, starting from the leftmost + // cell. Each byte contains a bit pattern indicating which dots should be + // raised in the corresponding cell with the low-order bit representing + // dot 1 and so on until bit 7 which corresponds to dot 8. If the number + // of bytes in the buffer is not equal to the display size, the buffer + // will either be clipped or padded with blank cells on the right. The + // buffer is a 2D array compressed into 1D. The |columns| and |rows| + // parameters give the original 2D dimensions of the buffer. To access + // an element cells[r][c], simply access cells[r * columns + c]. + static void writeDots(ArrayBuffer cells, long columns, long rows); + + // Updates the single user-preferred braille device with the given bluetooth + // device address and starts or restarts the Brltty daemon. + static void updateBluetoothBrailleDisplayAddress(DOMString address); + }; + + interface Events { + // Fired when a braille display is connected or disconnected. + static void onDisplayStateChanged(DisplayState state); + // Fired when an input event is received from the display. + static void onKeyEvent(KeyEvent event); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/certificate_provider.idl b/tools/under-control/src/chrome/common/extensions/api/certificate_provider.idl new file mode 100755 index 000000000..ea9b24607 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/certificate_provider.idl @@ -0,0 +1,305 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use this API to expose certificates to the platform which can use these +// certificates for TLS authentications. +namespace certificateProvider { + + // Types of supported cryptographic signature algorithms. + enum Algorithm { + // Specifies the RSASSA PKCS#1 v1.5 signature algorithm with the MD5-SHA-1 + // hashing. The extension must not prepend a DigestInfo prefix but only + // add PKCS#1 padding. This algorithm is deprecated and will never be requested + // by Chrome as of version 109. + RSASSA_PKCS1_v1_5_MD5_SHA1, + // Specifies the RSASSA PKCS#1 v1.5 signature algorithm + // with the SHA-1 hash function. + RSASSA_PKCS1_v1_5_SHA1, + // Specifies the RSASSA PKCS#1 v1.5 signature algorithm + // with the SHA-256 hashing function. + RSASSA_PKCS1_v1_5_SHA256, + // Specifies the RSASSA PKCS#1 v1.5 signature algorithm + // with the SHA-384 hashing function. + RSASSA_PKCS1_v1_5_SHA384, + // Specifies the RSASSA PKCS#1 v1.5 signature algorithm + // with the SHA-512 hashing function. + RSASSA_PKCS1_v1_5_SHA512, + // Specifies the RSASSA PSS signature algorithm with the SHA-256 hashing + // function, MGF1 mask generation function and the salt of the same size as + // the hash. + RSASSA_PSS_SHA256, + // Specifies the RSASSA PSS signature algorithm with the SHA-384 hashing + // function, MGF1 mask generation function and the salt of the same size as + // the hash. + RSASSA_PSS_SHA384, + // Specifies the RSASSA PSS signature algorithm with the SHA-512 hashing + // function, MGF1 mask generation function and the salt of the same size as + // the hash. + RSASSA_PSS_SHA512 + }; + + // Types of errors that the extension can report. + enum Error { + // General error that cannot be represented by other more specific + // error codes. + GENERAL_ERROR + }; + + // Information about a client certificate. + [noinline_doc] dictionary ClientCertificateInfo { + // The array must contain the DER encoding of the X.509 client certificate + // as its first element. + //

This must include exactly one certificate.

+ ArrayBuffer[] certificateChain; + // All algorithms supported for this certificate. The extension will only be + // asked for signatures using one of these algorithms. + Algorithm[] supportedAlgorithms; + }; + + dictionary SetCertificatesDetails { + // When called in response to $(ref:onCertificatesUpdateRequested), should + // contain the received certificatesRequestId value. Otherwise, + // should be unset. + long? certificatesRequestId; + // Error that occurred while extracting the certificates, if any. This error + // will be surfaced to the user when appropriate. + Error? error; + // List of currently available client certificates. + ClientCertificateInfo[] clientCertificates; + }; + + dictionary CertificatesUpdateRequest { + // Request identifier to be passed to $(ref:setCertificates). + long certificatesRequestId; + }; + + dictionary SignatureRequest { + // Request identifier to be passed to $(ref:reportSignature). + long signRequestId; + // Data to be signed. Note that the data is not hashed. + ArrayBuffer input; + // Signature algorithm to be used. + Algorithm algorithm; + // The DER encoding of a X.509 certificate. The extension must sign + // input using the associated private key. + ArrayBuffer certificate; + }; + + dictionary ReportSignatureDetails { + // Request identifier that was received via the $(ref:onSignatureRequested) + // event. + long signRequestId; + // Error that occurred while generating the signature, if any. + Error? error; + // The signature, if successfully generated. + ArrayBuffer? signature; + }; + + // Deprecated. Replaced by $(ref:Algorithm). + enum Hash { + // Specifies the MD5 and SHA1 hashing algorithms. + MD5_SHA1, + // Specifies the SHA1 hashing algorithm. + SHA1, + // Specifies the SHA256 hashing algorithm. + SHA256, + // Specifies the SHA384 hashing algorithm. + SHA384, + // Specifies the SHA512 hashing algorithm. + SHA512 + }; + + // The type of code being requested by the extension with requestPin function. + enum PinRequestType { + // Specifies the requested code is a PIN. + PIN, + // Specifies the requested code is a PUK. + PUK + }; + + // The types of errors that can be presented to the user through the + // requestPin function. + enum PinRequestErrorType { + // Specifies the PIN is invalid. + INVALID_PIN, + // Specifies the PUK is invalid. + INVALID_PUK, + // Specifies the maximum attempt number has been exceeded. + MAX_ATTEMPTS_EXCEEDED, + // Specifies that the error cannot be represented by the above types. + UNKNOWN_ERROR + }; + + // Deprecated. Replaced by $(ref:ClientCertificateInfo). + dictionary CertificateInfo { + // Must be the DER encoding of a X.509 certificate. Currently, only + // certificates of RSA keys are supported. + ArrayBuffer certificate; + + // Must be set to all hashes supported for this certificate. This extension + // will only be asked for signatures of digests calculated with one of these + // hash algorithms. This should be in order of decreasing hash preference. + Hash[] supportedHashes; + }; + + // Deprecated. Replaced by $(ref:SignatureRequest). + dictionary SignRequest { + // The unique ID to be used by the extension should it need to call a method + // that requires it, e.g. requestPin. + long signRequestId; + + // The digest that must be signed. + ArrayBuffer digest; + + // Refers to the hash algorithm that was used to create digest. + Hash hash; + + // The DER encoding of a X.509 certificate. The extension must sign + // digest using the associated private key. + ArrayBuffer certificate; + }; + + dictionary RequestPinDetails { + // The ID given by Chrome in SignRequest. + long signRequestId; + + // The type of code requested. Default is PIN. + PinRequestType? requestType; + + // The error template displayed to the user. This should be set if the + // previous request failed, to notify the user of the failure reason. + PinRequestErrorType? errorType; + + // The number of attempts left. This is provided so that any UI can present + // this information to the user. Chrome is not expected to enforce this, + // instead stopPinRequest should be called by the extension with + // errorType = MAX_ATTEMPTS_EXCEEDED when the number of pin requests is + // exceeded. + long? attemptsLeft; + }; + + dictionary StopPinRequestDetails { + // The ID given by Chrome in SignRequest. + long signRequestId; + + // The error template. If present it is displayed to user. Intended to + // contain the reason for stopping the flow if it was caused by an error, + // e.g. MAX_ATTEMPTS_EXCEEDED. + PinRequestErrorType? errorType; + }; + + dictionary PinResponseDetails { + // The code provided by the user. Empty if user closed the dialog or some + // other error occurred. + DOMString? userInput; + }; + + callback RequestPinCallback = void (optional PinResponseDetails details); + + callback StopPinRequestCallback = void (); + + callback SetCertificatesCallback = void (); + + callback ReportSignatureCallback = void (); + + // The callback provided by the extension that Chrome uses to report back + // rejected certificates. See CertificatesCallback. + callback ResultCallback = void (ArrayBuffer[] rejectedCertificates); + + // If no error occurred, this function must be called with the signature of + // the digest using the private key of the requested certificate. + // For an RSA key, the signature must be a PKCS#1 signature. The extension + // is responsible for prepending the DigestInfo prefix and adding PKCS#1 + // padding. If an error occurred, this callback should be called without + // signature. + callback SignCallback = void (optional ArrayBuffer signature); + + // Call this exactly once with the list of certificates that this extension is + // providing. The list must only contain certificates for which the extension + // can sign data using the associated private key. If the list contains + // invalid certificates, these will be ignored. All valid certificates are + // still registered for the extension. Chrome will call back with the list of + // rejected certificates, which might be empty. + callback CertificatesCallback = + void (CertificateInfo[] certificates, ResultCallback callback); + + interface Events { + // This event fires if the certificates set via $(ref:setCertificates) + // are insufficient or the browser requests updated information. The + // extension must call $(ref:setCertificates) with the updated list of + // certificates and the received certificatesRequestId. + static void onCertificatesUpdateRequested( + CertificatesUpdateRequest request); + + // This event fires every time the browser needs to sign a message using a + // certificate provided by this extension via $(ref:setCertificates). + //

The extension must sign the input data from request using + // the appropriate algorithm and private key and return it by calling + // $(ref:reportSignature) with the received signRequestId.

+ static void onSignatureRequested(SignatureRequest request); + + //

This event fires every time the browser requests the current list of + // certificates provided by this extension. The extension must call + // reportCallback exactly once with the current list of + // certificates.

+ [deprecated="Use $(ref:onCertificatesUpdateRequested) instead."] + static void onCertificatesRequested(CertificatesCallback reportCallback); + + // This event fires every time the browser needs to sign a message using + // a certificate provided by this extension in reply to an + // $(ref:onCertificatesRequested) event. + // The extension must sign the data in request using the + // appropriate algorithm and private key and return it by calling + // reportCallback. reportCallback must be called + // exactly once. + // |request|: Contains the details about the sign request. + [deprecated="Use $(ref:onSignatureRequested) instead."] + static void onSignDigestRequested(SignRequest request, + SignCallback reportCallback); + }; + + interface Functions { + // Requests the PIN from the user. Only one ongoing request at a time is + // allowed. The requests issued while another flow is ongoing are rejected. + // It's the extension's responsibility to try again later if another flow is + // in progress. + // |details|: Contains the details about the requested dialog. + // |callback|: Is called when the dialog is resolved with the user input, or + // when the dialog request finishes unsuccessfully (e.g. the dialog was + // canceled by the user or was not allowed to be shown). + static void requestPin( + RequestPinDetails details, + RequestPinCallback callback); + + // Stops the pin request started by the $(ref:requestPin) function. + // |details|: Contains the details about the reason for stopping the + // request flow. + // |callback|: To be used by Chrome to send to the extension the status from + // their request to close PIN dialog for user. + static void stopPinRequest( + StopPinRequestDetails details, + StopPinRequestCallback callback); + + // Sets a list of certificates to use in the browser. + //

The extension should call this function after initialization and on + // every change in the set of currently available certificates. The + // extension should also call this function in response to + // $(ref:onCertificatesUpdateRequested) every time this event is + // received.

+ // |details|: The certificates to set. Invalid certificates will be ignored. + // |callback|: Called upon completion. + static void setCertificates( + SetCertificatesDetails details, + optional SetCertificatesCallback callback); + + // Should be called as a response to $(ref:onSignatureRequested). + //

The extension must eventually call this function for every + // $(ref:onSignatureRequested) event; the API implementation will stop + // waiting for this call after some time and respond with a timeout + // error when this function is called.

+ static void reportSignature( + ReportSignatureDetails details, + optional ReportSignatureCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/certificate_provider_internal.idl b/tools/under-control/src/chrome/common/extensions/api/certificate_provider_internal.idl new file mode 100755 index 000000000..073a57bd8 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/certificate_provider_internal.idl @@ -0,0 +1,34 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Internal API backing the chrome.certificateProvider API events. +// The internal API associates events with replies to these events using request +// IDs. A custom binding is used to hide these IDs from the public API. +// Before an event hits the extension, the request ID is removed and instead a +// callback is added to the event arguments. On the way back, when the extension +// runs the callback to report its results, the callback magically prepends the +// request ID to the results and calls the respective internal report function +// (reportSignature or reportCertificates). +[implemented_in = "chrome/browser/extensions/api/certificate_provider/certificate_provider_api.h"] +namespace certificateProviderInternal { + callback DoneCallback = void (); + callback ResultCallback = void (ArrayBuffer[] rejectedCertificates); + + interface Functions { + // Matches certificateProvider.SignCallback. Must be called without the + // signature to report an error. + static void reportSignature( + long requestId, + optional ArrayBuffer signature, + optional DoneCallback callback); + + // Matches certificateProvider.CertificatesCallback. Must be called without + // the certificates argument to report an error. + static void reportCertificates( + long requestId, + optional certificateProvider.CertificateInfo[] certificates, + optional ResultCallback callback); + }; +}; + diff --git a/tools/under-control/src/chrome/common/extensions/api/chrome_url_overrides.idl b/tools/under-control/src/chrome/common/extensions/api/chrome_url_overrides.idl new file mode 100755 index 000000000..f6cdf569a --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/chrome_url_overrides.idl @@ -0,0 +1,25 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Stub namespace for the "chrome_url_overrides" manifest key. +namespace chrome_url_overrides { + dictionary UrlOverrideInfo { + // Override for the chrome://newtab page. + DOMString? newtab; + + // Override for the chrome://bookmarks page. + DOMString? bookmarks; + + // Override for the chrome://history page. + DOMString? history; + + [nodoc, platforms=("chromeos")] DOMString? activationmessage; + [nodoc, platforms=("chromeos")] DOMString? keyboard; + }; + + dictionary ManifestKeys { + // Chrome url overrides. Note that an extension can override only one page. + UrlOverrideInfo chrome_url_overrides; + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/crash_report_private.idl b/tools/under-control/src/chrome/common/extensions/api/crash_report_private.idl new file mode 100755 index 000000000..2575400ae --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/crash_report_private.idl @@ -0,0 +1,54 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Private API for Chrome component extensions to report errors. +[platforms=("chromeos")] +namespace crashReportPrivate { + // A dictionary containing additional context about the error. + dictionary ErrorInfo { + // The error message. + DOMString message; + + // URL where the error occurred. + // Must be the full URL, containing the protocol (e.g. + // http://www.example.com). + DOMString url; + + // Name of the product where the error occurred. + // Defaults to the product variant of Chrome that is hosting the extension. + // (e.g. "Chrome" or "Chrome_ChromeOS"). + DOMString? product; + + // Version of the product where the error occurred. + // Defaults to the version of Chrome that is hosting the extension (e.g. + // "73.0.3683.75"). + DOMString? version; + + // Line number where the error occurred. + long? lineNumber; + + // Column number where the error occurred. + long? columnNumber; + + // Used to map the obfuscated source code back to a source map. If present, + // must match the debug_id used to upload the source map. + DOMString? debugId; + + // String containing the stack trace for the error. + // Defaults to the empty string. + DOMString? stackTrace; + }; + + // Callback for |reportError|. + callback ReportCallback = void (); + + interface Functions { + // Report and upload an error to Crash. + // |info|: Information about the error. + // |callback|: Called when the error has been uploaded. + static void reportError( + ErrorInfo info, + ReportCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/developer_private.idl b/tools/under-control/src/chrome/common/extensions/api/developer_private.idl new file mode 100755 index 000000000..d9843cfd3 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/developer_private.idl @@ -0,0 +1,893 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// developerPrivate API. +// This is a private API exposing developing and debugging functionalities for +// apps and extensions. +namespace developerPrivate { + + // DEPRECATED: Prefer ExtensionType. + enum ItemType { + hosted_app, + packaged_app, + legacy_packaged_app, + extension, + theme + }; + + // DEPRECATED: Prefer ExtensionView. + dictionary ItemInspectView { + // path to the inspect page. + DOMString path; + + // For lazy background pages, the value is -1. + long render_process_id; + // This actually refers to a render frame. + long render_view_id; + + boolean incognito; + boolean generatedBackgroundPage; + }; + + // DEPRECATED: Use OpenDevTools. + dictionary InspectOptions { + DOMString extension_id; + (DOMString or long) render_process_id; + (DOMString or long) render_view_id; + boolean incognito; + }; + + dictionary InstallWarning { + DOMString message; + }; + + enum ExtensionType { + HOSTED_APP, + PLATFORM_APP, + LEGACY_PACKAGED_APP, + EXTENSION, + THEME, + SHARED_MODULE + }; + + enum Location { + FROM_STORE, + UNPACKED, + THIRD_PARTY, + INSTALLED_BY_DEFAULT, + // "Unknown" includes crx's installed from chrome://extensions. + UNKNOWN + }; + + enum ViewType { + APP_WINDOW, + BACKGROUND_CONTENTS, + COMPONENT, + EXTENSION_BACKGROUND_PAGE, + EXTENSION_GUEST, + EXTENSION_POPUP, + EXTENSION_SERVICE_WORKER_BACKGROUND, + TAB_CONTENTS, + OFFSCREEN_DOCUMENT, + EXTENSION_SIDE_PANEL + }; + + enum ErrorType { + MANIFEST, + RUNTIME + }; + + enum ErrorLevel { + LOG, + WARN, + ERROR + }; + + enum ExtensionState { + ENABLED, + DISABLED, + TERMINATED, + BLACKLISTED + }; + + enum CommandScope { + GLOBAL, + CHROME + }; + + enum SafetyCheckWarningReason { + UNPUBLISHED, + POLICY, + MALWARE, + OFFSTORE, + UNWANTED, + NO_PRIVACY_PRACTICE + }; + + dictionary AccessModifier { + boolean isEnabled; + boolean isActive; + }; + + dictionary StackFrame { + long lineNumber; + long columnNumber; + DOMString url; + DOMString functionName; + }; + + dictionary ManifestError { + ErrorType type; + DOMString extensionId; + boolean fromIncognito; + DOMString source; + DOMString message; + long id; + DOMString manifestKey; + DOMString? manifestSpecific; + }; + + dictionary RuntimeError { + ErrorType type; + DOMString extensionId; + boolean fromIncognito; + DOMString source; + DOMString message; + long id; + ErrorLevel severity; + DOMString contextUrl; + long occurrences; + long renderViewId; + long renderProcessId; + boolean canInspect; + StackFrame[] stackTrace; + }; + + dictionary DisableReasons { + boolean suspiciousInstall; + boolean corruptInstall; + boolean updateRequired; + boolean publishedInStoreRequired; + boolean blockedByPolicy; + boolean reloading; + boolean custodianApprovalRequired; + boolean parentDisabledPermissions; + boolean unsupportedManifestVersion; + }; + + dictionary OptionsPage { + boolean openInTab; + DOMString url; + }; + + dictionary HomePage { + DOMString url; + boolean specified; + }; + + dictionary ExtensionView { + DOMString url; + long renderProcessId; + // This actually refers to a render frame. + long renderViewId; + boolean incognito; + boolean isIframe; + ViewType type; + }; + + enum HostAccess { + ON_CLICK, + ON_SPECIFIC_SITES, + ON_ALL_SITES + }; + + dictionary SafetyCheckStrings { + DOMString? panelString; + DOMString? detailString; + }; + + dictionary ControlledInfo { + DOMString text; + }; + + dictionary Command { + DOMString description; + DOMString keybinding; + DOMString name; + boolean isActive; + CommandScope scope; + boolean isExtensionAction; + }; + + dictionary DependentExtension { + DOMString id; + DOMString name; + }; + + dictionary Permission { + DOMString message; + DOMString[] submessages; + }; + + dictionary SiteControl { + // The host pattern for the site. + DOMString host; + // Whether the pattern has been granted. + boolean granted; + }; + + dictionary RuntimeHostPermissions { + // True if |hosts| contains an all hosts like pattern. + boolean hasAllHosts; + + // The current HostAccess setting for the extension. + HostAccess hostAccess; + + // The site controls for all granted and requested patterns. + SiteControl[] hosts; + }; + + dictionary Permissions { + Permission[] simplePermissions; + + // Only populated for extensions that can be affected by the runtime host + // permissions feature. + RuntimeHostPermissions? runtimeHostPermissions; + + // True if the extension can access site data through host permissions or + // API permissions such as activeTab. + boolean canAccessSiteData; + }; + + dictionary ExtensionInfo { + DOMString? blacklistText; + SafetyCheckStrings? safetyCheckText; + Command[] commands; + ControlledInfo? controlledInfo; + DependentExtension[] dependentExtensions; + DOMString description; + DisableReasons disableReasons; + AccessModifier errorCollection; + AccessModifier fileAccess; + HomePage homePage; + DOMString iconUrl; + DOMString id; + AccessModifier incognitoAccess; + DOMString[] installWarnings; + DOMString? launchUrl; + Location location; + DOMString? locationText; + ManifestError[] manifestErrors; + DOMString manifestHomePageUrl; + boolean mustRemainInstalled; + DOMString name; + boolean offlineEnabled; + OptionsPage? optionsPage; + DOMString? path; + Permissions permissions; + DOMString? prettifiedPath; + DOMString? recommendationsUrl; + RuntimeError[] runtimeErrors; + DOMString[] runtimeWarnings; + ExtensionState state; + ExtensionType type; + DOMString updateUrl; + boolean userMayModify; + DOMString version; + ExtensionView[] views; + DOMString webStoreUrl; + boolean showSafeBrowsingAllowlistWarning; + SafetyCheckWarningReason? safetyCheckWarningReason; + boolean showAccessRequestsInToolbar; + boolean? pinnedToToolbar; + boolean isAffectedByMV2Deprecation; + boolean didAcknowledgeMV2DeprecationNotice; + }; + + dictionary ProfileInfo { + boolean canLoadUnpacked; + boolean inDeveloperMode; + boolean isDeveloperModeControlledByPolicy; + boolean isIncognitoAvailable; + boolean isChildAccount; + boolean isMv2DeprecationNoticeDismissed; + }; + + // DEPRECATED: Prefer ExtensionInfo. + dictionary ItemInfo { + DOMString id; + DOMString name; + DOMString version; + DOMString description; + boolean may_disable; + boolean enabled; + boolean isApp; + ItemType type; + boolean allow_activity; + boolean allow_file_access; + boolean wants_file_access; + boolean incognito_enabled; + boolean is_unpacked; + boolean allow_reload; + boolean terminated; + boolean allow_incognito; + DOMString icon_url; + + // Path of an unpacked extension. + DOMString? path; + + // Options settings page for the item. + DOMString? options_url; + DOMString? app_launch_url; + DOMString? homepage_url; + DOMString? update_url; + InstallWarning[] install_warnings; + any[] manifest_errors; + any[] runtime_errors; + boolean offline_enabled; + + // All views of the current extension. + ItemInspectView[] views; + }; + + dictionary GetExtensionsInfoOptions { + boolean? includeDisabled; + boolean? includeTerminated; + }; + + dictionary ExtensionConfigurationUpdate { + DOMString extensionId; + boolean? fileAccess; + boolean? incognitoAccess; + boolean? errorCollection; + HostAccess? hostAccess; + boolean? showAccessRequestsInToolbar; + SafetyCheckWarningReason? acknowledgeSafetyCheckWarningReason; + boolean? acknowledgeSafetyCheckWarning; + boolean? pinnedToToolbar; + }; + + dictionary ProfileConfigurationUpdate { + boolean? inDeveloperMode; + boolean? isMv2DeprecationNoticeDismissed; + }; + + dictionary ExtensionCommandUpdate { + DOMString extensionId; + DOMString commandName; + CommandScope? scope; + DOMString? keybinding; + }; + + dictionary ReloadOptions { + // If false, an alert dialog will show in the event of a reload error. + // Defaults to false. + boolean? failQuietly; + + // If true, populates a LoadError for the response rather than setting + // lastError. Only relevant for unpacked extensions; it will be ignored for + // any other extension. + boolean? populateErrorForUnpacked; + }; + + dictionary LoadUnpackedOptions { + // If false, an alert dialog will show in the event of a reload error. + // Defaults to false. + boolean? failQuietly; + + // If true, populates a LoadError for the response rather than setting + // lastError. + boolean? populateError; + + // A unique identifier for retrying a previous failed load. This should be + // the identifier returned in the LoadError. If specified, the path + // associated with the identifier will be loaded, and the file chooser + // will be skipped. + DOMString? retryGuid; + + // True if the function should try to load an extension from the drop data + // of the page. notifyDragInstallInProgress() needs to be called prior to + // this being used. This cannot be used with |retryGuid|. + boolean? useDraggedPath; + }; + + // Describes which set of sites a given url/string is associated with. Note + // that a site can belong to multiple sets at the same time. + enum SiteSet { + // The site is specified by the user to automatically grant access to all + // extensions with matching host permissions. Mutually exclusive with + // USER_RESTRICTED but takes precedence over EXTENSION_SPECIFIED. + USER_PERMITTED, + // The site is specified by the user to disallow all extensions from running + // on it. Mutually exclusive with USER_PERMITTED but takes precedence over + // EXTENSION_SPECIFIED. + USER_RESTRICTED, + // The site is specified by one or more extensions' set of host permissions. + EXTENSION_SPECIFIED + }; + + dictionary UserSiteSettingsOptions { + // Specifies which set of user specified sites that the host will be added + // to or removed from. + SiteSet siteSet; + // The sites to add/remove. + DOMString[] hosts; + }; + + dictionary UserSiteSettings { + // The list of origins where the user has allowed all extensions to run on. + DOMString[] permittedSites; + // The list of origins where the user has blocked all extensions from + // running on. + DOMString[] restrictedSites; + }; + + dictionary SiteInfo { + // The site set that `site` belongs to. + SiteSet siteSet; + // The number of extensions with access to `site`. + // TODO(crbug.com/40227416): A tricky edge case is when one extension + // specifies something like *.foo.com and another specifies foo.com. + // Patterns which match all subdomains should be represented differently. + long numExtensions; + // The site itself. This could either be a user specified site or an + // extension host permission pattern. + DOMString site; + }; + + dictionary SiteGroup { + // The common effective top level domain plus one (eTLD+1) for all sites in + // `sites`. + DOMString etldPlusOne; + // The number of extensions that can run on at least one site inside `sites` + // for this eTLD+1. + long numExtensions; + // The list of user or extension specified sites that share the same eTLD+1. + SiteInfo[] sites; + }; + + dictionary MatchingExtensionInfo { + // The id of the matching extension. + DOMString id; + // Describes the extension's access to the queried site from + // getMatchingExtensionsForSite. Note that the meaning is different from the + // original enum: + // - ON_CLICK: The extension requested access to the site but its access is + // withheld. + // - ON_SPECIFIC_SITES: the extension is permitted to run on at least one + // site specified by the queried site but it does not request access to + // all sites or it has its access withheld on at least one site in its + // host permissions. + // - ON_ALL_SITES: the extension is permitted to run on all sites. + HostAccess siteAccess; + // Whether the matching extension requests access to all sites in its + // host permissions. + boolean canRequestAllSites; + }; + + dictionary ExtensionSiteAccessUpdate { + // The id of the extension to update its site access settings for. + DOMString id; + // Describes the update made to the extension's site access for a given site + // Note that this has a different meaning from the original enum: + // - ON_CLICK: Withholds the extension's access to the given site, + // - ON_SPECIFIC_SITES: Grants the extension access to the intersection of + // (given site, extension's specified host permissions.) + // - ON_ALL_SITES: Grants access to all of the extension's specified host + // permissions. + HostAccess siteAccess; + }; + + enum PackStatus { + SUCCESS, + ERROR, + WARNING + }; + + enum FileType { + LOAD, + PEM + }; + + enum SelectType { + FILE, + FOLDER + }; + + enum EventType { + INSTALLED, + UNINSTALLED, + LOADED, + UNLOADED, + // New window / view opened. + VIEW_REGISTERED, + // window / view closed. + VIEW_UNREGISTERED, + ERROR_ADDED, + ERRORS_REMOVED, + PREFS_CHANGED, + WARNINGS_CHANGED, + COMMAND_ADDED, + COMMAND_REMOVED, + PERMISSIONS_CHANGED, + SERVICE_WORKER_STARTED, + SERVICE_WORKER_STOPPED, + CONFIGURATION_CHANGED, + PINNED_ACTIONS_CHANGED + }; + + dictionary PackDirectoryResponse { + // The response message of success or error. + DOMString message; + + // Unpacked items's path. + DOMString item_path; + + // Permanent key path. + DOMString pem_path; + + long override_flags; + PackStatus status; + }; + + dictionary ProjectInfo { + DOMString name; + }; + + dictionary EventData { + EventType event_type; + DOMString item_id; + ExtensionInfo? extensionInfo; + }; + + dictionary ErrorFileSource { + // The region before the "highlight" portion. + // If the region which threw the error was not found, the full contents of + // the file will be in the "beforeHighlight" section. + DOMString beforeHighlight; + + // The region of the code which threw the error, and should be highlighted. + DOMString highlight; + + // The region after the "highlight" portion. + DOMString afterHighlight; + }; + + dictionary LoadError { + // The error that occurred when trying to load the extension. + DOMString error; + + // The path to the extension. + DOMString path; + + // The file source for the error, if it could be retrieved. + ErrorFileSource? source; + + // A unique identifier to pass to developerPrivate.loadUnpacked to retry + // loading the extension at the same path. + DOMString retryGuid; + }; + + dictionary RequestFileSourceProperties { + // The ID of the extension owning the file. + DOMString extensionId; + + // The path of the file, relative to the extension; e.g., manifest.json, + // script.js, or main.html. + DOMString pathSuffix; + + // The error message which was thrown as a result of the error in the file. + DOMString message; + + // The key in the manifest which caused the error (e.g., "permissions"). + // (Required for "manifest.json" files) + DOMString? manifestKey; + + // The specific portion of the manifest key which caused the error (e.g., + // "foo" in the "permissions" key). (Optional for "manifest.json" file). + DOMString? manifestSpecific; + + // The line number which caused the error (optional for non-manifest files). + long? lineNumber; + }; + + dictionary RequestFileSourceResponse { + // The region of the code which threw the error, and should be highlighted. + DOMString highlight; + + // The region before the "highlight" portion. + // If the region which threw the error was not found, the full contents of + // the file will be in the "beforeHighlight" section. + DOMString beforeHighlight; + + // The region after the "highlight" portion. + DOMString afterHighlight; + + // A title for the file in the form ': '. + DOMString title; + + // The error message. + DOMString message; + }; + + dictionary OpenDevToolsProperties { + // The ID of the extension. This is only needed if opening its background + // page or its background service worker (where renderViewId and + // renderProcessId are -1). + DOMString? extensionId; + + // The ID of the render frame in which the error occurred. + // Despite being called renderViewId, this refers to a render frame. + long renderViewId; + + // The ID of the process in which the error occurred. + long renderProcessId; + + // Whether or not the background is service worker based. + boolean? isServiceWorker; + + boolean? incognito; + + // The URL in which the error occurred. + DOMString? url; + + // The line to focus the devtools at. + long? lineNumber; + + // The column to focus the devtools at. + long? columnNumber; + }; + + dictionary DeleteExtensionErrorsProperties { + DOMString extensionId; + long[]? errorIds; + ErrorType? type; + }; + + callback VoidCallback = void (); + callback BooleanCallback = void (boolean result); + callback ExtensionInfosCallback = void (ExtensionInfo[] result); + callback ExtensionInfoCallback = void (ExtensionInfo result); + callback ItemsInfoCallback = void (ItemInfo[] result); + callback ProfileInfoCallback = void (ProfileInfo info); + callback GetProjectsInfoCallback = void (ProjectInfo[] result); + callback PackCallback = void (PackDirectoryResponse response); + callback StringCallback = void (DOMString string); + callback RequestFileSourceCallback = + void (RequestFileSourceResponse response); + callback LoadErrorCallback = void (optional LoadError error); + callback DragInstallInProgressCallback = void (DOMString loadGuid); + callback UserSiteSettingsCallback = void (UserSiteSettings settings); + callback UserAndExtensionSitesByEtldCallback = void (SiteGroup[] siteGroups); + callback GetMatchingExtensionsForSiteCallback = + void (MatchingExtensionInfo[] matchingExtensions); + + interface Functions { + // Runs auto update for extensions and apps immediately. + // |callback| : Called after update check completes. + static void autoUpdate(optional VoidCallback callback); + + // Returns information of all the extensions and apps installed. + // |options| : Options to restrict the items returned. + // |callback| : Called with extensions info. + static void getExtensionsInfo( + optional GetExtensionsInfoOptions options, + optional ExtensionInfosCallback callback); + + // Returns information of a particular extension. + // |id| : The id of the extension. + // |callback| : Called with the result. + static void getExtensionInfo( + DOMString id, + optional ExtensionInfoCallback callback); + + // Returns the size of a particular extension on disk (already formatted). + // |id| : The id of the extension. + // |callback| : Called with the result. + static void getExtensionSize( + DOMString id, + StringCallback callback); + + // Returns the current profile's configuration. + static void getProfileConfiguration( + ProfileInfoCallback callback); + + // Updates the active profile. + // |update| : The parameters for updating the profile's configuration. Any + // properties omitted from |update| will not be changed. + static void updateProfileConfiguration( + ProfileConfigurationUpdate update, + optional VoidCallback callback); + + // Reloads a given extension. + // |extensionId| : The id of the extension to reload. + // |options| : Additional configuration parameters. + static void reload( + DOMString extensionId, + optional ReloadOptions options, + optional LoadErrorCallback callback); + + // Modifies an extension's current configuration. + // |update| : The parameters for updating the extension's configuration. + // Any properties omitted from |update| will not be changed. + static void updateExtensionConfiguration( + ExtensionConfigurationUpdate update, + optional VoidCallback callback); + + // Loads a user-selected unpacked item. + // |options| : Additional configuration parameters. + static void loadUnpacked( + optional LoadUnpackedOptions options, + optional LoadErrorCallback callback); + + // Installs the file that was dragged and dropped onto the associated + // page. + static void installDroppedFile( + optional VoidCallback callback); + + // Notifies the browser that a user began a drag in order to install an + // extension. + static void notifyDragInstallInProgress(); + + // Loads an extension / app. + // |directory| : The directory to load the extension from. + static void loadDirectory( + [instanceOf=DirectoryEntry] object directory, + StringCallback callback); + + // Open Dialog to browse to an entry. + // |selectType| : Select a file or a folder. + // |fileType| : Required file type. For example, pem type is for private + // key and load type is for an unpacked item. + // |callback| : called with selected item's path. + static void choosePath( + SelectType selectType, + FileType fileType, + StringCallback callback); + + // Pack an extension. + // |rootPath| : The path of the extension. + // |privateKeyPath| : The path of the private key, if one is given. + // |flags| : Special flags to apply to the loading process, if any. + // |callback| : called with the success result string. + static void packDirectory( + DOMString path, + optional DOMString privateKeyPath, + optional long flags, + optional PackCallback callback); + + // Returns true if the profile is managed. + static void isProfileManaged(BooleanCallback callback); + + // Reads and returns the contents of a file related to an extension which + // caused an error. + static void requestFileSource( + RequestFileSourceProperties properties, + RequestFileSourceCallback callback); + + // Open the developer tools to focus on a particular error. + static void openDevTools( + OpenDevToolsProperties properties, + optional VoidCallback callback); + + // Delete reported extension errors. + // |properties| : The properties specifying the errors to remove. + static void deleteExtensionErrors( + DeleteExtensionErrorsProperties properties, + optional VoidCallback callback); + + // Repairs the extension specified. + // |extensionId| : The id of the extension to repair. + static void repairExtension( + DOMString extensionId, + optional VoidCallback callback); + + // Shows the options page for the extension specified. + // |extensionId| : The id of the extension to show the options page for. + static void showOptions( + DOMString extensionId, + optional VoidCallback callback); + + // Shows the path of the extension specified. + // |extensionId| : The id of the extension to show the path for. + static void showPath( + DOMString extensionId, + optional VoidCallback callback); + + // (Un)suspends global shortcut handling. + // |isSuspended| : Whether or not shortcut handling should be suspended. + static void setShortcutHandlingSuspended( + boolean isSuspended, + optional VoidCallback callback); + + // Updates an extension command. + // |update| : The parameters for updating the extension command. + static void updateExtensionCommand( + ExtensionCommandUpdate update, + optional VoidCallback callback); + + // Adds a new host permission to the extension. The extension will only + // have access to the host if it is within the requested permissions. + // |extensionId|: The id of the extension to modify. + // |host|: The host to add. + static void addHostPermission( + DOMString extensionId, + DOMString host, + optional VoidCallback callback); + + // Removes a host permission from the extension. This should only be called + // with a host that the extension has access to. + // |extensionId|: The id of the extension to modify. + // |host|: The host to remove. + static void removeHostPermission( + DOMString extensionId, + DOMString host, + optional VoidCallback callback); + + // Returns the user specified site settings (which origins can extensions + // always/never run on) for the current profile. + static void getUserSiteSettings( + UserSiteSettingsCallback callback); + + // Adds hosts to the set of user permitted or restricted sites. If any hosts + // are in the other set than what's specified in `options`, then they are + // removed from that set. + static void addUserSpecifiedSites( + UserSiteSettingsOptions options, + optional VoidCallback callback); + + // Removes hosts from the specified set of user permitted or restricted + // sites. + static void removeUserSpecifiedSites( + UserSiteSettingsOptions options, + optional VoidCallback callback); + + // Returns all hosts specified by user site settings, grouped by each host's + // eTLD+1. + static void getUserAndExtensionSitesByEtld( + UserAndExtensionSitesByEtldCallback callback); + + // Returns a list of extensions which have at least one matching site in + // common between its set of host permissions and `site`. + static void getMatchingExtensionsForSite( + DOMString site, + GetMatchingExtensionsForSiteCallback callback); + + // Updates the site access settings for multiple extensions for the given + // `site` and calls `callback` once all updates have been finished. + // Each update species an extension id an a new HostAccess setting. + static void updateSiteAccess( + DOMString site, + ExtensionSiteAccessUpdate[] updates, + optional VoidCallback callback); + + // Removes multiple installed extensions. + static void removeMultipleExtensions( + DOMString[] extensionIds, + optional VoidCallback callback); + + // Dismisses the menu notification for the extensions module in Safety Hub + // if one is active. + static void dismissSafetyHubExtensionsMenuNotification(); + + // Triggers the dismissal of the mv2 deprecation notice for `extensionId`. + static void dismissMv2DeprecationNoticeForExtension(DOMString extensionId); + + [nocompile, deprecated="Use openDevTools"] + static void inspect(InspectOptions options, + optional VoidCallback callback); + }; + + interface Events { + // Fired when a item state is changed. + static void onItemStateChanged(EventData response); + + // Fired when the profile's state has changed. + static void onProfileStateChanged(ProfileInfo info); + + // Fired when the lists of sites in the user's site settings have changed. + static void onUserSiteSettingsChanged(UserSiteSettings settings); + }; + +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/document_scan.idl b/tools/under-control/src/chrome/common/extensions/api/document_scan.idl new file mode 100755 index 000000000..501cdc0a4 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/document_scan.idl @@ -0,0 +1,654 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.documentScan API to discover and retrieve +// images from attached document scanners. +[platforms=("chromeos", "lacros"), +implemented_in="chrome/browser/extensions/api/document_scan/document_scan_api.h"] +namespace documentScan { + dictionary ScanOptions { + // The MIME types that are accepted by the caller. + DOMString[]? mimeTypes; + + // The number of scanned images allowed. The default is 1. + long? maxImages; + }; + + dictionary ScanResults { + // An array of data image URLs in a form that can be passed as the "src" + // value to an image tag. + DOMString[] dataUrls; + + // The MIME type of the dataUrls. + DOMString mimeType; + }; + + // An enum that indicates the result of each operation. + enum OperationResult { + // An unknown or generic failure occurred. + UNKNOWN, + + // The operation succeeded. + SUCCESS, + + // The operation is not supported. + UNSUPPORTED, + + // The operation was cancelled. + CANCELLED, + + // The device is busy. + DEVICE_BUSY, + + // Either the data or an argument passed to the method is not valid. + INVALID, + + // The supplied value is the wrong data type for the underlying option. + WRONG_TYPE, + + // No more data is available. + EOF, + + // The document feeder is jammed. + ADF_JAMMED, + + // The document feeder is empty. + ADF_EMPTY, + + // The flatbed cover is open. + COVER_OPEN, + + // An error occurred while communicating with the device. + IO_ERROR, + + // The device requires authentication. + ACCESS_DENIED, + + // Not enough memory is available on the Chromebook to complete the + // operation. + NO_MEMORY, + + // The device is not reachable. + UNREACHABLE, + + // The device is disconnected. + MISSING, + + // An error has occurred somewhere other than the calling application. + INTERNAL_ERROR + }; + + // Indicates how the scanner is connected to the computer. + enum ConnectionType { + UNSPECIFIED, + USB, + NETWORK + }; + + // Contains general information about a scanner. It is + // intended for filtering and constructing user-facing information. to + // configure a scan, use $(ref:StartScanOptions). + dictionary ScannerInfo { + // The ID of a specific scanner. + DOMString scannerId; + + // A human-readable name for the scanner to display in the UI. + DOMString name; + + // The scanner manufacturer. + DOMString manufacturer; + + // The scanner model if it is available, or a generic description. + DOMString model; + + // For matching against other ScannerInfo entries that point + // to the same physical device. + DOMString deviceUuid; + + // Indicates how the scanner is connected to the computer. + ConnectionType connectionType; + + // If true, the scanner connection's transport cannot be intercepted by a + // passive listener, such as TLS or USB. + boolean secure; + + // An array of MIME types that can be requested for returned scans. + DOMString[] imageFormats; + + // A human-readable description of the protocol or driver used to + // access the scanner, such as Mopria, WSD, or epsonds. This is primarily + // useful for allowing a user to choose between protocols if a device + // supports multiple protocols. + DOMString protocolType; + }; + + // The data type of an option. + enum OptionType { + // The option's data type is unknown. The value property + // will be unset. + UNKNOWN, + + // The value property will be one of truefalse. + BOOL, + + // A signed 32-bit integer. The value property will be long or + // long[], depending on whether the option takes more than one value. + INT, + + // A double in the range -32768-32767.9999 with a resolution of 1/65535. + // The value property will be double or double[] depending + // on whether the option takes more than one value. Double values that + // can't be exactly represented will be rounded to the available range + // and precision. + FIXED, + + // A sequence of any bytes except NUL ('\0'). The value + // property will be a DOMString. + STRING, + + // An option of this type has no value. Instead, setting an option of + // this type causes an option-specific side effect in the scanner + // driver. For example, a button-typed option could be used by a + // scanner driver to provide a means to select default values or to + // tell an automatic document feeder to advance to the next sheet of + // paper. + BUTTON, + + // Grouping option. No value. This is included for compatibility, but + // will not normally be returned in ScannerOption values. Use + // getOptionGroups() to retrieve the list of groups with their + // member options. + GROUP + }; + + // Indicates the data type for $(ref:ScannerOption.unit). + enum OptionUnit { + // The value is a unitless number. For example, it can be a threshold. + UNITLESS, + + // The value is a number of pixels, for example, scan dimensions. + PIXEL, + + // The value is the number of bits, for example, color depth. + BIT, + + // The value is measured in millimeters, for example, scan dimensions. + MM, + + // The value is measured in dots per inch, for example, resolution. + DPI, + + // The value is a percent, for example, brightness. + PERCENT, + + // The value is measured in microseconds, for example, exposure time. + MICROSECOND + }; + + // The data type of constraint represented by an $(ref:OptionConstraint). + enum ConstraintType { + // The constraint on a range of OptionType.INT values. + // The min, max, and quant properties + // of OptionConstraint will be long, and its + // list propety will be unset. + INT_RANGE, + + // The constraint on a range of OptionType.FIXED values. + // The min, max, and quant properties + // of OptionConstraint will be double, and its + // list property will be unset. + FIXED_RANGE, + + // The constraint on a specific list of OptionType.INT + // values. The OptionConstraint.list property will contain + // long values, and the other properties will be unset. + INT_LIST, + + // The constraint on a specific list of OptionType.FIXED + // values. The OptionConstraint.list property will contain + // double values, and the other properties will be unset. + FIXED_LIST, + + // The constraint on a specific list of OptionType.STRING + // values. The OptionConstraint.list property will contain + // DOMString values, and the other properties will be unset. + STRING_LIST + }; + + // The specific values for the $(ref:ConstraintType) structure. + // An unconstrained value is represented by a lack of constraints; + // there is no separate ConstraintType value to indicate an + // unconstrained value. + dictionary OptionConstraint { + ConstraintType type; + (long or double)? min; + (long or double)? max; + (long or double)? quant; + (double[] or long[] or DOMString[])? list; + }; + + // How an option can be changed. + enum Configurability { + // The option is read-only. + NOT_CONFIGURABLE, + + // The option can be set in software. + SOFTWARE_CONFIGURABLE, + + // The option can be set by the user toggling or pushing a button on + // the scanner. + HARDWARE_CONFIGURABLE + }; + + // A self-describing configurable scanner option and its current value. + dictionary ScannerOption { + // The option name using lowercase ASCII letters, numbers, and dashes. + // Diacritics are not allowed. + DOMString name; + + // A printable one-line title. + DOMString title; + + // A longer description of the option. + DOMString description; + + // The data type contained in the value property, which + // is needed for setting this option. + OptionType type; + + // The unit of measurement for this option. + OptionUnit unit; + + // The current value of the option, if relevant. Note that the data + // type of this property must match the data type specified in + // type. + (boolean or double or double[] or long or long[] or DOMString)? value; + + // Defines $(ref:OptionConstraint) on the current scanner option. + OptionConstraint? constraint; + + // Indicates that this option can be detected from software. + boolean isDetectable; + + // Indicates whether and how the option can be changed. + Configurability configurability; + + // Can be automatically set by the scanner driver. + boolean isAutoSettable; + + // Emulated by the scanner driver if true. + boolean isEmulated; + + // Indicates the option is active and can be set or retrieved. If false, + // the value property will not be set. + boolean isActive; + + // Indicates that the UI should not display this option by default. + boolean isAdvanced; + + // Indicates that the option is used for internal configuration and + // should never be displayed in the UI. + boolean isInternal; + }; + + // A set of criteria passed to getScannerList(). Only devices + // that match all of the criteria will be returned. + dictionary DeviceFilter { + // Only return scanners that are directly attached to the computer. + boolean? local; + + // Only return scanners that use a secure transport, such as USB or TLS. + boolean? secure; + }; + + // Contains a list of option names. The groups and their contents are + // determined by the scanner driver and do not have any defined semantics + // or consistent membership. This structure is primarily intended + // for UI layout assistance; it does not affect individual option + // behaviors. + dictionary OptionGroup { + // Provides a printable title, for example "Geometry options". + DOMString title; + + // An array of option names in driver-provided order. + DOMString[] members; + }; + + // The response from $(ref:getScannerList). + dictionary GetScannerListResponse { + // The enumeration result. Note that partial results could be + // returned even if this indicates an error. + OperationResult result; + + // A possibly-empty list of scanners that match the provided + // $(ref:DeviceFilter). + ScannerInfo[] scanners; + }; + + // The response from $(ref:openScanner). + dictionary OpenScannerResponse { + // The scanner ID passed to openScanner(). + DOMString scannerId; + + // The result of opening the scanner. If the value of this is + // SUCCESS, the scannerHandle and + // options properties will be populated. + OperationResult result; + + // If result is SUCCESS, a + // handle to the scanner that can be used for further operations. + DOMString? scannerHandle; + + // If result is SUCCESS, + // provides a key-value mapping where the key is a device-specific + // option and the value is an instance of $(ref:ScannerOption). + object? options; + }; + + // The response from $(ref:getOptionGroups). + dictionary GetOptionGroupsResponse { + // The same scanner handle as was passed to $(ref:getOptionGroups). + DOMString scannerHandle; + + // The result of getting the option groups. If the value of this is + // SUCCESS, the groups property will be + // populated. + OperationResult result; + + // If result is SUCCESS, provides a + // list of option groups in the order supplied by the scanner driver. + OptionGroup[]? groups; + }; + + // The response from closeScanner(). + dictionary CloseScannerResponse { + // The same scanner handle as was passed to $(ref:closeScanner). + DOMString scannerHandle; + + // The result of closing the scanner. Even if this value is not + // SUCCESS, the handle will be invalid and + // should not be used for any further operations. + OperationResult result; + }; + + // Passed to $(ref:setOptions) to set an option to $(ref:ScannerOption) to + // a new value. + dictionary OptionSetting { + // Indicates the name of the option to set. + DOMString name; + + // Indicates the data type of the option. The requested data type must + // match the real data type of the underlying option. + OptionType type; + + // Indicates the value to set. Leave unset to request automatic setting for + // options that have autoSettable enabled. The data type + // supplied for value must match type. + (boolean or double or double[] or long or long[] or DOMString)? value; + }; + + // The result of setting an individual option. Each individual option + // supplied to setOptions() produces a separate result + // due to things like rounding and constraints. + dictionary SetOptionResult { + // Indicates the name of the option that was set. + DOMString name; + + // Indicates the result of setting the option. + OperationResult result; + }; + + // The response from a call to $(ref:setOptions). + dictionary SetOptionsResponse { + // Provides the scanner handle passed to setOptions(). + DOMString scannerHandle; + + // An array of results, one each for every passed-in + // OptionSetting. + SetOptionResult[] results; + + // An updated key-value mapping from option names to + // $(ref:ScannerOption) values containing the new configuration after + // attempting to set all supplied options. This has the same structure as + // the options property in $(ref:OpenScannerResponse). + // + // This property will be set even if some options were not set successfully, + // but will be unset if retrieving the updated configuration fails (for + // example, if the scanner is disconnected in the middle of scanning). + object? options; + }; + + // Specifies options for $(ref:startScan). + dictionary StartScanOptions { + // Specifies the MIME type to return scanned data in. + DOMString format; + + // If a non-zero value is specified, limits the maximum scanned bytes + // returned in a single $(ref:readScanData) response to that value. The + // smallest allowed value is 32768 (32 KB). If this property is not + // specified, the size of a returned chunk may be as large as the entire + // scanned image. + long? maxReadSize; + }; + + // The response from startScan(). + dictionary StartScanResponse { + // Provides the same scanner handle that was passed to + // startScan(). + DOMString scannerHandle; + + // The result of starting a scan. If the value of this is + // SUCCESS, the job property will be populated. + OperationResult result; + + // If result is SUCCESS, provides a + // handle that can be used to read scan data or cancel the job. + DOMString? job; + }; + + // The response from cancelScan(). + dictionary CancelScanResponse { + // Provides the same job handle that was passed to + // cancelScan(). + DOMString job; + + // The backend's cancel scan result. If the result is + // OperationResult.SUCCESS or + // OperationResult.CANCELLED, the scan has been cancelled and + // the scanner is ready to start a new scan. If the result is + // OperationResult.DEVICE_BUSY , the scanner is still + // processing the requested cancellation; the caller should wait a short + // time and try the request again. Other result values indicate a permanent + // error that should not be retried. + OperationResult result; + }; + + // The response from $(ref:readScanData). + dictionary ReadScanDataResponse { + // Provides the job handle passed to readScanData(). + DOMString job; + + // The result of reading data. If its value is + // SUCCESS, then data contains the + // next (possibly zero-length) chunk of image data that is ready + // for reading. If its value is EOF, the data + // contains the last chunk of image data. + OperationResult result; + + // If result is SUCCESS, contains + // the next chunk of scanned image data. If result is + // EOF, contains the last chunk of + // scanned image data. + ArrayBuffer? data; + + // If result is SUCCESS, an estimate of + // how much of the total scan data has been delivered so far, in the range + // 0 to 100. + long? estimatedCompletion; + }; + + // Callback from the $(ref:scan) method. + // |result| Provides the results from the scan, if successful. + // Otherwise, this value will be null and $(ref:runtime.lastError) + // will be set. + callback ScanCallback = void (ScanResults result); + + // Callback from the $(ref:getScannerList) method. + // |response| The response from enumeration, if the call was valid. + // Otherwise, this value will be null and $(ref:runtime.lastError) + // will be set. + callback GetScannerListCallback = void (GetScannerListResponse response); + + // Callback from the $(ref:openScanner) method. + // |response| The response from opening the scanner, if the call was valid. + // Otherwise, this value will be null and $(ref:runtime.lastError) + // will be set. + callback OpenScannerCallback = void (OpenScannerResponse response); + + // Callback from the $(ref:getOptionGroups) method. + // |response| The response from getting the option groups, if the call was + // valid. Otherwise, this value will be null and $(ref:runtime.lastError) + // will be set. + callback GetOptionGroupsCallback = + void (GetOptionGroupsResponse response); + + // Callback from the $(ref:closeScanner) method. + // |response| The response from closing the scanner, if the call was valid. + // Otherwise, this value will be null and $(ref:runtime.lastError) + // will be set. + callback CloseScannerCallback = void (CloseScannerResponse response); + + // Callback from the $(ref:setOptions) method. + // |response| The response from setting the options, if the call was valid. + // Otherwise, this value will be null and $(ref:runtime.lastError) + // will be set. + callback SetOptionsCallback = void (SetOptionsResponse response); + + // Callback from the $(ref:startScan) method. + // |response| The response from starting the scan, if the call was valid. + // Otherwise, this value will be null and $(ref:runtime.lastError) + // will be set. + callback StartScanCallback = void (StartScanResponse response); + + // Callback from the $(ref:cancelScan) method. + // |response| The response from canceling the scan, if the call was valid. + // Otherwise, this value will be null and $(ref:runtime.lastError) + // will be set. + callback CancelScanCallback = void (CancelScanResponse response); + + // Callback from the $(ref:readScanData) method. + // |response| The response from reading the next chunk of scanned image data, + // if the call was valid. Otherwise, this value will be null and + // $(ref:runtime.lastError) will be set. + callback ReadScanDataCallback = void (ReadScanDataResponse response); + + interface Functions { + // Performs a document scan and returns a Promise that resolves + // with a $(ref:ScanResults) object. If a callback is passed to + // this function, the returned data is passed to it instead. + // |options| : An object containing scan parameters. + // |callback| : Called with the result and data from the scan. + static void scan( + ScanOptions options, + ScanCallback callback); + + // Gets the list of available scanners and returns a Promise that + // resolves with a $(ref:GetScannerListResponse) object. If a callback + // is passed to this function, returned data is passed to it instead. + // |filter| : A $(ref:DeviceFilter) indicating which types of scanners + // should be returned. + // |callback| : Called with the result and list of scanners. + static void getScannerList( + DeviceFilter filter, GetScannerListCallback callback); + + // Opens a scanner for exclusive access and returns a Promise that + // resolves with an $(ref:OpenScannerResponse) object. If a callback + // is passed to this function, returned data is passed to it instead. + // |scannerId| : The ID of a scanner to be opened. This value is one + // returned from a previous call to $(ref:getScannerList). + // |callback| : Called with the result. + static void openScanner( + DOMString scannerId, OpenScannerCallback callback); + + // Gets the group names and member options from a scanner previously + // opened by $(ref:openScanner). This method returns a Promise that + // resolves with a $(ref:GetOptionGroupsResponse) object. If a callback + // is passed to this function, returned data is passed to it instead. + // |scannerHandle| : The handle of an open scanner returned from a call + // to $(ref:openScanner). + // |callback| : Called with the result. + static void getOptionGroups( + DOMString scannerHandle, GetOptionGroupsCallback callback); + + // Closes the scanner with the passed in handle and returns a Promise + // that resolves with a $(ref:CloseScannerResponse) object. If a callback + // is used, the object is passed to it instead. Even if the response is + // not a success, the supplied handle becomes invalid and should not be + // used for further operations. + // |scannerHandle| : Specifies the handle of an open scanner that was + // previously returned from a call to $(ref:openScanner). + // |callback| : Called with the result. + static void closeScanner( + DOMString scannerHandle, CloseScannerCallback callback); + + // Sets options on the specified scanner and returns a Promise that + // resolves with a $(ref:SetOptionsResponse) object containing the + // result of trying to set every value in the order of the passed-in + // $(ref:OptionSetting) object. If a callback is used, the object is + // passed to it instead. + // |scannerHandle| : The handle of the scanner to set options on. This + // should be a value previously returned from a call to $(ref:openScanner). + // |options| : A list of OptionSetting objects to be applied to + // the scanner. + // |callback| : Called with the result. + static void setOptions( + DOMString scannerHandle, OptionSetting[] options, + SetOptionsCallback callback); + + // Starts a scan on the specified scanner and returns a Promise that + // resolves with a $(ref:StartScanResponse). If a callback is used, + // the object is passed to it instead. If the call was successful, the + // response includes a job handle that can be used in subsequent calls + // to read scan data or cancel a scan. + // |scannerHandle| : The handle of an open scanner. This should be a value + // previously returned from a call to $(ref:openScanner). + // |options| : A $(ref:StartScanOptions) object indicating the options to + // be used for the scan. The StartScanOptions.format property + // must match one of the entries returned in the scanner's + // ScannerInfo. + // |callback| : Called with the result. + static void startScan( + DOMString scannerHandle, StartScanOptions options, + StartScanCallback callback); + + // Cancels a started scan and returns a Promise that resolves with a + // $(ref:CancelScanResponse) object. If a callback is used, the object + // is passed to it instead. + // |job| : The handle of an active scan job previously returned from a + // call to $(ref:startScan). + // |callback| : Called with the result. + static void cancelScan( + DOMString job, CancelScanCallback callback); + + // Reads the next chunk of available image data from an active job handle, + // and returns a Promise that resolves with a $(ref:ReadScanDataResponse) + // object. If a callback is used, the object is passed to it instead. + // + // + // + // |job| : Active job handle previously returned from + // $(ref:startScan). + // |callback| : Called with the result. + static void readScanData( + DOMString job, ReadScanDataCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/downloads.idl b/tools/under-control/src/chrome/common/extensions/api/downloads.idl new file mode 100755 index 000000000..1e2adc5ef --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/downloads.idl @@ -0,0 +1,630 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.downloads API to programmatically initiate, +// monitor, manipulate, and search for downloads. +[permissions=downloads] +namespace downloads { + [inline_doc] dictionary HeaderNameValuePair { + // Name of the HTTP header. + DOMString name; + + // Value of the HTTP header. + DOMString value; + }; + + //
uniquify
+ //
To avoid duplication, the filename is changed to + // include a counter before the filename extension.
+ //
overwrite
+ //
The existing file will be overwritten with the new file.
+ //
prompt
+ //
The user will be prompted with a file chooser dialog.
+ //
+ enum FilenameConflictAction {uniquify, overwrite, prompt}; + + [inline_doc] dictionary FilenameSuggestion { + // The $(ref:DownloadItem)'s new target $(ref:DownloadItem.filename), as a path + // relative to the user's default Downloads directory, possibly containing + // subdirectories. Absolute paths, empty paths, and paths containing + // back-references ".." will be ignored. filename is ignored if + // there are any $(ref:onDeterminingFilename) listeners registered by any + // extensions. + DOMString filename; + + // The action to take if filename already exists. + FilenameConflictAction? conflictAction; + }; + + [inline_doc] enum HttpMethod {GET, POST}; + + enum InterruptReason { + FILE_FAILED, + FILE_ACCESS_DENIED, + FILE_NO_SPACE, + FILE_NAME_TOO_LONG, + FILE_TOO_LARGE, + FILE_VIRUS_INFECTED, + FILE_TRANSIENT_ERROR, + FILE_BLOCKED, + FILE_SECURITY_CHECK_FAILED, + FILE_TOO_SHORT, + FILE_HASH_MISMATCH, + FILE_SAME_AS_SOURCE, + NETWORK_FAILED, + NETWORK_TIMEOUT, + NETWORK_DISCONNECTED, + NETWORK_SERVER_DOWN, + NETWORK_INVALID_REQUEST, + SERVER_FAILED, + SERVER_NO_RANGE, + SERVER_BAD_CONTENT, + SERVER_UNAUTHORIZED, + SERVER_CERT_PROBLEM, + SERVER_FORBIDDEN, + SERVER_UNREACHABLE, + SERVER_CONTENT_LENGTH_MISMATCH, + SERVER_CROSS_ORIGIN_REDIRECT, + USER_CANCELED, + USER_SHUTDOWN, + CRASH}; + + [inline_doc] dictionary DownloadOptions { + // The URL to download. + DOMString url; + + // A file path relative to the Downloads directory to contain the downloaded + // file, possibly containing subdirectories. Absolute paths, empty paths, + // and paths containing back-references ".." will cause an error. + // $(ref:onDeterminingFilename) allows suggesting a filename after the file's + // MIME type and a tentative filename have been determined. + DOMString? filename; + + // The action to take if filename already exists. + FilenameConflictAction? conflictAction; + + // Use a file-chooser to allow the user to select a filename regardless of + // whether filename is set or already exists. + boolean? saveAs; + + // The HTTP method to use if the URL uses the HTTP[S] protocol. + HttpMethod? method; + + // Extra HTTP headers to send with the request if the URL uses the HTTP[s] + // protocol. Each header is represented as a dictionary containing the keys + // name and either value or + // binaryValue, restricted to those allowed by XMLHttpRequest. + HeaderNameValuePair[]? headers; + + // Post body. + DOMString? body; + }; + + //
file
+ //
The download's filename is suspicious.
+ //
url
+ //
The download's URL is known to be malicious.
+ //
content
+ //
The downloaded file is known to be malicious.
+ //
uncommon
+ //
The download's URL is not commonly downloaded and could be + // dangerous.
+ //
host
+ //
The download came from a host known to distribute malicious + // binaries and is likely dangerous.
+ //
unwanted
+ //
The download is potentially unwanted or unsafe. E.g. it could make + // changes to browser or computer settings.
+ //
safe
+ //
The download presents no known danger to the user's computer.
+ //
accepted
+ //
The user has accepted the dangerous download.
+ //
+ enum DangerType { + file, + url, + content, + uncommon, + host, + unwanted, + safe, + accepted, + allowlistedByPolicy, + asyncScanning, + asyncLocalPasswordScanning, + passwordProtected, + blockedTooLarge, + sensitiveContentWarning, + sensitiveContentBlock, + deepScannedFailed, + deepScannedSafe, + deepScannedOpenedDangerous, + promptForScanning, + promptForLocalPasswordScanning, + accountCompromise, + blockedScanFailed + }; + + //
in_progress
+ //
The download is currently receiving data from the server.
+ //
interrupted
+ //
An error broke the connection with the file host.
+ //
complete
+ //
The download completed successfully.
+ //
+ enum State {in_progress, interrupted, complete}; + + // The state of the process of downloading a file. + dictionary DownloadItem { + // An identifier that is persistent across browser sessions. + long id; + + // The absolute URL that this download initiated from, before any + // redirects. + DOMString url; + + // The absolute URL that this download is being made from, after all + // redirects. + DOMString finalUrl; + + // Absolute URL. + DOMString referrer; + + // Absolute local path. + DOMString filename; + + // False if this download is recorded in the history, true if it is not + // recorded. + boolean incognito; + + // Indication of whether this download is thought to be safe or known to be + // suspicious. + DangerType danger; + + // The file's MIME type. + DOMString mime; + + // The time when the download began in ISO 8601 format. May be passed + // directly to the Date constructor: chrome.downloads.search({}, + // function(items){items.forEach(function(item){console.log(new + // Date(item.startTime))})}) + DOMString startTime; + + // The time when the download ended in ISO 8601 format. May be passed + // directly to the Date constructor: chrome.downloads.search({}, + // function(items){items.forEach(function(item){if (item.endTime) + // console.log(new Date(item.endTime))})}) + DOMString? endTime; + + // Estimated time when the download will complete in ISO 8601 format. May be + // passed directly to the Date constructor: + // chrome.downloads.search({}, + // function(items){items.forEach(function(item){if (item.estimatedEndTime) + // console.log(new Date(item.estimatedEndTime))})}) + DOMString? estimatedEndTime; + + // Indicates whether the download is progressing, interrupted, or complete. + State state; + + // True if the download has stopped reading data from the host, but kept the + // connection open. + boolean paused; + + // True if the download is in progress and paused, or else if it is + // interrupted and can be resumed starting from where it was interrupted. + boolean canResume; + + // Why the download was interrupted. Several kinds of HTTP errors may be + // grouped under one of the errors beginning with SERVER_. + // Errors relating to the network begin with NETWORK_, errors + // relating to the process of writing the file to the file system begin with + // FILE_, and interruptions initiated by the user begin with + // USER_. + InterruptReason? error; + + // Number of bytes received so far from the host, without considering file + // compression. + double bytesReceived; + + // Number of bytes in the whole file, without considering file compression, + // or -1 if unknown. + double totalBytes; + + // Number of bytes in the whole file post-decompression, or -1 if unknown. + double fileSize; + + // Whether the downloaded file still exists. This information may be out of + // date because Chrome does not automatically watch for file removal. Call + // $(ref:search)() in order to trigger the check for file existence. When the + // existence check completes, if the file has been deleted, then an + // $(ref:onChanged) event will fire. Note that $(ref:search)() does not wait + // for the existence check to finish before returning, so results from + // $(ref:search)() may not accurately reflect the file system. Also, + // $(ref:search)() may be called as often as necessary, but will not check for + // file existence any more frequently than once every 10 seconds. + boolean exists; + + // The identifier for the extension that initiated this download if this + // download was initiated by an extension. Does not change once it is set. + DOMString? byExtensionId; + + // The localized name of the extension that initiated this download if this + // download was initiated by an extension. May change if the extension + // changes its name or if the user changes their locale. + DOMString? byExtensionName; + }; + + [inline_doc] dictionary DownloadQuery { + // This array of search terms limits results to $(ref:DownloadItem) whose + // filename or url or finalUrl + // contain all of the search terms that do not begin with a dash '-' and + // none of the search terms that do begin with a dash. + DOMString[]? query; + + // Limits results to $(ref:DownloadItem) that + // started before the given ms in ISO 8601 format. + DOMString? startedBefore; + + // Limits results to $(ref:DownloadItem) that + // started after the given ms in ISO 8601 format. + DOMString? startedAfter; + + // Limits results to $(ref:DownloadItem) that ended before the given ms in + // ISO 8601 format. + DOMString? endedBefore; + + // Limits results to $(ref:DownloadItem) that ended after the given ms in + // ISO 8601 format + DOMString? endedAfter; + + // Limits results to $(ref:DownloadItem) whose + // totalBytes is greater than the given integer. + double? totalBytesGreater; + + // Limits results to $(ref:DownloadItem) whose + // totalBytes is less than the given integer. + double? totalBytesLess; + + // Limits results to $(ref:DownloadItem) whose + // filename matches the given regular expression. + DOMString? filenameRegex; + + // Limits results to $(ref:DownloadItem) whose + // url matches the given regular expression. + DOMString? urlRegex; + + // Limits results to $(ref:DownloadItem) whose + // finalUrl matches the given regular expression. + DOMString? finalUrlRegex; + + // The maximum number of matching $(ref:DownloadItem) returned. Defaults to + // 1000. Set to 0 in order to return all matching $(ref:DownloadItem). See + // $(ref:search) for how to page through results. + long? limit; + + // Set elements of this array to $(ref:DownloadItem) properties in order to + // sort search results. For example, setting + // orderBy=['startTime'] sorts the $(ref:DownloadItem) by their + // start time in ascending order. To specify descending order, prefix with a + // hyphen: '-startTime'. + DOMString[]? orderBy; + + // The id of the $(ref:DownloadItem) to query. + long? id; + + // The absolute URL that this download initiated from, before any + // redirects. + DOMString? url; + + // The absolute URL that this download is being made from, after all + // redirects. + DOMString? finalUrl; + + // Absolute local path. + DOMString? filename; + + // Indication of whether this download is thought to be safe or known to be + // suspicious. + DangerType? danger; + + // The file's MIME type. + DOMString? mime; + + // The time when the download began in ISO 8601 format. + DOMString? startTime; + + // The time when the download ended in ISO 8601 format. + DOMString? endTime; + + // Indicates whether the download is progressing, interrupted, or complete. + State? state; + + // True if the download has stopped reading data from the host, but kept the + // connection open. + boolean? paused; + + // Why a download was interrupted. + InterruptReason? error; + + // Number of bytes received so far from the host, without considering file + // compression. + double? bytesReceived; + + // Number of bytes in the whole file, without considering file compression, + // or -1 if unknown. + double? totalBytes; + + // Number of bytes in the whole file post-decompression, or -1 if unknown. + double? fileSize; + + // Whether the downloaded file exists; + boolean? exists; + }; + + dictionary StringDelta { + DOMString? previous; + DOMString? current; + }; + + dictionary DoubleDelta { + double? previous; + double? current; + }; + + dictionary BooleanDelta { + boolean? previous; + boolean? current; + }; + + // Encapsulates a change in a DownloadItem. + [inline_doc] dictionary DownloadDelta { + // The id of the $(ref:DownloadItem) + // that changed. + long id; + + // The change in url, if any. + StringDelta? url; + + // The change in finalUrl, if any. + StringDelta? finalUrl; + + // The change in filename, if any. + StringDelta? filename; + + // The change in danger, if any. + StringDelta? danger; + + // The change in mime, if any. + StringDelta? mime; + + // The change in startTime, if any. + StringDelta? startTime; + + // The change in endTime, if any. + StringDelta? endTime; + + // The change in state, if any. + StringDelta? state; + + // The change in canResume, if any. + BooleanDelta? canResume; + + // The change in paused, if any. + BooleanDelta? paused; + + // The change in error, if any. + StringDelta? error; + + // The change in totalBytes, if any. + DoubleDelta? totalBytes; + + // The change in fileSize, if any. + DoubleDelta? fileSize; + + // The change in exists, if any. + BooleanDelta? exists; + }; + + [inline_doc] dictionary GetFileIconOptions { + // The size of the returned icon. The icon will be square with dimensions + // size * size pixels. The default and largest size for the icon is 32x32 + // pixels. The only supported sizes are 16 and 32. It is an error to specify + // any other size. + long? size; + }; + + // Encapsulates a change in the download UI. + [inline_doc] dictionary UiOptions { + // Enable or disable the download UI. + boolean enabled; + }; + + callback DownloadCallback = void(long downloadId); + callback SearchCallback = void(DownloadItem[] results); + callback EraseCallback = void(long[] erasedIds); + callback NullCallback = void(); + callback GetFileIconCallback = void(optional DOMString iconURL); + callback SuggestFilenameCallback = void( + optional FilenameSuggestion suggestion); + + interface Functions { + // Download a URL. If the URL uses the HTTP[S] protocol, then the request + // will include all cookies currently set for its hostname. If both + // filename and saveAs are specified, then the + // Save As dialog will be displayed, pre-populated with the specified + // filename. If the download started successfully, + // callback will be called with the new $(ref:DownloadItem)'s + // downloadId. If there was an error starting the download, + // then callback will be called with + // downloadId=undefined and $(ref:runtime.lastError) will contain + // a descriptive string. The error strings are not guaranteed to remain + // backwards compatible between releases. Extensions must not parse it. + // |options|: What to download and how. + // |callback|: Called with the id of the new $(ref:DownloadItem). + static void download( + DownloadOptions options, + optional DownloadCallback callback); + + // Find $(ref:DownloadItem). Set query to the empty object to get + // all $(ref:DownloadItem). To get a specific $(ref:DownloadItem), set only the + // id field. To page through a large number of items, set + // orderBy: ['-startTime'], set limit to the + // number of items per page, and set startedAfter to the + // startTime of the last item from the last page. + static void search( + DownloadQuery query, + SearchCallback callback); + + // Pause the download. If the request was successful the download is in a + // paused state. Otherwise $(ref:runtime.lastError) contains an error message. + // The request will fail if the download is not active. + // |downloadId|: The id of the download to pause. + // |callback|: Called when the pause request is completed. + static void pause( + long downloadId, + optional NullCallback callback); + + // Resume a paused download. If the request was successful the download is + // in progress and unpaused. Otherwise $(ref:runtime.lastError) contains an + // error message. The request will fail if the download is not active. + // |downloadId|: The id of the download to resume. + // |callback|: Called when the resume request is completed. + static void resume( + long downloadId, + optional NullCallback callback); + + // Cancel a download. When callback is run, the download is + // cancelled, completed, interrupted or doesn't exist anymore. + // |downloadId|: The id of the download to cancel. + // |callback|: Called when the cancel request is completed. + static void cancel( + long downloadId, + optional NullCallback callback); + + // Retrieve an icon for the specified download. For new downloads, file + // icons are available after the $(ref:onCreated) event has been received. The + // image returned by this function while a download is in progress may be + // different from the image returned after the download is complete. Icon + // retrieval is done by querying the underlying operating system or toolkit + // depending on the platform. The icon that is returned will therefore + // depend on a number of factors including state of the download, platform, + // registered file types and visual theme. If a file icon cannot be + // determined, $(ref:runtime.lastError) will contain an error message. + // |downloadId|: The identifier for the download. + // |callback|: A URL to an image that represents the download. + static void getFileIcon( + long downloadId, + optional GetFileIconOptions options, + GetFileIconCallback callback); + + // Opens the downloaded file now if the $(ref:DownloadItem) is complete; + // otherwise returns an error through $(ref:runtime.lastError). This method + // requires the "downloads.open" permission in addition to the + // "downloads" permission. An $(ref:onChanged) event fires + // when the item is opened for the first time. This method can only be called + // in response to a user gesture. + // |downloadId|: The identifier for the downloaded file. + static void open(long downloadId, + optional NullCallback callback); + + // Show the downloaded file in its folder in a file manager. + // |downloadId|: The identifier for the downloaded file. + static void show(long downloadId); + + // Show the default Downloads folder in a file manager. + static void showDefaultFolder(); + + // Erase matching $(ref:DownloadItem) from history without deleting the + // downloaded file. An $(ref:onErased) event will fire for each + // $(ref:DownloadItem) that matches query, then + // callback will be called. + static void erase( + DownloadQuery query, + optional EraseCallback callback); + + // Remove the downloaded file if it exists and the $(ref:DownloadItem) is + // complete; otherwise return an error through $(ref:runtime.lastError). + static void removeFile( + long downloadId, + optional NullCallback callback); + + // Prompt the user to accept a dangerous download. Can only be called from a + // visible context (tab, window, or page/browser action popup). Does not + // automatically accept dangerous downloads. If the download is accepted, + // then an $(ref:onChanged) event will fire, otherwise nothing will happen. + // When all the data is fetched into a temporary file and either the + // download is not dangerous or the danger has been accepted, then the + // temporary file is renamed to the target filename, the |state| changes to + // 'complete', and $(ref:onChanged) fires. + // |downloadId|: The identifier for the $(ref:DownloadItem). + // |callback|: Called when the danger prompt dialog closes. + static void acceptDanger( + long downloadId, + optional NullCallback callback); + + // Enable or disable the gray shelf at the bottom of every window associated + // with the current browser profile. The shelf will be disabled as long as + // at least one extension has disabled it. Enabling the shelf while at least + // one other extension has disabled it will return an error through + // $(ref:runtime.lastError). Requires the "downloads.shelf" + // permission in addition to the "downloads" permission. + [deprecated="Use $(ref:setUiOptions) instead."] + static void setShelfEnabled(boolean enabled); + + // Change the download UI of every window associated with the current + // browser profile. As long as at least one extension has set + // $(ref:UiOptions.enabled) to false, the download UI will be hidden. + // Setting $(ref:UiOptions.enabled) to true while at least one other + // extension has disabled it will return an error through + // $(ref:runtime.lastError). Requires the "downloads.ui" + // permission in addition to the "downloads" permission. + // |options|: Encapsulate a change to the download UI. + // |callback|: Called when the UI update is completed. + static void setUiOptions( + UiOptions options, + optional NullCallback callback); + }; + + interface Events { + // This event fires with the $(ref:DownloadItem) object when a download + // begins. + static void onCreated(DownloadItem downloadItem); + + // Fires with the downloadId when a download is erased from + // history. + // |downloadId|: The id of the $(ref:DownloadItem) that was + // erased. + static void onErased(long downloadId); + + // When any of a $(ref:DownloadItem)'s properties except + // bytesReceived and estimatedEndTime changes, + // this event fires with the downloadId and an object + // containing the properties that changed. + static void onChanged(DownloadDelta downloadDelta); + + // During the filename determination process, extensions will be given the + // opportunity to override the target $(ref:DownloadItem.filename). Each + // extension may not register more than one listener for this event. Each + // listener must call suggest exactly once, either + // synchronously or asynchronously. If the listener calls + // suggest asynchronously, then it must return + // true. If the listener neither calls suggest + // synchronously nor returns true, then suggest + // will be called automatically. The $(ref:DownloadItem) will not complete + // until all listeners have called suggest. Listeners may call + // suggest without any arguments in order to allow the download + // to use downloadItem.filename for its filename, or pass a + // suggestion object to suggest in order to + // override the target filename. If more than one extension overrides the + // filename, then the last extension installed whose listener passes a + // suggestion object to suggest wins. In order to + // avoid confusion regarding which extension will win, users should not + // install extensions that may conflict. If the download is initiated by + // $(ref:download) and the target filename is known before the MIME type and + // tentative filename have been determined, pass filename to + // $(ref:download) instead. + [maxListeners=1] static void onDeterminingFilename( + DownloadItem downloadItem, SuggestFilenameCallback suggest); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/downloads_internal.idl b/tools/under-control/src/chrome/common/extensions/api/downloads_internal.idl new file mode 100755 index 000000000..aa75a073d --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/downloads_internal.idl @@ -0,0 +1,14 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// downloadsInternal +[nodoc=true] +namespace downloadsInternal { + interface Functions { + // Secretly called when onDeterminingFilename handlers return. + static void determineFilename(long downloadId, + DOMString filename, + DOMString conflict_action); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/enterprise_device_attributes.idl b/tools/under-control/src/chrome/common/extensions/api/enterprise_device_attributes.idl new file mode 100755 index 000000000..d98920391 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/enterprise_device_attributes.idl @@ -0,0 +1,61 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.enterprise.deviceAttributes API to read device +// attributes. +// Note: This API is only available to extensions force-installed by enterprise +// policy. +namespace enterprise.deviceAttributes { + callback GetDirectoryDeviceIdCallback = void (DOMString deviceId); + + callback GetDeviceSerialNumberCallback = void (DOMString serialNumber); + + callback GetDeviceAssetIdCallback = void (DOMString assetId); + + callback GetDeviceAnnotatedLocationCallback = void (DOMString annotatedLocation); + + callback GetDeviceHostnameCallback = void (DOMString hostname); + + interface Functions { + // Fetches the value of + // the device identifier of the directory API, + // that is generated by the server and identifies the cloud record of the + // device for querying in the cloud directory API. + // If the current user is not affiliated, returns an empty string. + // |callback| : Called with the device identifier of the directory API when + // received. + void getDirectoryDeviceId( + GetDirectoryDeviceIdCallback callback); + + // Fetches the device's serial number. Please note the purpose of this API + // is to administrate the device (e.g. generating Certificate Sign Requests + // for device-wide certificates). This API may not be used for tracking + // devices without the consent of the device's administrator. + // If the current user is not affiliated, returns an empty string. + // |callback| : Called with the serial number of the device. + void getDeviceSerialNumber( + GetDeviceSerialNumberCallback callback); + + // Fetches the administrator-annotated Asset Id. + // If the current user is not affiliated or no Asset Id has been set by the + // administrator, returns an empty string. + // |callback| : Called with the Asset ID of the device. + void getDeviceAssetId(GetDeviceAssetIdCallback callback); + + // Fetches the administrator-annotated Location. + // If the current user is not affiliated or no Annotated Location has been + // set by the administrator, returns an empty string. + // |callback| : Called with the Annotated Location of the device. + void getDeviceAnnotatedLocation( + GetDeviceAnnotatedLocationCallback callback); + + // Fetches the device's hostname as set by DeviceHostnameTemplate policy. + // If the current user is not affiliated or no hostname has been set by the + // enterprise policy, returns an empty string. + // |callback| : Called with hostname of the device. + void getDeviceHostname( + GetDeviceHostnameCallback callback); + }; + +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/enterprise_hardware_platform.idl b/tools/under-control/src/chrome/common/extensions/api/enterprise_hardware_platform.idl new file mode 100755 index 000000000..e3b1adb8e --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/enterprise_hardware_platform.idl @@ -0,0 +1,24 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.enterprise.hardwarePlatform API to get the +// manufacturer and model of the hardware platform where the browser runs. +// Note: This API is only available to extensions installed by enterprise +// policy. +namespace enterprise.hardwarePlatform { + dictionary HardwarePlatformInfo { + DOMString model; + DOMString manufacturer; + }; + + callback HardwarePlatformInfoCallback = void(HardwarePlatformInfo info); + + interface Functions { + // Obtains the manufacturer and model for the hardware platform and, if + // the extension is authorized, returns it via |callback|. + // |callback|: Called with the hardware platform info. + static void getHardwarePlatformInfo( + HardwarePlatformInfoCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/enterprise_kiosk_input.idl b/tools/under-control/src/chrome/common/extensions/api/enterprise_kiosk_input.idl new file mode 100755 index 000000000..356628e03 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/enterprise_kiosk_input.idl @@ -0,0 +1,36 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.enterprise.kioskInput API to change input +// settings for Kiosk sessions. +// Note: This API is only available to extensions installed by enterprise +// policy in ChromeOS Kiosk sessions. +[platforms = ("chromeos", "lacros"), + implemented_in = "chrome/browser/extensions/api/enterprise_kiosk_input/enterprise_kiosk_input_api.h"] +namespace enterprise.kioskInput { + dictionary SetCurrentInputMethodOptions { + // The input method ID to set as current input method. This input + // method has to be enabled by enterprise policies. Supported IDs + // are located in https://crsrc.org/c/chrome/browser/resources/chromeos/input_method. + DOMString inputMethodId; + }; + + callback SetCurrentInputMethodCallback = void(); + + interface Functions { + // Sets the current input method. This function only changes + // the current input method to an enabled input method. + // Input methods can be enabled by enterprise polices. + // If the input method ID is invalid, or not enabled, + // $(ref:runtime.lastError) will be set with a failure reason. + // |options|: Object containing the fields defined in + // $(ref:SetCurrentInputMethodOptions). + // |callback|: Called when the input method is changed or if + // there is an error. + static void setCurrentInputMethod( + SetCurrentInputMethodOptions options, + SetCurrentInputMethodCallback callback); +}; + +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/enterprise_networking_attributes.idl b/tools/under-control/src/chrome/common/extensions/api/enterprise_networking_attributes.idl new file mode 100755 index 000000000..f52570e6c --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/enterprise_networking_attributes.idl @@ -0,0 +1,34 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.enterprise.networkingAttributes API to read +// information about your current network. +// Note: This API is only available to extensions force-installed by enterprise +// policy. +[platforms = ("chromeos", "lacros"), + implemented_in = "chrome/browser/extensions/api/enterprise_networking_attributes/enterprise_networking_attributes_api.h"] +namespace enterprise.networkingAttributes { + [noinline_doc] dictionary NetworkDetails { + // The device's MAC address. + DOMString macAddress; + + // The device's local IPv4 address (undefined if not configured). + DOMString? ipv4; + + // The device's local IPv6 address (undefined if not configured). + DOMString? ipv6; + }; + + callback GetNetworkDetailsCallback = void(NetworkDetails networkAddresses); + + interface Functions { + // Retrieves the network details of the device's default network. + // If the user is not affiliated or the device is not connected to a + // network, $(ref:runtime.lastError) will be set with a failure reason. + // |callback| : Called with the device's default network's + // $(ref:NetworkDetails). + void getNetworkDetails( + GetNetworkDetailsCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/enterprise_platform_keys.idl b/tools/under-control/src/chrome/common/extensions/api/enterprise_platform_keys.idl new file mode 100755 index 000000000..3e26da0b5 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/enterprise_platform_keys.idl @@ -0,0 +1,230 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.enterprise.platformKeys API to generate keys and +// install certificates for these keys. The certificates will be managed by the +// platform and can be used for TLS authentication, network access or by other +// extension through $(ref:platformKeys chrome.platformKeys). +[platforms = ("chromeos", "lacros")] +namespace enterprise.platformKeys { + [nocompile, noinline_doc] dictionary Token { + // Uniquely identifies this Token. + //

Static IDs are "user" and "system", + // referring to the platform's user-specific and the system-wide hardware + // token, respectively. Any other tokens (with other identifiers) might be + // returned by $(ref:enterprise.platformKeys.getTokens).

+ DOMString id; + + // Implements the WebCrypto's + // SubtleCrypto + // interface. The cryptographic operations, including key generation, are + // hardware-backed. + //

Only non-extractable RSASSA-PKCS1-V1_5 keys with + // modulusLength up to 2048 and ECDSA with + // namedCurve P-256 can be generated. Each key can be + // used for signing data at most once.

+ //

Keys generated on a specific Token cannot be used with + // any other Tokens, nor can they be used with + // window.crypto.subtle. Equally, Key objects + // created with window.crypto.subtle cannot be used with this + // interface.

+ [instanceOf = SubtleCrypto] object subtleCrypto; + + // Implements the WebCrypto's + // SubtleCrypto + // interface. The cryptographic operations, including key generation, are + // software-backed. Protection of the keys, and thus implementation of the + // non-extractable property, is done in software, so the keys are less + // protected than hardware-backed keys. + //

Only non-extractable RSASSA-PKCS1-V1_5 keys with + // modulusLength up to 2048 can be generated. Each key can be + // used for signing data at most once.

+ //

Keys generated on a specific Token cannot be used with + // any other Tokens, nor can they be used with + // window.crypto.subtle. Equally, Key objects + // created with window.crypto.subtle cannot be used with this + // interface.

+ [instanceOf = SubtleCrypto] object softwareBackedSubtleCrypto; + }; + + // Whether to use the Enterprise User Key or the Enterprise Machine Key. + enum Scope { USER, MACHINE }; + + // Type of key to generate. + enum Algorithm { RSA, ECDSA }; + + // Invoked by getTokens with the list of available Tokens. + // |tokens|: The list of available tokens. + callback GetTokensCallback = void(Token[] tokens); + + // Callback to which the certificates are passed. + // |certificates|: The list of certificates, each in DER encoding of a X.509 + // certificate. + callback GetCertificatesCallback = void(ArrayBuffer[] certificates); + + // Invoked by importCertificate or removeCertificate when the respective + // operation is finished. + callback DoneCallback = void(); + + // Invoked by challengeMachineKey or + // challengeUserKey with the challenge response. + // |response|: The challenge response. + callback ChallengeCallback = void(ArrayBuffer response); + + dictionary RegisterKeyOptions { + // Which algorithm the registered key should use. + Algorithm algorithm; + }; + + dictionary ChallengeKeyOptions { + // A challenge as emitted by the Verified Access Web API. + ArrayBuffer challenge; + // If present, registers the challenged key with the specified + // scope's token. The key can then be associated with a + // certificate and used like any other signing key. Subsequent calls to + // this function will then generate a new Enterprise Key in the specified + // scope. + RegisterKeyOptions? registerKey; + // Which Enterprise Key to challenge. + Scope scope; + }; + + + interface Functions { + // Returns the available Tokens. In a regular user's session the list will + // always contain the user's token with id "user". + // If a system-wide TPM token is available, the returned list will also + // contain the system-wide token with id "system". + // The system-wide token will be the same for all sessions on this device + // (device in the sense of e.g. a Chromebook). + [nocompile] static void getTokens(GetTokensCallback callback); + + // Returns the list of all client certificates available from the given + // token. Can be used to check for the existence and expiration of client + // certificates that are usable for a certain authentication. + // |tokenId|: The id of a Token returned by getTokens. + // |callback|: Called back with the list of the available certificates. + static void getCertificates(DOMString tokenId, + GetCertificatesCallback callback); + + // Imports certificate to the given token if the certified key + // is already stored in this token. + // After a successful certification request, this function should be used to + // store the obtained certificate and to make it available to the operating + // system and browser for authentication. + // |tokenId|: The id of a Token returned by getTokens. + // |certificate|: The DER encoding of a X.509 certificate. + // |callback|: Called back when this operation is finished. + static void importCertificate(DOMString tokenId, + ArrayBuffer certificate, + optional DoneCallback callback); + + // Removes certificate from the given token if present. + // Should be used to remove obsolete certificates so that they are not + // considered during authentication and do not clutter the certificate + // choice. Should be used to free storage in the certificate store. + // |tokenId|: The id of a Token returned by getTokens. + // |certificate|: The DER encoding of a X.509 certificate. + // |callback|: Called back when this operation is finished. + static void removeCertificate(DOMString tokenId, + ArrayBuffer certificate, + optional DoneCallback callback); + + // Similar to challengeMachineKey and + // challengeUserKey, but allows specifying the algorithm of a + // registered key. Challenges a hardware-backed Enterprise Machine Key and + // emits the response as part of a remote attestation protocol. Only useful + // on Chrome OS and in conjunction with the Verified Access Web API which + // both issues challenges and verifies responses. + // + // A successful verification by the Verified Access Web API is a strong + // signal that the current device is a legitimate Chrome OS device, the + // current device is managed by the domain specified during verification, + // the current signed-in user is managed by the domain specified during + // verification, and the current device state complies with enterprise + // device policy. For example, a policy may specify that the device must not + // be in developer mode. Any device identity emitted by the verification is + // tightly bound to the hardware of the current device. If + // "user" Scope is specified, the identity is also tighly bound + // to the current signed-in user. + // + // This function is highly restricted and will fail if the current device is + // not managed, the current user is not managed, or if this operation has + // not explicitly been enabled for the caller by enterprise device policy. + // The challenged key does not reside in the "system" or + // "user" token and is not accessible by any other API. + // |options|: Object containing the fields defined in + // $(ref:ChallengeKeyOptions). + // |callback|: Called back with the challenge response. + static void challengeKey(ChallengeKeyOptions options, + ChallengeCallback callback); + + // Challenges a hardware-backed Enterprise Machine Key and emits the + // response as part of a remote attestation protocol. Only useful on Chrome + // OS and in conjunction with the Verified Access Web API which both issues + // challenges and verifies responses. A successful verification by the + // Verified Access Web API is a strong signal of all of the following: + // * The current device is a legitimate Chrome OS device. + // * The current device is managed by the domain specified during + // verification. + // * The current signed-in user is managed by the domain specified during + // verification. + // * The current device state complies with enterprise device policy. For + // example, a policy may specify that the device must not be in developer + // mode. + // * Any device identity emitted by the verification is tightly bound to the + // hardware of the current device. + // This function is highly restricted and will fail if the current device + // is not managed, the current user is not managed, or if this operation + // has not explicitly been enabled for the caller by enterprise device + // policy. The Enterprise Machine Key does not reside in the + // "system" token and is not accessible by any other API. + // |challenge|: A challenge as emitted by the Verified Access Web API. + // |registerKey|: If set, the current Enterprise Machine Key is registered + // with the "system" token and relinquishes the + // Enterprise Machine Key role. The key can then be + // associated with a certificate and used like any other + // signing key. This key is 2048-bit RSA. Subsequent calls + // to this function will then generate a new Enterprise + // Machine Key. + // |callback|: Called back with the challenge response. + [deprecated="Use $(ref:challengeKey) instead."] + static void challengeMachineKey(ArrayBuffer challenge, + optional boolean registerKey, + ChallengeCallback callback); + + // Challenges a hardware-backed Enterprise User Key and emits the response + // as part of a remote attestation protocol. Only useful on Chrome OS and in + // conjunction with the Verified Access Web API which both issues challenges + // and verifies responses. A successful verification by the Verified Access + // Web API is a strong signal of all of the following: + // * The current device is a legitimate Chrome OS device. + // * The current device is managed by the domain specified during + // verification. + // * The current signed-in user is managed by the domain specified during + // verification. + // * The current device state complies with enterprise user policy. For + // example, a policy may specify that the device must not be in developer + // mode. + // * The public key emitted by the verification is tightly bound to the + // hardware of the current device and to the current signed-in user. + // This function is highly restricted and will fail if the current device is + // not managed, the current user is not managed, or if this operation has + // not explicitly been enabled for the caller by enterprise user policy. + // The Enterprise User Key does not reside in the "user" token + // and is not accessible by any other API. + // |challenge|: A challenge as emitted by the Verified Access Web API. + // |registerKey|: If set, the current Enterprise User Key is registered with + // the "user" token and relinquishes the + // Enterprise User Key role. The key can then be associated + // with a certificate and used like any other signing key. + // This key is 2048-bit RSA. Subsequent calls to this + // function will then generate a new Enterprise User Key. + // |callback|: Called back with the challenge response. + [deprecated="Use $(ref:challengeKey) instead."] + static void challengeUserKey(ArrayBuffer challenge, + boolean registerKey, + ChallengeCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/enterprise_platform_keys_internal.idl b/tools/under-control/src/chrome/common/extensions/api/enterprise_platform_keys_internal.idl new file mode 100755 index 000000000..73f84feea --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/enterprise_platform_keys_internal.idl @@ -0,0 +1,60 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Internal API for platform keys and certificate management. +[ platforms = ("chromeos", "lacros"), + implemented_in = "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" ] +namespace enterprise.platformKeysInternal { + dictionary Hash { + DOMString name; + }; + + // For more information about the RSA key generation parameters, please refer + // to: https://www.w3.org/TR/WebCryptoAPI/#RsaHashedKeyGenParams-dictionary + // For more information about the ECDSA key generation parameters, please + // refer to: https://www.w3.org/TR/WebCryptoAPI/#dfn-EcdsaParams + // Note: |hash| is not used by generateKey() but is added to completely + // mirror WebCrypto in using RsaHashedKeyAlgorithm to be able to wrap all + // parameters in one structure. + dictionary Algorithm { + // Provided for all algorithms. + DOMString name; + + // Provided in case of RSASSA-PKCS1-v1_5. + long? modulusLength; + ArrayBuffer? publicExponent; + Hash? hash; + + // Provided in case of ECDSA. + DOMString? namedCurve; + }; + + // Invoked by getTokens. + // |tokenIds| The list of IDs of the avialable Tokens. + callback GetTokensCallback = void(DOMString[] tokenIds); + + // Invoked by generateKey. + // |publicKey| The Subject Public Key Info (see X.509) of the generated key + // in DER encoding. + callback GenerateKeyCallback = void(ArrayBuffer publicKey); + + interface Functions { + // Internal version of entrprise.platformKeys.getTokens. Returns a list of + // token IDs instead of token objects. + static void getTokens(GetTokensCallback callback); + + // Internal version of Token.generateKey, currently supporting only + // RSASSA-PKCS1-v1_5 and ECDSA. + // |tokenId| The id of a Token returned by |getTokens|. + // |algorithm| The algorithm parameters as specified by WebCrypto. + // |softwareBacked| Whether the key operations should be executed in + // software. + // |callback| Called back with the Subject Public Key Info of the generated + // key. + static void generateKey(DOMString tokenId, + Algorithm algorithm, + boolean softwareBacked, + GenerateKeyCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/enterprise_reporting_private.idl b/tools/under-control/src/chrome/common/extensions/api/enterprise_reporting_private.idl new file mode 100755 index 000000000..40b8965cf --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/enterprise_reporting_private.idl @@ -0,0 +1,407 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Private API for reporting Chrome browser status to admin console. +namespace enterprise.reportingPrivate { + + // Invoked by UploadChromeDesktopReport when the upload is + // finished. + // Also Invoked by setDeviceData when data is stored. + [platforms = ("win", "mac", "linux")] + callback DoneCallback = void(); + + // Invoked by getDeviceId to return the ID. + [platforms = ("win", "mac", "linux")] + callback GetDeviceIdCallback = void(DOMString id); + + // Invoked by getPersistentSecret to return the secret. + [platforms = ("win", "mac")] + callback GetPersistentSecretCallback = void(ArrayBuffer secret); + + // Invoked by getDeviceDataCallback to return the device data. + [platforms = ("win", "mac", "linux")] + callback GetDeviceDataCallback = void(ArrayBuffer data); + + // Possible states a particular device setting can be in. + [platforms = ("win", "mac", "linux")] + enum SettingValue { UNKNOWN, DISABLED, ENABLED }; + + // Device info fields returned by the getDeviceInfo API. + [platforms = ("win", "mac", "linux")] + dictionary DeviceInfo { + DOMString osName; + DOMString osVersion; + DOMString deviceHostName; + DOMString deviceModel; + DOMString serialNumber; + SettingValue screenLockSecured; + SettingValue diskEncrypted; + DOMString[] macAddresses; + DOMString? windowsMachineDomain; + DOMString? windowsUserDomain; + DOMString securityPatchLevel; + + // This value is only returned on Windows for now. + SettingValue? secureBootEnabled; + }; + + // Invoked by getDeviceInfo to return device information. + [platforms = ("win", "mac", "linux")] + callback GetDeviceInfoCallback = void(DeviceInfo deviceInfo); + + // Possible states for the EnterpriseRealTimeUrlCheckMode policy. + enum RealtimeUrlCheckMode { DISABLED, ENABLED_MAIN_FRAME }; + + // Possible states for the SafeBrowsingProtectionLevel policy. + enum SafeBrowsingLevel { DISABLED, STANDARD, ENHANCED }; + + // Possible states for the PasswordProtectionWarningTrigger policy + enum PasswordProtectionTrigger { + PASSWORD_PROTECTION_OFF, + PASSWORD_REUSE, + PHISHING_REUSE, + POLICY_UNSET + }; + + // Context info fields returned by the getContextInfo API. + dictionary ContextInfo { + DOMString[] browserAffiliationIds; + DOMString[] profileAffiliationIds; + DOMString[] onFileAttachedProviders; + DOMString[] onFileDownloadedProviders; + DOMString[] onBulkDataEntryProviders; + DOMString[] onPrintProviders; + RealtimeUrlCheckMode realtimeUrlCheckMode; + DOMString[] onSecurityEventProviders; + DOMString browserVersion; + SafeBrowsingLevel safeBrowsingProtectionLevel; + boolean siteIsolationEnabled; + boolean builtInDnsClientEnabled; + PasswordProtectionTrigger passwordProtectionWarningTrigger; + boolean chromeRemoteDesktopAppBlocked; + boolean? thirdPartyBlockingEnabled; + SettingValue osFirewall; + DOMString[] systemDnsServers; + DOMString? enterpriseProfileId; + }; + + // Invoked by getContextInfo to return context information. + callback GetContextInfoCallback = void(ContextInfo contextInfo); + + // The status passed to the callback of getCertificate to + // indicate if the required policy is set. + enum CertificateStatus { OK, POLICY_UNSET }; + + // The certificate, if one meets the requirements, returned by the + // $(ref:getCertificate) API. encodedCertificate will be + // the DER encoding (binary encoding following X.690 Distinguished Encoding + // Rules) of the X.509 certificate. + dictionary Certificate { + CertificateStatus status; + ArrayBuffer? encodedCertificate; + }; + + // Invoked by getCertificate to return the selected certificate. + callback CertificateCallback = void(Certificate certificate); + + // Captures the type of event so it can be associated with user or device in + // Chrome for reporting purposes + [platforms = ("chromeos", "lacros")] + enum EventType { DEVICE, USER }; + + // Composite object that captures the information we need to report events. + // Some fields like the record and priority are serialized to avoid any + // dependency on proto definitions here, given the fact that they will likely + // change in the future. These will be deserialized and validated in Chrome. + [platforms = ("chromeos", "lacros")] + dictionary EnqueueRecordRequest { + // Serialized record data binary based on the proto definition in + // //components/reporting/proto/synced/record.proto. + [instanceOf=Uint8Array] ArrayBufferView recordData; + // Serialized priority based on the proto definition in + // //components/reporting/proto/synced/record_constants.proto. Used to + // determine which records are shed first. + long priority; + EventType eventType; + }; + + // Context object containing the content-area user's ID for whom the signals + // collection request is for. This will be used to identify the organization + // in which the user is, and can then be used to determine their affiliation + // with the current browser management state. + [platforms = ("win")] + dictionary UserContext { + DOMString userId; + }; + + // Enumeration of the various states an AntiVirus software product can be in. + [platforms = ("win")] + enum AntiVirusProductState { ON, OFF, SNOOZED, EXPIRED }; + + // Metadata about a specific AntiVirus software product. + [platforms = ("win")] + dictionary AntiVirusSignal { + DOMString displayName; + DOMString productId; + AntiVirusProductState state; + }; + + // Invoked by getAvInfo to return information about installed + // AntiVirus software. + [platforms = ("win")] + callback AvInfoCallback = void(AntiVirusSignal[] avSignals); + + // ID of an installed hotfix system update. + [platforms = ("win")] + dictionary HotfixSignal { + DOMString hotfixId; + }; + + // Invoked by getHotfixes to return the IDs of installed hotfix + // system updates. + [platforms = ("win")] + callback HotfixesCallback = void(HotfixSignal[] hotfixSignals); + + // Used to indicate whether a given signal was correctly found or not, or + // indicate a reason for not being able to find it. + [platforms = ("win", "mac", "linux")] + enum PresenceValue { + // Was unable to determine whether the signal source exists or not. This + // typically indicates that a failure occurred before even trying to assess + // its presence. + UNSPECIFIED, + + // Current user does not have access to the signal's source. + ACCESS_DENIED, + + // The resource was not found. + NOT_FOUND, + + // The resource was found. + FOUND + }; + + // Parameter used to collect information about a specific file system + // resource. + [platforms = ("win", "mac", "linux")] + dictionary GetFileSystemInfoOptions { + DOMString path; + boolean computeSha256; + boolean computeExecutableMetadata; + }; + + [platforms = ("win", "mac", "linux")] + dictionary GetFileSystemInfoRequest { + // Information about the for whom the signal collection request is for. + UserContext userContext; + + // Collection of parameters used to conduct signals collection about + // specific file system resources. + GetFileSystemInfoOptions[] options; + }; + + [platforms = ("win", "mac", "linux")] + dictionary GetFileSystemInfoResponse { + // Path to the file system object for whom those signals were collected. + DOMString path; + + // Value indicating whether the specific resource could be found or not. + PresenceValue presence; + + // Sha256 hash of a file's bytes. Ignored when path points to a + // directory. Collected only when computeSha256 is set to true in the + // given signals collection parameters. + DOMString? sha256Hash; + + // Set of properties only relevant for executable files. Will only be + // collected if computeExecutableMetadata is set to true in the given + // signals collection parameters and if path points to an executable file. + + // Is true if a currently running process was spawned from this file. + boolean? isRunning; + + // SHA-256 hashes of the public keys of the certificates used to sign the + // executable. A hash is computed over the DER-encoded SubjectPublicKeyInfo + // representation of the key. + DOMString[]? publicKeysHashes; + + // Product name of this executable. + DOMString? productName; + + // Version of this executable. + DOMString? version; + }; + + [platforms = ("win", "mac", "linux")] + callback FileSystemInfoCallback = + void(GetFileSystemInfoResponse[] fileSystemSignals); + + [platforms = ("win")] + enum RegistryHive { + HKEY_CLASSES_ROOT, + HKEY_LOCAL_MACHINE, + HKEY_CURRENT_USER + }; + + [platforms = ("win", "mac")] + dictionary GetSettingsOptions { + // Path to a collection of settings. + // On Windows it would be the path to the reg key inside the hive. + // On Mac it would be the path to the plist file. + DOMString path; + + // Key specifying the setting entry we're looking for. + // On Windows, that will be the registry key itself. + // On Mac, this is a key path used to retrieve a value from + // valueForKeyPath:. + DOMString key; + + // When set to true, the retrieved signal will also include the setting's + // value. When false, the signal will only contain the setting's + // presence. + // Supported setting types on Windows: + // - REG_SZ + // - REG_DWORD + // - REG_QWORD + // Supported setting types on Mac: + // - NSString + // - NSNumber + boolean getValue; + + // Windows registry hive containing the desired value. + // Required value on Windows, will be ignored on other platforms. + RegistryHive? hive; + }; + + [platforms = ("win", "mac")] + dictionary GetSettingsRequest { + // Information about the for whom the signal collection request is for. + UserContext userContext; + + // Collection of parameters used to conduct signals collection about + // specific settings of the system. + GetSettingsOptions[] options; + }; + + [platforms = ("win", "mac")] + dictionary GetSettingsResponse { + // Path as given in the corresponding GetSettingsOptions + // request. + DOMString path; + + // Key as given in the corresponding GetSettingsOptions + // request. + DOMString key; + + // Hive as given in the corresponding GetSettingsOptions + // request. + // Present on Windows only. + RegistryHive? hive; + + // Value indicating whether the specific resource could be found or not. + PresenceValue presence; + + // JSON-stringified value of the setting. Only set if getValue + // was true in the corresponding request, and if the setting value was + // retrievable. + DOMString? value; + }; + + [platforms = ("win", "mac")] + callback SettingsCallback = + void(GetSettingsResponse[] settings); + + interface Functions { + // Gets the identity of device that Chrome browser is running on. The ID is + // retrieved from the local device and used by the Google admin console. + [platforms = ("win", "mac", "linux")] + static void getDeviceId(optional GetDeviceIdCallback callback); + + // Gets a randomly generated persistent secret (symmetric key) that + // can be used to encrypt the data stored with |setDeviceData|. If the + // optional parameter |forceCreation| is set to true the secret is recreated + // in case of any failure to retrieve the currently stored one. Sets + // $(ref:runtime.lastError) on failure. + [platforms = ("win", "mac")] + static void getPersistentSecret( + optional boolean resetSecret, + GetPersistentSecretCallback callback); + + // Gets the device data for |id|. Sets $(ref:runtime.lastError) on failure. + [platforms = ("win", "mac", "linux")] + static void getDeviceData(DOMString id, GetDeviceDataCallback callback); + + // Sets the device data for |id|. Sets $(ref:runtime.lastError) on failure. + // If the |data| parameter is undefined and there is already data + // associated with |id| it will be cleared. + [platforms = ("win", "mac", "linux")] + static void setDeviceData( + DOMString id, + optional ArrayBuffer data, + optional DoneCallback callback); + + // Gets the device information (including disk encryption status, + // screen lock status, serial number, model). + [platforms = ("win", "mac", "linux")] + static void getDeviceInfo(GetDeviceInfoCallback callback); + + // Gets the context information (including management status of the browser, + // state of key security policies, browser version). + static void getContextInfo( + GetContextInfoCallback callback); + + // Returns the certificate that would be selected by the filters in the + // AutoSelectCertificateForUrls policy for url. + static void getCertificate( + DOMString url, + CertificateCallback callback); + + // Enqueues a record for upload to the reporting service + // |request|: Composite object that captures everything + // we need for uploading records. + // |callback|: Callback that is triggered upon completion + [platforms = ("chromeos", "lacros")] + static void enqueueRecord( + EnqueueRecordRequest request, + optional DoneCallback callback); + + // Gets information about file system resources, specified by the contents + // of request, on the current device. request must + // hold a user context to be used to verify the affiliation between the + // user's organization and the organization managing the browser. If the + // management or affiliation states are not suitable, no results will be + // returned. + [platforms = ("win", "mac", "linux")] + static void getFileSystemInfo( + GetFileSystemInfoRequest request, + FileSystemInfoCallback callback); + + // Gets information about system settings specified by the contents of + // request. request must hold a user context to be + // used to verify the affiliation between the user's organization and the + // organization managing the browser. If the management or affiliation + // states are not suitable, no results will be returned. + [platforms = ("win", "mac")] + static void getSettings( + GetSettingsRequest request, + SettingsCallback callback); + + // Gets information about AntiVirus software installed on the current + // device. userContext is used to verify the affiliation + // between the user's organization and the organization managing the + // browser. If the management, or affiliation, state is not suitable, no + // results will be returned. + [platforms = ("win")] + static void getAvInfo(UserContext userContext, AvInfoCallback callback); + + // Gets information about hotfix system updates installed on the current + // device. userContext is used to verify the affiliation + // between the user's organization and the organization managing the + // browser. If the management, or affiliation, state is not suitable, no + // results will be returned. + [platforms = ("win")] + static void getHotfixes(UserContext userContext, HotfixesCallback callback); + }; + +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/file_manager_private.idl b/tools/under-control/src/chrome/common/extensions/api/file_manager_private.idl new file mode 100755 index 000000000..59fe9d97c --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/file_manager_private.idl @@ -0,0 +1,2127 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// fileManagerPrivate API. +// This is a private API used by the file manager on ChromeOS. The API can +// roughly be divided into two parts: functions and events. +// +// Functions: The Functions interface defines a number of privileged operations +// that allow File Manager to execute tasks not available via public APIs. Most +// of the time this is due to the fact that enabling those tasks via public APIs +// would allow malicious applications to either take control of the hardware +// or leak private information about the user. None of these API must be exposed +// in any public services. +// +// Events: The Event interface defines a number of events that are supported +// by the API. These events allow one to register, in JavaScript, a listener +// that is invoked with event's parameters, every time the event is observed +// by the file_manager::EventRouter. +// +// Both the functions and events interface are only available to clients that +// are explicitly granted permission to use the fileManagerPrivate API. This +// API is not available to any client without code reviewed changes +// (eg. via _api_features.json) +// +// CAVEAT: An application A registering as a listener to any events must assume +// that an application B can listen to any events that are destined for A, where +// A and B are any applications that are granted access to fileManagerPrivate. +// For example, if applications A and B listen to onDirectoryChanged events on +// two unique paths, they both receive events about changes in either path. This +// is due to the fact that events are broadcasted to ALL listeners. It is the +// responsibility of the listener to discard events not destined for it. It is +// also the responsibility of all listeners not to log information transmitted +// in those events, as it may record in logs information that is private to a +// given user (e.g., the full paths and name of a given file). This API is +// designed with the assumption that all users are equal in terms of their +// permission to observe events, call the function interface and access the file +// system of the device. As the API is only used by Chrome OS' File Manager, and +// the File Manager is being used by the user to access their own files, this +// assumption holds true. +// +// The API defined in this file may use W3C Entry object (FileEntry and +// DirectoryEntry). Since these cannot be directly sent or received by the C++ +// code, there exists an additional layer, in file_manager_private_internal.idl, +// that provides translation from or to W3C Entry objects. +[platforms=("chromeos"), + implemented_in="chrome/browser/ash/extensions/file_manager/file_manager_private_api_functions.h"] +namespace fileManagerPrivate { +// Type of the mounted volume. +enum VolumeType { drive, downloads, removable, archive, provided, mtp, + media_view, crostini, android_files, documents_provider, + testing, smb, system_internal, guest_os }; + +// Device type. Available if this is removable volume. +enum DeviceType { usb, sd, optical, mobile, unknown }; + +// List of device connection statuses. +enum DeviceConnectionState {OFFLINE, ONLINE}; + +// List of connection types of drive. +enum DriveConnectionStateType {OFFLINE, METERED, ONLINE}; + +// List of reasons of DriveConnectionStateType. +enum DriveOfflineReason {NOT_READY, NO_NETWORK, NO_SERVICE}; + +// Additional information of the context the volume was mounted. +enum MountContext { user, auto }; + +// Is the event raised for mounting or unmounting. +enum MountCompletedEventType { mount, unmount }; + +// Event type that tells listeners if mount was successful or an error +// occurred. It also specifies the error. +enum MountError { + success, + in_progress, + unknown_error, + internal_error, + invalid_argument, + invalid_path, + path_already_mounted, + path_not_mounted, + directory_creation_failed, + invalid_mount_options, + insufficient_permissions, + mount_program_not_found, + mount_program_failed, + invalid_device_path, + unknown_filesystem, + unsupported_filesystem, + need_password, + cancelled, + busy +}; + +// Filesystem to format to. +enum FormatFileSystemType { vfat, exfat, ntfs }; + +// File transfer progress state. +enum TransferState { in_progress, queued, completed, failed }; + +// The response when starting installing a Linux package. +enum InstallLinuxPackageStatus { + started, + failed, + install_already_active +}; + +// Specifies type of event that is raised. +enum FileWatchEventType { changed, error }; + +// Specifies type of change in file watch event. +enum ChangeType { add_or_update, delete }; + +// The type of entry that is needed. Default to ALL. +enum SearchType { EXCLUDE_DIRECTORIES, SHARED_WITH_ME, OFFLINE, ALL }; + +// Zooming mode. +enum ZoomOperationType { in, out, reset }; + +// Specifies how to open inspector. +enum InspectionType { + // Open inspector for foreground page. + normal, + // Open inspector for foreground page and bring focus to the console. + console, + // Open inspector for foreground page in inspect element mode. + element, + // Open inspector for background page. + background +}; + +// Device event type. +enum DeviceEventType { + // If the device is disabled by preference. + disabled, + // Device is removed. + removed, + // Device is hard unplugged. + hard_unplugged, + // Format started. + format_start, + // Format succeeded. + format_success, + // Format failed. + format_fail, + // Rename started. + rename_start, + // Rename succeeded. + rename_success, + // Rename failed. + rename_fail, + // Partition started. + partition_start, + // Partition succeeded. + partition_success, + // Partition failed. + partition_fail +}; + +// Drive sync error type. +// Keep it synced with DriveError::Type in drivefs.mojom. +enum DriveSyncErrorType { + // Request to delete a file without permission. + delete_without_permission, + // Google Drive is temporarily unavailable. + service_unavailable, + // There is no server space for the user to sync a file. + no_server_space, + // There is no server space for the organization to sync a file. + no_server_space_organization, + // There is no local space to sync a file. + no_local_space, + // There is no space left on a shared drive. + no_shared_drive_space, + // Miscellaneous errors other than listed above. + misc +}; + +// Drive confirm dialog type. +// Keep it synced with DialogReason::Type in drivefs.mojom. +enum DriveConfirmDialogType { + // Request to enable Docs Offline to allow saving hosted files offline. + enable_docs_offline +}; + +// Possible result of dialog displayed as a result of the onDriveConfirmDialog +// event. Sent back to the browser via notifyDriveDialogResult(). +enum DriveDialogResult { + // The dialog was not displayed to the user. + not_displayed, + // The user accepted the action proposed by the dialog. + accept, + // The user rejected the action proposed by the dialog. + reject, + // The user closed the dialog without selecting an option. + dismiss +}; + +// Result of task execution. If changing, update the strings used in +// ui/file_manager/file_manager/foreground/js/file_tasks.js +enum TaskResult { + // The task execution succeeded and a new window/tab was opened on the current + // desktop. + opened, + // The task execution succeeded and the message was sent to the proper + // extension or app. This could result in a window being opened on a different + // desktop. + message_sent, + // The task execution failed. + failed, + // No URL is specified. + empty, + // The task was a |plugin_vm| task, and the file was in an unshared directory + failed_plugin_vm_directory_not_shared +}; + +// Drive share type. +enum DriveShareType { + can_edit, + can_comment, + can_view +}; + +// Names of properties for getEntryProperties(). +enum EntryPropertyName { + size, + modificationTime, + modificationByMeTime, + thumbnailUrl, + croppedThumbnailUrl, + imageWidth, + imageHeight, + imageRotation, + pinned, + present, + hosted, + availableOffline, + availableWhenMetered, + dirty, + customIconUrl, + contentMimeType, + sharedWithMe, + shared, + starred, + externalFileUrl, + alternateUrl, + shareUrl, + canCopy, + canDelete, + canRename, + canAddChildren, + canShare, + canPin, + isMachineRoot, + isExternalMedia, + isArbitrarySyncFolder, + syncStatus, + progress, + shortcut, + syncCompletedTime +}; + +// Source of the volume data. +enum Source { + file, + device, + network, + system +}; + +// Recent file sources allowed in getRecentFiles(). +enum SourceRestriction { + // Allows any source. + any_source, + + // Allows source with native local file system only. + native_source +}; + +// File categories to filter results from getRecentFiles(). +enum FileCategory { + all, + audio, + image, + video, + document +}; + +enum CrostiniEventType { + enable, + disable, + share, + unshare, + drop_failed_plugin_vm_directory_not_shared +}; + +enum ProviderSource { + file, + device, + network +}; + +enum SharesheetLaunchSource { + context_menu, + sharesheet_button, + unknown +}; + +enum IoTaskState { + queued, + scanning, + in_progress, + paused, + success, + error, + need_password, + cancelled +}; + +enum IoTaskType { + copy, + delete, + empty_trash, + extract, + move, + restore, + restore_to_destination, + trash, + zip +}; + +enum PolicyErrorType { + dlp, + enterprise_connectors, + dlp_warning_timeout +}; + +enum PolicyDialogType { + warning, + error +}; + +enum RecentDateBucket { + today, + yesterday, + earlier_this_week, + earlier_this_month, + earlier_this_year, + older +}; + +enum VmType { termina, plugin_vm, borealis, bruschetta, arcvm }; + +enum UserType { + // User doesn't belong to any organization. + unmanaged, + // User is a member of an organization. + organization +}; + +enum DlpLevel { + // Report every action to the admin, doesn't affect the user. + report, + // Warn the user on every action. + warn, + // Block the user on every action. + block, + // No restriction. + allow +}; + +enum SyncStatus { + // No sync status available for file. + not_found, + // File is queued up for syncing. + queued, + // File is currently being synced. + in_progress, + // File is done syncing. + completed, + // There was an error syncing the file. + error +}; + +// Describes how admin policy affects the default task in a ResultingTasks. +// See chrome/browser/ash/file_manager/file_tasks.h for details. +enum PolicyDefaultHandlerStatus { + default_handler_assigned_by_policy, + incorrect_assignment +}; + +// Describes the stage the bulk pinning manager is in. This enum should be kept +// in sync with chromeos/ash/components/drivefs/mojom/pin_manager_types.mojom. +enum BulkPinStage { + // Initial stage. + stopped, + + // Paused because of unfavorable network conditions. + paused_offline, + // Paused due to battery saver mode active. + paused_battery_saver, + + // In-progress stages. + getting_free_space, + listing_files, + syncing, + + // Final success stage. + success, + + // Final error stages. + not_enough_space, + cannot_get_free_space, + cannot_list_files, + cannot_enable_docs_offline +}; + +// The default location/volume that the user should use. +// It's usually MyFiles. When SkyVault is enabled the admin might +// choose between Google Drive and OneDrive. +// NOTE: This is independent of the Downloads folder which is mostly used +// in the browser (lacros or ash). +enum DefaultLocation { + my_files, + google_drive, + onedrive +}; + +// These three fields together uniquely identify a task. +dictionary FileTaskDescriptor { + DOMString appId; + DOMString taskType; + DOMString actionId; +}; + +// A file task represents an action that the file manager can perform over the +// currently selected files. See chrome/browser/ash/file_manager/file_tasks.h +// for details about how file tasks are handled. +dictionary FileTask { + // Unique identifier for the task. + FileTaskDescriptor descriptor; + + // Task title (ex. App name). + DOMString title; + + // Task icon url (from chrome://extension-icon/...) + DOMString? iconUrl; + + // True if this task is a default task for the selected files. + boolean? isDefault; + + // True if this task is from generic file handler. Generic file handler is a + // file handler which handles any type of files (e.g. extensions: ["*"], + // types: ["*/*"]). Partial wild card (e.g. types: ["image/*"]) is not + // generic file handler. + boolean? isGenericFileHandler; + + // True if this is task is blocked by Data Leak Prevention (DLP). + boolean? isDlpBlocked; +}; + +// Represents a set of tasks capable of handling file entries. +// See chrome/browser/ash/file_manager/file_tasks.h for details. +dictionary ResultingTasks { + FileTask[] tasks; + + // Note that this field is non-null if and only if at least one entry has been affected by policy. + PolicyDefaultHandlerStatus? policyDefaultHandlerStatus; +}; + +// Additional entry properties. +dictionary EntryProperties { + // Size of this file. + double? size; + + // Timestamp of entry update time, in milliseconds past the epoch. + double? modificationTime; + + // Timestamp of entry update time by me, in milliseconds past the epoch. + double? modificationByMeTime; + + // Date bucket calculated by |modificationTime| or |modificationByMeTime|. + RecentDateBucket? recentDateBucket; + + // URL to the Drive thumbnail image for this file. + DOMString? thumbnailUrl; + + // URL to the Drive cropped thumbnail image for this file. + DOMString? croppedThumbnailUrl; + + // Width, if the entry is an image. + long? imageWidth; + + // Height, if the entry is an image. + long? imageHeight; + + // Rotation in clockwise degrees, if the entry is an image. + long? imageRotation; + + // True if the file is pinned in cache. + boolean? pinned; + + // True if the file is present in cache. + boolean? present; + + // True if the file is hosted on a server instead of local. + boolean? hosted; + + // True if the file is available offline. + boolean? availableOffline; + + // True if the file is available on metered connection. + boolean? availableWhenMetered; + + // True if the file has local change (has not been fully synced to the cloud). + boolean? dirty; + + // URL to the custom icon for this file. + DOMString? customIconUrl; + + // Drive MIME type for this file. + DOMString? contentMimeType; + + // True if the entry is labeled as shared-with-me. + boolean? sharedWithMe; + + // True if the entry is labeled as shared (either from me to others or to me + // by others.) + boolean? shared; + + // True if the entry is starred by the user. + boolean? starred; + + // externalfile:// URL to open the file in browser. + DOMString? externalFileUrl; + + // https:// URL to open the file or folder in the Drive website. + DOMString? alternateUrl; + + // https:// URL to open the file or folder in the Drive website with the + // sharing dialog open. + DOMString? shareUrl; + + // True if the entry can be copied by the user. + boolean? canCopy; + + // True if the entry can be deleted by the user. + boolean? canDelete; + + // True if the entry can be renamed by the user. + boolean? canRename; + + // True if the entry can have children added to it by the user (directories + // only). + boolean? canAddChildren; + + // True if the entry can be shared by the user. + boolean? canShare; + + // True if the entry can be pinned by the user. + boolean? canPin; + + // True if the entry is a machine root for backup and sync. + boolean? isMachineRoot; + + // True if the entry is a external media folder, that contains one time only + // uploads for USB devices, SD cards etc. + boolean? isExternalMedia; + + // True if the entry is an arbitrary sync folder. + boolean? isArbitrarySyncFolder; + + // Sync status for files tracked by different cloud filesystem providers. + SyncStatus? syncStatus; + + // Progress representing some ongoing operation with the file. + // E.g., pasting, syncing. Note: currently, this is exclusively being used + // for Drive syncing. + double? progress; + + // Time in milliseconds since the epoch when the file last received a + // "completed" sync status. + double? syncCompletedTime; + + // True if the entry is a shortcut. + boolean? shortcut; +}; + +// Information about total and remaining size on the mount point. +dictionary MountPointSizeStats { + // Approximate total available size on the mount point. + double totalSize; + + // Approximate remaining available size on the mount point. + double remainingSize; +}; + +dictionary SearchDriveResponse { + // Search results. + [instanceOf=Entry] object[] entries; + + // ID of the feed that contains next chunk of the search result. + // Should be sent to the next searchDrive request to perform + // incremental search. + DOMString nextFeed; +}; + +// Free and total space available in Drive relative to both the user and their +// organization, if they belong to one. +dictionary DriveQuotaMetadata { + UserType userType; + + // How much space the individual user, or shared drive has used. + double usedBytes; + // The individual user, or shared drive limit. -1 means infinite. + double totalBytes; + + // The following two fields only have meaning if user_type is kOrganization. + // Whether the organization has exceeded its storage limit. + boolean organizationLimitExceeded; + // Name of the organization the user belongs to. + DOMString organizationName; +}; + +// Information about a profile. +dictionary ProfileInfo { + // Profile ID. This is currently e-mail address of the profile. + DOMString profileId; + + // The name of the profile for display purpose. + DOMString displayName; + + // True if the profile is the one running the current file manager instance. + // TODO(hirono): Remove the property because of the design change of + // multi-profile suuport. + boolean isCurrentProfile; +}; + +// The return data for getProfiles() API. +dictionary ProfilesResponse { + // List of profile information. + ProfileInfo[] profiles; + + // ID of the profile that runs the application instance. + DOMString currentProfileId; + + // ID of the profile that shows the application window. + DOMString displayedProfileId; +}; + +// Represents an icon in multiple dimensions. All are optional. +dictionary IconSet { + DOMString? icon16x16Url; + DOMString? icon32x32Url; +}; + +// Mounted disk volume metadata. +dictionary VolumeMetadata { + // ID of the disk volume. + DOMString volumeId; + + // Id the provided file system (for provided file systems). + DOMString? fileSystemId; + + // ID of the provider, if the volume is backed by FSP. + DOMString? providerId; + + // Source of the volume's data. + Source source; + + // Label of the volume (if available). + DOMString? volumeLabel; + + // Description of the profile where the volume belongs. + // TODO(hirono): Remove the property because of the design change of + // multi-profile support. + ProfileInfo profile; + + // The path to the mounted device, archive file or network resource. + DOMString? sourcePath; + + // Type of the mounted volume. + VolumeType volumeType; + + // Device type. Available if this is removable volume. + DeviceType? deviceType; + + // Path to identify the device. This is consistent with DeviceEvent's + // devicePath. + DOMString? devicePath; + + // Whether the device is parent or not (i.e. sdb rather than sdb1). + boolean? isParentDevice; + + // Flag that specifies if volume is mounted in read-only mode. + boolean isReadOnly; + + // Flag that specifies if the device is write-protected. + // Valid only for the volumes of removable device partitions. + boolean isReadOnlyRemovableDevice; + + // Flag that specifies whether the volume contains media. + boolean hasMedia; + + // Flag that specifies whether the volume is configurable. + boolean configurable; + + // Flag that specifies whether the volume is watchable. + boolean watchable; + + // Additional data about mount, for example, that the filesystem is not + // supported. + MountError? mountCondition; + + // Context in which the volume has been mounted. + MountContext? mountContext; + + // File system type indentifier. + DOMString? diskFileSystemType; + + // Icons for the volume. + IconSet iconSet; + + // Drive label of the volume. Removable partitions that belong to the + // same physical removable device share the same drive label. + DOMString? driveLabel; + + // The path on the remote host where this volume is mounted, for crostini this + // is the user's homedir (/home/). + DOMString? remoteMountPath; + + // Flag that specifies whether the volume is hidden from the user. + boolean hidden; + + // Type of the VM which owns this volume. + VmType? vmType; +}; + +// Payload data for mount event. +dictionary MountCompletedEvent { + // Is the event raised for mounting or unmounting. + MountCompletedEventType eventType; + + // Event type that tells listeners if mount was successful or an error + // occurred. It also specifies the error. + MountError status; + + // Metadata of the mounted volume. + VolumeMetadata volumeMetadata; + + // Whether the volume event should be notified or not. + boolean shouldNotify; +}; + +// Payload data for aggregate file transfer status updates. +dictionary FileTransferStatus { + // URL of file that is being transferred. + DOMString fileUrl; + + // File transfer progress state. + TransferState transferState; + + // Approximated completed portion of the transfer operation. + double processed; + + // Approximated total size of transfer operation. + double total; + + // Total number of jobs. + long numTotalJobs; + + // Indicates whether a notification should be shown for the transfer update. + boolean showNotification; + + // If true, hide when a job is completed when there are zero jobs in + // progress. Otherwise, hide when one job is in progress. + boolean hideWhenZeroJobs; +}; + +// Information about the syncing state of an individual file. +dictionary SyncState { + // URL of file that is being transferred. + DOMString fileUrl; + + // File transfer progress state. + SyncStatus syncStatus; + + // Transfer progress so far. Ranges from 0 to 1. + double progress; +}; + +// Error during the drive sync. +dictionary DriveSyncErrorEvent { + // Error type. + DriveSyncErrorType type; + + // File URL of the entry that the error happens to. + DOMString fileUrl; + + // Shared drive name if the error relates to a shared drive. + DOMString? sharedDrive; +}; + +// Confirmation dialog from Drive asking the user to accept or reject an +// action. +dictionary DriveConfirmDialogEvent { + // Dialog type. + DriveConfirmDialogType type; + + // File URL of the entry associated with the dialog. + DOMString fileUrl; +}; + +// Detailed information of change. +dictionary FileChange { + // URL of changed file (or directory). + DOMString url; + + // Type of change, which may be multiple. + ChangeType[] changes; +}; + +// Directory change notification details. +dictionary FileWatchEvent { + // Specifies type of event that is raised. + FileWatchEventType eventType; + + // An Entry object which represents a changed directory. The conversion into a + // kind of FileEntry object is done in + // file_browser_handler_custom_bindings.cc. For filesystem API's Entry + // interface, see The Entry + // interface. + [instanceOf=Entry] object entry; + + // Detailed change information of change. It would be null if the detailed + // information is not available. + FileChange[]? changedFiles; +}; + +// Parameters passed to fileManagerPrivateInternal.getVolumeRoot function. +dictionary GetVolumeRootOptions { + // The ID of the requested volume. + DOMString volumeId; + + // Whether the requested file system should be writable. The default is + // read-only. + boolean? writable; +}; + +dictionary Preferences { + boolean driveEnabled; + boolean driveSyncEnabledOnMeteredNetwork; + boolean searchSuggestEnabled; + boolean use24hourClock; + DOMString timezone; + boolean arcEnabled; + boolean arcRemovableMediaAccessEnabled; + DOMString[] folderShortcuts; + boolean trashEnabled; + double officeFileMovedOneDrive; + double officeFileMovedGoogleDrive; + boolean driveFsBulkPinningAvailable; + boolean driveFsBulkPinningEnabled; + boolean localUserFilesAllowed; + DefaultLocation defaultLocation; +}; + +dictionary PreferencesChange { + boolean? driveSyncEnabledOnMeteredNetwork; + boolean? arcEnabled; + boolean? arcRemovableMediaAccessEnabled; + DOMString[]? folderShortcuts; + boolean? driveFsBulkPinningEnabled; +}; + +dictionary SearchParams { + // Search query. + DOMString query; + + // The category of files to which the search is limited. + FileCategory? category; + + // The minimum modified time of the files to be returned + double? modifiedTimestamp; + + // ID of the search feed that should be fetched next. Value passed here should + // be gotten from previous searchDrive call. It can be empty for the initial + // search request. + DOMString nextFeed; +}; + +dictionary SearchMetadataParams { + // Optional root directory from which to start the search. If not present, + // the search begins at the local root. + [instanceOf=DirectoryEntry] object? rootDir; + + // Search query. It can be empty. Any filename matches to an empty query. + DOMString query; + + // The type of entry that is needed. Default to ALL. + SearchType types; + + // Maximum number of results. + long maxResults; + + // Modified timestamp. The file must have modified timestamp more recent + // than this to be included in results. + double? modifiedTimestamp; + + // The category of files to which the search is limited. + FileCategory? category; +}; + +// Entry and Drive-related properties representing a search result. +dictionary DriveMetadataSearchResult { + // A dictionary object which represents a Drive file. This will be converted + // into a kind of FileEntry object. See + // file_browser_handler_custom_bindings.cc for details. For filesystem API's + // Entry interface, see The Entry + // interface. + [instanceOf=Entry] object entry; + + // The base name of a Drive file that matched the search query. The matched + // sub strings are highlighted with element. Meta characters are escaped + // like <. + DOMString highlightedBaseName; + + // Whether the file is available while offline. May be unset if not + // applicable. + boolean? availableOffline; +}; + +dictionary DriveConnectionState { + DriveConnectionStateType type; + + // Reasons of offline. + DriveOfflineReason? reason; +}; + +// Device event dispatched to listeners of onDeviceChaged. See also +// DeviceEventType to know when the event dispatched. +dictionary DeviceEvent { + // Event type of the device event. + DeviceEventType type; + // Device path to identify the device. + DOMString devicePath; + // Human readable label for the device. + DOMString deviceLabel; +}; + +// Describes an installed provider. +dictionary Provider { + // ID of the provider. + DOMString providerId; + + // Set of icons for the provider. + IconSet iconSet; + + // Name of the provider. + DOMString name; + + // Whether supports configuration dialog. + boolean configurable; + + // Whether supports watching entries. + boolean watchable; + + // Whether supports mounting multiple instances. + boolean multipleMounts; + + // Source of file systems' data. + ProviderSource source; +}; + +// chrome/common/extensions/api/file_system_provider.idl:Action +// Information about an action for an entry. +dictionary FileSystemProviderAction { + // The identifier of the action. Any string or $(ref:CommonActionId) for + // common actions. + DOMString id; + + // The title of the action. It may be ignored for common actions. + DOMString? title; +}; + +// Information about a Linux package in response to GetLinuxPackageInfo. +dictionary LinuxPackageInfo { + DOMString name; + DOMString version; + + // A one-line summary of the project. Almost always present. + DOMString? summary; + // A longer description of the project. Almost always present. + DOMString? description; +}; + +// Payload data for crostini event. +dictionary CrostiniEvent { + // Is the event raised for enable, disable, share, or unshare. + CrostiniEventType eventType; + + // VM that this event relates to. + DOMString vmName; + + // Name of the container this event relates to. + DOMString containerName; + + // Paths that have been shared or unshared. + [instanceOf=Entry] object[] entries; +}; + +dictionary CrostiniSharedPathResponse { + // Entries shared with crostini container. + [instanceOf=Entry] object[] entries; + + // true the first time this is called for the session. + boolean firstForSession; +}; + +// Represents an Android app (activity). +dictionary AndroidApp { + // Name of the app to be shown to the user (e.g. Photos). + DOMString name; + + // Package name (e.g. com.google.android.apps.photos). + DOMString packageName; + + // Activity name (e.g. .PhotosPickerActivity). + DOMString activityName; + + // App icon. + IconSet? iconSet; +}; + +dictionary StreamInfo { + // The stream type e.g., "mp3", "h264", "ogg". + DOMString type; + + // An unfiltered string->string dictionary of tags from the stream. + object tags; +}; + +dictionary AttachedImages { + // Data encoded as a dataURL. + DOMString data; + + // Data type. + DOMString type; +}; + +dictionary MediaMetadata { + // Content mime type. + DOMString mimeType; + + // Defined for video. In pixels. + long? height; + long? width; + + // Defined for audio and video. In seconds. + double? duration; + + // Defined for video. In degrees. + long? rotation; + + // Defined for audio and video. + DOMString? album; + DOMString? artist; + DOMString? comment; + DOMString? copyright; + long? disc; + DOMString? genre; + DOMString? language; + DOMString? title; + long? track; + + // All the metadata in the media file. For formats with multiple streams, + // stream order is preserved. Container metadata is the first stream. + StreamInfo[] rawTags; + + // Raw images embedded in the media file. This is most often audio album + // art or video thumbnails. + AttachedImages[] attachedImages; +}; + +dictionary HoldingSpaceState { + // File system URLs of items pinned to the holding space. + DOMString[] itemUrls; +}; + +dictionary OpenWindowParams { + // The desired target directory when opening a new window. If omitted Files + // app displays the default directory: MyFiles. + DOMString? currentDirectoryURL; + + // The URL for a file or directory to be selected once a new window is + // spawned. + DOMString? selectionURL; +}; + +dictionary IoTaskParams { + // Destination folder for tasks that require one. Not required by |delete| + // task. + [instanceOf=DirectoryEntry] object? destinationFolder; + + // Password used for unpacking encrypted archives. + DOMString? password; + + // Whether to display a notification in the UI. This does not stop the + // IOProgressStatus event propagating instead it provides a true boolean on + // the event that the UI can choose to show / hide the notification. + boolean? showNotification; +}; + +// Holds information about data protection policy errors, see file_manager::io_task::PolicyError. +dictionary PolicyError { + // Type of the error. + PolicyErrorType type; + // The number of files blocked by the policy. + long policyFileCount; + // The name of the first blocked file. Used for notifications. + DOMString fileName; + // Normally the review button is only shown when `policyFileCount` is >1, this option allows to force + // the display of the review button irrespective of other conditions. + boolean alwaysShowReview; +}; + +// IO task state::PAUSED name conflict parameters, see file_manager::io_task::ConflictPauseParams. +dictionary ConflictPauseParams { + // The conflict file name. + DOMString? conflictName; + + // True if the conflict file name is a directory. + boolean? conflictIsDirectory; + + // Set true if there are potentially multiple conflicted file names. + boolean? conflictMultiple; + + // The conflict copy or move target URL. + DOMString? conflictTargetUrl; +}; + +// IO task state::PAUSED policy parameters, see file_manager::io_task::PolicyPauseParams. +dictionary PolicyPauseParams { + // One of DLP or Enterprise Connectors. + PolicyErrorType type; + // The number of files under warning restriction. + long policyFileCount; + // The name of the first file under warning restriction. Used for notifications. + DOMString fileName; + // Normally the review button is only shown when `policyFileCount` is >1, this option allows to force + // the display of the review button irrespective of other conditions. + boolean alwaysShowReview; +}; + +// IO task state::PAUSED parameters, see file_manager::io_task::PauseParams. +dictionary PauseParams { + // Set iff pausing due to name conflict. + ConflictPauseParams? conflictParams; + // Set iff pausing due to policy. + PolicyPauseParams? policyParams; +}; + +// Resume IO Task parameters, see file_manager::io_task::ConflictResumeParams. +dictionary ConflictResumeParams { + // How to resolve a CopyOrMoveIOTask file name conflict: either 'keepboth' + // or 'replace'. + DOMString? conflictResolve; + + // Set true if conflictResolve should apply to future file name conflicts. + boolean? conflictApplyToAll; +}; + +// Resume IO Task parameters, see file_manager::io_task::PolicyResumeParams. +dictionary PolicyResumeParams { + PolicyErrorType type; +}; + +// Resume IO Task parameters, see file_manager::io_task::ResumeParams. +dictionary ResumeParams { + // Set iff paused due to name conflict. + ConflictResumeParams? conflictParams; + // Set iff paused due to policy. + PolicyResumeParams? policyParams; +}; + +// IO Task Progress status, see file_manager::io_task::ProgressStatus. +dictionary ProgressStatus { + + // Type of the task sending the progress. + IoTaskType type; + + // Current state of the task sending the progress. + IoTaskState state; + + // Type of policy error that occurred, if any. + // Used only if Data Leak Prevention or Enterprise Connectors policies apply. + PolicyError? policyError; + + // Name of the first source entry. + DOMString sourceName; + + // Number of remaining entries to be processed. + long numRemainingItems; + + // Total number of entries to be processed. + long itemCount; + + // Name of the destination folder for operations that transfer files to a + // directory (e.g. copy or move). + DOMString destinationName; + + // ProgressStatus over all |sources|. + long bytesTransferred; + + // Total size of all |sources|. + long totalBytes; + + // The task id for this progress status. + long taskId; + + // The estimate time to finish the operation. + double remainingSeconds; + + // Number of sources scanned. Only used when in SCANNING state. + // When scanning files, the progress is roughly the percentage of the + // number of scanned items out of the total items. This isn't always + // accurate, e.g. when uploading entire folders or because some items + // are not scanned at all. The goal is to show the user that some + // progress is happening. + long sourcesScanned; + + // Whether notifications should be shown on progress status. + boolean showNotification; + + // The name of the last error that happened. + DOMString errorName; + + // I/O task state::PAUSED parameters. + PauseParams? pauseParams; + + // The files affected by the IOTask. Currently only returned for TrashIOTask. + [instanceOf=Entry] object[]? outputs; + + // List of files skipped during the operation because we couldn't decrypt + // them. + DOMString[] skippedEncryptedFiles; + + // Volume id of the destination for operations that transfer files to a + // directory (e.g. copy or move). + DOMString destinationVolumeId; +}; + +dictionary DlpMetadata { + // The source URL of the file, if it's been downloaded. + DOMString sourceUrl; + + // True if there is any DLP policy on the file, false otherwise. + boolean isDlpRestricted; + + // True if the file cannot be accessed by a specific destination, + // which is passed when collecting the metadata. + boolean isRestrictedForDestination; +}; + +dictionary DlpRestrictionDetails { + // The level for which the restriction is enforced. + DlpLevel level; + + // List of URLs for which the restriction is enforced. + DOMString[] urls; + + // List of components for which the restriction is enforced. + VolumeType[] components; +}; + +dictionary DialogCallerInformation { + // The URL of the caller. + DOMString? url; + + // The component type of the caller. + VolumeType? component; +}; + +// A Guest OS that supports guest->host file sharing. This definition should +// match the one in file_manager_private.js. +dictionary MountableGuest { + // The ID of this guest, used to identify it in calls to the backend. + long id; + + // The localised display name of this guest as e.g. shown in the sidebar. + DOMString displayName; + + // The type of the VM backing this guest. + VmType vmType; +}; + +dictionary ParsedTrashInfoFile { + // The entry that the trashed file should be restored to. This does not exist + // but is used to identify whether the parent location still exists and + // identify the file name to restore to. + [instanceOf=Entry] object restoreEntry; + + // The file name for the .trashinfo. + DOMString trashInfoFileName; + + // The date the file was originally deleted. + double deletionDate; +}; + +// The current progress of the bulk pinning manager. This is a subset of the +// Progress struct in chromeos/ash/components/drivefs/drivefs_pinning_manager.h +dictionary BulkPinProgress { + // The stage the bulk pin manager is in. + BulkPinStage stage; + + // Estimated amount of free space on the stateful partition in bytes. + double freeSpaceBytes; + + // Estimated amount of free space required in order to successfully complete + // pinning. + double requiredSpaceBytes; + + // Estimated amount of bytes remaining to be downloaded in order to + // successfully complete pinning. + double bytesToPin; + + // Bytes that have been downloaded so far. + double pinnedBytes; + + // Total number of files to pin. + long filesToPin; + + // Show the total number of files enumerated during the Listing files stage. + long listedFiles; + + // Estimated time remaining to pin all the `bytesToPin`. + double remainingSeconds; + + // Should the bulk-pinning manager actually pin files, or should it stop after + // checking the space requirements? + boolean shouldPin; + + // Has the bulk-pinning manager ever emptied its set of tracked items? + boolean emptiedQueue; +}; + +// Represents a custom view of files to be displayed. +dictionary MaterializedView { + // Unique indentifier for the view. + long viewId; + + // Name of the view displayed to the user. + DOMString name; +}; + +// Used by EntryData to store the file system of the entry. +dictionary FileSystemData { + // Name of the file system. Will be unique. + DOMString name; + + // File system URL of the root entry of the file system. + DOMString rootUrl; +}; + +// Representation of an entry as a replacement for File/Directory Entries. +dictionary EntryData { + // File system URL of the entry. + DOMString entryUrl; + + // If false, the entry is a file. + boolean isDirectory; + + // Localized name of the entry for display. + DOMString name; + + // Information about the filesystem the entry is located in. + FileSystemData filesystem; +}; + +// Callback that does not take arguments. +callback SimpleCallback = void(); + +// |result| Boolean result returned by the invoked function. +callback BooleanCallback = void(boolean result); + +// |result| Result of the task execution. +callback ExecuteTaskCallback = void(TaskResult result); + +// |resultingTasks| The list of matched file entries for this task. +callback GetFileTasksCallback = void(ResultingTasks resultingTasks); + +// |result| Mime type of the file. +callback GetMimeTypeCallback = void(DOMString result); + +// |result| Content sniffed mime type of the file. +callback GetContentMimeTypeCallback = void(DOMString result); + +// |result| Metadata of the Audio or Video file. +callback GetContentMetadataCallback = void(MediaMetadata result); + +// |result| Hash containing the string assets. +callback GetStringsCallback = void(object result); + +// |success| True when file watch is successfully added. +callback AddFileWatchCallback = void(optional boolean success); + +// |success| True when file watch is successfully removed. +callback RemoveFileWatchCallback = void(optional boolean success); + +// |entryProperties| A dictionary containing properties of the requested +// entries. +callback GetEntryPropertiesCallback = + void(EntryProperties[] entryProperties); + +// |sourcePath| Source path of the mount. +callback AddMountCallback = void(DOMString sourcePath); + +// |volumeMetadataList| The list of VolumeMetadata representing mounted volumes. +callback GetVolumeMetadataListCallback = + void(VolumeMetadata[] volumeMetadataList); + +// |disallowedEntries| A list of files not allowed to be transfered. +callback GetDisallowedTransfersCallback = + void([instanceOf=Entry] object[] disallowedEntries); + +// |dlpMetadata| A list of DlpMetadata containing DLP information about +// the entries. +callback GetDlpMetadataCallback = + void(DlpMetadata[] dlpMetadata); + +// |restrictionDetails| A list of DlpRestrictionDetails containing +// summarized restriction information about an entry. +callback GetDlpRestrictionDetailsCallback = + void(DlpRestrictionDetails[] restrictionDetails); + +// |blockedComponents| A list of components (subset of VolumeType) to which +// transferring an Entry is blocked by Data Leak Prevention (DLP) policy. +callback GetDlpBlockedComponentsCallback = void(VolumeType[] blockedComponents); + +// |caller| Either the URL or a component (subset of VolumeType) of +// the caller that created the dialog (Save As/File Picker). +callback GetDialogCallerCallback = void(DialogCallerInformation caller); + +// |taskId| ID of the task that was started. Can be used to cancel ongoing task. +callback IOTaskIdCallback = void(long taskId); + +// |sizeStats| Name/value pairs of size stats. Will be undefined if stats could +// not be determined. +callback GetSizeStatsCallback = void(optional MountPointSizeStats sizeStats); + +// |driveQuotaMetadata| Name/value pairs of drive quota metadata. Will be +// undefined if quota metadata could not be determined. +callback GetDriveQuotaMetadataCallback = void(optional DriveQuotaMetadata driveQuotaMetadata); + +callback GetPreferencesCallback = void(Preferences result); + +// |entries| +// |nextFeed| ID of the feed that contains next chunk of the search result. +// Should be sent to the next searchDrive request to perform +// incremental search. +callback SearchDriveCallback = void(SearchDriveResponse response); + +callback SearchDriveMetadataCallback = + void(DriveMetadataSearchResult[] results); + +callback SearchFilesCallback = void([instanceOf=Entry] object[] entries); + +// |paths| A map of hash to array of drive paths. The array can be empty +// if the corresponding file is not found. However, the array will only +// contain at most one path per hash. +callback SearchFilesByHashesCallback = void(object paths); + +callback GetDeviceConnectionStateCallback = void(DeviceConnectionState result); + +callback GetDriveConnectionStateCallback = void(DriveConnectionState result); + +// |result| true if the length is in the valid range, false otherwise. +callback ValidatePathNameLengthCallback = void(boolean result); + +callback GetProfilesCallback = void(ProfilesResponse response); + +// |entries| External entries. +callback ResolveEntriesCallback = + void([instanceOf=Entry] object[] entries); + +// |checksum| Result checksum. +callback ComputeChecksumCallback = void(DOMString checksum); + +// |extensions| List of providers. +callback GetProvidersCallback = void(Provider[] extensions); + +// |actions| List of actions. +callback GetCustomActionsCallback = void(FileSystemProviderAction[] actions); + +// |size| result size. +callback GetDirectorySizeCallback = void(double size); + +// |entries| Recently modified entries. +callback GetRecentFilesCallback = void([instanceOf=Entry] object[] entries); + +// |rootDir| The root directory of the volume to which access was requested. +callback GetVolumeRootCallback = + void([instanceOf=DirectoryEntry] object rootDir); + +callback GetCrostiniSharedPathsCallback = + void(CrostiniSharedPathResponse response); + +// |linux_package_info| Package info for the queried package. +callback GetLinuxPackageInfoCallback = + void(LinuxPackageInfo linux_package_info); + +callback InstallLinuxPackageCallback = void(InstallLinuxPackageStatus status); + +// |apps| List of Android picker apps. +callback GetAndroidPickerAppsCallback = void(AndroidApp[] apps); + +// |state| Describes the current holding space state. +callback HoldingSpaceStateCallback = void(HoldingSpaceState state); + +// |guests| List of Guest OSs which have available mounts. +callback ListMountableGuestsCallback = void(MountableGuest[] guest); + +callback ParseTrashInfoFilesCallback = void(ParsedTrashInfoFile[] files); + +callback GetBulkPinProgressCallback = void(BulkPinProgress progress); + +callback GetMaterializedViewsCallback = void(MaterializedView[] views); + +callback ReadMaterializedViewCallback = void(EntryData[] files); + +interface Functions { + // Cancels file selection. + static void cancelDialog(); + + // Executes file browser task over selected files. + // |descriptor| The unique identifier of task to execute. + // |entries| Array of entries + // |callback| + [nocompile, doesNotSupportPromises] + static void executeTask(FileTaskDescriptor descriptor, + [instanceOf=Entry] object[] entries, + ExecuteTaskCallback callback); + + // Sets the default task for the supplied MIME types and path extensions. + // Lists of MIME types and URLs may contain duplicates. Additionally, the + // list of MIME types can be empty. + // |descriptor| The unique identifier of task to mark as default. + // |entries| Array of selected entries to extract path extensions from. + // |mimeTypes| Array of selected file MIME types. + // |callback| + [nocompile, doesNotSupportPromises] + static void setDefaultTask(FileTaskDescriptor descriptor, + [instanceOf=Entry] object[] entries, + DOMString[] mimeTypes, + SimpleCallback callback); + + // Gets the list of tasks that can be performed over selected files. + // |entries| Array of selected entries + // |dlpSourceUrls| Array of source URLs corresponding to the entries, used to + // check Data Leak Prevention (DLP) restrictions + // |callback| + [nocompile, doesNotSupportPromises] + static void getFileTasks([instanceOf=Entry] object[] entries, + DOMString[] dlpSourceUrls, + GetFileTasksCallback callback); + + // Gets the MIME type of an entry. + // |entry| The entry to be checked. + // |callback| + static void getMimeType(DOMString url, + GetMimeTypeCallback callback); + + // Gets the content sniffed MIME type of a file. + // |fileEntry| The file entry to be checked. + // |callback| + [nocompile, doesNotSupportPromises] + static void getContentMimeType([instanceOf=FileEntry] object fileEntry, + GetContentMimeTypeCallback callback); + + // Gets metadata from an Audio or Video file. + // |fileEntry| The file entry to be checked. + // |mimeType| Content sniffed mimeType of the file. + // |includeImages| False returns metadata tags only. True returns + // metadata tags and metadata (thumbnail) images. + // |callback| + [nocompile, doesNotSupportPromises] + static void getContentMetadata([instanceOf=FileEntry] object fileEntry, + DOMString mimeType, + boolean includeImages, + GetContentMetadataCallback callback); + + // Gets localized strings and initialization data. + // |callback| + [doesNotSupportPromises] + static void getStrings(GetStringsCallback callback); + + // Adds file watch. + // |entry| Entry to watch + // |callback| + [nocompile, doesNotSupportPromises] + static void addFileWatch([instanceOf=Entry] object entry, + AddFileWatchCallback callback); + + // Removes file watch. + // |entry| Watched entry + // |callback| + [nocompile, doesNotSupportPromises] + static void removeFileWatch([instanceOf=Entry] object entry, + RemoveFileWatchCallback callback); + + // Enables the extenal file scheme necessary to initiate drags to the browser + // window for files on the external backend. + static void enableExternalFileScheme(); + + // Requests granting R/W permissions for the passed entries. It's a best + // effort operation. Some files may not be granted access if the url is + // invalid or not backed by the external file system. + // |entryUrls| Urls for the entries to be accessed. + // |callback| + [doesNotSupportPromises] + static void grantAccess(DOMString[] entryUrls, SimpleCallback callback); + + // Selects multiple files. + // |selectedPaths| Array of selected paths + // |shouldReturnLocalPath| true if paths need to be resolved to local paths. + // |callback| + [doesNotSupportPromises] + static void selectFiles(DOMString[] selectedPaths, + boolean shouldReturnLocalPath, + SimpleCallback callback); + + // Selects a file. + // |selectedPath| A selected path + // |index| Index of Filter + // |forOpening| true if paths are selected for opening. false if for saving. + // |shouldReturnLocalPath| true if paths need to be resolved to local paths. + // |callback| + [doesNotSupportPromises] + static void selectFile(DOMString selectedPath, + long index, + boolean forOpening, + boolean shouldReturnLocalPath, + SimpleCallback callback); + + // Requests additional properties for files. + // |entries| list of entries + // |names| list of requested properties by their names. + // |callback| Completion callback. May return less than requested properties + // if some are not available. In the same time, it can return properties + // which were not requested (if it's cheap to compute them). + [nocompile, doesNotSupportPromises] + static void getEntryProperties( + [instanceOf=Entry] object[] entries, + EntryPropertyName[] names, + GetEntryPropertiesCallback callback); + + // Pins/unpins a Drive file in the cache. + // |entry| Entry to pin/unpin. + // |pin| Pass true to pin the file. + // |callback| Completion callback. $(ref:runtime.lastError) will be set if + // there was an error. + [nocompile, doesNotSupportPromises] + static void pinDriveFile([instanceOf=Entry] object entry, + boolean pin, + SimpleCallback callback); + + // Resolves entries in the isolated file system and returns corresponding + // entries in the external file system mounted to Chrome OS file manager + // backend. If resolving entry fails, the entry will be just ignored and the + // corresponding entry does not appear in the result. + [nocompile, doesNotSupportPromises] + static void resolveIsolatedEntries( + [instanceOf=Entry] object[] entries, + ResolveEntriesCallback callback); + + // Mounts a resource or an archive. + // |fileUrl| Mount point source. + // |password| Optional password to decrypt the archive. + // |callback| Callback called with the source path of the mount. + [doesNotSupportPromises] + static void addMount(DOMString fileUrl, optional DOMString password, + AddMountCallback callback); + + // Cancels an archive mounting operation. + // |fileUrl| Mount point source. Should be same as the one passed to addMount. + // |callback| + [doesNotSupportPromises] + static void cancelMounting(DOMString fileUrl, SimpleCallback callback); + + // Unmounts a mounted resource. + // |volumeId| An ID of the volume. + [doesNotSupportPromises] + static void removeMount(DOMString volumeId, SimpleCallback callback); + + // Get the list of mounted volumes. + // |callback| + [doesNotSupportPromises] + static void getVolumeMetadataList(GetVolumeMetadataListCallback callback); + + // Returns the list of files not allowed to be transfered. + // |entries| List of the source entries to be transfered. + // |destinationEntry| Entry for the destination (parent) directory. + // |isMove| True if the operation is move, false otherwise. + // |callback| Result callback. + [nocompile, doesNotSupportPromises] + static void getDisallowedTransfers( + [instanceOf=Entry] object[] entries, + [instanceOf=DirectoryEntry] object destinationEntry, + boolean isMove, + GetDisallowedTransfersCallback callback); + + // Returns the list of DlpMetadata containing DLP information + // about the entries. + // |entries| List of the source entries to be checked. + // |callback| Result callback. + [nocompile, doesNotSupportPromises] + static void getDlpMetadata( + [instanceOf=Entry] object[] entries, + GetDlpMetadataCallback callback); + + // Retrieves Data Leak Prevention (DLP) restriction details. + // |sourceUrl| Source URL of the Entry for which the details should be shown. + // |callback| Result callback. + [doesNotSupportPromises] + static void getDlpRestrictionDetails( + DOMString sourceUrl, + GetDlpRestrictionDetailsCallback callback); + + // Retrieves the list of components to which the transfer of an Entry + // is blocked by Data Leak Prevention (DLP) policy. + // |sourceUrl| Source URL of the Entry that should be checked. + // |callback| Result callback. + [doesNotSupportPromises] + static void getDlpBlockedComponents( + DOMString sourceUrl, + GetDlpBlockedComponentsCallback callback); + + // Retrieves the caller that created the dialog (Save As/File Picker). + // |callback| Result callback. + [doesNotSupportPromises] + static void getDialogCaller(GetDialogCallerCallback callback); + + // Retrieves total and remaining size of a mount point. + // |volumeId| ID of the volume to be checked. + // |callback| + [doesNotSupportPromises] + static void getSizeStats(DOMString volumeId, GetSizeStatsCallback callback); + + + // Retrieves metadata about the user's Drive volume's quota. + // |entry| If entry is within a Shared Drive, then the applicable shared + // drive quota is returned, else the overall Drive quota is returned. + // |callback| + [nocompile, doesNotSupportPromises] + static void getDriveQuotaMetadata([instanceOf=Entry] object entry, + GetDriveQuotaMetadataCallback callback); + + // Formats a mounted volume. + // |volumeId| ID of the volume to be formatted. + // |filesystem| Filesystem type to be formatted to. + // |volumeLabel| Label of the drive after formatting. + static void formatVolume(DOMString volumeId, + FormatFileSystemType filesystem, + DOMString volumeLabel); + + // Deletes partitions of removable device, creates a new partition and format + // it. + // |deviceStoragePath| Storage path of the device to be formatted. + // |filesystem| Filesystem type to be formatted to. + // |volumeLabel| Label of the drive after formatting. + static void singlePartitionFormat(DOMString deviceStoragePath, + FormatFileSystemType filesystem, + DOMString volumeLabel); + + // Renames a mounted volume. + // |volumeId| ID of the volume to be renamed. + // |newName| New name of the target volume. + static void renameVolume(DOMString volumeId, DOMString newName); + + // Retrieves file manager preferences. + // |callback| + [doesNotSupportPromises] + static void getPreferences(GetPreferencesCallback callback); + + // Sets file manager preferences. + // |changeInfo| + static void setPreferences(PreferencesChange changeInfo); + + // Performs drive content search. + // |searchParams| + // |callback| + [doesNotSupportPromises] + static void searchDrive(SearchParams searchParams, + SearchDriveCallback callback); + + // Performs drive metadata search. + // |searchParams| + // |callback| + [doesNotSupportPromises] + static void searchDriveMetadata(SearchMetadataParams searchParams, + SearchDriveMetadataCallback callback); + + // Search files in MyFiles. + [nocompile, doesNotSupportPromises] + static void searchFiles(SearchMetadataParams searchParams, + SearchFilesCallback callback); + + // Retrieves the current device connection status. + // |callback| + [doesNotSupportPromises] + static void getDeviceConnectionState(GetDeviceConnectionStateCallback callback); + + // Retrieves the state of the current drive connection. + // |callback| + [doesNotSupportPromises] + static void getDriveConnectionState(GetDriveConnectionStateCallback callback); + + // Checks whether the path name length fits in the limit of the filesystem. + // |parentEntry| The entry of the parent directory entry. + // |name| The name of the file. + // |callback| Called back when the check is finished. + [nocompile, doesNotSupportPromises] + static void validatePathNameLength( + [instanceOf=DirectoryEntry] object parentEntry, + DOMString name, + ValidatePathNameLengthCallback callback); + + // Changes the zoom factor of the Files app. + // |operation| Zooming mode. + static void zoom(ZoomOperationType operation); + + // Obtains a list of profiles that are logged-in. + [doesNotSupportPromises] + static void getProfiles(GetProfilesCallback callback); + + // Opens inspector window. + // |type| InspectionType which specifies how to open inspector. + static void openInspector(InspectionType type); + + // Opens page in Settings window. + // |subPage| Name of a subPage to show. + static void openSettingsSubpage(DOMString subPage); + + // Returns list of available providers. + [doesNotSupportPromises] + static void getProviders(GetProvidersCallback callback); + + // Requests adding a new provided file system. On failure, sets + // $(ref:runtime.lastError). + [doesNotSupportPromises] + static void addProvidedFileSystem(DOMString providerId, + SimpleCallback callback); + + // Requests configuring an existing volume. On failure, sets + // $(ref:runtime.lastError). + [doesNotSupportPromises] + static void configureVolume(DOMString volumeId, SimpleCallback callback); + + // Requests list of custom actions for the specified entries. On failure, sets + // $(ref:runtime.lastError). + [nocompile, doesNotSupportPromises] + static void getCustomActions([instanceOf=Entry] object[] entries, + GetCustomActionsCallback callback); + + // Executes a custom action for a set of entries. On failure, sets + // $(ref:runtime.lastError). + [nocompile, doesNotSupportPromises] + static void executeCustomAction([instanceOf=Entry] object[] entries, + DOMString actionId, + SimpleCallback callback); + + // Get the total size of a directory. + // |entry| Entry of the target directory. + // |callback| + [nocompile, doesNotSupportPromises] + static void getDirectorySize([instanceOf=DirectoryEntry] object entry, + GetDirectorySizeCallback callback); + + // Gets recently modified files across file systems. + // |restriction| Flag to restrict sources of recent files. + // |fileType| Requested file type to filter recent files. + // |query| When not empty, removes files with non-matching names. + // |cutoffDays| Specifies oldest modification time. + // |callback| Called with zero or more matched files. + [nocompile, doesNotSupportPromises] + static void getRecentFiles(SourceRestriction restriction, + DOMString query, + long cutoffDays, + FileCategory fileCategory, + boolean invalidateCache, + GetRecentFilesCallback callback); + + // Requests the root directory of the volume with the ID specified in + // |options.volumeId|. + [nocompile, doesNotSupportPromises] + static void getVolumeRoot(GetVolumeRootOptions options, + GetVolumeRootCallback callback); + + // Starts and mounts crostini container. + // |callback| + [doesNotSupportPromises] + static void mountCrostini(SimpleCallback callback); + + // Shares paths with crostini container. + // |vmName| VM to share path with. + // |entries| Entries of the files or directories to share. + // |persist| If true, shares will persist across restarts. + // |callback| + [nocompile, doesNotSupportPromises] + static void sharePathsWithCrostini(DOMString vmName, + [instanceOf=Entry] object[] entries, + boolean persist, + SimpleCallback callback); + + // Unshares path with crostini container. + // |vmName| VM to unshare path from. + // |entry| Entry of the file or directory to unshare. + // |callback| + [nocompile, doesNotSupportPromises] + static void unsharePathWithCrostini(DOMString vmName, + [instanceOf=Entry] object entry, + SimpleCallback callback); + + // Returns list of paths shared with crostini container. + // |observeFirstForSession| If true, callback provides whether this is the + // |vmName| VM to get shared paths of. + // first time this function has been called with observeFirstForSession true. + [nocompile, doesNotSupportPromises] + static void getCrostiniSharedPaths(boolean observeFirstForSession, + DOMString vmName, + GetCrostiniSharedPathsCallback callback); + + // Requests information about a Linux package. |entry| is a .deb file. + [nocompile, doesNotSupportPromises] + static void getLinuxPackageInfo([instanceOf=Entry] object entry, + GetLinuxPackageInfoCallback callback); + + // Starts installation of a Linux package. + [nocompile, doesNotSupportPromises] + static void installLinuxPackage([instanceOf=Entry] object entry, + InstallLinuxPackageCallback callback); + + // Imports a Crostini Image File (.tini). This overrides the existing Linux + // apps and files. + [nocompile] + static void importCrostiniImage([instanceOf=Entry] object entry); + + // Returns a list of Android picker apps to be shown in file selector. + [doesNotSupportPromises] + static void getAndroidPickerApps(DOMString[] extensions, + GetAndroidPickerAppsCallback callback); + + // Called when the user selects an Android picker app in file selector. + [doesNotSupportPromises] + static void selectAndroidPickerApp(AndroidApp androidApp, + SimpleCallback callback); + + // Return true if sharesheet contains share targets for entries. + // |entries| Array of selected entries + // |callback| is called with error in case of failure and with no arguments + // if successfully launched the Sharesheet dialog, but before user has + // finished the sharing. + static void sharesheetHasTargets(DOMString[] fileUrls, + BooleanCallback callback); + + // Invoke Sharesheet for selected files. + // |entries| Array of selected entries. + // |launchSource| Source from which sharesheet was invoked. + // |dlpSourceUrls| Array of source URLs corresponding to the entries, used to + // check Data Leak Prevention (DLP) restrictions + // |callback| + static void invokeSharesheet(DOMString[] fileUrls, + SharesheetLaunchSource launchSource, + DOMString[] dlpSourceUrls, + SimpleCallback callback); + + // Adds or removes a list of entries to temporary holding space. Any entries + // whose current holding space state matches the intended state will be + // skipped. + // |entries| The list of entries whose holding space needs to be updated. + // |add| Whether items should be added or removed from the holding space. + // |callback| Completion callback. + [nocompile, doesNotSupportPromises] + static void toggleAddedToHoldingSpace([instanceOf=Entry] object[] entries, + boolean added, + optional SimpleCallback callback); + + // Retrieves the current holding space state, for example the list of items + // the holding space currently contains. + // |callback| The result callback. + [doesNotSupportPromises] + static void getHoldingSpaceState(HoldingSpaceStateCallback callback); + + // Returns true via `callback` if tablet mode is enabled, false otherwise. + [doesNotSupportPromises] + static void isTabletModeEnabled(BooleanCallback callback); + + // Notifies the browser of the result of a dialog displayed earlier as a + // result of the onDriveConfirmDialog event. + static void notifyDriveDialogResult(DriveDialogResult result); + + // Opens a new browser tab and navigates to `url`. + static void openURL(DOMString url); + + // Creates a new Files app window in the directory provided in `params`. + [doesNotSupportPromises] + static void openWindow(OpenWindowParams params, BooleanCallback callback); + + // Opens the feedback report window. + static void sendFeedback(); + + // Starts an I/O task of type |type| on |entries|. Task type specific + // parameters are passed via |params|. + [nocompile, doesNotSupportPromises] + static void startIOTask( + IoTaskType type, + [instanceOf=Entry] object[] entries, + IoTaskParams params, + optional IOTaskIdCallback callback); + + // Cancels an I/O task by id. Task ids are communicated to the Files App in + // each I/O task's progress status. + static void cancelIOTask(long taskId); + + // Resumes an I/O task by id. Task ids are communicated to the Files App in + // each I/O task's progress status. + static void resumeIOTask(long taskId, ResumeParams params); + + // Notifies the browser that any info still stored about an already completed + // I/O task identified by |taskId| can be cleared. + [doesNotSupportPromises] + static void dismissIOTask(long taskId, SimpleCallback callback); + + // Shows a policy dialog for a task. Task ids are communicated to the Files + // App in each I/O task's progress status. + [doesNotSupportPromises] + static void showPolicyDialog( + long taskId, + PolicyDialogType type, + SimpleCallback callback); + + // Makes I/O tasks in state::PAUSED emit (broadcast) their current I/O task + // progress status. + [doesNotSupportPromises] + static void progressPausedTasks(SimpleCallback callback); + + // Lists mountable Guest OSs. + [doesNotSupportPromises] + static void listMountableGuests(ListMountableGuestsCallback callback); + + // Starts and mounts the target Guest OS. + // |callback| + [doesNotSupportPromises] + static void mountGuest(long id, SimpleCallback callback); + + // Tells DriveFS to update its cached pin states of hosted files (once). + static void pollDriveHostedFilePinStates(); + + // Opens the dialog to manage the currently syncing folders. + static void openManageSyncSettings(); + + // Validates and parses the supplied `entries` as .trashinfo files. + [nocompile, doesNotSupportPromises] + static void parseTrashInfoFiles([instanceOf=Entry] object[] entries, + ParseTrashInfoFilesCallback callback); + + // Returns the current progress of the bulk pinning manager. + [doesNotSupportPromises] + static void getBulkPinProgress(GetBulkPinProgressCallback callback); + + // Starts calculating the space required to pin all the items in a users My + // drive. + [doesNotSupportPromises] + static void calculateBulkPinRequiredSpace(SimpleCallback callback); + + // Returns a list of views that can be displayed to the user. + static void getMaterializedViews(GetMaterializedViewsCallback callback); + + // Returns the list of entries contained in the view identified by `viewId`. + static void readMaterializedView(long viewId, + ReadMaterializedViewCallback callback); +}; + +// Events supported by fileManagerPrivate API. These events are broadcasted. +// See the note at the top of the file with regards implications of event +// broadcasting to applications that can use fileManagerPrivate Event API. +interface Events { + static void onMountCompleted(MountCompletedEvent event); + + static void onFileTransfersUpdated(FileTransferStatus event); + + static void onPinTransfersUpdated(FileTransferStatus event); + + static void onIndividualFileTransfersUpdated(SyncState[] event); + + static void onDirectoryChanged(FileWatchEvent event); + + static void onPreferencesChanged(); + + static void onDeviceConnectionStatusChanged(DeviceConnectionState state); + + static void onDriveConnectionStatusChanged(); + + static void onDeviceChanged(DeviceEvent event); + + static void onDriveSyncError(DriveSyncErrorEvent event); + + static void onDriveConfirmDialog(DriveConfirmDialogEvent event); + + static void onAppsUpdated(); + + static void onCrostiniChanged(CrostiniEvent event); + + static void onTabletModeChanged(boolean enabled); + + static void onIOTaskProgressStatus(ProgressStatus status); + + // Event broadcast when the list of Guest OSs that support Guest->Host file + // sharing changes. + static void onMountableGuestsChanged(MountableGuest[] guests); + + static void onBulkPinProgress(BulkPinProgress progress); +}; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/file_manager_private_internal.idl b/tools/under-control/src/chrome/common/extensions/api/file_manager_private_internal.idl new file mode 100755 index 000000000..e1841a6bd --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/file_manager_private_internal.idl @@ -0,0 +1,180 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Internal, used by fileManagerPrivate's custom bindings. +[platforms=("chromeos"), + implemented_in="chrome/browser/ash/extensions/file_manager/file_manager_private_api_functions.h"] +namespace fileManagerPrivateInternal { + // Entry information that renderers need to create an Entry instance. + dictionary EntryDescription { + DOMString fileSystemName; + DOMString fileSystemRoot; + DOMString fileFullPath; + boolean fileIsDirectory; + }; + dictionary IOTaskParams { + DOMString? destinationFolderUrl; + DOMString? password; + boolean? showNotification; + }; + dictionary ParsedTrashInfoFile { + EntryDescription restoreEntry; + DOMString trashInfoFileName; + double deletionDate; + }; + dictionary SearchFilesParams { + DOMString? rootUrl; + DOMString query; + fileManagerPrivate.SearchType types; + long maxResults; + double modifiedTimestamp; + fileManagerPrivate.FileCategory category; + }; + dictionary CrostiniSharedPathResponse { + EntryDescription[] entries; + boolean firstForSession; + }; + + callback SimpleCallback = void(); + callback ResolveIsolatedEntriesCallback = void(EntryDescription[] entries); + callback GetEntryPropertiesCallback = void( + fileManagerPrivate.EntryProperties[] entryProperties); + callback AddFileWatchCallback = void(optional boolean success); + callback RemoveFileWatchCallback = void(optional boolean success); + callback GetCustomActionsCallback = void(fileSystemProvider.Action[] actions); + callback GetMimeTypeCallback = void(DOMString result); + callback GetContentMimeTypeCallback = void(DOMString result); + callback GetContentMetadataCallback = void( + fileManagerPrivate.MediaMetadata result); + callback ExecuteTaskCallback = void(fileManagerPrivate.TaskResult result); + callback GetFileTasksCallback = void(fileManagerPrivate.ResultingTasks resultingTasks); + callback GetDisallowedTransfersCallback = + void(EntryDescription[] entries); + callback GetDlpMetadataCallback = + void(fileManagerPrivate.DlpMetadata[] entries); + callback GetDriveQuotaMetadataCallback = + void(optional fileManagerPrivate.DriveQuotaMetadata driveQuotaMetadata); + callback IOTaskIdCallback = void(long taskId); + callback ValidatePathNameLengthCallback = void(boolean result); + callback GetDirectorySizeCallback = void(double size); + callback GetRecentFilesCallback = void(EntryDescription[] entries); + callback GetCrostiniSharedPathsCallback = + void(CrostiniSharedPathResponse response); + callback GetLinuxPackageInfoCallback = + void(fileManagerPrivate.LinuxPackageInfo linux_package_info); + callback InstallLinuxPackageCallback = + void(fileManagerPrivate.InstallLinuxPackageStatus status); + callback GetThumbnailCallback = void(DOMString ThumbnailDataUrl); + callback BooleanCallback = void(boolean result); + callback GetVolumeRootCallback = void(EntryDescription rootDir); + callback ParseTrashInfoFilesCallback = void(ParsedTrashInfoFile[] files); + callback SearchFilesCallback = void(EntryDescription[] entries); + + interface Functions { + static void resolveIsolatedEntries( + DOMString[] urls, + ResolveIsolatedEntriesCallback callback); + static void getEntryProperties( + DOMString[] urls, + fileManagerPrivate.EntryPropertyName[] names, + GetEntryPropertiesCallback callback); + static void addFileWatch( + DOMString url, + AddFileWatchCallback callback); + static void removeFileWatch( + DOMString url, + RemoveFileWatchCallback callback); + static void getCustomActions( + DOMString[] urls, + GetCustomActionsCallback callback); + static void executeCustomAction( + DOMString[] urls, + DOMString actionId, + SimpleCallback callback); + static void getContentMimeType( + DOMString blobUUID, + GetContentMimeTypeCallback callback); + static void getContentMetadata( + DOMString blobUUID, + DOMString mimeType, + boolean includeImages, + GetContentMetadataCallback callback); + static void pinDriveFile( + DOMString url, + boolean pin, + SimpleCallback callback); + static void executeTask( + fileManagerPrivate.FileTaskDescriptor descriptor, + DOMString[] urls, + ExecuteTaskCallback callback); + static void searchFiles( + SearchFilesParams searchParams, SearchFilesCallback callback); + static void setDefaultTask( + fileManagerPrivate.FileTaskDescriptor descriptor, + DOMString[] urls, + DOMString[] mimeTypes, + SimpleCallback callback); + static void getFileTasks( + DOMString[] urls, + DOMString[] dlpSourceUrls, + GetFileTasksCallback callback); + static void getDisallowedTransfers( + DOMString[] entries, + DOMString destinationEntry, + boolean isMove, + GetDisallowedTransfersCallback callback); + static void getDlpMetadata( + DOMString[] entries, + GetDlpMetadataCallback callback); + static void getDriveQuotaMetadata( + DOMString url, + GetDriveQuotaMetadataCallback callback); + static void validatePathNameLength( + DOMString parentUrl, + DOMString name, + ValidatePathNameLengthCallback callback); + static void getDirectorySize( + DOMString url, + GetDirectorySizeCallback callback); + static void getVolumeRoot( + fileManagerPrivate.GetVolumeRootOptions options, + GetVolumeRootCallback callback); + static void getRecentFiles( + fileManagerPrivate.SourceRestriction restriction, + DOMString query, + long cutoff_days, + fileManagerPrivate.FileCategory file_category, + boolean invalidate_cache, + GetRecentFilesCallback callback); + static void sharePathsWithCrostini( + DOMString vmName, DOMString[] urls, + boolean persist, + SimpleCallback callback); + static void unsharePathWithCrostini( + DOMString vmName, DOMString url, + SimpleCallback callback); + static void getCrostiniSharedPaths( + boolean observeFirstForSession, + DOMString vmName, + GetCrostiniSharedPathsCallback callback); + static void getLinuxPackageInfo( + DOMString url, + GetLinuxPackageInfoCallback callback); + static void installLinuxPackage( + DOMString url, + InstallLinuxPackageCallback callback); + static void importCrostiniImage(DOMString url); + static void toggleAddedToHoldingSpace( + DOMString[] urls, boolean add, + optional SimpleCallback callback); + static void startIOTask( + fileManagerPrivate.IoTaskType type, + DOMString[] urls, + IOTaskParams params, + optional IOTaskIdCallback callback); + static void parseTrashInfoFiles( + DOMString[] urls, + ParseTrashInfoFilesCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/file_system_provider.idl b/tools/under-control/src/chrome/common/extensions/api/file_system_provider.idl new file mode 100755 index 000000000..dc6c3ddd3 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/file_system_provider.idl @@ -0,0 +1,833 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.fileSystemProvider API to create file systems, +// that can be accessible from the file manager on Chrome OS. +[implemented_in="chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h"] +namespace fileSystemProvider { + // Error codes used by providing extensions in response to requests as well + // as in case of errors when calling methods of the API. For success, + // "OK" must be used. + enum ProviderError { + OK, + FAILED, + IN_USE, + EXISTS, + NOT_FOUND, + ACCESS_DENIED, + TOO_MANY_OPENED, + NO_MEMORY, + NO_SPACE, + NOT_A_DIRECTORY, + INVALID_OPERATION, + SECURITY, + ABORT, + NOT_A_FILE, + NOT_EMPTY, + INVALID_URL, + IO + }; + + // Mode of opening a file. Used by $(ref:onOpenFileRequested). + enum OpenFileMode { + READ, + WRITE + }; + + // Type of a change detected on the observed directory. + enum ChangeType { + CHANGED, + DELETED + }; + + // List of common actions. "SHARE" is for sharing files with + // others. "SAVE_FOR_OFFLINE" for pinning (saving for offline + // access). "OFFLINE_NOT_NECESSARY" for notifying that the file + // doesn't need to be stored for offline access anymore. + // Used by $(ref:onGetActionsRequested) and $(ref:onExecuteActionRequested). + enum CommonActionId { + SAVE_FOR_OFFLINE, + OFFLINE_NOT_NECESSARY, + SHARE + }; + + // Cloud storage representation of a file system entry. + dictionary CloudIdentifier { + // Identifier for the cloud storage provider (e.g. 'drive.google.com'). + DOMString providerName; + + // The provider's identifier for the given file/directory. + DOMString id; + }; + + // Information relating to files that are served by a cloud file system. + dictionary CloudFileInfo { + // A tag that represents the version of the file. + DOMString? versionTag; + }; + + // Represents metadata of a file or a directory. + dictionary EntryMetadata { + // True if it is a directory. Must be provided if requested in + // options. + boolean? isDirectory; + + // Name of this entry (not full path name). Must not contain '/'. For root + // it must be empty. Must be provided if requested in options. + DOMString? name; + + // File size in bytes. Must be provided if requested in + // options. + double? size; + + // The last modified time of this entry. Must be provided if requested in + // options. + [instanceOf=Date] object? modificationTime; + + // Mime type for the entry. Always optional, but should be provided if + // requested in options. + DOMString? mimeType; + + // Thumbnail image as a data URI in either PNG, JPEG or WEBP format, at most + // 32 KB in size. Optional, but can be provided only when explicitly + // requested by the $(ref:onGetMetadataRequested) event. + DOMString? thumbnail; + + // Cloud storage representation of this entry. Must be provided if requested + // in options and the file is backed by cloud storage. For + // local files not backed by cloud storage, it should be undefined when + // requested. + CloudIdentifier? cloudIdentifier; + + // Information that identifies a specific file in the underlying cloud file + // system. Must be provided if requested in options and the + // file is backed by cloud storage. + CloudFileInfo? cloudFileInfo; + }; + + // Represents a watcher. + dictionary Watcher { + // The path of the entry being observed. + DOMString entryPath; + + // Whether watching should include all child entries recursively. It can be + // true for directories only. + boolean recursive; + + // Tag used by the last notification for the watcher. + DOMString? lastTag; + }; + + // Represents an opened file. + dictionary OpenedFile { + // A request ID to be be used by consecutive read/write and close requests. + long openRequestId; + + // The path of the opened file. + DOMString filePath; + + // Whether the file was opened for reading or writing. + OpenFileMode mode; + }; + + // Represents a mounted file system. + dictionary FileSystemInfo { + // The identifier of the file system. + DOMString fileSystemId; + + // A human-readable name for the file system. + DOMString displayName; + + // Whether the file system supports operations which may change contents + // of the file system (such as creating, deleting or writing to files). + boolean writable; + + // The maximum number of files that can be opened at once. If 0, then not + // limited. + long openedFilesLimit; + + // List of currently opened files. + OpenedFile[] openedFiles; + + // Whether the file system supports the tag field for observing + // directories. + boolean? supportsNotifyTag; + + // List of watchers. + Watcher[] watchers; + }; + + // Options for the $(ref:mount) method. + dictionary MountOptions { + // The string indentifier of the file system. Must be unique per each + // extension. + DOMString fileSystemId; + + // A human-readable name for the file system. + DOMString displayName; + + // Whether the file system supports operations which may change contents + // of the file system (such as creating, deleting or writing to files). + boolean? writable; + + // The maximum number of files that can be opened at once. If not specified, + // or 0, then not limited. + long? openedFilesLimit; + + // Whether the file system supports the tag field for observed + // directories. + boolean? supportsNotifyTag; + + // Whether the framework should resume the file system at the next sign-in + // session. True by default. + boolean? persistent; + }; + + // Options for the $(ref:unmount) method. + dictionary UnmountOptions { + // The identifier of the file system to be unmounted. + DOMString fileSystemId; + }; + + // Options for the $(ref:onUnmountRequested) event. + dictionary UnmountRequestedOptions { + // The identifier of the file system to be unmounted. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + }; + + // Options for the $(ref:onGetMetadataRequested) event. + dictionary GetMetadataRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The path of the entry to fetch metadata about. + DOMString entryPath; + + // Set to true if is_directory value is requested. + boolean isDirectory; + + // Set to true if name value is requested. + boolean name; + + // Set to true if size value is requested. + boolean size; + + // Set to true if modificationTime value is + // requested. + boolean modificationTime; + + // Set to true if mimeType value is requested. + boolean mimeType; + + // Set to true if thumbnail value is requested. + boolean thumbnail; + + // Set to true if cloudIdentifier value is + // requested. + boolean cloudIdentifier; + + // Set to true if cloudFileInfo value is + // requested. + boolean cloudFileInfo; + }; + + // Options for the $(ref:onGetActionsRequested) event. + dictionary GetActionsRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // List of paths of entries for the list of actions. + DOMString[] entryPaths; + }; + + // Options for the $(ref:onReadDirectoryRequested) event. + dictionary ReadDirectoryRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The path of the directory which contents are requested. + DOMString directoryPath; + + // Set to true if is_directory value is requested. + boolean isDirectory; + + // Set to true if name value is requested. + boolean name; + + // Set to true if size value is requested. + boolean size; + + // Set to true if modificationTime value is + // requested. + boolean modificationTime; + + // Set to true if mimeType value is requested. + boolean mimeType; + + // Set to true if thumbnail value is requested. + boolean thumbnail; + }; + + // Options for the $(ref:onOpenFileRequested) event. + dictionary OpenFileRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // A request ID which will be used by consecutive read/write and close + // requests. + long requestId; + + // The path of the file to be opened. + DOMString filePath; + + // Whether the file will be used for reading or writing. + OpenFileMode mode; + }; + + // Options for the $(ref:onCloseFileRequested) event. + dictionary CloseFileRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // A request ID used to open the file. + long openRequestId; + }; + + // Options for the $(ref:onReadFileRequested) event. + dictionary ReadFileRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // A request ID used to open the file. + long openRequestId; + + // Position in the file (in bytes) to start reading from. + double offset; + + // Number of bytes to be returned. + double length; + }; + + // Options for the $(ref:onCreateDirectoryRequested) event. + dictionary CreateDirectoryRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The path of the directory to be created. + DOMString directoryPath; + + // Whether the operation is recursive (for directories only). + boolean recursive; + }; + + // Options for the $(ref:onDeleteEntryRequested) event. + dictionary DeleteEntryRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The path of the entry to be deleted. + DOMString entryPath; + + // Whether the operation is recursive (for directories only). + boolean recursive; + }; + + // Options for the $(ref:onCreateFileRequested) event. + dictionary CreateFileRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The path of the file to be created. + DOMString filePath; + }; + + // Options for the $(ref:onCopyEntryRequested) event. + dictionary CopyEntryRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The source path of the entry to be copied. + DOMString sourcePath; + + // The destination path for the copy operation. + DOMString targetPath; + }; + + // Options for the $(ref:onMoveEntryRequested) event. + dictionary MoveEntryRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The source path of the entry to be moved into a new place. + DOMString sourcePath; + + // The destination path for the copy operation. + DOMString targetPath; + }; + + // Options for the $(ref:onTruncateRequested) event. + dictionary TruncateRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The path of the file to be truncated. + DOMString filePath; + + // Number of bytes to be retained after the operation completes. + double length; + }; + + // Options for the $(ref:onWriteFileRequested) event. + dictionary WriteFileRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // A request ID used to open the file. + long openRequestId; + + // Position in the file (in bytes) to start writing the bytes from. + double offset; + + // Buffer of bytes to be written to the file. + ArrayBuffer data; + }; + + // Options for the $(ref:onAbortRequested) event. + dictionary AbortRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // An ID of the request to be aborted. + long operationRequestId; + }; + + // Options for the $(ref:onAddWatcherRequested) event. + dictionary AddWatcherRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The path of the entry to be observed. + DOMString entryPath; + + // Whether observing should include all child entries recursively. It can be + // true for directories only. + boolean recursive; + }; + + // Options for the $(ref:onRemoveWatcherRequested) event. + dictionary RemoveWatcherRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The path of the watched entry. + DOMString entryPath; + + // Mode of the watcher. + boolean recursive; + }; + + // Information about an action for an entry. + dictionary Action { + // The identifier of the action. Any string or $(ref:CommonActionId) for + // common actions. + DOMString id; + + // The title of the action. It may be ignored for common actions. + DOMString? title; + }; + + // Options for the $(ref:onExecuteActionRequested) event. + dictionary ExecuteActionRequestedOptions { + // The identifier of the file system related to this operation. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + + // The set of paths of the entries to be used for the action. + DOMString[] entryPaths; + + // The identifier of the action to be executed. + DOMString actionId; + }; + + // Information about a change happened to an entry within the observed + // directory (including the entry itself). + dictionary Change { + // The path of the changed entry. + DOMString entryPath; + + // The type of the change which happened to the entry. + ChangeType changeType; + + // Information relating to the file if backed by a cloud file system. + CloudFileInfo? cloudFileInfo; + }; + + // Options for the $(ref:notify) method. + dictionary NotifyOptions { + // The identifier of the file system related to this change. + DOMString fileSystemId; + + // The path of the observed entry. + DOMString observedPath; + + // Mode of the observed entry. + boolean recursive; + + // The type of the change which happened to the observed entry. If it is + // DELETED, then the observed entry will be automatically removed from the + // list of observed entries. + ChangeType changeType; + + // List of changes to entries within the observed directory (including the + // entry itself) + Change[]? changes; + + // Tag for the notification. Required if the file system was mounted with + // the supportsNotifyTag option. Note, that this flag is + // necessary to provide notifications about changes which changed even + // when the system was shutdown. + DOMString? tag; + }; + + // Options for the $(ref:onConfigureRequested) event. + dictionary ConfigureRequestedOptions { + // The identifier of the file system to be configured. + DOMString fileSystemId; + + // The unique identifier of this request. + long requestId; + }; + + // Callback to receive the result of $(ref:getAll) function. + callback GetAllCallback = void(FileSystemInfo[] fileSystems); + + // Callback to receive the result of $(ref:get) function. + callback GetCallback = void(FileSystemInfo fileSystem); + + // Callback to be called by the providing extension in case of a success. + [nocompile] callback ProviderSuccessCallback = void(); + + // Callback to be called by the providing extension in case of an error. + // Any error code is allowed except OK. + [nocompile] callback ProviderErrorCallback = void(ProviderError error); + + // Success callback for the $(ref:onGetMetadataRequested) event. + [nocompile] callback MetadataCallback = void(EntryMetadata metadata); + + // Success callback for the $(ref:onGetActionsRequested) event. + [nocompile] callback ActionsCallback = void(Action[] actions); + + // Success callback for the $(ref:onReadDirectoryRequested) event. If more + // entries will be returned, then hasMore must be true, and it + // has to be called again with additional entries. If no more entries are + // available, then hasMore must be set to false. + [nocompile] callback EntriesCallback = void( + EntryMetadata[] entries, boolean hasMore); + + // Success callback for the $(ref:onReadFileRequested) event. If more + // data will be returned, then hasMore must be true, and it + // has to be called again with additional entries. If no more data is + // available, then hasMore must be set to false. + [nocompile] callback FileDataCallback = void( + ArrayBuffer data, boolean hasMore); + + // Success callback for the $(ref:onOpenFileRequested) event. + [nocompile] callback OpenFileSuccessCallback = void( + optional EntryMetadata metadata); + + // A generic result callback to indicate success or failure. + callback ResultCallback = void(); + + interface Functions { + // Mounts a file system with the given fileSystemId and + // displayName. displayName will be shown in the + // left panel of the Files app. displayName can contain any + // characters including '/', but cannot be an empty string. + // displayName must be descriptive but doesn't have to be + // unique. The fileSystemId must not be an empty string. + // + // Depending on the type of the file system being mounted, the + // source option must be set appropriately. + // + // In case of an error, $(ref:runtime.lastError) will be set with a + // corresponding error code. + static void mount( + MountOptions options, + optional ResultCallback callback); + + // Unmounts a file system with the given fileSystemId. It + // must be called after $(ref:onUnmountRequested) is invoked. Also, + // the providing extension can decide to perform unmounting if not requested + // (eg. in case of lost connection, or a file error). + // + // In case of an error, $(ref:runtime.lastError) will be set with a + // corresponding error code. + static void unmount( + UnmountOptions options, + optional ResultCallback callback); + + // Returns all file systems mounted by the extension. + static void getAll(GetAllCallback callback); + + // Returns information about a file system with the passed + // fileSystemId. + static void get( + DOMString fileSystemId, + GetCallback callback); + + // Notifies about changes in the watched directory at + // observedPath in recursive mode. If the file + // system is mounted with supportsNotifyTag, then + // tag must be provided, and all changes since the last + // notification always reported, even if the system was shutdown. The last + // tag can be obtained with $(ref:getAll). + // + // To use, the file_system_provider.notify manifest option + // must be set to true. + // + // Value of tag can be any string which is unique per call, + // so it's possible to identify the last registered notification. Eg. if + // the providing extension starts after a reboot, and the last registered + // notification's tag is equal to "123", then it should call $(ref:notify) + // for all changes which happened since the change tagged as "123". It + // cannot be an empty string. + // + // Not all providers are able to provide a tag, but if the file system has + // a changelog, then the tag can be eg. a change number, or a revision + // number. + // + // Note that if a parent directory is removed, then all descendant entries + // are also removed, and if they are watched, then the API must be notified + // about the fact. Also, if a directory is renamed, then all descendant + // entries are in fact removed, as there is no entry under their original + // paths anymore. + // + // In case of an error, $(ref:runtime.lastError) will be set + // will a corresponding error code. + static void notify( + NotifyOptions options, + optional ResultCallback callback); + }; + + interface Events { + // Raised when unmounting for the file system with the + // fileSystemId identifier is requested. In the response, the + // $(ref:unmount) API method must be called together with + // successCallback. If unmounting is not possible (eg. due to + // a pending operation), then errorCallback must be called. + [maxListeners=1] static void onUnmountRequested( + UnmountRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when metadata of a file or a directory at entryPath + // is requested. The metadata must be returned with the + // successCallback call. In case of an error, + // errorCallback must be called. + [maxListeners=1] static void onGetMetadataRequested( + GetMetadataRequestedOptions options, + MetadataCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when a list of actions for a set of files or directories at + // entryPaths is requested. All of the returned actions must + // be applicable to each entry. If there are no such actions, an empty array + // should be returned. The actions must be returned with the + // successCallback call. In case of an error, + // errorCallback must be called. + [maxListeners=1] static void onGetActionsRequested( + GetActionsRequestedOptions options, + ActionsCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when contents of a directory at directoryPath are + // requested. The results must be returned in chunks by calling the + // successCallback several times. In case of an error, + // errorCallback must be called. + [maxListeners=1] static void onReadDirectoryRequested( + ReadDirectoryRequestedOptions options, + EntriesCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when opening a file at filePath is requested. If the + // file does not exist, then the operation must fail. Maximum number of + // files opened at once can be specified with MountOptions. + [maxListeners=1] static void onOpenFileRequested( + OpenFileRequestedOptions options, + OpenFileSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when opening a file previously opened with + // openRequestId is requested to be closed. + [maxListeners=1] static void onCloseFileRequested( + CloseFileRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when reading contents of a file opened previously with + // openRequestId is requested. The results must be returned in + // chunks by calling successCallback several times. In case of + // an error, errorCallback must be called. + [maxListeners=1] static void onReadFileRequested( + ReadFileRequestedOptions options, + FileDataCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when creating a directory is requested. The operation must fail + // with the EXISTS error if the target directory already exists. + // If recursive is true, then all of the missing directories + // on the directory path must be created. + [maxListeners=1] static void onCreateDirectoryRequested( + CreateDirectoryRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when deleting an entry is requested. If recursive is + // true, and the entry is a directory, then all of the entries inside + // must be recursively deleted as well. + [maxListeners=1] static void onDeleteEntryRequested( + DeleteEntryRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when creating a file is requested. If the file already exists, + // then errorCallback must be called with the + // "EXISTS" error code. + [maxListeners=1] static void onCreateFileRequested( + CreateFileRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when copying an entry (recursively if a directory) is requested. + // If an error occurs, then errorCallback must be called. + [maxListeners=1] static void onCopyEntryRequested( + CopyEntryRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when moving an entry (recursively if a directory) is requested. + // If an error occurs, then errorCallback must be called. + [maxListeners=1] static void onMoveEntryRequested( + MoveEntryRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when truncating a file to a desired length is requested. + // If an error occurs, then errorCallback must be called. + [maxListeners=1] static void onTruncateRequested( + TruncateRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when writing contents to a file opened previously with + // openRequestId is requested. + [maxListeners=1] static void onWriteFileRequested( + WriteFileRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when aborting an operation with operationRequestId + // is requested. The operation executed with operationRequestId + // must be immediately stopped and successCallback of this + // abort request executed. If aborting fails, then + // errorCallback must be called. Note, that callbacks of the + // aborted operation must not be called, as they will be ignored. Despite + // calling errorCallback, the request may be forcibly aborted. + [maxListeners=1] static void onAbortRequested( + AbortRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when showing a configuration dialog for fileSystemId + // is requested. If it's handled, the + // file_system_provider.configurable manfiest option must be + // set to true. + [maxListeners=1] static void onConfigureRequested( + ConfigureRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when showing a dialog for mounting a new file system is requested. + // If the extension/app is a file handler, then this event shouldn't be + // handled. Instead app.runtime.onLaunched should be handled in + // order to mount new file systems when a file is opened. For multiple + // mounts, the file_system_provider.multiple_mounts manifest + // option must be set to true. + [maxListeners=1] static void onMountRequested( + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when setting a new directory watcher is requested. If an error + // occurs, then errorCallback must be called. + [maxListeners=1] static void onAddWatcherRequested( + AddWatcherRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when the watcher should be removed. If an error occurs, then + // errorCallback must be called. + [maxListeners=1] static void onRemoveWatcherRequested( + RemoveWatcherRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + + // Raised when executing an action for a set of files or directories is\ + // requested. After the action is completed, successCallback + // must be called. On error, errorCallback must be called. + [maxListeners=1] static void onExecuteActionRequested( + ExecuteActionRequestedOptions options, + ProviderSuccessCallback successCallback, + ProviderErrorCallback errorCallback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/file_system_provider_internal.idl b/tools/under-control/src/chrome/common/extensions/api/file_system_provider_internal.idl new file mode 100755 index 000000000..ce8384e4b --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/file_system_provider_internal.idl @@ -0,0 +1,82 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Internal, used by fileSystemProvider's custom bindings. These functions are +// called when events' callbacks are invoked. +[implemented_in="chrome/browser/chromeos/extensions/file_system_provider/file_system_provider_api.h", + nodoc] +namespace fileSystemProviderInternal { + interface Functions { + // Internal. Callback for mount requests. + static void respondToMountRequest( + long requestId, + fileSystemProvider.ProviderError error, + long executionTime); + + // Internal. Success callback of the onUnmountRequested + // event. Must be called when unmounting is completed. + static void unmountRequestedSuccess( + DOMString fileSystemId, + long requestId, + long executionTime); + + // Internal. Success callback of the onGetMetadataRequested + // event. Must be called if metadata is available. + static void getMetadataRequestedSuccess( + DOMString fileSystemId, + long requestId, + fileSystemProvider.EntryMetadata metadata, + long executionTime); + + // Internal. Success callback of the onGetActionsRequested + // event. Must be called if actions are available. + static void getActionsRequestedSuccess( + DOMString fileSystemId, + long requestId, + fileSystemProvider.Action[] actions, + long executionTime); + + // Internal. Success callback of the onReadDirectoryRequested + // event. Can be called multiple times per request. + static void readDirectoryRequestedSuccess( + DOMString fileSystemId, + long requestId, + fileSystemProvider.EntryMetadata[] entries, + boolean hasMore, + long executionTime); + + // Internal. Success callback of the onReadFileRequested + // event. Can be called multiple times per request. + static void readFileRequestedSuccess( + DOMString fileSystemId, + long requestId, + ArrayBuffer data, + boolean hasMore, + long executionTime); + + // Internal. Success callback of the onOpenFileRequested + // event. + static void openFileRequestedSuccess( + DOMString fileSystemId, + long requestId, + long executionTime, + optional fileSystemProvider.EntryMetadata metadata); + + // Internal. Success callback of all of the operation requests, which do not + // return any value. Must be called in case of a success. + static void operationRequestedSuccess( + DOMString fileSystemId, + long requestId, + long executionTime); + + // Internal. Error callback of all of the operation requests. Must be called + // if an operation fails. + static void operationRequestedError( + DOMString fileSystemId, + long requestId, + fileSystemProvider.ProviderError error, + long executionTime); + }; +}; + diff --git a/tools/under-control/src/chrome/common/extensions/api/identity.idl b/tools/under-control/src/chrome/common/extensions/api/identity.idl new file mode 100755 index 000000000..471462c63 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/identity.idl @@ -0,0 +1,243 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.identity API to get OAuth2 access tokens. +namespace identity { + + dictionary AccountInfo { + // A unique identifier for the account. This ID will not change + // for the lifetime of the account. + DOMString id; + }; + + enum AccountStatus { + // Specifies that Sync is enabled for the primary account. + SYNC, + // Specifies the existence of a primary account, if any. + ANY + }; + + dictionary ProfileDetails { + // A status of the primary account signed into a profile whose + // ProfileUserInfo should be returned. Defaults to + // SYNC account status. + AccountStatus? accountStatus; + }; + + dictionary ProfileUserInfo { + // An email address for the user account signed into the current + // profile. Empty if the user is not signed in or the + // identity.email manifest permission is not + // specified. + DOMString email; + + // A unique identifier for the account. This ID will not change + // for the lifetime of the account. Empty if the user is not + // signed in or (in M41+) the identity.email + // manifest permission is not specified. + DOMString id; + }; + + dictionary TokenDetails { + // Fetching a token may require the user to sign-in to Chrome, or + // approve the application's requested scopes. If the interactive + // flag is true, getAuthToken will + // prompt the user as necessary. When the flag is + // false or omitted, getAuthToken will + // return failure any time a prompt would be required. + boolean? interactive; + + // The account ID whose token should be returned. If not specified, the + // function will use an account from the Chrome profile: the Sync account if + // there is one, or otherwise the first Google web account. + AccountInfo? account; + + // A list of OAuth2 scopes to request. + // + // When the scopes field is present, it overrides the + // list of scopes specified in manifest.json. + DOMString[]? scopes; + + // The enableGranularPermissions flag allows extensions to + // opt-in early to the granular permissions consent screen, in which + // requested permissions are granted or denied individually. + boolean? enableGranularPermissions; + }; + + dictionary InvalidTokenDetails { + // The specific token that should be removed from the cache. + DOMString token; + }; + + dictionary WebAuthFlowDetails { + // The URL that initiates the auth flow. + DOMString url; + + // Whether to launch auth flow in interactive mode. + // + // Since some auth flows may immediately redirect to a result URL, + // launchWebAuthFlow hides its web view until the first + // navigation either redirects to the final URL, or finishes loading a page + // meant to be displayed. + // + // If the interactive flag is true, the window + // will be displayed when a page load completes. If the flag is + // false or omitted, launchWebAuthFlow will return + // with an error if the initial navigation does not complete the flow. + // + // For flows that use JavaScript for redirection, + // abortOnLoadForNonInteractive can be set to false + // in combination with setting timeoutMsForNonInteractive to give + // the page a chance to perform any redirects. + boolean? interactive; + + // Whether to terminate launchWebAuthFlow for non-interactive + // requests after the page loads. This parameter does not affect interactive + // flows. + // + // When set to true (default) the flow will terminate + // immediately after the page loads. When set to false, the + // flow will only terminate after the + // timeoutMsForNonInteractive passes. This is useful for + // identity providers that use JavaScript to perform redirections after the + // page loads. + boolean? abortOnLoadForNonInteractive; + + // The maximum amount of time, in miliseconds, + // launchWebAuthFlow is allowed to run in non-interactive mode + // in total. Only has an effect if interactive is + // false. + long? timeoutMsForNonInteractive; + }; + + dictionary GetAuthTokenResult { + // The specific token associated with the request. + DOMString? token; + + // A list of OAuth2 scopes granted to the extension. + DOMString[]? grantedScopes; + }; + + callback GetAuthTokenCallback = void (GetAuthTokenResult result); + callback GetAccountsCallback = void (AccountInfo[] accounts); + callback GetProfileUserInfoCallback = void (ProfileUserInfo userInfo); + callback InvalidateAuthTokenCallback = void (); + callback ClearAllCachedAuthTokensCallback = void (); + callback LaunchWebAuthFlowCallback = void (optional DOMString responseUrl); + + interface Functions { + // Retrieves a list of AccountInfo objects describing the accounts + // present on the profile. + // + // getAccounts is only supported on dev channel. + static void getAccounts(GetAccountsCallback callback); + + // Gets an OAuth2 access token using the client ID and scopes + // specified in the oauth2 + // section of manifest.json. + // + // The Identity API caches access tokens in memory, so it's ok to + // call getAuthToken non-interactively any time a token is + // required. The token cache automatically handles expiration. + // + // For a good user experience it is important interactive token requests are + // initiated by UI in your app explaining what the authorization is for. + // Failing to do this will cause your users to get authorization requests, + // or Chrome sign in screens if they are not signed in, with with no + // context. In particular, do not use getAuthToken + // interactively when your app is first launched. + // + // Note: When called with a callback, instead of returning an object this + // function will return the two properties as separate arguments passed to + // the callback. + // + // |details| : Token options. + // |callback| : Called with an OAuth2 access token as specified by the + // manifest, or undefined if there was an error. The + // grantedScopes parameter is populated since Chrome 87. When + // available, this parameter contains the list of granted scopes + // corresponding with the returned token. + static void getAuthToken( + optional TokenDetails details, + optional GetAuthTokenCallback callback); + + // Retrieves email address and obfuscated gaia id of the user + // signed into a profile. + // + // Requires the identity.email manifest permission. Otherwise, + // returns an empty result. + // + // This API is different from identity.getAccounts in two + // ways. The information returned is available offline, and it + // only applies to the primary account for the profile. + // + // |details|: Profile options. + // |callback|: Called with the ProfileUserInfo of the primary + // Chrome account, of an empty ProfileUserInfo if the account + // with given details doesn't exist. + static void getProfileUserInfo( + optional ProfileDetails details, + GetProfileUserInfoCallback callback); + + // Removes an OAuth2 access token from the Identity API's token cache. + // + // If an access token is discovered to be invalid, it should be + // passed to removeCachedAuthToken to remove it from the + // cache. The app may then retrieve a fresh token with + // getAuthToken. + // + // |details| : Token information. + // |callback| : Called when the token has been removed from the cache. + static void removeCachedAuthToken( + InvalidTokenDetails details, + optional InvalidateAuthTokenCallback callback); + + // Resets the state of the Identity API: + //
    + //
  • Removes all OAuth2 access tokens from the token cache
  • + //
  • Removes user's account preferences
  • + //
  • De-authorizes the user from all auth flows
  • + //
+ // + // |callback| : Called when the state has been cleared. + static void clearAllCachedAuthTokens( + ClearAllCachedAuthTokensCallback callback); + + // Starts an auth flow at the specified URL. + // + // This method enables auth flows with non-Google identity + // providers by launching a web view and navigating it to the + // first URL in the provider's auth flow. When the provider + // redirects to a URL matching the pattern + // https://<app-id>.chromiumapp.org/*, the + // window will close, and the final redirect URL will be passed to + // the callback function. + // + // For a good user experience it is important interactive auth flows are + // initiated by UI in your app explaining what the authorization is for. + // Failing to do this will cause your users to get authorization requests + // with no context. In particular, do not launch an interactive auth flow + // when your app is first launched. + // + // |details| : WebAuth flow options. + // |callback| : Called with the URL redirected back to your application. + static void launchWebAuthFlow( + WebAuthFlowDetails details, + LaunchWebAuthFlowCallback callback); + + // Generates a redirect URL to be used in |launchWebAuthFlow|. + // + // The generated URLs match the pattern + // https://<app-id>.chromiumapp.org/*. + // + // |path| : The path appended to the end of the generated URL. + [nocompile] static DOMString getRedirectURL(optional DOMString path); + }; + + interface Events { + // Fired when signin state changes for an account on the user's profile. + static void onSignInChanged(AccountInfo account, boolean signedIn); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/idltest.idl b/tools/under-control/src/chrome/common/extensions/api/idltest.idl new file mode 100755 index 000000000..6ccc07044 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/idltest.idl @@ -0,0 +1,33 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// An API to test IDL schema specifications. +namespace idltest { + + callback LongArrayCallback = void(long[] array); + callback ArrayBufferCallback = void(ArrayBuffer buffer); + + interface Functions { + // Functions for testing binary data request/response parameters. The first + // two just return back the bytes they were passed in an array. + static void sendArrayBuffer( + ArrayBuffer input, + LongArrayCallback callback); + + // TODO(asargent) - we currently can't have [instanceOf=ArrayBufferView], + // I think because ArrayBufferView isn't an instantiable type. The best + // we might be able to do is have a 'choices' list including all the + // typed array subclasses like Uint8Array, Uint16Array, Float32Array, etc. + static void sendArrayBufferView( + [instanceOf=Uint8Array] ArrayBufferView input, + LongArrayCallback callback); + static void getArrayBuffer(ArrayBufferCallback callback); + + // This function should not have C++ code autogenerated (the variable name + // |switch| should cause compile errors if it does). But the name should + // get defined and made visible from within extensions/apps code. + [nocompile] static void nocompileFunc(long switch); + }; + +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/image_loader_private.idl b/tools/under-control/src/chrome/common/extensions/api/image_loader_private.idl new file mode 100755 index 000000000..44d8fb4b2 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/image_loader_private.idl @@ -0,0 +1,45 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// imageLoaderPrivate API. +// This is a private API used by the ChromeOS FilesApp ImageLoader extension. +[platforms=("chromeos"), + implemented_in="chrome/browser/ash/extensions/file_manager/image_loader_private_api.h"] +namespace imageLoaderPrivate { + // |thumbnailDataUrl| A data URL for the thumbnail; |thumbnailDataUrl| is + // empty if no thumbnail was available. + callback GetThumbnailCallback = void(DOMString thumbnailDataUrl); + + interface Functions { + // For a file in DriveFS, retrieves its thumbnail. If |cropToSquare| is + // true, returns a thumbnail appropriate for file list or grid views; + // otherwise, returns a thumbnail appropriate for quickview. + [doesNotSupportPromises] + static void getDriveThumbnail(DOMString url, + boolean cropToSquare, + GetThumbnailCallback callback); + + // For a local PDF file, retrieves its thumbnail with a given |width| and + // |height|. + [doesNotSupportPromises] + static void getPdfThumbnail(DOMString url, + long width, + long height, + GetThumbnailCallback callback); + + // Retrieves a thumbnail of an ARC DocumentsProvider file, closely matching + // the hinted size specified by |widthHint| and |heightHint|, but not + // necessarily the exact size. |callback| is called with thumbnail data + // encoded as a data URL. If the document does not support thumbnails, + // |callback| is called with an empty string. + // Note: The thumbnail data may originate from third-party application code, + // and is untrustworthy (Security). + [doesNotSupportPromises] + static void getArcDocumentsProviderThumbnail(DOMString url, + long widthHint, + long heightHint, + GetThumbnailCallback callback); + }; +}; + diff --git a/tools/under-control/src/chrome/common/extensions/api/image_writer_private.idl b/tools/under-control/src/chrome/common/extensions/api/image_writer_private.idl new file mode 100755 index 000000000..b75c53d02 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/image_writer_private.idl @@ -0,0 +1,145 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.image_writer API to write images to +// removable media. +// +// See the design doc for a detailed description of this API. +// https://goo.gl/KzMEFq +namespace imageWriterPrivate { + // The different stages of a write call. + // + //
+ //
confirmation
+ //
The process starts by prompting the user for confirmation.
+ //
download
+ //
The image file is being download if a remote image was + // requested.
+ //
verifyDownload
+ //
The download is being verified to match the image hash, if + // provided
+ //
unzip
+ //
The image is being extracted from the downloaded zip file
+ //
write
+ //
The image is being written to disk.
+ //
verifyWrite
+ //
The system is verifying that the written image matches the + // downloaded image. + //
+ enum Stage { + confirmation, + download, + verifyDownload, + unzip, + write, + verifyWrite, + unknown + }; + + // Options for writing an image. + dictionary UrlWriteOptions { + // If present, verify that the downloaded image matches this hash. + DOMString? imageHash; + // If true, save the downloaded image as a file using the user's downloads + // preferences. + boolean? saveAsDownload; + }; + + dictionary ProgressInfo { + // The $(ref:Stage) that the write process is currently in. + Stage stage; + // Current progress within the stage. + long percentComplete; + }; + + dictionary RemovableStorageDevice { + DOMString storageUnitId; + double capacity; + DOMString vendor; + DOMString model; + boolean removable; + }; + + callback WriteImageCallback = void (); + callback WriteCancelCallback = void (); + callback ListRemovableStorageDevicesCallback = void (RemovableStorageDevice[] devices); + callback DestroyPartitionsCallback = void (); + + interface Functions { + // Write an image to the disk downloaded from the provided URL. The + // callback will be called when the entire operation completes, either + // successfully or on error. + // + // |storageUnitId|: The identifier for the storage unit + // |imageUrl|: The url of the image to download which will be written + // to the storage unit identified by |storageUnitId| + // |options|: Optional parameters if comparing the download with a given + // hash or saving the download to the users Downloads folder instead of a + // temporary directory is desired + // |callback|: The callback which signifies that the write operation has + // been started by the system and provides a unique ID for this operation. + static void writeFromUrl( + DOMString storageUnitId, + DOMString imageUrl, + optional UrlWriteOptions options, + WriteImageCallback callback); + + // Write an image to the disk, prompting the user to supply the image from + // a local file. The callback will be called when the entire operation + // completes, either successfully or on error. + // + // |storageUnitId|: The identifier for the storage unit + // |fileEntry|: The FileEntry object of the image to be burned. + // |callback|: The callback which signifies that the write operation has + // been started by the system and provides a unique ID for this operation. + static void writeFromFile( + DOMString storageUnitId, + [instanceOf=FileEntry] object fileEntry, + WriteImageCallback callback); + + // Cancel a current write operation. + // + // |callback|: The callback which is triggered with the write is + // successfully cancelled, passing the $(ref:ProgressInfo) of the operation at + // the time it was cancelled. + static void cancelWrite(WriteCancelCallback callback); + + // Destroys the partition table of a disk, effectively erasing it. This is + // a fairly quick operation and so it does not have complex stages or + // progress information, just a write phase. + // + // |storageUnitId|: The identifier of the storage unit to wipe + // |callback|: A callback that triggers when the operation has been + // successfully started. + static void destroyPartitions( + DOMString storageUnitId, + DestroyPartitionsCallback callback); + + // List all the removable block devices currently attached to the system. + // |callback|: A callback called with a list of removable storage devices + static void listRemovableStorageDevices( + ListRemovableStorageDevicesCallback callback); + }; + + interface Events { + // Fires periodically throughout the writing operation and at least once per + // stage. + static void onWriteProgress(ProgressInfo info); + + // Fires when the write operation has completely finished, such as all + // devices being finalized and resources released. + static void onWriteComplete(); + + // Fires when an error occured during writing, passing the $(ref:ProgressInfo) + // of the operation at the time the error occured. + static void onWriteError(ProgressInfo info, DOMString error); + + // Fires when a removable storage device is inserted. + static void onDeviceInserted(RemovableStorageDevice device); + + // Fires when a removable storage device is removed. + static void onDeviceRemoved(RemovableStorageDevice device); + }; + +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/language_settings_private.idl b/tools/under-control/src/chrome/common/extensions/api/language_settings_private.idl new file mode 100755 index 000000000..52dcfd64b --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/language_settings_private.idl @@ -0,0 +1,183 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.languageSettingsPrivate API to get or change +// language and input method settings. +namespace languageSettingsPrivate { + enum MoveType { + TOP, + UP, + DOWN, + UNKNOWN + }; + + dictionary Language { + // The unique code identifying the language. + DOMString code; + + // The name of the language, in the current UI language. + DOMString displayName; + + // The name of the language as it is in its own language. + DOMString nativeDisplayName; + + // Whether the UI can be displayed in this language. Defaults to false. + boolean? supportsUI; + + // Whether this language can be used for spell checking. Defaults to false. + boolean? supportsSpellcheck; + + // Whether this language has translations for the current target language. + // Defaults to false. + boolean? supportsTranslate; + + // Whether this language is prohibited as a UI locale (not in the list of + // the 'AllowedLanguages' policy). Defaults to false. + boolean? isProhibitedLanguage; + }; + + dictionary SpellcheckDictionaryStatus { + // The language code of the dictionary that the status describes. + DOMString languageCode; + + // Whether the dictionary is ready (has been loaded from disk or + // successfully downloaded). + boolean isReady; + + // Whether the dictionary is being downloaded. Defaults to false. + boolean? isDownloading; + + // Whether the dictionary download failed. Defaults to false. + boolean? downloadFailed; + }; + + dictionary InputMethod { + // The ID of the input method descriptor. + DOMString id; + + // The human-readable name of the input method. + DOMString displayName; + + // The language codes this input method supports. + DOMString[] languageCodes; + + // The search terms for the input method. + DOMString[] tags; + + // True if the input method is enabled. + boolean? enabled; + + // True if the input method extension has an options page. + boolean? hasOptionsPage; + + // True if the input method is not allowed by policy. + boolean? isProhibitedByPolicy; + }; + + dictionary InputMethodLists { + // The list of component extension input methods. + InputMethod[] componentExtensionImes; + + // The list of third-party extension input methods. + InputMethod[] thirdPartyExtensionImes; + }; + + callback GetLanguageListCallback = void (Language[] languages); + callback GetAlwaysTranslateLanguagesCallback = + void (DOMString[] languageCodes); + callback GetNeverTranslateLanguagesCallback = + void (DOMString[] languageCodes); + callback GetInputMethodListsCallback = void (InputMethodLists lists); + callback GetSpellcheckWordsCallback = void (DOMString[] words); + callback GetTranslateTargetLanguageCallback = void (DOMString languageCode); + callback GetSpellcheckDictionaryStatusesCallback = + void (SpellcheckDictionaryStatus[] status); + + interface Functions { + // Gets languages available for translate, spell checking, input and locale. + static void getLanguageList( + GetLanguageListCallback callback); + + // Enables a language, adding it to the Accept-Language list (used to decide + // which languages to translate, generate the Accept-Language header, etc.). + static void enableLanguage(DOMString languageCode); + + // Disables a language, removing it from the Accept-Language list. + static void disableLanguage(DOMString languageCode); + + // Enables or disables translation for a given language. + static void setEnableTranslationForLanguage( + DOMString languageCode, boolean enable); + + // Moves a language inside the language list. + static void moveLanguage(DOMString languageCode, MoveType moveType); + + // Gets languages that should always be automatically translated. + static void getAlwaysTranslateLanguages( + GetAlwaysTranslateLanguagesCallback callback); + + // Sets whether a given language should always be automatically translated. + static void setLanguageAlwaysTranslateState( + DOMString languageCode, boolean alwaysTranslate); + + // Gets languages that should never be offered to translate. + static void getNeverTranslateLanguages( + GetNeverTranslateLanguagesCallback callback); + + // Gets the current status of the chosen spell check dictionaries. + static void getSpellcheckDictionaryStatuses( + GetSpellcheckDictionaryStatusesCallback callback); + + // Gets the custom spell check words, in sorted order. + static void getSpellcheckWords( + GetSpellcheckWordsCallback callback); + + // Adds a word to the custom dictionary. + static void addSpellcheckWord(DOMString word); + + // Removes a word from the custom dictionary. + static void removeSpellcheckWord(DOMString word); + + // Gets the translate target language (in most cases, the display locale). + static void getTranslateTargetLanguage( + GetTranslateTargetLanguageCallback callback); + + // Sets the translate target language given a language code. + static void setTranslateTargetLanguage(DOMString languageCode); + + // Gets all supported input methods, including third-party IMEs. + // Chrome OS only. + static void getInputMethodLists( + GetInputMethodListsCallback callback); + + // Adds the input method to the current user's list of enabled input + // methods, enabling the input method for the current user. Chrome OS only. + static void addInputMethod(DOMString inputMethodId); + + // Removes the input method from the current user's list of enabled input + // methods, disabling the input method for the current user. Chrome OS only. + static void removeInputMethod(DOMString inputMethodId); + + // Tries to download the dictionary after a failed download. + static void retryDownloadDictionary(DOMString languageCode); + }; + + interface Events { + // Called when the pref for the dictionaries used for spell checking changes + // or the status of one of the spell check dictionaries changes. + static void onSpellcheckDictionariesChanged( + SpellcheckDictionaryStatus[] statuses); + + // Called when words are added to and/or removed from the custom spell check + // dictionary. + static void onCustomDictionaryChanged( + DOMString[] wordsAdded, DOMString[] wordsRemoved); + + // Called when an input method is added. + static void onInputMethodAdded(DOMString inputMethodId); + + // Called when an input method is removed. + static void onInputMethodRemoved(DOMString inputMethodId); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/login.idl b/tools/under-control/src/chrome/common/extensions/api/login.idl new file mode 100755 index 000000000..56a42db48 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/login.idl @@ -0,0 +1,180 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.login API to launch and exit user sessions. +[platforms=("chromeos", "lacros"), + implemented_in="chrome/browser/chromeos/extensions/login_screen/login/login_api.h"] +namespace login { + callback VoidCallback = void (); + callback StringCallback = void (DOMString result); + dictionary SamlUserSessionProperties { + // User's email address. + DOMString email; + + // User's Gaia ID. + DOMString gaiaId; + + // User's password. + DOMString password; + + // Oauth_code cookie set in the SAML handshake. + DOMString oauthCode; + }; + + interface Functions { + // Launches a managed guest session if one is set up via the admin console. + // If there are several managed guest sessions set up, it will launch the + // first available one. + // |password|: If provided, the launched managed guest session will be + // lockable, and can only be unlocked by calling + // $(ref:unlockManagedGuestSession) with the same password. + // |callback|: Note: If the function succeeds, the callback is not + // guaranteed to be invoked as the extension will be disabled when the + // session starts. Use this callback only to handle the failure case by + // checking $(ref:runtime.lastError). + static void launchManagedGuestSession( + optional DOMString password, + optional VoidCallback callback); + + // Exits the current session. + // |dataForNextLoginAttempt|: If set, stores data which can be read by + // $(ref:fetchDataForNextLoginAttempt) from the login screen. If unset, any + // currently stored data will be cleared. + static void exitCurrentSession( + optional DOMString dataForNextLoginAttempt, + optional VoidCallback callback); + + // Reads the $(ref:dataForNextLoginAttempt) set by + // $(ref:exitCurrentSession). Clears the previously stored data after + // reading so it can only be read once. + // |callback|: Called with the stored data, or an empty string if there was + // no previously stored data. + static void fetchDataForNextLoginAttempt( + StringCallback callback); + + // Deprecated. Please use $(ref:lockCurrentSession) instead. + [deprecated="Use $(ref:lockCurrentSession) instead."] + static void lockManagedGuestSession(optional VoidCallback callback); + + // Locks the current session. The session has to be either a user session or + // a Managed Guest Session launched by $(ref:launchManagedGuestSession) with + // a password. + static void lockCurrentSession( + optional VoidCallback callback); + + // Deprecated. Please use $(ref:unlockCurrentSession) instead. + [deprecated="Use $(ref:unlockCurrentSession) instead."] + static void unlockManagedGuestSession( + DOMString password, + optional VoidCallback callback); + + // Unlocks the current session. The session has to be either a user session + // or a Managed Guest Session launched by $(ref:launchManagedGuestSession) + // with a password. The session will unlock if the provided password matches + // the one used to launch the session. + // |password|: The password which will be used to unlock the session. + // |callback|: Note: If the function succeeds, the callback is not + // guaranteed to be invoked as the extension will be disabled when the + // session starts. Use this callback only to handle the failure case by + // checking $(ref:runtime.lastError). + static void unlockCurrentSession( + DOMString password, + optional VoidCallback callback); + + // Launches a SAML-backed user session. + // |properties|: User's email address, gaia ID, password and oauth_code. + // |callback|: Note: If the function succeeds, the callback is not + // guaranteed to be invoked as the extension will be disabled when the + // session starts. Use this callback only to handle the failure case by + // checking $(ref:runtime.lastError). + static void launchSamlUserSession( + SamlUserSessionProperties properties, + optional VoidCallback callback); + + // Starts a ChromeOS Managed Guest Session which will host the shared user + // sessions. An initial shared session is entered with |password| as the + // password. When this shared session is locked, it can only be unlocked by + // the same extension calling $(ref:unlockSharedSession) with the same + // password. + // Fails when another shared ChromeOS Managed Guest Session has already + // been launched. Can only be called from the login screen. + // |password|: The password which can be used to unlock the shared session. + // |callback|: Note: If the function succeeds, the callback is not + // guaranteed to be invoked as the extension will be disabled when the + // session starts. Use this callback only to handle the failure case by + // checking $(ref:runtime.lastError). + static void launchSharedManagedGuestSession( + DOMString password, + optional VoidCallback callback); + + // Enters the shared session with the given password. If the session is + // locked, it can only be unlocked by calling $(ref:unlockSharedSession) + // with the same password. + // Fails if calling extension is not the same as the one which called + // $(ref:launchSharedManagedGuestSession) or there is already a shared + // session running. Can only be called from the lock screen. + // |password|: The password which can be used to unlock the shared session. + // |callback|: Note: If the function succeeds, the callback is not + // guaranteed to be invoked as the extension will be disabled when the + // session starts. Use this callback only to handle the failure case by + // checking $(ref:runtime.lastError). + static void enterSharedSession( + DOMString password, + optional VoidCallback callback); + + // Unlocks the shared session with the provided password. Fails if the + // password does not match the one provided to + // $(ref:launchSharedManagedGuestSession) or $(ref:enterSharedSession). + // Fails if the calling extension is not the same as the one which called + // $(ref:launchSharedManagedGuestSession) or if there is no existing shared + // session. Can only be called from the lock screen. + // |password|: The password used to unlock the shared session. + // |callback|: Note: If the function succeeds, the callback is not + // guaranteed to be invoked as the extension will be disabled when the + // session starts. Use this callback only to handle the failure case by + // checking $(ref:runtime.lastError). + static void unlockSharedSession( + DOMString password, + optional VoidCallback callback); + + // Ends the shared session. Security- and privacy-sensitive data in the + // session will be cleaned up on a best effort basis. + // The calling extension does not have to be the same one which called + // $(ref:launchSharedManagedGuestSession). Can be called from both the + // lock screen or in session. + // Fails if there is no existing shared session. + // |callback|: Invoked after cleanup operations have finished and the + // session is locked. + static void endSharedSession( + optional VoidCallback callback); + + // Sets data for the next login attempt. The data can be retrieved by + // calling $(ref:fetchDataForNextLoginAttempt). The data is cleared when + // it is fetched so it can only be read once. + // |dataForNextLoginAttempt|: The data to be set. + static void setDataForNextLoginAttempt( + DOMString dataForNextLoginAttempt, + optional VoidCallback callback); + + // Dispatches a $(ref:onRequestExternalLogout) event. Called from the login + // screen extension on the lock screen. + static void requestExternalLogout( + optional VoidCallback callback); + + // Dispatches a $(ref:onExternalLogoutDone) event. Called from the + // in-session extension. + static void notifyExternalLogoutDone( + optional VoidCallback callback); + }; + + interface Events { + // Event dispatched when an external logout is requested. The in-session + // extension listens for this event. + static void onRequestExternalLogout(); + + // Event dispatched when an external logout is completed. The login screen + // extension on the lock screen listens for this event. + static void onExternalLogoutDone(); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/login_screen_storage.idl b/tools/under-control/src/chrome/common/extensions/api/login_screen_storage.idl new file mode 100755 index 000000000..118c785d7 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/login_screen_storage.idl @@ -0,0 +1,51 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.loginScreenStorage API to store persistent data +// from the login screen or inject data into the session. +[platforms=("chromeos", "lacros"), + implemented_in="chrome/browser/chromeos/extensions/login_screen/login_screen_storage/login_screen_storage_api.h"] +namespace loginScreenStorage { + callback StoreCallback = void (); + callback RetrieveCallback = void (DOMString data); + + interface Functions { + // Stores persistent data from the login screen. This data can be accessed + // later using $(ref:retrievePersistentData) by any extension from the + // specified extension ids. This method will fail if called while a user + // session is active. + // |extensionIds|: IDs of the extensions that should have access to the + // stored data. + // |data|: The data to store. + static void storePersistentData( + DOMString[] extensionIds, + DOMString data, + StoreCallback callback); + + // Retrieves persistent data that was previously stored using + // $(ref:storePersistentData) for the caller's extension ID. + // |ownerId|: ID of the extension that saved the data that the caller is + // trying to retrieve. + static void retrievePersistentData( + DOMString ownerId, + RetrieveCallback callback); + + // Stores credentials for later access from the user session. This method + // will fail if called while a user session is active. + // |extensionId|: ID of the in-session extension that should have access to + // these credentials. Credentials stored using this method are deleted on + // session exit. + // |credentials|: The credentials to store. + static void storeCredentials( + DOMString extensionId, + DOMString credentials, + StoreCallback callback); + + // Retrieves credentials that were previosly stored using + // $(ref:storeCredentials). The caller's extension ID should be the same as + // the extension id passed to the $(ref:storeCredentials). + static void retrieveCredentials( + RetrieveCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/login_screen_ui.idl b/tools/under-control/src/chrome/common/extensions/api/login_screen_ui.idl new file mode 100755 index 000000000..7f0259081 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/login_screen_ui.idl @@ -0,0 +1,33 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.loginScreenUi API to show and hide custom +// login UI. +[platforms=("chromeos"), + implemented_in="chrome/browser/ash/extensions/login_screen_ui/login_screen_ui_api.h"] +namespace loginScreenUi { + + dictionary ShowOptions { + // Relative url of the contents to show. + DOMString url; + + // Whether the user can close the window, defaults to false. + boolean? userCanClose; + }; + + // Callback that does not take arguments. + callback SimpleCallback = void (); + + interface Functions { + // Opens a window, which is visible on top of the login and lock screen. + // |options|: Options for the custom login UI window. + static void show( + ShowOptions options, + optional SimpleCallback callback); + + // Closes the login/lock screen UI window previously opened by this + // extension. + static void close(optional SimpleCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/login_state.idl b/tools/under-control/src/chrome/common/extensions/api/login_state.idl new file mode 100755 index 000000000..3a1f702e3 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/login_state.idl @@ -0,0 +1,55 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.loginState API to read and monitor the login +// state. +[platforms=("chromeos", "lacros"), + implemented_in="chrome/browser/chromeos/extensions/login_screen/login_state/login_state_api.h"] +namespace loginState { + enum ProfileType { + // Specifies that the extension is in the signin profile. + SIGNIN_PROFILE, + + // Specifies that the extension is in the user profile. + USER_PROFILE + }; + + enum SessionState { + // Specifies that the session state is unknown. + UNKNOWN, + + // Specifies that the user is in the out-of-box-experience screen. + IN_OOBE_SCREEN, + + // Specifies that the user is in the login screen. + IN_LOGIN_SCREEN, + + // Specifies that the user is in the session. + IN_SESSION, + + // Specifies that the user is in the lock screen. + IN_LOCK_SCREEN, + + // Specifies that the device is in RMA mode, finalizing repairs. + IN_RMA_SCREEN + }; + + callback ProfileTypeCallback = void (ProfileType result); + callback SessionStateCallback = void (SessionState result); + + interface Functions { + // Gets the type of the profile the extension is in. + static void getProfileType(ProfileTypeCallback callback); + + // Gets the current session state. + static void getSessionState( + SessionStateCallback callback); + }; + + interface Events { + // Dispatched when the session state changes. sessionState + // is the new session state. + static void onSessionStateChanged(SessionState sessionState); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/mdns.idl b/tools/under-control/src/chrome/common/extensions/api/mdns.idl new file mode 100755 index 000000000..33d714256 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/mdns.idl @@ -0,0 +1,53 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.mdns API to discover services over mDNS. +// This comprises a subset of the features of the NSD spec: +// http://www.w3.org/TR/discovery-api/ +namespace mdns { + + // Represents a mDNS/DNS-SD service. + dictionary MDnsService { + // The service name of an mDNS advertised service, + // .. + DOMString serviceName; + + // The host:port pair of an mDNS advertised service. + DOMString serviceHostPort; + + // The IP address of an mDNS advertised service. + DOMString ipAddress; + + // Metadata for an mDNS advertised service. + DOMString[] serviceData; + }; + + // Callback invoked after ForceDiscovery() has started. + callback VoidCallback = void(); + + interface Functions { + // Immediately issues a multicast DNS query for all service types. + // |callback| is invoked immediately. At a later time, queries will be + // sent, and any service events will be fired. + static void forceDiscovery(VoidCallback callback); + }; + + interface Properties { + // The maximum number of service instances that will be included in + // onServiceList events. If more instances are available, they may be + // truncated from the onServiceList event. + [value=2048] static long MAX_SERVICE_INSTANCES_PER_EVENT(); + }; + + interface Events { + // Event fired to inform clients of the current complete set of known + // available services. Clients should only need to store the list from the + // most recent event. The service type that the extension is interested in + // discovering should be specified as the event filter with the + // 'serviceType' key. Not specifying an event filter will not start any + // discovery listeners. + [supportsFilters=true, maxListeners=10] static void onServiceList( + MDnsService[] services); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/notifications.idl b/tools/under-control/src/chrome/common/extensions/api/notifications.idl new file mode 100755 index 000000000..65f7a35b6 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/notifications.idl @@ -0,0 +1,218 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.notifications API to create rich notifications +// using templates and show these notifications to users in the system tray. +namespace notifications { + [noinline_doc] enum TemplateType { + // Contains an icon, title, message, expandedMessage, and up to two + // buttons. + basic, + + // Contains an icon, title, message, expandedMessage, image, and up + // to two buttons. + [deprecated="The image is not visible for Mac OS X users."] + image, + + // Contains an icon, title, message, items, and up to two buttons. + // Users on Mac OS X only see the first item. + list, + + // Contains an icon, title, message, progress, and up to two buttons. + progress + }; + + enum PermissionLevel { + // Specifies that the user has elected to show notifications + // from the app or extension. This is the default at install time. + granted, + + // Specifies that the user has elected not to show notifications + // from the app or extension. + denied + }; + + dictionary NotificationItem { + // Title of one item of a list notification. + DOMString title; + + // Additional details about this item. + DOMString message; + }; + + [nodoc] dictionary NotificationBitmap { + long width; + long height; + ArrayBuffer? data; + }; + + dictionary NotificationButton { + DOMString title; + [deprecated="Button icons not visible for Mac OS X users."] + DOMString? iconUrl; + [nodoc] NotificationBitmap? iconBitmap; + }; + + dictionary NotificationOptions { + // Which type of notification to display. + // Required for $(ref:notifications.create) method. + TemplateType? type; + + // A URL to the sender's avatar, app icon, or a thumbnail for image + // notifications. + // + // URLs can be a data URL, a blob URL, or a URL relative to a resource + // within this extension's .crx file + // + DOMString? iconUrl; + [nodoc] NotificationBitmap? iconBitmap; + + // A URL to the app icon mask. URLs have the same restrictions as + // $(ref:notifications.NotificationOptions.iconUrl iconUrl). + // + // The app icon mask should be in alpha channel, as only the alpha channel + // of the image will be considered. + [deprecated="The app icon mask is not visible for Mac OS X users."] + DOMString? appIconMaskUrl; + [nodoc] NotificationBitmap? appIconMaskBitmap; + + // Title of the notification (e.g. sender name for email). + // + DOMString? title; + + // Main notification content. + // + DOMString? message; + + // Alternate notification content with a lower-weight font. + DOMString? contextMessage; + + // Priority ranges from -2 to 2. -2 is lowest priority. 2 is highest. Zero + // is default. On platforms that don't support a notification center + // (Windows, Linux & Mac), -2 and -1 result in an error as notifications + // with those priorities will not be shown at all. + long? priority; + + // A timestamp associated with the notification, in milliseconds past the + // epoch (e.g. Date.now() + n). + double? eventTime; + + // Text and icons for up to two notification action buttons. + NotificationButton[]? buttons; + + // Secondary notification content. + [nodoc] DOMString? expandedMessage; + + // A URL to the image thumbnail for image-type notifications. + // URLs have the same restrictions as + // $(ref:notifications.NotificationOptions.iconUrl iconUrl). + [deprecated="The image is not visible for Mac OS X users."] + DOMString? imageUrl; + [nodoc] NotificationBitmap? imageBitmap; + + // Items for multi-item notifications. Users on Mac OS X only see the first + // item. + NotificationItem[]? items; + + // Current progress ranges from 0 to 100. + long? progress; + + [deprecated="This UI hint is ignored as of Chrome 67"] + boolean? isClickable; + + // Indicates that the notification should remain visible on screen until the + // user activates or dismisses the notification. This defaults to false. + boolean? requireInteraction; + + // Indicates that no sounds or vibrations should be made when the + // notification is being shown. This defaults to false. + boolean? silent; + }; + + callback CreateCallback = void (DOMString notificationId); + + callback UpdateCallback = void (boolean wasUpdated); + + callback ClearCallback = void (boolean wasCleared); + + callback GetAllCallback = void (object notifications); + + callback PermissionLevelCallback = void (PermissionLevel level); + + interface Functions { + // Creates and displays a notification. + // |notificationId|: Identifier of the notification. If not set or empty, an + // ID will automatically be generated. If it matches an existing + // notification, this method first clears that notification before + // proceeding with the create operation. The identifier may not be longer + // than 500 characters. + // + // The notificationId parameter is required before Chrome 42. + // |options|: Contents of the notification. + // |callback|: Returns the notification id (either supplied or generated) + // that represents the created notification. + // + // The callback is required before Chrome 42. + static void create( + optional DOMString notificationId, + NotificationOptions options, + optional CreateCallback callback); + + // Updates an existing notification. + // |notificationId|: The id of the notification to be updated. This is + // returned by $(ref:notifications.create) method. + // |options|: Contents of the notification to update to. + // |callback|: Called to indicate whether a matching notification existed. + // + // The callback is required before Chrome 42. + static void update( + DOMString notificationId, + NotificationOptions options, + optional UpdateCallback callback); + + // Clears the specified notification. + // |notificationId|: The id of the notification to be cleared. This is + // returned by $(ref:notifications.create) method. + // |callback|: Called to indicate whether a matching notification existed. + // + // The callback is required before Chrome 42. + static void clear( + DOMString notificationId, + optional ClearCallback callback); + + // Retrieves all the notifications of this app or extension. + // |callback|: Returns the set of notification_ids currently in the system. + static void getAll(GetAllCallback callback); + + // Retrieves whether the user has enabled notifications from this app + // or extension. + // |callback|: Returns the current permission level. + static void getPermissionLevel( + PermissionLevelCallback callback); + }; + + interface Events { + // The notification closed, either by the system or by user action. + static void onClosed(DOMString notificationId, boolean byUser); + + // The user clicked in a non-button area of the notification. + static void onClicked(DOMString notificationId); + + // The user pressed a button in the notification. + static void onButtonClicked(DOMString notificationId, long buttonIndex); + + // The user changes the permission level. As of Chrome 47, only ChromeOS + // has UI that dispatches this event. + static void onPermissionLevelChanged(PermissionLevel level); + + // The user clicked on a link for the app's notification settings. As of + // Chrome 47, only ChromeOS has UI that dispatches this event. + // As of Chrome 65, that UI has been removed from ChromeOS, too. + [deprecated="Custom notification settings button is no longer supported."] + static void onShowSettings(); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/odfs_config_private.idl b/tools/under-control/src/chrome/common/extensions/api/odfs_config_private.idl new file mode 100755 index 000000000..166ab9ff9 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/odfs_config_private.idl @@ -0,0 +1,66 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.odfsConfigPrivate API to configure the +// Microsoft OneDrive integration. +[implemented_in = "chrome/browser/chromeos/extensions/odfs_config_private/odfs_config_private_api.h", +modernised_enums] +namespace odfsConfigPrivate { + + enum Mount { + allowed, + disallowed, + automated + }; + + dictionary MountInfo { + Mount mode; + }; + + dictionary AccountRestrictionsInfo { + DOMString[] restrictions; + }; + + callback GetMountCallback = void(MountInfo mount); + callback GetAccountRestrictionsCallback = void( + AccountRestrictionsInfo restrictions); + callback ShowAutomatedMountErrorCallback = void(); + callback BoolCallback = void(boolean result); + + interface Functions { + // Returns the OneDrive mount mode from the admin policy. + // |callback|: Invoked when the policy value was retrieved. + static void getMount( + GetMountCallback callback); + + // Returns the OneDrive account restrictions from the admin policy. + // |callback|: Invoked when the policy value was retrieved. + static void getAccountRestrictions( + GetAccountRestrictionsCallback callback); + + // Shows a notification that the automated mount failed. + static void showAutomatedMountError( + ShowAutomatedMountErrorCallback callback); + + // Returns whether the FileSystemProviderCloudFileSystem feature flag is + // enabled. + static void isCloudFileSystemEnabled(BoolCallback callback); + + // Returns whether the FileSystemProviderContentCache feature flag is + // enabled. + static void isContentCacheEnabled(BoolCallback callback); + }; + + interface Events { + // Fired when the OneDrive mount mode changed. + // |event|: A OneDrive mount mode changed event. + static void onMountChanged(MountInfo event); + + // Fired when the OneDrive restrictions changed. + // |event|: A OneDrive restrictions changed event. + static void onAccountRestrictionsChanged( + AccountRestrictionsInfo event); + }; + +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/passwords_private.idl b/tools/under-control/src/chrome/common/extensions/api/passwords_private.idl new file mode 100755 index 000000000..fa0acdf05 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/passwords_private.idl @@ -0,0 +1,622 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.passwordsPrivate API to add or remove password +// data from the settings UI. +namespace passwordsPrivate { + // Possible reasons why a plaintext password was requested. + enum PlaintextReason { + // The user wants to view the password. + VIEW, + // The user wants to copy the password. + COPY, + // The user wants to edit the password. + EDIT + }; + + enum ExportProgressStatus { + // No export was started. + NOT_STARTED, + // Data is being written to the destination. + IN_PROGRESS, + // Data has been written. + SUCCEEDED, + // The user rejected the file selection prompts. + FAILED_CANCELLED, + // Writing to the destination failed. + FAILED_WRITE_FAILED + }; + + enum CompromiseType { + // If the credentials was leaked by a data breach. + LEAKED, + // If the credentials was reused on a phishing site. + PHISHED, + // If the credentials have a password which was reused by other credentials. + REUSED, + // If the credentials have a weak password. + WEAK + }; + + enum PasswordStoreSet { + // Corresponds to profile-scoped password store. + DEVICE, + // Corresponds to Gaia-account-scoped password store (i.e. account store). + ACCOUNT, + // Corresponds to both profile-scoped and Gaia-account-scoped password + // stores. + DEVICE_AND_ACCOUNT + }; + + enum PasswordCheckState { + // idle state, e.g. after successfully running to completion. + IDLE, + // Running, following an explicit user action to start the check. + RUNNING, + // Canceled, entered when the user explicitly cancels a check. + CANCELED, + // Offline, the user is offline. + OFFLINE, + // The user is not signed into Chrome. + SIGNED_OUT, + // The user does not have any passwords saved. + NO_PASSWORDS, + // The user hit the quota limit. + QUOTA_LIMIT, + // Any other error state. + OTHER_ERROR + }; + + enum ImportResultsStatus { + // Any other error state. + UNKNOWN_ERROR, + // Data was fully or partially imported. + SUCCESS, + // Failed to read provided file. + IO_ERROR, + // Header is missing, invalid or could not be read. + BAD_FORMAT, + // File selection dismissed. + DISMISSED, + // Size of the chosen file exceeds the limit. + MAX_FILE_SIZE, + // User has already started the import flow in a different window. + IMPORT_ALREADY_ACTIVE, + // User tried to import too many passwords from one file. + NUM_PASSWORDS_EXCEEDED, + // Conflicts found and they need to be resolved by the user. + CONFLICTS + }; + + enum ImportEntryStatus { + // Any other error state. + UNKNOWN_ERROR, + // Missing password field. + MISSING_PASSWORD, + // Missing url field. + MISSING_URL, + // Bad url formatting. + INVALID_URL, + // URL contains non-ASCII chars. + NON_ASCII_URL, + // URL is too long. + LONG_URL, + // Password is too long. + LONG_PASSWORD, + // Username is too long. + LONG_USERNAME, + // Credential is already stored in profile store. + CONFLICT_PROFILE, + // Credential is already stored in account store. + CONFLICT_ACCOUNT, + // Note is too long. + LONG_NOTE, + // Concatenation of imported and local notes is too long. + LONG_CONCATENATED_NOTE, + // Valid credential. + VALID + }; + + enum FamilyFetchStatus { + // Unknown or network error. + UNKNOWN_ERROR, + // No family members found. + NO_MEMBERS, + // At least one family member found. + SUCCESS + }; + + dictionary PublicKey { + // The value of the public key. + DOMString value; + // The version of the public key. + long version; + }; + + dictionary RecipientInfo { + // User ID of the recipient. + DOMString userId; + // Email of the recipient. + DOMString email; + // Name of the recipient. + DOMString displayName; + // Profile image URL of the recipient. + DOMString profileImageUrl; + // Whether the user can receive passwords. + boolean isEligible; + // The public key of the recipient. + PublicKey? publicKey; + }; + + dictionary FamilyFetchResults { + // Status of the family members fetch. + FamilyFetchStatus status; + // List of family members. + RecipientInfo[] familyMembers; + }; + + dictionary ImportEntry { + // The parsing status of individual row that represents + // credential during import process. + ImportEntryStatus status; + // The url of the credential. + DOMString url; + // The username of the credential. + DOMString username; + // The password of the credential. + DOMString password; + // Unique identifier of the credential. + long id; + }; + + dictionary ImportResults { + // General status of the triggered passwords import process. + ImportResultsStatus status; + // Number of successfully imported passwords. + long numberImported; + // Possibly emtpy, list of credentials that couldn't be imported. + ImportEntry[] displayedEntries; + // Name of file that user has chosen for the import. + DOMString fileName; + }; + + dictionary UrlCollection { + // The signon realm of the credential. + DOMString signonRealm; + + // A human readable version of the URL of the credential's origin. For + // android credentials this is usually App name. + DOMString shown; + + // The URL that will be linked to when an entry is clicked. + DOMString link; + }; + + // Information specific to compromised credentials. + dictionary CompromisedInfo { + // The timestamp of when this credential was determined to be compromised. + // Specified in milliseconds since the UNIX epoch. Intended to be passed to + // the JavaScript Date() constructor. + double compromiseTime; + + // The elapsed time since this credential was determined to be compromised. + // This is passed as an already formatted string, since JavaScript lacks the + // required formatting APIs. Example: "5 minutes ago" + DOMString elapsedTimeSinceCompromise; + + // The types of credential issues. + CompromiseType[] compromiseTypes; + + // Indicates whether this credential is muted. + boolean isMuted; + }; + + // Structure which hold required information to display a link. + dictionary DomainInfo { + // A human readable version of the URL of the credential's origin. For + // android credentials this is usually the app name. + DOMString name; + + // The URL that will be linked to when an entry is clicked. + DOMString url; + + // The signon_realm of corresponding PasswordForm. + DOMString signonRealm; + }; + + // Entry used to display a password in the settings UI. + dictionary PasswordUiEntry { + // The URL collection corresponding to this saved password entry. + DomainInfo[] affiliatedDomains; + + // The username used in conjunction with the saved password. + DOMString username; + + // If this is a passkey, the user's display name. Empty otherwise. + DOMString? displayName; + + // The password of the credential. Empty by default, only set if explicitly + // requested. + DOMString? password; + + // Text shown if the password was obtained via a federated identity. + DOMString? federationText; + + // An index to refer back to a unique password entry record. + long id; + + // Corresponds to where the credential is stored. + PasswordStoreSet storedIn; + + // Indicates whether this credential is a passkey. + boolean isPasskey; + + // The value of the attached note. + DOMString? note; + + // The URL where the insecure password can be changed. Might be not set for + // Android apps. + DOMString? changePasswordUrl; + + // Additional information in case a credential is compromised. + CompromisedInfo? compromisedInfo; + + // The timestamp of when this credential was created, or undefined if not a + // passkey. Specified in milliseconds since the UNIX epoch. Intended to be + // passed to the JavaScript Date() constructor. + double? creationTime; + }; + + // Group representing affiliated PasswordUiEntries. + dictionary CredentialGroup { + // Group name being displayed. + DOMString name; + + // Icon url for the given group. + DOMString iconUrl; + + // Entries in the group. + PasswordUiEntry[] entries; + }; + + dictionary ExceptionEntry { + // The URL collection corresponding to this exception entry. + UrlCollection urls; + + // An id to refer back to a unique exception entry record. + long id; + }; + + dictionary PasswordExportProgress { + // The current status of the export task. + ExportProgressStatus status; + + // If |status| is $ref(ExportProgressStatus.SUCCEEDED), this will + // be the full path of the written file. + DOMString? filePath; + + // If |status| is $ref(ExportProgressStatus.FAILED_WRITE_FAILED), this will + // be the name of the selected folder to export to. + DOMString? folderName; + }; + + // Object describing the current state of the password check. The check could + // be in any of the above described states. + dictionary PasswordCheckStatus { + // The state of the password check. + PasswordCheckState state; + + // Total number of saved passwords. + long? totalNumberOfPasswords; + + // How many passwords have already been processed. Populated if and only if + // the password check is currently running. + long? alreadyProcessed; + + // How many passwords are remaining in the queue. Populated if and only if + // the password check is currently running. + long? remainingInQueue; + + // The elapsed time since the last full password check was performed. This + // is passed as a string, since JavaScript lacks the required formatting + // APIs. If no check has been performed yet this is not set. + DOMString? elapsedTimeSinceLastCheck; + }; + + // Object describing a password entry to be saved and storage to be used. + dictionary AddPasswordOptions { + // The url to save the password for. + DOMString url; + + // The username to save the password for. + DOMString username; + + // The password value to be saved. + DOMString password; + + // The note attached the password. + DOMString note; + + // True for account store, false for device store. + boolean useAccountStore; + }; + + // An object holding an array of PasswordUiEntries. + dictionary PasswordUiEntryList { + PasswordUiEntry[] entries; + }; + + callback PlaintextPasswordCallback = void(DOMString password); + callback PasswordListCallback = void(PasswordUiEntry[] entries); + callback CredentialsGroupCallback = void(CredentialGroup[] entries); + callback ExceptionListCallback = void(ExceptionEntry[] exceptions); + callback ExportProgressStatusCallback = void(ExportProgressStatus status); + callback VoidCallback = void(); + callback OptInCallback = void(boolean optedIn); + callback PasswordCheckStatusCallback = void(PasswordCheckStatus status); + callback ImportPasswordsCallback = void(ImportResults results); + callback FetchFamilyResultsCallback = void(FamilyFetchResults results); + callback IsAccountStoreDefaultCallback = void(boolean isDefault); + callback GetUrlCollectionCallback = void(UrlCollection urlCollection); + callback CredentialsWithReusedPasswordCallback = + void(PasswordUiEntryList[] entries); + callback PasswordManagerPinAvailableCallback = void(boolean available); + callback PasswordManagerPinChangedCallback = void(boolean success); + callback DisconnectCloudAuthenticatorCallback = void(boolean success); + callback IsConnectedToCloudAuthenticatorCallback = void(boolean connected); + callback DeleteAllPasswordManagerDataCallback = void(boolean success); + callback AuthenticationResultCallback = void(boolean result); + + interface Functions { + // Function that logs that the Passwords page was accessed from the Chrome + // Settings WebUI. + static void recordPasswordsPageAccessInSettings(); + + // Changes the credential. Not all attributes can be updated. + // Optional attributes that are not set will be unchanged. + // Returns a promise that resolves if successful, and rejects otherwise. + // |credential|: The credential to update. This will be matched to the + // existing credential by id. + static void changeCredential( + PasswordUiEntry credential, + optional VoidCallback callback); + + // Removes the credential corresponding to |id| in |fromStores|. If no + // credential for this pair exists, this function is a no-op. + // |id|: The id for the credential being removed. + // |fromStores|: The store(s) from which the credential is being removed. + static void removeCredential(long id, PasswordStoreSet fromStores); + + // Removes the saved password exception corresponding to |id|. If + // no exception with this id exists, this function is a no-op. This will + // remove exception from both stores. + // |id|: The id for the exception url entry is being removed. + static void removePasswordException(long id); + + // Undoes the last removal of saved password(s) or exception(s). + static void undoRemoveSavedPasswordOrException(); + + // Returns the plaintext password corresponding to |id|. Note that on + // some operating systems, this call may result in an OS-level + // reauthentication. Once the password has been fetched, it will be returned + // via |callback|. + // |id|: The id for the password entry being being retrieved. + // |reason|: The reason why the plaintext password is requested. + // |callback|: The callback that gets invoked with the retrieved password. + static void requestPlaintextPassword( + long id, + PlaintextReason reason, + PlaintextPasswordCallback callback); + + // Returns the PasswordUiEntries (with |password|, |note| field filled) corresponding + // to |ids|. Note that on some operating systems, this call may result in an + // OS-level reauthentication. Once the PasswordUiEntry has been fetched, it + // will be returned via |callback|. + // |ids|: Ids for the password entries being retrieved. + // |callback|: The callback that gets invoked with the retrieved + // PasswordUiEntries. + static void requestCredentialsDetails( + long[] ids, + PasswordListCallback callback); + + // Returns the list of saved passwords. + // |callback|: Called with the list of saved passwords. + static void getSavedPasswordList( + PasswordListCallback callback); + + // Returns the list of Credential groups. + // |callback|: Called with the list of groups. + static void getCredentialGroups(CredentialsGroupCallback callback); + + // Returns the list of password exceptions. + // |callback|: Called with the list of password exceptions. + static void getPasswordExceptionList( + ExceptionListCallback callback); + + // Moves passwords currently stored on the device to being stored in the + // signed-in, non-syncing Google Account. For each id, the result is a + // no-op if any of these is true: |id| is invalid; |id| corresponds to a + // password already stored in the account; or the user is not using the + // account-scoped password storage. + // |ids|: The ids for the password entries being moved. + static void movePasswordsToAccount(long[] ids); + + // Fetches family members (password share recipients). + static void fetchFamilyMembers( + FetchFamilyResultsCallback callback); + + // Sends sharing invitations to the recipients. + // |id|: The id of the password entry to be shared. + // |recipients|: The list of selected recipients. + // |callback|: The callback that gets invoked on success. + static void sharePassword( + long id, + RecipientInfo[] recipients, + optional VoidCallback callback); + + // Triggers the Password Manager password import functionality. + static void importPasswords( + PasswordStoreSet toStore, + ImportPasswordsCallback callback); + + // Resumes the password import process when user has selected which + // passwords to replace. + // |selectedIds|: The ids of passwords that need to be replaced. + static void continueImport( + long[] selectedIds, + ImportPasswordsCallback callback); + + // Resets the PasswordImporter if it is in the CONFLICTS/FINISHED state + // and the user closes the dialog. Only when the PasswordImporter is in + // FINISHED state, |deleteFile| option is taken into account. + // |deleteFile|: Whether to trigger deletion of the last imported file. + static void resetImporter( + boolean deleteFile, + optional VoidCallback callback); + + // Triggers the Password Manager password export functionality. Completion + // Will be signaled by the onPasswordsFileExportProgress event. + // |callback| will be called when the request is started or rejected. If + // rejected $(ref:runtime.lastError) will be set to + // 'in-progress' or 'reauth-failed'. + static void exportPasswords(VoidCallback callback); + + // Requests the export progress status. This is the same as the last value + // seen on the onPasswordsFileExportProgress event. This function is useful + // for checking if an export has already been initiated from an older tab, + // where we might have missed the original event. + static void requestExportProgressStatus( + ExportProgressStatusCallback callback); + + // Requests the account-storage opt-in state of the current user. + static void isOptedInForAccountStorage( + OptInCallback callback); + + // Triggers the opt-in or opt-out flow for the account storage. + static void optInForAccountStorage(boolean optIn); + + // Requests the latest insecure credentials. + static void getInsecureCredentials( + PasswordListCallback callback); + + // Requests group of credentials which reuse passwords. Each group contains + // credentials with the same password value. + static void getCredentialsWithReusedPassword( + CredentialsWithReusedPasswordCallback callback); + + // Requests to mute |credential| from the password store. + // Invokes |callback| on completion. + static void muteInsecureCredential( + PasswordUiEntry credential, optional VoidCallback callback); + + // Requests to unmute |credential| from the password store. + // Invokes |callback| on completion. + static void unmuteInsecureCredential( + PasswordUiEntry credential, optional VoidCallback callback); + + // Starts a check for insecure passwords. Invokes |callback| on completion. + static void startPasswordCheck( + optional VoidCallback callback); + + // Returns the current status of the check via |callback|. + static void getPasswordCheckStatus( + PasswordCheckStatusCallback callback); + + // Requests whether the account store is a default location for saving + // passwords. False means the device store is a default one. Must be called + // when the current user has already opted-in for account storage. + static void isAccountStoreDefault( + IsAccountStoreDefaultCallback callback); + + // Requests whether the given |url| meets the requirements to save a + // password for it (e.g. valid, has proper scheme etc.) and returns the + // corresponding URLCollection on success. Otherwise it raises an error. + static void getUrlCollection( + DOMString url, + GetUrlCollectionCallback callback); + + // Saves a new password entry described by the given |options|. Invokes + // |callback| or raises an error depending on whether the operation + // succeeded. + // |options|: Details about a new password and storage to be used. + // |callback|: The callback that gets invoked on success. + static void addPassword( + AddPasswordOptions options, + optional VoidCallback callback); + + // Restarts the authentication timeout timer if the user is authenticated. + // |callback|: The callback that gets invoked on success. + static void extendAuthValidity( + optional VoidCallback callback); + + // Switches Biometric authentication before filling state after + // successful authentication. + // |callback|: The callback that gets invoked with the authentication + // result. + [platforms = ("win", "mac")] static void + switchBiometricAuthBeforeFillingState( + AuthenticationResultCallback callback); + + // Shows a dialog for creating a shortcut for the Password Manager page. + static void showAddShortcutDialog(); + + // Opens a file with exported passwords in the OS shell. + static void showExportedFileInShell(DOMString file_path); + + // Shows a dialog for changing the Password Manager PIN. + static void changePasswordManagerPin( + optional PasswordManagerPinChangedCallback callback); + + // Checks whether changing Password Manager PIN is possible. + static void isPasswordManagerPinAvailable( + PasswordManagerPinAvailableCallback callback); + + // Disconnects the Chrome client from the cloud authenticator. + static void disconnectCloudAuthenticator( + DisconnectCloudAuthenticatorCallback callback); + + // Checks whether the Chrome client is registered with/connected to + // the cloud authenticator. + static void isConnectedToCloudAuthenticator( + IsConnectedToCloudAuthenticatorCallback callback); + + // Deletes all password manager data (passwords, passkeys, etc.) + // |callback|: The callback that gets invoked with true on successful + // deletion and false on failure (e.g. not all data was deleted). + static void deleteAllPasswordManagerData( + DeleteAllPasswordManagerDataCallback callback); + }; + + interface Events { + // Fired when the saved passwords list has changed, meaning that an entry + // has been added or removed. + // |entries|: The updated list of password entries. + static void onSavedPasswordsListChanged(PasswordUiEntry[] entries); + + // Fired when the password exceptions list has changed, meaning that an + // entry has been added or removed. + // |exceptions|: The updated list of password exceptions. + static void onPasswordExceptionsListChanged(ExceptionEntry[] exceptions); + + // Fired when the status of the export has changed. + // |status|: The progress status and an optional UI message. + static void onPasswordsFileExportProgress(PasswordExportProgress status); + + // Fired when the opt-in state for the account-scoped storage has changed. + // |optedIn|: The new opt-in state. + static void onAccountStorageOptInStateChanged(boolean optedIn); + + // Fired when the insecure credentials changed. + // |insecureCredentials|: The updated insecure credentials. + static void onInsecureCredentialsChanged( + PasswordUiEntry[] insecureCredentials); + + // Fired when the status of the password check changes. + // |status|: The updated status of the password check. + static void onPasswordCheckStatusChanged(PasswordCheckStatus status); + + // Fired when the password manager access timed out. + static void onPasswordManagerAuthTimeout(); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/pdf_viewer_private.idl b/tools/under-control/src/chrome/common/extensions/api/pdf_viewer_private.idl new file mode 100755 index 000000000..c3bcc770b --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/pdf_viewer_private.idl @@ -0,0 +1,72 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.pdfViewerPrivate API for specific browser +// functionality that the PDF Viewer needs from outside the PDF plugin. This API +// is exclusively for the PDF Viewer. +namespace pdfViewerPrivate { + // Nearly identical to mimeHandlerPrivate.StreamInfo, but without a mime type + // nor a response header field. Those fields are unused by the PDF viewer. + dictionary StreamInfo { + // The original URL that was intercepted. + DOMString originalUrl; + + // The URL that the stream can be read from. + DOMString streamUrl; + + // The ID of the tab that opened the stream. If the stream is not opened in + // a tab, it will be -1. + long tabId; + + // Whether the stream is embedded within another document. + boolean embedded; + }; + + // Identical to mimeHandlerPrivate.StreamInfo. + dictionary PdfPluginAttributes { + // The background color in ARGB format for painting. Since the background + // color is an unsigned 32-bit integer which can be outside the range of + // "long" type, define it as a "double" type here. + double backgroundColor; + + // Indicates whether the plugin allows to execute JavaScript and maybe XFA. + // Loading XFA for PDF forms will automatically be disabled if this flag is + // false. + boolean allowJavascript; + }; + + callback GetStreamInfoCallback = void(StreamInfo streamInfo); + callback IsAllowedLocalFileAccessCallback = void(boolean result); + callback VoidCallback = void(); + + interface Functions { + // Returns the StreamInfo for the stream for this context if there is one. + static void getStreamInfo( + GetStreamInfoCallback callback); + + // Determines if the given URL should be allowed to access local files from + // the PDF Viewer. |callback|: Called with true if URL should be allowed to + // access local files from the PDF Viewer, false otherwise. + static void isAllowedLocalFileAccess( + DOMString url, + IsAllowedLocalFileAccessCallback callback); + + // Sets the current tab title to `title` for a full-page PDF. + static void setPdfDocumentTitle( + DOMString title, + optional VoidCallback callback); + + // Sets PDF plugin attributes in the stream for this context if there is + // one. + static void setPdfPluginAttributes( + PdfPluginAttributes attributes, + optional VoidCallback callback); + }; + + interface Events { + // Fired when the browser wants the listener to perform a save. + // `streamUrl`: Unique ID for the instance that should perform the save. + static void onSave(DOMString streamUrl); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/platform_keys.idl b/tools/under-control/src/chrome/common/extensions/api/platform_keys.idl new file mode 100755 index 000000000..916abf8f6 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/platform_keys.idl @@ -0,0 +1,185 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.platformKeys API to access client certificates +// managed by the platform. If the user or policy grants the permission, an +// extension can use such a certficate in its custom authentication protocol. +// E.g. this allows usage of platform managed certificates in third party VPNs +// (see $(ref:vpnProvider chrome.vpnProvider)). +namespace platformKeys { + [noinline_doc] dictionary Match { + // The DER encoding of a X.509 certificate. + ArrayBuffer certificate; + + // The + // + // KeyAlgorithm of the certified key. This contains algorithm + // parameters that are inherent to the key of the certificate (e.g. the key + // length). Other parameters like the hash function used by the sign + // function are not included. + object keyAlgorithm; + }; + + enum ClientCertificateType { + rsaSign, + ecdsaSign + }; + + // Analogous to TLS1.1's CertificateRequest. + // See http://tools.ietf.org/html/rfc4346#section-7.4.4 . + dictionary ClientCertificateRequest { + // This field is a list of the types of certificates requested, sorted in + // order of the server's preference. Only certificates of a type contained + // in this list will be retrieved. If certificateTypes is the + // empty list, however, certificates of any type will be returned. + ClientCertificateType[] certificateTypes; + + // List of distinguished names of certificate authorities allowed by the + // server. Each entry must be a DER-encoded X.509 DistinguishedName. + ArrayBuffer[] certificateAuthorities; + }; + + dictionary SelectDetails { + // Only certificates that match this request will be returned. + ClientCertificateRequest request; + + // If given, the selectClientCertificates operates on this + // list. Otherwise, obtains the list of all certificates from the platform's + // certificate stores that are available to this extensions. + // Entries that the extension doesn't have permission for or which doesn't + // match the request, are removed. + ArrayBuffer[]? clientCerts; + + // If true, the filtered list is presented to the user to manually select a + // certificate and thereby granting the extension access to the + // certificate(s) and key(s). Only the selected certificate(s) will be + // returned. If is false, the list is reduced to all certificates that the + // extension has been granted access to (automatically or manually). + boolean interactive; + }; + + dictionary VerificationDetails { + // Each chain entry must be the DER encoding of a X.509 certificate, the + // first entry must be the server certificate and each entry must certify + // the entry preceding it. + ArrayBuffer[] serverCertificateChain; + + // The hostname of the server to verify the certificate for, e.g. the server + // that presented the serverCertificateChain. + DOMString hostname; + }; + + dictionary VerificationResult { + // The result of the trust verification: true if trust for the given + // verification details could be established and false if trust is rejected + // for any reason. + boolean trusted; + + // If the trust verification failed, this array contains the errors reported + // by the underlying network layer. Otherwise, this array is empty. + // + // Note: This list is meant for debugging only and may not + // contain all relevant errors. The errors returned may change in future + // revisions of this API, and are not guaranteed to be forwards or backwards + // compatible. + DOMString[] debug_errors; + }; + + // |matches|: The list of certificates that match the request, that the + // extension has permission for and, if interactive is true, that + // were selected by the user. + callback SelectCallback = void (Match[] matches); + + // The public and private + // CryptoKey + // of a certificate which can only be used with + // $(ref:platformKeys.subtleCrypto). + // |privateKey|: Might be null if this extension does not have + // access to it. + callback GetKeyPairCallback = void (object publicKey, + optional object privateKey); + + callback VerificationCallback = void (VerificationResult result); + + interface Functions { + // This method filters from a list of client certificates the ones that + // are known to the platform, match request and for which the + // extension has permission to access the certificate and its private key. + // If interactive is true, the user is presented a dialog where + // they can select from matching certificates and grant the extension access + // to the certificate. + // The selected/filtered client certificates will be passed to + // callback. + [nocompile] static void selectClientCertificates( + SelectDetails details, + SelectCallback callback); + + // Passes the key pair of certificate for usage with + // $(ref:platformKeys.subtleCrypto) to callback. + // |certificate|: The certificate of a $(ref:Match) returned by + // $(ref:selectClientCertificates). + // |parameters|: Determines signature/hash algorithm parameters additionally + // to the parameters fixed by the key itself. The same parameters are + // accepted as by WebCrypto's importKey + // function, e.g. RsaHashedImportParams for a RSASSA-PKCS1-v1_5 + // key and EcKeyImportParams for EC key. + // Additionally for RSASSA-PKCS1-v1_5 keys, hashing algorithm name parameter + // can be specified with one of the following values: "none", "SHA-1", + // "SHA-256", "SHA-384", or "SHA-512", e.g. + // {"hash": { "name": "none" } }. The sign function will then + // apply PKCS#1 v1.5 padding but not hash the given data. + //

Currently, this method only supports the "RSASSA-PKCS1-v1_5" and + // "ECDSA" algorithms.

+ [nocompile, doesNotSupportPromises= + "Multi-parameter callback crbug.com/1313625"] + static void getKeyPair(ArrayBuffer certificate, + object parameters, + GetKeyPairCallback callback); + + // Passes the key pair identified by publicKeySpkiDer for + // usage with $(ref:platformKeys.subtleCrypto) to callback. + // |publicKeySpkiDer|: A DER-encoded X.509 SubjectPublicKeyInfo, obtained + // e.g. by calling WebCrypto's exportKey function with format="spki". + // |parameters|: Provides signature and hash algorithm parameters, in + // addition to those fixed by the key itself. The same parameters are + // accepted as by WebCrypto's importKey + // function, e.g. RsaHashedImportParams for a RSASSA-PKCS1-v1_5 + // key. For RSASSA-PKCS1-v1_5 keys, we need to also pass a "hash" parameter + // { "hash": { "name": string } }. The "hash" parameter + // represents the name of the hashing algorithm to be used in the digest + // operation before a sign. It is possible to pass "none" as the hash name, + // in which case the sign function will apply PKCS#1 v1.5 padding and but + // not hash the given data. + //

Currently, this method supports the "ECDSA" algorithm with + // named-curve P-256 and "RSASSA-PKCS1-v1_5" algorithm with one of the + // hashing algorithms "none", "SHA-1", "SHA-256", "SHA-384", and + // "SHA-512".

+ [nocompile, doesNotSupportPromises= + "Multi-parameter callback crbug.com/1313625"] + static void getKeyPairBySpki(ArrayBuffer publicKeySpkiDer, + object parameters, + GetKeyPairCallback callback); + + // An implementation of WebCrypto's + // + // SubtleCrypto + // that allows crypto operations on keys of client certificates that are + // available to this extension. + [nocompile] static object subtleCrypto(); + + // Checks whether details.serverCertificateChain can be trusted + // for details.hostname according to the trust settings of the + // platform. + // Note: The actual behavior of the trust verification is not fully + // specified and might change in the future. + // The API implementation verifies certificate expiration, validates the + // certification path and checks trust by a known CA. + // The implementation is supposed to respect the EKU serverAuth and to + // support subject alternative names. + static void verifyTLSServerCertificate(VerificationDetails details, + VerificationCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/platform_keys_internal.idl b/tools/under-control/src/chrome/common/extensions/api/platform_keys_internal.idl new file mode 100755 index 000000000..ba8568e8f --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/platform_keys_internal.idl @@ -0,0 +1,76 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Internal API for to implement the platformKeys and enterprise.platformKeys +// APIs. +[implemented_in = "chrome/browser/extensions/api/platform_keys/platform_keys_api.h"] +namespace platformKeysInternal { + callback SelectCallback = void (platformKeys.Match[] certs); + + // Invoked by sign. + // |signature| The signature, a octet string. + callback SignCallback = void(ArrayBuffer signature); + + // Called back by getPublicKey. + // |publicKey| The Subject Public Key Info (see X.509) of the requested + // certificate. + // |algorithm| A partial WebCrypto KeyAlgorithm containing all information + // that is available from the Subject Public Key Info. It does not contain + // signature/hash parameters. + callback GetPublicKeyCallback = void(ArrayBuffer publicKey, object algorithm); + + interface Functions { + // See documentation in platformKeys. + static void selectClientCertificates( + platformKeys.SelectDetails details, + SelectCallback callback); + + // Internal version of platformKeys.subtleCrypto.sign and + // enterprise.platformKeys.Token.subtleCrypto.sign. + // |tokenId| The id of a Token returned by |getTokens|. + // |publicKey| The Subject Public Key Info of a key previously generated by + // |generateKey| in DER encoding. + // |algorithmName| The name of the algorithm used to generate the key pair. + // |hashAlgorithmName| The recognized algorithm name of the hash algorithm, + // as specified by WebCrypto, that will be used to digest |data| + // before signing. Currently supported are: SHA-{1,256,384,512}. + // If instead the algorithm name "none" is provided, no hashing will be + // applied, the data is PKCS#1 v1.5 padded but not hashed. + // TODO(pneubeck): use an enum once supported: + // http://www.crbug.com/385539 . + // |data| The data to sign. + // |callback| Called back with the signature of |data|. + // TODO: Instead of ArrayBuffer should be (ArrayBuffer or ArrayBufferView), + // or at least (ArrayBuffer or Uint8Array). + static void sign(DOMString tokenId, + ArrayBuffer publicKey, + DOMString algorithmName, + DOMString hashAlgorithmName, + ArrayBuffer data, + SignCallback callback); + + // Checks whether certificate certifies a key that allows usage + // of the WebCrypto algorithm algorithmName. If so, calls back + // callback with the key info and a WebCrypto + // KeyAlgorithm dictionary describing the key's algorithm. The + // name property will equal algorithmName. + // Otherwise, calls back with an error. + [doesNotSupportPromises="Multi-parameter callback crbug.com/1313625"] + static void getPublicKey(ArrayBuffer certificate, + DOMString algorithmName, + GetPublicKeyCallback callback); + + // Takes as arguments a publicKeySpkiDer and + // algorithmName. Checks if publicKeySpkiDer is + // not empty and if the algorithmName specified is supported. + // If so, calls back callback with the key info and a WebCrypto + // KeyAlgorithm dictionary describing the key's algorithm. The + // name property will equal algorithmName. + // Otherwise, calls back with an error. + [doesNotSupportPromises="Multi-parameter callback crbug.com/1313625"] + static void getPublicKeyBySpki(ArrayBuffer publicKeySpkiDer, + DOMString algorithmName, + GetPublicKeyCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/printing.idl b/tools/under-control/src/chrome/common/extensions/api/printing.idl new file mode 100755 index 000000000..7f7585382 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/printing.idl @@ -0,0 +1,203 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.printing API to send print jobs to printers +// installed on Chromebook. +[platforms=("chromeos", "lacros"), +implemented_in="chrome/browser/extensions/api/printing/printing_api.h"] +namespace printing { + dictionary SubmitJobRequest { + // The print job to be submitted. + // The only supported content type is "application/pdf", and the + // Cloud Job Ticket + // shouldn't include FitToPageTicketItem, + // PageRangeTicketItem, ReverseOrderTicketItem + // and VendorTicketItem fields since they are + // irrelevant for native printing. All other fields must be present. + printerProvider.PrintJob job; + + // Used internally to store the blob uuid after parameter customization and + // shouldn't be populated by the extension. + [nodoc] DOMString? documentBlobUuid; + }; + + // The status of $(ref:submitJob) request. + enum SubmitJobStatus { + // Sent print job request is accepted. + OK, + + // Sent print job request is rejected by the user. + USER_REJECTED + }; + + // Response for $(ref:submitJob) request. + dictionary SubmitJobResponse { + // The status of the request. + SubmitJobStatus status; + + // The id of created print job. This is a unique identifier among all print + // jobs on the device. If status is not OK, jobId will be null. + DOMString? jobId; + }; + + // The source of the printer. + enum PrinterSource { + // Printer was added by user. + USER, + + // Printer was added via policy. + POLICY + }; + + // Description of the printer. + dictionary Printer { + // The printer's identifier; guaranteed to be unique among printers on the + // device. + DOMString id; + + // The name of the printer. + DOMString name; + + // The human-readable description of the printer. + DOMString description; + + // The printer URI. This can be used by extensions to choose the printer for + // the user. + DOMString uri; + + // The source of the printer (user or policy configured). + PrinterSource source; + + // The flag which shows whether the printer fits + // + // DefaultPrinterSelection rules. + // Note that several printers could be flagged. + boolean isDefault; + + // The value showing how recent the printer was used for printing from + // Chrome. The lower the value is the more recent the printer was used. The + // minimum value is 0. Missing value indicates that the printer wasn't used + // recently. This value is guaranteed to be unique amongst printers. + long? recentlyUsedRank; + }; + + // The status of the printer. + enum PrinterStatus { + // The door of the printer is open. Printer still accepts print jobs. + DOOR_OPEN, + + // The tray of the printer is missing. Printer still accepts print jobs. + TRAY_MISSING, + + // The printer is out of ink. Printer still accepts print jobs. + OUT_OF_INK, + + // The printer is out of paper. Printer still accepts print jobs. + OUT_OF_PAPER, + + // The output area of the printer (e.g. tray) is full. Printer still accepts + // print jobs. + OUTPUT_FULL, + + // The printer has a paper jam. Printer still accepts print jobs. + PAPER_JAM, + + // Some generic issue. Printer still accepts print jobs. + GENERIC_ISSUE, + + // The printer is stopped and doesn't print but still accepts print jobs. + STOPPED, + + // The printer is unreachable and doesn't accept print jobs. + UNREACHABLE, + + // The SSL certificate is expired. Printer accepts jobs but they fail. + EXPIRED_CERTIFICATE, + + // The printer is available. + AVAILABLE + }; + + // Response for $(ref:getPrinterInfo) request. + dictionary GetPrinterInfoResponse { + // Printer capabilities in + // + // CDD format. + // The property may be missing. + object? capabilities; + + // The status of the printer. + PrinterStatus status; + }; + + // Status of the print job. + enum JobStatus { + // Print job is received on Chrome side but was not processed yet. + PENDING, + + // Print job is sent for printing. + IN_PROGRESS, + + // Print job was interrupted due to some error. + FAILED, + + // Print job was canceled by the user or via API. + CANCELED, + + // Print job was printed without any errors. + PRINTED + }; + + callback SubmitJobCallback = void(SubmitJobResponse response); + callback CancelJobCallback = void(); + callback GetPrintersCallback = void(Printer[] printers); + callback GetPrinterInfoCallback = void(GetPrinterInfoResponse response); + + interface Functions { + // Submits the job for printing. If the extension is not listed in + // the + // PrintingAPIExtensionsAllowlist policy, + // the user is prompted to accept the print job.
+ // Before Chrome 120, this function did not return a promise. + static void submitJob( + SubmitJobRequest request, + SubmitJobCallback callback); + + // Cancels previously submitted job. + // |jobId|: The id of the print job to cancel. This should be the same id + // received in a $(ref:SubmitJobResponse). + static void cancelJob( + DOMString jobId, + CancelJobCallback callback); + + // Returns the list of available printers on the device. This includes + // manually added, enterprise and discovered printers. + static void getPrinters(GetPrintersCallback callback); + + // Returns the status and capabilities of the printer in + // + // CDD format. + // This call will fail with a runtime error if no printers with given id are + // installed. + static void getPrinterInfo( + DOMString printerId, + GetPrinterInfoCallback callback); + }; + + interface Properties { + // The maximum number of times that $(ref:submitJob) can be called per + // minute. + [value=40] static long MAX_SUBMIT_JOB_CALLS_PER_MINUTE(); + + // The maximum number of times that $(ref:getPrinterInfo) can be called per + // minute. + [value=20] static long MAX_GET_PRINTER_INFO_CALLS_PER_MINUTE(); + }; + + interface Events { + // Event fired when the status of the job is changed. + // This is only fired for the jobs created by this extension. + static void onJobStatusChanged(DOMString jobId, JobStatus status); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/printing_metrics.idl b/tools/under-control/src/chrome/common/extensions/api/printing_metrics.idl new file mode 100755 index 000000000..55cdc5a2c --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/printing_metrics.idl @@ -0,0 +1,157 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.printingMetrics API to fetch data about +// printing usage. +[platforms=("chromeos", "lacros"), + implemented_in="chrome/browser/chromeos/extensions/printing_metrics/printing_metrics_api.h"] +namespace printingMetrics { + // The source of the print job. + enum PrintJobSource { + // Specifies that the job was created from the Print Preview page + // initiated by the user. + PRINT_PREVIEW, + + // Specifies that the job was created from an Android App. + ANDROID_APP, + + // Specifies that the job was created by extension via Chrome API. + EXTENSION, + + // Specifies that the job was created by an Isolated Web App via API. + ISOLATED_WEB_APP + }; + + // Specifies the final status of the print job. + enum PrintJobStatus { + // Specifies that the print job was interrupted due to some error. + FAILED, + + // Specifies that the print job was canceled by the user or via API. + CANCELED, + + // Specifies that the print job was printed without any errors. + PRINTED + }; + + // The source of the printer. + enum PrinterSource { + // Specifies that the printer was added by user. + USER, + + // Specifies that the printer was added via policy. + POLICY + }; + + enum ColorMode { + // Specifies that black and white mode was used. + BLACK_AND_WHITE, + + // Specifies that color mode was used. + COLOR + }; + + enum DuplexMode { + // Specifies that one-sided printing was used. + ONE_SIDED, + + // Specifies that two-sided printing was used, flipping on long edge. + TWO_SIDED_LONG_EDGE, + + // Specifies that two-sided printing was used, flipping on short edge. + TWO_SIDED_SHORT_EDGE + }; + + // The size of requested media. + dictionary MediaSize { + // Width (in micrometers) of the media used for printing. + long width; + + // Height (in micrometers) of the media used for printing. + long height; + + // Vendor-provided ID, e.g. "iso_a3_297x420mm" or "na_index-3x5_3x5in". + // Possible values are values of "media" IPP attribute and can be found on + // + // IANA page . + DOMString vendorId; + }; + + // The requested settings of print job. + dictionary PrintSettings { + // The requested color mode. + ColorMode color; + + // The requested duplex mode. + DuplexMode duplex; + + // The requested media size. + MediaSize mediaSize; + + // The requested number of copies. + long copies; + }; + + // The printer info. + dictionary Printer { + // Displayed name of the printer. + DOMString name; + + // The full path for the printer. + // Contains protocol, hostname, port, and queue. + DOMString uri; + + // The source of the printer. + PrinterSource source; + }; + + // Print job information. + dictionary PrintJobInfo { + // The ID of the job. + DOMString id; + + // The title of the document which was printed. + DOMString title; + + // Source showing who initiated the print job. + PrintJobSource source; + + // ID of source. Null if source is PRINT_PREVIEW or ANDROID_APP. + DOMString? sourceId; + + // The final status of the job. + PrintJobStatus status; + + // The job creation time (in milliseconds past the Unix epoch). + double creationTime; + + // The job completion time (in milliseconds past the Unix epoch). + double completionTime; + + // The info about the printer which printed the document. + Printer printer; + + // The settings of the print job. + PrintSettings settings; + + // The number of pages in the document. + long numberOfPages; + + // The status of the printer. + printing.PrinterStatus printer_status; + }; + + callback GetPrintJobsCallback = void(PrintJobInfo[] jobs); + + interface Functions { + // Returns the list of the finished print jobs. + static void getPrintJobs(GetPrintJobsCallback callback); + }; + + interface Events { + // Event fired when the print job is finished. + // This includes any of termination statuses: FAILED, CANCELED and PRINTED. + static void onPrintJobFinished(PrintJobInfo jobInfo); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/processes.idl b/tools/under-control/src/chrome/common/extensions/api/processes.idl new file mode 100755 index 000000000..866a98f5f --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/processes.idl @@ -0,0 +1,183 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.processes API to interact with the browser's +// processes. +namespace processes { + // The types of the browser processes. + enum ProcessType { + browser, + renderer, + extension, + notification, + plugin, + worker, + nacl, + service_worker, + utility, + gpu, + other + }; + + // An object that represents a Chrome task running on a process. Several tasks + // can share the same process. + dictionary TaskInfo { + // The title of the task. + DOMString title; + // Optional tab ID, if this task represents a tab running on a renderer + // process. + long? tabId; + }; + + // The Cache object contains information about the size and utilization of a + // cache used by the browser. + dictionary Cache { + // The size of the cache, in bytes. + double size; + // The part of the cache that is utilized, in bytes. + double liveSize; + }; + + // An object containing information about one of the browser's processes. + dictionary Process { + // Unique ID of the process provided by the browser. + long id; + // The ID of the process, as provided by the OS. + long osProcessId; + // The type of process. + ProcessType type; + // The profile which the process is associated with. + DOMString profile; + // The debugging port for Native Client processes. Zero for other process + // types and for NaCl processes that do not have debugging enabled. + long naclDebugPort; + // Array of TaskInfos representing the tasks running on this process. + TaskInfo[] tasks; + // The most recent measurement of the process's CPU usage, expressed as the + // percentage of a single CPU core used in total, by all of the process's + // threads. This gives a value from zero to CpuInfo.numOfProcessors*100, + // which can exceed 100% in multi-threaded processes. + // Only available when receiving the object as part of a callback from + // onUpdated or onUpdatedWithMemory. + double? cpu; + // The most recent measurement of the process network usage, in bytes per + // second. Only available when receiving the object as part of a callback + // from onUpdated or onUpdatedWithMemory. + double? network; + // The most recent measurement of the process private memory usage, in + // bytes. Only available when receiving the object as part of a callback + // from onUpdatedWithMemory or getProcessInfo with the includeMemory flag. + double? privateMemory; + // The most recent measurement of the process JavaScript allocated memory, + // in bytes. Only available when receiving the object as part of a callback + // from onUpdated or onUpdatedWithMemory. + double? jsMemoryAllocated; + // The most recent measurement of the process JavaScript memory used, in + // bytes. Only available when receiving the object as part of a callback + // from onUpdated or onUpdatedWithMemory. + double? jsMemoryUsed; + // The most recent measurement of the process's SQLite memory usage, in + // bytes. Only available when receiving the object as part of a callback + // from onUpdated or onUpdatedWithMemory. + double? sqliteMemory; + // The most recent information about the image cache for the process. Only + // available when receiving the object as part of a callback from onUpdated + // or onUpdatedWithMemory. + Cache? imageCache; + // The most recent information about the script cache for the process. Only + // available when receiving the object as part of a callback from onUpdated + // or onUpdatedWithMemory. + Cache? scriptCache; + // The most recent information about the CSS cache for the process. Only + // available when receiving the object as part of a callback from onUpdated + // or onUpdatedWithMemory. + Cache? cssCache; + }; + + // A callback to report the status of the termination. + // |didTerminate|: True if terminating the process was successful, and false + // otherwise. + callback TerminateCallback = void(boolean didTerminate); + + // A callback to return the ID of the renderer process of a tab. + // |processId|: Process ID of the tab's renderer process. + callback GetProcessIdForTabCallback = void(long processId); + + // A callback called when the processes information is collected. + // |processes|: A dictionary of $(ref:Process) objects for each requested + // process that is a live child process of the current browser process, + // indexed by process ID. Metrics requiring aggregation over time will not be + // populated in each Process object. + callback GetProcessInfoCallback = void(object processes); + + interface Functions { + // Returns the ID of the renderer process for the specified tab. + // |tabId|: The ID of the tab for which the renderer process ID is to be + // returned. + static void getProcessIdForTab( + long tabId, + GetProcessIdForTabCallback callback); + + // Terminates the specified renderer process. Equivalent to visiting + // about:crash, but without changing the tab's URL. + // |processId|: The ID of the process to be terminated. + static void terminate( + long processId, + optional TerminateCallback callback); + + // Retrieves the process information for each process ID specified. + // |processIds|: The list of process IDs or single process ID for which + // to return the process information. An empty list indicates all processes + // are requested. + // |includeMemory|: True if detailed memory usage is required. Note, + // collecting memory usage information incurs extra CPU usage and should + // only be queried for when needed. + static void getProcessInfo( + (long or long[]) processIds, + boolean includeMemory, + GetProcessInfoCallback callback); + }; + + interface Events { + // Fired each time the Task Manager updates its process statistics, + // providing the dictionary of updated Process objects, indexed by process + // ID. + // |processes|: A dictionary of updated $(ref:Process) objects for each live + // process in the browser, indexed by process ID. Metrics requiring + // aggregation over time will be populated in each Process object. + static void onUpdated(object processes); + + // Fired each time the Task Manager updates its process statistics, + // providing the dictionary of updated Process objects, indexed by process + // ID. Identical to onUpdate, with the addition of memory usage details + // included in each Process object. Note, collecting memory usage + // information incurs extra CPU usage and should only be listened for when + // needed. + // |processes|: A dictionary of updated $(ref:Process) objects for each live + // process in the browser, indexed by process ID. Memory usage details will + // be included in each Process object. + static void onUpdatedWithMemory(object processes); + + // Fired each time a process is created, providing the corrseponding Process + // object. + // |process|: Details of the process that was created. Metrics requiring + // aggregation over time will not be populated in the object. + static void onCreated(Process process); + + // Fired each time a process becomes unresponsive, providing the + // corrseponding Process object. + // |process|: Details of the unresponsive process. Metrics requiring + // aggregation over time will not be populated in the object. Only available + // for renderer processes. + static void onUnresponsive(Process process); + + // Fired each time a process is terminated, providing the type of exit. + // |processId|: The ID of the process that exited. + // |exitType|: The type of exit that occurred for the process - normal, + // abnormal, killed, crashed. Only available for renderer processes. + // |exitCode|: The exit code if the process exited abnormally. Only + // available for renderer processes. + static void onExited(long processId, long exitType, long exitCode); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/quick_unlock_private.idl b/tools/under-control/src/chrome/common/extensions/api/quick_unlock_private.idl new file mode 100755 index 000000000..435e75fb9 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/quick_unlock_private.idl @@ -0,0 +1,153 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.quickUnlockPrivate API to change whether the +// lock screen is enabled and which modes are allowed (active) for unlocking a +// Chrome OS device from the lock screen. The API is also used to set quick +// unlock credentials. +// Note: The API is named 'quickUnlock' for historical reasons but it should be +// used for all lock screen settings. +// Note: This API can not be used to actually unlock the device. + +[platforms=("chromeos", "lacros")] +namespace quickUnlockPrivate { + dictionary TokenInfo { + // The authentication token that can be passed to $(ref:setModes) calls. + DOMString token; + + // The number of seconds until the token expires. The UI should refresh the + // token before it expires. + long lifetimeSeconds; + }; + + // TODO(jdufault): Add more quick unlock modes, such as a pattern unlock. + enum QuickUnlockMode { + PIN + }; + + // The problems a given PIN might have. + enum CredentialProblem { + TOO_SHORT, + TOO_LONG, + TOO_WEAK, + CONTAINS_NONDIGIT + }; + + dictionary CredentialCheck { + // The given PINs errors. Users cannot proceed with an error. + CredentialProblem[] errors; + + // THe given PINs warnings. Users can, but are not advised to proceed with + // a warning. + CredentialProblem[] warnings; + }; + + dictionary CredentialRequirements { + // The minimum allowed length for a PIN. + long minLength; + + // The maximum allowed length for a PIN. A value of 0 indicates no maximum + // length. + long maxLength; + }; + + callback VoidResultCallback = void (); + callback BooleanResultCallback = void (boolean value); + callback TokenResultCallback = void (TokenInfo result); + callback ModesCallback = void (QuickUnlockMode[] modes); + callback CredentialCheckCallback = void (CredentialCheck check); + callback CredentialRequirementsCallback = + void (CredentialRequirements requirements); + + interface Functions { + // Returns a token that can be used for future operations and the number + // of seconds until the token expires. + // |accountPassword|: The account password for the logged in user. + static void getAuthToken( + DOMString accountPassword, + TokenResultCallback onComplete); + + // Sets the lock screen enabled state. NOTE: The lock enabled state is + // reflected in the settings.enable_screen_lock pref, which can be read + // but not written using the settings_private API (which also provides + // policy information). This API must be used to change the pref. + // |token|: The token returned by $(ref:getAuthToken). + // |enabled|: Whether to enable the lock screen. + [platforms=("chromeos")] static void setLockScreenEnabled( + DOMString token, + boolean enabled, + optional VoidResultCallback onComplete); + + // Sets the PIN auto submit enabled state. NOTE: The PIN autosubmit state is + // reflected in the pin_unlock_autosubmit_enabled pref, which can be read + // but not written using the settings_private API (which also provides + // policy information). This API must be used to change the pref. + // |token|: The authentication token. + // |pin|: The PIN of the logged in user. + // |enabled|: Whether to enable PIN auto submit. + // |onComplete|: Called with true if the quick unlock state was updated, + // false otherwise. The update is treated as a single atomic operation. + [platforms=("chromeos")] + static void setPinAutosubmitEnabled( + DOMString token, + DOMString pin, + boolean enabled, + BooleanResultCallback onComplete); + + // Tests wether it is currently possible to authenticate using PIN. + [platforms=("chromeos")] static void canAuthenticatePin( + BooleanResultCallback onComplete); + + // Returns the set of quick unlock modes that are available for the user to + // use. Some quick unlock modes may be disabled by policy. + [platforms=("chromeos")] static void getAvailableModes( + ModesCallback onComplete); + + // Returns the quick unlock modes that are currently enabled and usable on + // the lock screen. + [platforms=("chromeos")] + static void getActiveModes(ModesCallback onComplete); + + + // Checks if the given credential can be used for the given unlock mode. + // Enterprise policy can change credential requirements. + // |mode|: The quick unlock mode that is used. + // |credential|: The given credential. + // |onComplete|: Called with a list of warnings and errors the given + // |credential| has (or an empty list if there are none). + [platforms=("chromeos")] static void checkCredential( + QuickUnlockMode mode, + DOMString credential, + CredentialCheckCallback onComplete); + + // Gets the credential requirements for the given unlock mode. + // |mode|: The quick unlock mode that is used. + // |onComplete|: Called with the credential requirements of the given + // |mode|. + [platforms=("chromeos")] + static void getCredentialRequirements( + QuickUnlockMode mode, + CredentialRequirementsCallback onComplete); + + // Update the set of quick unlock modes that are currently active/enabled. + // |token|: The token returned by $(ref:getAuthToken). + // |modes|: The quick unlock modes that should be active. + // |credentials|: The associated credential for each mode. To keep the + // credential the same for the associated mode, pass an empty string. + // |onComplete|: Called with true if the quick unlock state was updated, + // false otherwise. The update is treated as a single atomic operation. + [platforms=("chromeos")] + static void setModes( + DOMString token, + QuickUnlockMode[] modes, + DOMString[] credentials, + VoidResultCallback onComplete); + }; + + interface Events { + // Called after the active set of quick unlock modes has changed. + // |activeModes|: The set of quick unlock modes which are now active. + static void onActiveModesChanged(QuickUnlockMode[] activeModes); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/reading_list.idl b/tools/under-control/src/chrome/common/extensions/api/reading_list.idl new file mode 100755 index 000000000..c25885a04 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/reading_list.idl @@ -0,0 +1,117 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.readingList API to read from and modify +// the items in the +// Reading List. +namespace readingList{ + dictionary ReadingListEntry { + // The url of the entry. + DOMString url; + + // The title of the entry. + DOMString title; + + // Will be true if the entry has been read. + boolean hasBeenRead; + + // The last time the entry was updated. + // This value is in milliseconds since Jan 1, 1970. + double lastUpdateTime; + + // The time the entry was created. + // Recorded in milliseconds since Jan 1, 1970. + double creationTime; + }; + + dictionary AddEntryOptions { + // The url of the entry. + DOMString url; + + // The title of the entry. + DOMString title; + + // Will be true if the entry has been read. + boolean hasBeenRead; + }; + + dictionary RemoveOptions { + // The url to remove. + DOMString url; + }; + + dictionary UpdateEntryOptions { + // The url that will be updated. + DOMString url; + + // The new title. The existing tile remains if a value isn't provided. + DOMString? title; + + // The updated read status. The existing status remains if a value + // isn't provided. + boolean? hasBeenRead; + }; + + dictionary QueryInfo { + // A url to search for. + DOMString? url; + + // A title to search for. + DOMString? title; + + // Indicates whether to search for read (true) or unread + // (false) items. + boolean? hasBeenRead; + }; + + callback AddEntryCallback = void (); + callback RemoveEntryCallback = void(); + callback UpdateEntryCallback = void(); + callback QueryCallback = void(ReadingListEntry[] entries); + + interface Functions { + // Adds an entry to the reading list if it does not exist. + // |entry|: The entry to add to the reading list. + // |callback|: Invoked once the entry has been added. + static void addEntry( + AddEntryOptions entry, + optional AddEntryCallback callback); + + // Removes an entry from the reading list if it exists. + // |info|: The entry to remove from the reading list. + // |callback|: Invoked once the entry has been removed. + static void removeEntry( + RemoveOptions info, + optional RemoveEntryCallback callback); + + // Updates a reading list entry if it exists. + // |info|: The entry to update. + // |callback|: Invoked once the matched entries have been updated. + static void updateEntry( + UpdateEntryOptions info, + optional UpdateEntryCallback callback); + + // Retrieves all entries that match the QueryInfo properties. + // Properties that are not provided will not be matched. + // |info|: The properties to search for. + // |callback|: Invoked once the entries have been matched. + static void query( + QueryInfo info, + QueryCallback callback); + }; + + interface Events { + // Triggered when a ReadingListEntry is added to the reading list. + // |entry|: The entry that was added. + static void onEntryAdded(ReadingListEntry entry); + + // Triggered when a ReadingListEntry is removed from the reading list. + // |entry|: The entry that was removed. + static void onEntryRemoved(ReadingListEntry entry); + + // Triggered when a ReadingListEntry is updated in the reading list. + // |entry|: The entry that was updated. + static void onEntryUpdated(ReadingListEntry entry); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/resources_private.idl b/tools/under-control/src/chrome/common/extensions/api/resources_private.idl new file mode 100755 index 000000000..236b7d12d --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/resources_private.idl @@ -0,0 +1,24 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// resourcesPrivate. +namespace resourcesPrivate { + enum Component { identity, pdf }; + + callback GetStringsCallback = void (object result); + + interface Functions { + // Gets localized strings for a component extension. Includes default WebUI + // loadTimeData values for text and language settings (fontsize, fontfamily, + // language, textdirection). See + // chrome/browser/extensions/api/resources_private/resources_private_api.cc + // for instructions on adding a new component to this API. + // + // |component| : Internal Chrome component to get strings for. + // |callback| : Called with a dictionary mapping names to strings. + static void getStrings( + Component component, + GetStringsCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/safe_browsing_private.idl b/tools/under-control/src/chrome/common/extensions/api/safe_browsing_private.idl new file mode 100755 index 000000000..59ba9f746 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/safe_browsing_private.idl @@ -0,0 +1,173 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.safeBrowsingPrivate API to observe events +// or retrieve referrer chain. +namespace safeBrowsingPrivate { + + enum URLType { + // Ends with the final URL of the referrer chain. + EVENT_URL, + + // One gesture away from the EVENT_URL, i.e. the user will click on the + // LANDING_PAGE, go through zero or more CLIENT_REDIRECTS, then end up + // at EVENT_URL. + LANDING_PAGE, + + // One gesture away from LANDING_PAGE. + LANDING_REFERRER, + + // The navigation is RENDER_INITIATED_WITHOUT_USER_GESTURE. + CLIENT_REDIRECT, + + // Doesn't directly lead to the EVENT_URL, but the navigation occurred + // recently, so it might be involved in the event. + RECENT_NAVIGATION, + + // Triggered by a user gesture and precedes the LANDING_REFERRER. + REFERRER + }; + + enum NavigationInitiation { + // Typically from Chrome UI, e.g. bookmarks or omnibox. + BROWSER_INITIATED, + + // Renderer initiated navigations involve interactions with the content + // area, such as link clicks or JS. + RENDERER_INITIATED_WITHOUT_USER_GESTURE, + RENDERER_INITIATED_WITH_USER_GESTURE, + + // Navigation is initiated by the browser process and it is believed the + // navigation is the result of the user copy and paste the address from the + // browser into the address bar. + COPY_PASTE_USER_INITIATED, + + // Navigation is initiated by a click on a Push Notification. + NOTIFICATION_INITIATED + }; + + dictionary PolicySpecifiedPasswordReuse { + // URL where this reuse happened. + DOMString url; + + // The user name of the policy specified password. + DOMString userName; + + // If this a phishing url. + boolean isPhishingUrl; + }; + + dictionary DangerousDownloadInfo { + // URL of the download. + DOMString url; + + // File name and path of the download on user's machine. + DOMString fileName; + + // SHA256 digest of this download. + DOMString downloadDigestSha256; + + // User name of the profile. Empty string if user name not available. + DOMString userName; + }; + + dictionary InterstitialInfo { + // Top level URL that triggers this interstitial. + DOMString url; + + // Human-readable string indicate why this interstitial is shown. + DOMString reason; + + // Net error code. + DOMString? netErrorCode; + + // User name of the profile. Empty string if user name not available. + DOMString userName; + }; + + dictionary ServerRedirect { + // Server redirect URL. + DOMString? url; + }; + + // From ReferrerChainEntry in //src/components/safe_browsing/core/common/proto/csd.proto + dictionary ReferrerChainEntry { + // URL of this entry. + DOMString url; + + // Only set if different from |url|. + DOMString? mainFrameUrl; + + // Types of URLs, such as event url, landing page, etc. + URLType urlType; + + // IP addresses corresponding to this host. + DOMString[]? ipAddresses; + + // Referrer URL of this entry. + DOMString? referrerUrl; + + // Main frame URL of referrer. Only set if different from |referrer_url|. + DOMString? referrerMainFrameUrl; + + // If this URL loads in a different tab/frame from previous one. + boolean? isRetargeting; + + double? navigationTimeMs; + + // Set only if server redirects happened in navigation. + ServerRedirect[]? serverRedirectChain; + + // How this navigation is initiated. + NavigationInitiation? navigationInitiation; + + // Whether this entry may have been launched by an external application. + boolean? maybeLaunchedByExternalApp; + + // Whether subframe URLs are removed due to user consent restriction. + boolean? isSubframeUrlRemoved; + + // Whether subframe referrer URLs are removed due to user consent + // restriction. + boolean? isSubframeReferrerUrlRemoved; + + // Whether any of the URLs are removed because the URL matches the + // SafeBrowsingAllowlistDomains enterprise policy in Chrome. + boolean isUrlRemovedByPolicy; + }; + + callback GetReferrerChainCallback = void(ReferrerChainEntry[] entries); + + interface Functions { + // Gets referrer chain for the specified tab. + // |tabId|: Id of the tab from which to retrieve the referrer. + // |callback|: Called with the list of referrer chain entries. + static void getReferrerChain( + long tabId, + GetReferrerChainCallback callback); + }; + + interface Events { + // Fired when Chrome detects a reuse of a policy specified password. + // + // |reuseDetails|: Details about where the password reuse occurred. + static void onPolicySpecifiedPasswordReuseDetected( + PolicySpecifiedPasswordReuse reuseDetails); + + // Fired when the user changed their policy specified password. + // + // |userName|: The user name of the policy specified password. + static void onPolicySpecifiedPasswordChanged(DOMString userName); + + // Fired when the user opened a dangerous download. + static void onDangerousDownloadOpened(DangerousDownloadInfo dict); + + // Fired when a security interstitial is shown to the user. + static void onSecurityInterstitialShown(InterstitialInfo dict); + + // Fired when the user clicked-through a security interstitial. + static void onSecurityInterstitialProceeded(InterstitialInfo dict); + }; + +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/scripting.idl b/tools/under-control/src/chrome/common/extensions/api/scripting.idl new file mode 100755 index 000000000..f029ede3f --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/scripting.idl @@ -0,0 +1,268 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.scripting API to execute script in different +// contexts. +namespace scripting { + callback InjectedFunction = void(); + + // The origin for a style change. + // See style origins + // for more info. + enum StyleOrigin { + AUTHOR, + USER + }; + + // The JavaScript world for a script to execute within. + enum ExecutionWorld { + // Specifies the isolated world, which is the execution environment unique + // to this extension. + ISOLATED, + // Specifies the main world of the DOM, which is the execution environment + // shared with the host page's JavaScript. + MAIN + }; + + dictionary InjectionTarget { + // The ID of the tab into which to inject. + long tabId; + + // The IDs + // of specific frames to inject into. + long[]? frameIds; + + // The IDs + // of specific documentIds to inject into. This must not be set if + // frameIds is set. + DOMString[]? documentIds; + + // Whether the script should inject into all frames within the tab. Defaults + // to false. + // This must not be true if frameIds is specified. + boolean? allFrames; + }; + + dictionary ScriptInjection { + // A JavaScript function to inject. This function will be serialized, and + // then deserialized for injection. This means that any bound parameters + // and execution context will be lost. + // Exactly one of files or func must be + // specified. + [serializableFunction]InjectedFunction? func; + + // The arguments to pass to the provided function. This is only valid if + // the func parameter is specified. These arguments must be + // JSON-serializable. + any[]? args; + + // We used to call the injected function `function`, but this is + // incompatible with JavaScript's object declaration shorthand (see + // https://crbug.com/1166438). We leave this silently in for backwards + // compatibility. + // TODO(devlin): Remove this in M95. + [nodoc, serializableFunction]InjectedFunction? function; + + // The path of the JS or CSS files to inject, relative to the extension's + // root directory. + // Exactly one of files or func must be + // specified. + DOMString[]? files; + + // Details specifying the target into which to inject the script. + InjectionTarget target; + + // The JavaScript "world" to run the script in. Defaults to + // ISOLATED. + ExecutionWorld? world; + + // Whether the injection should be triggered in the target as soon as + // possible. Note that this is not a guarantee that injection will occur + // prior to page load, as the page may have already loaded by the time the + // script reaches the target. + boolean? injectImmediately; + }; + + dictionary CSSInjection { + // Details specifying the target into which to insert the CSS. + InjectionTarget target; + + // A string containing the CSS to inject. + // Exactly one of files and css must be + // specified. + DOMString? css; + + // The path of the CSS files to inject, relative to the extension's root + // directory. + // Exactly one of files and css must be + // specified. + DOMString[]? files; + + // The style origin for the injection. Defaults to 'AUTHOR'. + StyleOrigin? origin; + }; + + dictionary InjectionResult { + // The result of the script execution. + any? result; + + // The frame associated with the injection. + long frameId; + + // The document associated with the injection. + DOMString documentId; + }; + + // Describes a content script to be injected into a web page registered + // through this API. + dictionary RegisteredContentScript { + // The id of the content script, specified in the API call. Must not start + // with a '_' as it's reserved as a prefix for generated script IDs. + DOMString id; + // Specifies which pages this content script will be injected into. See + // Match Patterns for more + // details on the syntax of these strings. Must be specified for + // $(ref:registerContentScripts). + DOMString[]? matches; + // Excludes pages that this content script would otherwise be injected into. + // See Match Patterns for + // more details on the syntax of these strings. + DOMString[]? excludeMatches; + // The list of CSS files to be injected into matching pages. These are + // injected in the order they appear in this array, before any DOM is + // constructed or displayed for the page. + DOMString[]? css; + // The list of JavaScript files to be injected into matching pages. These + // are injected in the order they appear in this array. + DOMString[]? js; + // If specified true, it will inject into all frames, even if the frame is + // not the top-most frame in the tab. Each frame is checked independently + // for URL requirements; it will not inject into child frames if the URL + // requirements are not met. Defaults to false, meaning that only the top + // frame is matched. + boolean? allFrames; + // Indicates whether the script can be injected into frames where the URL + // contains an unsupported scheme; specifically: about:, data:, blob:, or + // filesystem:. In these cases, the URL's origin is checked to determine if + // the script should be injected. If the origin is `null` (as is the case + // for data: URLs) then the used origin is either the frame that created + // the current frame or the frame that initiated the navigation to this + // frame. Note that this may not be the parent frame. + boolean? matchOriginAsFallback; + // Specifies when JavaScript files are injected into the web page. The + // preferred and default value is document_idle. + extensionTypes.RunAt? runAt; + // Specifies if this content script will persist into future sessions. The + // default is true. + boolean? persistAcrossSessions; + // The JavaScript "world" to run the script in. Defaults to + // ISOLATED. + ExecutionWorld? world; + }; + + // An object used to filter content scripts for + // ${ref:getRegisteredContentScripts}. + dictionary ContentScriptFilter { + // If specified, $(ref:getRegisteredContentScripts) will only return scripts + // with an id specified in this list. + DOMString[]? ids; + }; + + callback ScriptInjectionCallback = void(InjectionResult[] results); + + callback CSSInjectionCallback = void(); + + callback RegisterContentScriptsCallback = void(); + + callback GetRegisteredContentScriptsCallback = void( + RegisteredContentScript[] scripts); + + callback UnregisterContentScriptsCallback = void(); + + callback UpdateContentScriptsCallback = void(); + + interface Properties { + // An object available for content scripts running in isolated worlds to use + // and modify as a JS object. One instance exists per frame and is shared + // between all content scripts for a given extension. This object is + // initialized when the frame is created, before document_start. + // TODO(crbug.com/40119604): Enable this once implementation is complete. + [nodoc, nocompile] static long globalParams(); + }; + + interface Functions { + // Injects a script into a target context. By default, the script will be run + // at document_idle, or immediately if the page has already + // loaded. If the injectImmediately property is set, the script + // will inject without waiting, even if the page has not finished loading. If + // the script evaluates to a promise, the browser will wait for the promise to + // settle and return the resulting value. + // |injection|: The details of the script which to inject. + // |callback|: Invoked upon completion of the injection. The resulting + // array contains the result of execution for each frame where the + // injection succeeded. + static void executeScript( + ScriptInjection injection, + optional ScriptInjectionCallback callback); + + // Inserts a CSS stylesheet into a target context. + // If multiple frames are specified, unsuccessful injections are ignored. + // |injection|: The details of the styles to insert. + // |callback|: Invoked upon completion of the insertion. + static void insertCSS( + CSSInjection injection, + optional CSSInjectionCallback callback); + + // Removes a CSS stylesheet that was previously inserted by this extension + // from a target context. + // |injection|: The details of the styles to remove. Note that the + // css, files, and origin properties + // must exactly match the stylesheet inserted through $(ref:insertCSS). + // Attempting to remove a non-existent stylesheet is a no-op. + // |callback|: A callback to be invoked upon the completion of the removal. + static void removeCSS( + CSSInjection injection, + optional CSSInjectionCallback callback); + + // Registers one or more content scripts for this extension. + // |scripts|: Contains a list of scripts to be registered. If there are + // errors during script parsing/file validation, or if the IDs specified + // already exist, then no scripts are registered. + // |callback|: A callback to be invoked once scripts have been fully + // registered or if an error has occurred. + static void registerContentScripts( + RegisteredContentScript[] scripts, + optional RegisterContentScriptsCallback callback); + + // Returns all dynamically registered content scripts for this extension + // that match the given filter. + // |filter|: An object to filter the extension's dynamically registered + // scripts. + static void getRegisteredContentScripts( + optional ContentScriptFilter filter, + GetRegisteredContentScriptsCallback callback); + + // Unregisters content scripts for this extension. + // |filter|: If specified, only unregisters dynamic content scripts which + // match the filter. Otherwise, all of the extension's dynamic content + // scripts are unregistered. + // |callback|: A callback to be invoked once scripts have been unregistered + // or if an error has occurred. + static void unregisterContentScripts( + optional ContentScriptFilter filter, + optional UnregisterContentScriptsCallback callback); + + // Updates one or more content scripts for this extension. + // |scripts|: Contains a list of scripts to be updated. A property is only + // updated for the existing script if it is specified in this object. If + // there are errors during script parsing/file validation, or if the IDs + // specified do not correspond to a fully registered script, then no scripts + // are updated. + // |callback|: A callback to be invoked once scripts have been updated or + // if an error has occurred. + static void updateContentScripts( + RegisteredContentScript[] scripts, + optional RegisterContentScriptsCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/search.idl b/tools/under-control/src/chrome/common/extensions/api/search.idl new file mode 100755 index 000000000..f591b76c1 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/search.idl @@ -0,0 +1,42 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.search API to search via the default provider. +namespace search { + enum Disposition { + // Specifies that the search results display in the calling tab or the tab + // from the active browser. + CURRENT_TAB, + + // Specifies that the search results display in a new tab. + NEW_TAB, + + // Specifies that the search results display in a new window. + NEW_WINDOW + }; + + dictionary QueryInfo { + // String to query with the default search provider. + DOMString text; + + // Location where search results should be displayed. + // CURRENT_TAB is the default. + Disposition? disposition; + + // Location where search results should be displayed. + // tabId cannot be used with disposition. + long? tabId; + }; + + callback QueryCallback = void(); + + interface Functions { + // Used to query the default search provider. + // In case of an error, + // $(ref:runtime.lastError) will be set. + static void query( + QueryInfo queryInfo, + optional QueryCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/settings_private.idl b/tools/under-control/src/chrome/common/extensions/api/settings_private.idl new file mode 100755 index 000000000..fdc7d18f4 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/settings_private.idl @@ -0,0 +1,126 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.settingsPrivate API to get or set preferences +// from the settings UI. Access is restricted to a set of allowed user facing +// preferences. +namespace settingsPrivate { + enum PrefType { BOOLEAN, NUMBER, STRING, URL, LIST, DICTIONARY }; + + enum ControlledBy { + DEVICE_POLICY, + USER_POLICY, + OWNER, + PRIMARY_USER, + EXTENSION, + + // Preferences are controlled by the parent of the child user. + PARENT, + + // Preferences are controlled neither by parent nor the child user. + // Preference values are hard-coded values and can not be changed. + CHILD_RESTRICTION + }; + + enum Enforcement { + // Value cannot be changed by user. + ENFORCED, + // Value can be changed, but the administrator recommends a default. + RECOMMENDED, + // Value is protected by a code that only parents can access. The logic to + // require the code is NOT automatically added to a preference using this + // enforcement. This is only used to display the correct pref indicator. + PARENT_SUPERVISED + }; + + dictionary PrefObject { + // The key for the pref. + DOMString key; + + // The type of the pref (e.g., boolean, string, etc.). + PrefType type; + + // The current value of the pref. + any? value; + + // The policy source of the pref; an undefined value means there is no + // policy. + ControlledBy? controlledBy; + + // The owner name if controlledBy == OWNER. + // The primary user name if controlledBy == PRIMARY_USER. + // The extension name if controlledBy == EXTENSION. + DOMString? controlledByName; + + // The policy enforcement of the pref; must be specified if controlledBy is + // also present. + Enforcement? enforcement; + + // The recommended value if enforcement == RECOMMENDED. + any? recommendedValue; + + // If enforcement == ENFORCED this optionally specifies preference values + // that are still available for selection by the user. If set, must contain + // at least 2 distinct values, as must contain |value| and + // |recommendedValue| (if present). + any[]? userSelectableValues; + + // If true, user control of the preference is disabled for reasons unrelated + // to controlledBy (e.g. no signed-in profile is present). A false value is + // a no-op. + boolean? userControlDisabled; + + // The extension ID if controlledBy == EXTENSION. + DOMString? extensionId; + + // Whether the controlling extension can be disabled if controlledBy == + // EXTENSION. + boolean? extensionCanBeDisabled; + }; + + callback OnPrefSetCallback = void (boolean success); + callback GetAllPrefsCallback = void (PrefObject[] prefs); + callback GetPrefCallback = void (PrefObject pref); + callback GetDefaultZoomCallback = void (double zoom); + callback SetDefaultZoomCallback = void (boolean success); + + interface Functions { + // Sets a pref value. + // |name|: The name of the pref. + // |value|: The new value of the pref. + // |pageId|: An optional user metrics identifier. + // |callback|: The callback for whether the pref was set or not. + static void setPref( + DOMString name, + any value, + optional DOMString pageId, + optional OnPrefSetCallback callback); + + // Gets an array of all the prefs. + static void getAllPrefs(GetAllPrefsCallback callback); + + // Gets the value of a specific pref. + static void getPref( + DOMString name, + GetPrefCallback callback); + + // Gets the default page zoom factor. Possible values are currently between + // 0.25 and 5. For a full list, see zoom::kPresetBrowserZoomFactors. + static void getDefaultZoom( + GetDefaultZoomCallback callback); + + // Sets the page zoom factor. Must be less than 0.001 different than a value + // in zoom::kPresetBrowserZoomFactors. + static void setDefaultZoom( + double zoom, + optional SetDefaultZoomCallback callback); + }; + + interface Events { + // Fired when a set of prefs has changed. + // + // |prefs| The prefs that changed. + static void onPrefsChanged(PrefObject[] prefs); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/shared_storage_private.idl b/tools/under-control/src/chrome/common/extensions/api/shared_storage_private.idl new file mode 100755 index 000000000..5a11017c6 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/shared_storage_private.idl @@ -0,0 +1,30 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Used by gnubbyd in ash and lacros. Stores small amounts of data in ash prefs +// which is shared by ash and lacros versions of the extension. +// TODO(b/231890240): Once Terminal SWA runs in lacros rather than ash, we can +// migrate gnubbyd back to using chrome.storage.local and remove this private +// API. +[platforms=("chromeos", "lacros"), + implemented_in="chrome/browser/extensions/api/shared_storage/shared_storage_private_api.h"] +namespace sharedStoragePrivate { + + callback GetCallback = void (object items); + callback SetCallback = void (); + callback RemoveCallback = void (); + + interface Functions { + // Gets all items from shared extension local storage. + static void get(GetCallback callback); + + // Sets given items into shared extension local storage. + static void set(object items, SetCallback callback); + + // Removes item from shared extension local storage. + static void remove( + DOMString[] keys, RemoveCallback callback); + }; +}; + diff --git a/tools/under-control/src/chrome/common/extensions/api/side_panel.idl b/tools/under-control/src/chrome/common/extensions/api/side_panel.idl new file mode 100755 index 000000000..a36f83010 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/side_panel.idl @@ -0,0 +1,109 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the `chrome.sidePanel` API to host content in the browser's side panel +// alongside the main content of a webpage. +namespace sidePanel { + dictionary SidePanel { + // Developer specified path for side panel display. + DOMString default_path; + }; + + dictionary ManifestKeys { + SidePanel side_panel; + }; + + // The options used when setting a side panel. Omitted properties are + // unchanged. + dictionary PanelOptions { + // If specified, the side panel options will only apply to the tab with + // this id. If omitted, these options set the default behavior (used for any + // tab that doesn't have specific settings). Note: if the same path is set + // for this tabId and the default tabId, then the panel for this tabId will + // be a different instance than the panel for the default tabId. + long? tabId; + // The path to the side panel HTML file to use. This must be a local + // resource within the extension package. + DOMString? path; + // Whether the side panel should be enabled. This is optional. The default + // value is true. + boolean? enabled; + }; + + // A dictionary containing the extension's options for how its side panel + // behaves. + dictionary PanelBehavior { + // Whether clicking the extension's icon will toggle showing the extension's + // entry in the side panel. Defaults to false. + boolean? openPanelOnActionClick; + }; + + dictionary GetPanelOptions { + // If specified, the side panel options for the given tab will be returned. + // Otherwise, returns the default side panel options (used for any tab that + // doesn't have specific settings). + long? tabId; + }; + + // Options for opening the side panel. + // At least one of `tabId` or `windowId` must be specified. + dictionary OpenOptions { + // The window in which to open the side panel. This is only applicable if + // the extension has a global (non-tab-specific) side panel or + // tabId is also specified. This will override any + // currently-active global side panel the user has open in the given + // window. At least one of this or tabId must be provided. + long? windowId; + + // The tab in which to open the side panel. If the corresponding tab has + // a tab-specific side panel, the panel will only be open for that tab. + // If there is not a tab-specific panel, the global panel will be open in + // the specified tab and any other tabs without a currently-open tab- + // specific panel. This will override any currently-active side panel + // (global or tab-specific) in the corresponding tab. At least one of this + // or windowId must be provided. + long? tabId; + }; + + callback VoidCallback = void(); + callback PanelOptionsCallback = void(PanelOptions options); + callback PanelBehaviorCallback = void(PanelBehavior behavior); + + interface Functions { + // Configures the side panel. + // |options|: The configuration options to apply to the panel. + // |callback|: Invoked when the options have been set. + static void setOptions( + PanelOptions options, + optional VoidCallback callback); + + // Returns the active panel configuration. + // |options|: Specifies the context to return the configuration for. + // |callback|: Called with the active panel configuration. + static void getOptions( + GetPanelOptions options, + PanelOptionsCallback callback); + + // Configures the extension's side panel behavior. This is an upsert + // operation. + // |behavior|: The new behavior to be set. + // |callback|: Called when the new behavior has been set. + static void setPanelBehavior( + PanelBehavior behavior, + optional VoidCallback callback); + + // Returns the extension's current side panel behavior. + // |callback|: Called with the extension's side panel behavior. + static void getPanelBehavior( + PanelBehaviorCallback callback); + + // Opens the side panel for the extension. + // This may only be called in response to a user action. + // |options|: Specifies the context in which to open the side panel. + // |callback|: Called when the side panel has been opened. + static void open( + OpenOptions options, + VoidCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/smart_card_provider_private.idl b/tools/under-control/src/chrome/common/extensions/api/smart_card_provider_private.idl new file mode 100755 index 000000000..eb0b13ae2 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/smart_card_provider_private.idl @@ -0,0 +1,268 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use this API to give the browser access to a winscard.h[1] compatible +// PC/SC[2] implementation, which will be the backend of the browser's +// Web Smart Card API[3]. +// +// [1] https://pcsclite.apdu.fr/api/winscard_8h.html +// [2] https://en.wikipedia.org/wiki/PC/SC +// [3] https://github.com/WICG/web-smart-card/blob/main/README.md#web-idl +// +// TODO(crbug.com/40247152): Add API for the remaining SCard* functions. +[platforms=("chromeos", "lacros"), + implemented_in="chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.h"] +namespace smartCardProviderPrivate { + + // PC/SC error codes we can expect to hit (thus a non-exhaustive list). + // UNKNOWN means an SCARD error code that is not mapped in this enum (and + // thus should probably be added here). + enum ResultCode { + SUCCESS, + REMOVED_CARD, + RESET_CARD, + UNPOWERED_CARD, + UNRESPONSIVE_CARD, + UNSUPPORTED_CARD, + READER_UNAVAILABLE, + SHARING_VIOLATION, + NOT_TRANSACTED, + NO_SMARTCARD, + PROTO_MISMATCH, + SYSTEM_CANCELLED, + NOT_READY, + CANCELLED, + INSUFFICIENT_BUFFER, + INVALID_HANDLE, + INVALID_PARAMETER, + INVALID_VALUE, + NO_MEMORY, + TIMEOUT, + UNKNOWN_READER, + UNSUPPORTED_FEATURE, + NO_READERS_AVAILABLE, + SERVICE_STOPPED, + NO_SERVICE, + COMM_ERROR, + INTERNAL_ERROR, + UNKNOWN_ERROR, + SERVER_TOO_BUSY, + UNEXPECTED, + SHUTDOWN, + UNKNOWN + }; + + // Maps to the SCARD_SHARE_* values defined in the winscard.h API. + enum ShareMode { + SHARED, + EXCLUSIVE, + DIRECT + }; + + // What the reader should do with the card inserted in it. + enum Disposition { + // SCARD_LEAVE_CARD - Do nothing. + LEAVE_CARD, + // SCARD_RESET_CARD - Reset the card (warm reset). + RESET_CARD, + // SCARD_UNPOWER_CARD - Power down the card (cold reset). + UNPOWER_CARD, + // SCARD_EJECT_CARD - Eject the card. + EJECT_CARD + }; + + enum ConnectionState { + // SCARD_ABSENT + ABSENT, + // SCARD_PRESENT + PRESENT, + // SCARD_SWALLOWED + SWALLOWED, + // SCARD_POWERED + POWERED, + // SCARD_NEGOTIABLE + NEGOTIABLE, + // SCARD_SPECIFIC + SPECIFIC + }; + + // Maps to the SCARD_STATE_* flags defined in the winscard.h API. + dictionary ReaderStateFlags { + boolean? unaware; + boolean? ignore; + boolean? changed; + boolean? unknown; + boolean? unavailable; + boolean? empty; + boolean? present; + boolean? exclusive; + boolean? inuse; + boolean? mute; + boolean? unpowered; + }; + + // Maps to the SCARD_PROTOCOL_* flags defined in the winscard.h API. + dictionary Protocols { + boolean? t0; + boolean? t1; + boolean? raw; + }; + + // Maps to the SCARD_PROTOCOL_* values defined in the winscard.h API. + enum Protocol { + UNDEFINED, + T0, + T1, + RAW + }; + + dictionary ReaderStateIn { + DOMString reader; + ReaderStateFlags currentState; + // Number of card insertion and removal events that happened in this reader, + // as known by the application. + long currentCount; + }; + + dictionary ReaderStateOut { + DOMString reader; + ReaderStateFlags eventState; + // The actual number of card insertion and removal events that happened in + // this reader. + // Set to zero if not supported. + long eventCount; + ArrayBuffer atr; + }; + + dictionary Timeout { + // If absent, it means "infinite" or "never timeout" + long? milliseconds; + }; + + interface Events { + // Browser requested a SCardEstablishContext call. + // Extension must report the result to the browser by calling + // reportEstablishContextResult. + [maxListeners=1] static void onEstablishContextRequested(long requestId); + + // Browser requested a SCardReleaseContext call. + // Extension must report the result to the browser by calling + // reportReleaseContextResult. + [maxListeners=1] static void onReleaseContextRequested(long requestId, + long scardContext); + + // Browser requested a SCardListReaders call. + // Extension must report the result to the browser by calling + // reportListReadersResult. + [maxListeners=1] static void onListReadersRequested(long requestId, + long scardContext); + + // Browser requested a SCardGetStatusChange call. + // Extension must report the result to the browser by calling + // reportGetStatusChangeResult. + [maxListeners=1] static void onGetStatusChangeRequested(long requestId, + long scardContext, + Timeout timeout, + ReaderStateIn[] readerStates); + + // Browser requested a SCardCancel call. + // Extension must report the result to the browser by calling + // reportPlainResult. + [maxListeners=1] static void onCancelRequested(long requestId, + long scardContext); + + // Browser requested a SCardConnect call. + // Extension must report the result to the browser by calling + // reportConnectResult. + [maxListeners=1] static void onConnectRequested(long requestId, + long scardContext, + DOMString reader, + ShareMode shareMode, + Protocols preferredProtocols); + + // Browser requested a SCardDisconnect call. + // Extension must report the result to the browser by calling + // reportPlainResult. + [maxListeners=1] static void onDisconnectRequested(long requestId, + long scardHandle, Disposition disposition); + + // Browser requested a SCardTransmit call. + // Extension must report the result to the browser by calling + // reportDataResult. + [maxListeners=1] static void onTransmitRequested(long requestId, + long scardHandle, Protocol protocol, ArrayBuffer data); + + // Browser requested a SCardControl call. + // Extension must report the result to the browser by calling + // reportDataResult. + [maxListeners=1] static void onControlRequested(long requestId, + long scardHandle, long controlCode, ArrayBuffer data); + + // Browser requested a SCardGetAttrib call. + // Extension must report the result to the browser by calling + // reportDataResult. + [maxListeners=1] static void onGetAttribRequested(long requestId, + long scardHandle, long attribId); + + // Browser requested a SCardSetAttrib call. + // Extension must report the result to the browser by calling + // reportPlainResult. + [maxListeners=1] static void onSetAttribRequested(long requestId, + long scardHandle, long attribId, ArrayBuffer data); + + // Browser requested a SCardStatus call. + // Extension must report the result to the browser by calling + // reportStatusResult. + [maxListeners=1] static void onStatusRequested(long requestId, + long scardHandle); + + // Browser requested a SCardBeginTransaction call. + // Extension must report the result to the browser by calling + // reportPlainResult. + [maxListeners=1] static void onBeginTransactionRequested(long requestId, + long scardHandle); + + // Browser requested a SCardEndTransaction call. + // Extension must report the result to the browser by calling + // reportPlainResult. + [maxListeners=1] static void onEndTransactionRequested(long requestId, + long scardHandle, Disposition disposition); + }; + + interface Functions { + // Reports the result of a SCardEstablishContext call. + static void reportEstablishContextResult(long requestId, + long scardContext, ResultCode resultCode); + + // Reports the result of a SCardReleaseContext call. + static void reportReleaseContextResult(long requestId, + ResultCode resultCode); + + // Reports the result of a SCardListReaders call. + static void reportListReadersResult(long requestId, + DOMString[] readers, ResultCode resultCode); + + // Reports the result of a SCardGetStatusChange call. + static void reportGetStatusChangeResult(long requestId, + ReaderStateOut[] readerStates, ResultCode resultCode); + + // Reports the result of a call which doesn't send back any other + // information. + static void reportPlainResult(long requestId, + ResultCode resultCode); + + // Reports the result of a SCardConnect call. + static void reportConnectResult(long requestId, long scardHandle, + Protocol activeProtocol, ResultCode resultCode); + + // Reports the result of a call that sends back data on success. + static void reportDataResult(long requestId, ArrayBuffer data, + ResultCode resultCode); + + // Reports the result of a SCardStatus call. + static void reportStatusResult(long requestId, DOMString readerName, + ConnectionState state, Protocol protocol, ArrayBuffer atr, + ResultCode resultCode); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/speech_recognition_private.idl b/tools/under-control/src/chrome/common/extensions/api/speech_recognition_private.idl new file mode 100755 index 000000000..ef2bd3552 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/speech_recognition_private.idl @@ -0,0 +1,88 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.speechRecognitionPrivate API allows internal +// extensions to use either network-based or on-device speech recognition. +[platforms=("chromeos"), implemented_in="chrome/browser/ash/extensions/speech/speech_recognition_private_api.h"] + +namespace speechRecognitionPrivate { + // Possible types of speech recognition. + enum SpeechRecognitionType { + onDevice, + network + }; + + // Interface for an onStop event. + dictionary SpeechRecognitionStopEvent { + // Optional client ID. + long? clientId; + }; + + // Interface for a speech recognition result event. + dictionary SpeechRecognitionResultEvent { + // Optional client ID. + long? clientId; + // The recognized phrase or sentence. + DOMString transcript; + // Whether the result is a final or an interim result. + boolean isFinal; + }; + + // Interface for a speech recognition error event. + dictionary SpeechRecognitionErrorEvent { + // Optional client ID. + long? clientId; + // A message describing the error. + DOMString message; + }; + + // Interface for options used when starting speech recognition. + dictionary StartOptions { + // An optional ID to specify the client. + long? clientId; + // The locale, in BCP-47 format e.g. "en-US", to use for speech recognition. + DOMString? locale; + // Whether interim speech results should be returned. + boolean? interimResults; + }; + + // Interface for options used when stopping speech recognition. + dictionary StopOptions { + // An optional ID to specify the client. This must match the clientId + // used when starting speech recognition to work as intended. + long? clientId; + }; + + // Called when speech recognition has begun listening to the user's audio. + // The callback's parameter specifies which type of speech recognition + // is being used. + callback OnStartCallback = void(SpeechRecognitionType type); + // Called when speech recognition has stopped listening to the user's audio. + callback OnStopCallback = void(); + + interface Functions { + // Starts listening to audio from the user. The callback is invoked when + // speech recognition has started. If speech recognition is already active + // when calling start(), the callback is run with an error. + static void start( + StartOptions options, + OnStartCallback callback); + + // Stops listening to audio from the user. The callback is invoked when + // speech recognition has stopped. If speech recognition has already stopped + // when calling stop(), the callback is run with an error. + static void stop( + StopOptions options, + OnStopCallback callback); + }; + + interface Events { + // Fired when speech recognition stops. + static void onStop(SpeechRecognitionStopEvent event); + // Fired when a speech recognition result is returned. + static void onResult(SpeechRecognitionResultEvent event); + // Fired when a speech recognition error occurs. + static void onError(SpeechRecognitionErrorEvent event); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/system_indicator.idl b/tools/under-control/src/chrome/common/extensions/api/system_indicator.idl new file mode 100755 index 000000000..bbbe8f249 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/system_indicator.idl @@ -0,0 +1,38 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Manages an app's system indicator icon, an image displayed in the system's +// menubar, system tray, or other visible area provided by the OS. +// This is modelled after the other extension action APIs, such as +// chrome.browserAction and chrome.pageAction. +namespace systemIndicator { + dictionary SetIconDetails { + any? path; + any? imageData; + }; + + callback DoneCallback = void (); + + interface Functions { + // Set the image to be used as an indicator icon, using a set of ImageData + // objects. These objects should have multiple resolutions so that an + // appropriate size can be selected for the given icon size and DPI scaling + // settings. Only square ImageData objects are accepted. + static void setIcon( + SetIconDetails details, + optional DoneCallback callback); + + // Show the icon in the status tray. + static void enable(); + + // Hide the icon from the status tray. + static void disable(); + }; + + interface Events { + // Fired only when a click on the icon does not result in a menu being + // shown. + static void onClicked(); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/system_log.idl b/tools/under-control/src/chrome/common/extensions/api/system_log.idl new file mode 100755 index 000000000..33de2db1c --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/system_log.idl @@ -0,0 +1,26 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.systemLog API to record Chrome system logs from +// extensions. +[platforms=("chromeos", "lacros"), + implemented_in="chrome/browser/chromeos/extensions/system_log/system_log_api.h"] +namespace systemLog { + callback VoidCallback = void (); + + // Options for $(ref:add). + // |message|: A log message to record. + dictionary MessageOptions { + DOMString message; + }; + + interface Functions { + // Adds a new log record. + // |options|: The logging options. + // |callback|: A callback to invoke once the log has been added. + static void add( + MessageOptions options, + optional VoidCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/tab_capture.idl b/tools/under-control/src/chrome/common/extensions/api/tab_capture.idl new file mode 100755 index 000000000..4eb3a4a21 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/tab_capture.idl @@ -0,0 +1,130 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.tabCapture API to interact with tab media +// streams. +namespace tabCapture { + + enum TabCaptureState { + pending, + active, + stopped, + error + }; + + dictionary CaptureInfo { + // The id of the tab whose status changed. + long tabId; + + // The new capture status of the tab. + TabCaptureState status; + + // Whether an element in the tab being captured is in fullscreen mode. + boolean fullscreen; + }; + + // MediaTrackConstraints for the media streams that will be passed to WebRTC. + // See section on MediaTrackConstraints: + // http://dev.w3.org/2011/webrtc/editor/getusermedia.html + dictionary MediaStreamConstraint { + object mandatory; + object? _optional; + }; + + // Whether we are requesting tab video and/or audio and the + // MediaTrackConstraints that should be set for these streams. + dictionary CaptureOptions { + boolean? audio; + boolean? video; + MediaStreamConstraint? audioConstraints; + MediaStreamConstraint? videoConstraints; + [nodoc] DOMString? presentationId; + }; + + dictionary GetMediaStreamOptions { + // Optional tab id of the tab which will later invoke + // getUserMedia() to consume the stream. If not specified + // then the resulting stream can be used only by the calling extension. + // The stream can only be used by frames in the given tab whose security + // origin matches the consumber tab's origin. The tab's origin must be a + // secure origin, e.g. HTTPS. + long? consumerTabId; + + // Optional tab id of the tab which will be captured. If not specified + // then the current active tab will be selected. Only tabs for which the + // extension has been granted the activeTab permission can be + // used as the target tab. + long? targetTabId; + }; + + callback GetTabMediaCallback = + void ([instanceOf=LocalMediaStream] object stream); + + callback GetCapturedTabsCallback = void (CaptureInfo[] result); + + // To assemble MediaConstraints with this |streamId|, source type must be + // assigned as 'tab'. For example: + // + // const constraints = { + // mandatory: { + // chromeMediaSource: 'tab', + // chromeMediaSourceId: streamId + // } + // }; + // navigator.getUserMedia({audio: constraints, video: constraints}, + // successCallback, failCallback); + // + callback GetMediaStreamIdCallback = void (DOMString streamId); + + interface Functions { + // Captures the visible area of the currently active tab. Capture can + // only be started on the currently active tab after the extension has been + // invoked, similar to the way that + // activeTab works. + // Capture is maintained across page navigations within + // the tab, and stops when the tab is closed, or the media stream is closed + // by the extension. + // + // |options| : Configures the returned media stream. + // |callback| : Callback with either the tab capture MediaStream or + // null. null indicates an error has occurred + // and the client may query $(ref:runtime.lastError) to access the error + // details. + [doesNotSupportPromises="Custom hook sets lastError crbug.com/1504349"] + static void capture(CaptureOptions options, + GetTabMediaCallback callback); + + // Returns a list of tabs that have requested capture or are being + // captured, i.e. status != stopped and status != error. + // This allows extensions to inform the user that there is an existing + // tab capture that would prevent a new tab capture from succeeding (or + // to prevent redundant requests for the same tab). + // |callback| : Callback invoked with CaptureInfo[] for captured tabs. + static void getCapturedTabs( + GetCapturedTabsCallback callback); + + // Creates a stream ID to capture the target tab. + // Similar to chrome.tabCapture.capture() method, but returns a media + // stream ID, instead of a media stream, to the consumer tab. + // + // |GetMediaStreamOptions| : Options for the media stream id to retrieve. + // |callback| : Callback to invoke with the result. If successful, the + // result is an opaque string that can be passed to the + // getUserMedia() API to generate a media stream that + // corresponds to the target tab. The created streamId can + // only be used once and expires after a few seconds if it is not used. + static void getMediaStreamId( + optional GetMediaStreamOptions options, + GetMediaStreamIdCallback callback); + }; + + interface Events { + // Event fired when the capture status of a tab changes. + // This allows extension authors to keep track of the capture status of + // tabs to keep UI elements like page actions in sync. + // |info| : CaptureInfo with new capture status for the tab. + static void onStatusChanged(CaptureInfo info); + }; + +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/users_private.idl b/tools/under-control/src/chrome/common/extensions/api/users_private.idl new file mode 100755 index 000000000..2800567c0 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/users_private.idl @@ -0,0 +1,77 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.usersPrivate API to manage users. +[platforms=("chromeos"), + implemented_in="chrome/browser/ash/extensions/users_private/users_private_api.h"] +namespace usersPrivate { + + dictionary User { + // Email for the user. + DOMString email; + + // Display email for the user. + DOMString displayEmail; + + // Display name for the user. + DOMString name; + + // Whether this user is the device owner. + boolean isOwner; + + // Whether this user is Child. + boolean isChild; + }; + + dictionary LoginStatusDict { + // True if a user is logged in (including guest, public session, etc). + boolean isLoggedIn; + + // True if the screen is locked. + boolean isScreenLocked; + }; + + callback UsersCallback = void (User[] users); + callback UserAddedCallback = void (boolean success); + callback UserRemovedCallback = void (boolean success); + callback ManagedCallback = void (boolean managed); + callback UserCallback = void (User user); + callback LoginStatusCallback = void (LoginStatusDict status); + callback IsUserInListCallback = void (boolean found); + + interface Functions { + // Gets a list of known users. + static void getUsers(UsersCallback callback); + + // Checks to see if the user is already present in the user list. + static void isUserInList( + DOMString email, + IsUserInListCallback callback); + + // Adds a new user with the given email to the user list. + // The callback is called with true if the user was added succesfully, or + // with false if not (e.g. because the user was already present, or the + // current user isn't the owner). + static void addUser( + DOMString email, + UserAddedCallback callback); + + // Removes the user with the given email from the user list. + // The callback is called with true if the user was removed succesfully, or + // with false if not (e.g. because the user was not already present, or + // the current user isn't the owner). + static void removeUser( + DOMString email, + UserRemovedCallback callback); + + // Whether the user list is managed by enterprise. + static void isUserListManaged(ManagedCallback callback); + + // Returns the current user. + static void getCurrentUser(UserCallback callback); + + // Get login status. + static void getLoginStatus(LoginStatusCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/vpn_provider.idl b/tools/under-control/src/chrome/common/extensions/api/vpn_provider.idl new file mode 100755 index 000000000..95ad1eb04 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/vpn_provider.idl @@ -0,0 +1,201 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.vpnProvider API to implement a VPN +// client. +[platforms=("chromeos", "lacros"), + implemented_in="chrome/browser/chromeos/extensions/vpn_provider/vpn_provider_api.h"] +namespace vpnProvider { + // A parameters class for the VPN interface. + dictionary Parameters { + // IP address for the VPN interface in CIDR notation. + // IPv4 is currently the only supported mode. + DOMString address; + // Broadcast address for the VPN interface. (default: deduced + // from IP address and mask) + DOMString? broadcastAddress; + // MTU setting for the VPN interface. (default: 1500 bytes) + DOMString? mtu; + // Exclude network traffic to the list of IP blocks in CIDR notation from + // the tunnel. This can be used to bypass traffic to and from the VPN + // server. + // When many rules match a destination, the rule with the longest matching + // prefix wins. + // Entries that correspond to the same CIDR block are treated as duplicates. + // Such duplicates in the collated (exclusionList + inclusionList) list are + // eliminated and the exact duplicate entry that will be eliminated is + // undefined. + DOMString[] exclusionList; + // Include network traffic to the list of IP blocks in CIDR notation to the + // tunnel. This parameter can be used to set up a split tunnel. By default + // no traffic is directed to the tunnel. Adding the entry "0.0.0.0/0" to + // this list gets all the user traffic redirected to the tunnel. + // When many rules match a destination, the rule with the longest matching + // prefix wins. + // Entries that correspond to the same CIDR block are treated as duplicates. + // Such duplicates in the collated (exclusionList + inclusionList) list are + // eliminated and the exact duplicate entry that will be eliminated is + // undefined. + DOMString[] inclusionList; + // A list of search domains. (default: no search domain) + DOMString[]? domainSearch; + // A list of IPs for the DNS servers. + DOMString[] dnsServers; + // Whether or not the VPN extension implements auto-reconnection. + // + // If true, the linkDown, linkUp, + // linkChanged, suspend, and resume + // platform messages will be used to signal the respective events. + // If false, the system will forcibly disconnect the VPN if the network + // topology changes, and the user will need to reconnect manually. + // (default: false) + // + // This property is new in Chrome 51; it will generate an exception in + // earlier versions. try/catch can be used to conditionally enable the + // feature based on browser support. + DOMString? reconnect; + }; + + // The enum is used by the platform to notify the client of the VPN session + // status. + enum PlatformMessage { + // Indicates that the VPN configuration connected. + connected, + // Indicates that the VPN configuration disconnected. + disconnected, + // Indicates that an error occurred in VPN connection, for example a timeout. A description + // of the error is given as the + // error argument to onPlatformMessage. + error, + // Indicates that the default physical network connection is down. + linkDown, + // Indicates that the default physical network connection is back up. + linkUp, + // Indicates that the default physical network connection changed, e.g. wifi->mobile. + linkChanged, + // Indicates that the OS is preparing to suspend, so the VPN should drop its connection. + // The extension is not guaranteed to receive this event prior to + // suspending. + suspend, + // Indicates that the OS has resumed and the user has logged back in, so the VPN should + // try to reconnect. + resume + }; + + // The enum is used by the VPN client to inform the platform + // of its current state. This helps provide meaningful messages + // to the user. + enum VpnConnectionState { + // Specifies that VPN connection was successful. + connected, + // Specifies that VPN connection has failed. + failure + }; + + // The enum is used by the platform to indicate the event that triggered + // onUIEvent. + enum UIEvent { + // Requests that the VPN client show the add configuration dialog box to + // the user. + showAddDialog, + // Requests that the VPN client show the configuration settings dialog box + // to the user. + showConfigureDialog + }; + + // The callback is used by setParameters, sendPacket + // to signal completion. The callback is called with + // chrome.runtime.lastError set to error code if + // there is an error. + [inline_doc] callback CallCompleteCallback = void (); + + // The callback is used by createConfig to signal completion. + // The callback is called with chrome.runtime.lastError set to + // an error code if there is an error. + // |id|: A unique ID for the created configuration, or undefined + // on failure. + [inline_doc] callback CreateConfigCompleteCallback = void (DOMString id); + + interface Functions { + // Creates a new VPN configuration that persists across multiple login + // sessions of the user. + // |name|: The name of the VPN configuration. + // |callback|: Called when the configuration is created or if there is an + // error. + static void createConfig( + DOMString name, + CreateConfigCompleteCallback callback); + + // Destroys a VPN configuration created by the extension. + // |id|: ID of the VPN configuration to destroy. + // |callback|: Called when the configuration is destroyed or if there is an + // error. + static void destroyConfig( + DOMString id, + optional CallCompleteCallback callback); + + // Sets the parameters for the VPN session. This should be called + // immediately after "connected" is received from the platform. + // This will succeed only when the VPN session is owned by the extension. + // |parameters|: The parameters for the VPN session. + // |callback|: Called when the parameters are set or if there is an error. + static void setParameters( + Parameters parameters, + CallCompleteCallback callback); + + // Sends an IP packet through the tunnel created for the VPN session. + // This will succeed only when the VPN session is owned by the extension. + // |data|: The IP packet to be sent to the platform. + // |callback|: Called when the packet is sent or if there is an error. + static void sendPacket( + ArrayBuffer data, + optional CallCompleteCallback callback); + + // Notifies the VPN session state to the platform. + // This will succeed only when the VPN session is owned by the extension. + // |state|: The VPN session state of the VPN client. + // |callback|: Called when the notification is complete or if there is an + // error. + static void notifyConnectionStateChanged( + VpnConnectionState state, + optional CallCompleteCallback callback); + }; + + interface Events { + // Triggered when a message is received from the platform for a + // VPN configuration owned by the extension. + // |id|: ID of the configuration the message is intended for. + // |message|: The message received from the platform. Note that new + // message types may be added in future Chrome versions to support new + // features. + // |error|: Error message when there is an error. + static void onPlatformMessage(DOMString id, + PlatformMessage message, + DOMString error); + + // Triggered when an IP packet is received via the tunnel for the VPN + // session owned by the extension. + // |data|: The IP packet received from the platform. + static void onPacketReceived(ArrayBuffer data); + + // Triggered when a configuration created by the extension is removed by the + // platform. + // |id|: ID of the removed configuration. + static void onConfigRemoved(DOMString id); + + // Triggered when a configuration is created by the platform for the + // extension. + // |id|: ID of the configuration created. + // |name|: Name of the configuration created. + // |data|: Configuration data provided by the administrator. + static void onConfigCreated(DOMString id, DOMString name, object data); + + // Triggered when there is a UI event for the extension. UI events are + // signals from the platform that indicate to the app that a UI dialog + // needs to be shown to the user. + // |event|: The UI event that is triggered. + // |id|: ID of the configuration for which the UI event was triggered. + static void onUIEvent(UIEvent event, optional DOMString id); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/web_authentication_proxy.idl b/tools/under-control/src/chrome/common/extensions/api/web_authentication_proxy.idl new file mode 100755 index 000000000..c59885ae5 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/web_authentication_proxy.idl @@ -0,0 +1,196 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.webAuthenticationProxy API lets remote desktop +// software running on a remote host intercept Web Authentication API +// (WebAuthn) requests in order to handle them on a local client. +namespace webAuthenticationProxy { + // An object representing a + // PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() + // call. + dictionary IsUvpaaRequest { + // An opaque identifier for the request. + long requestId; + }; + + // An object representing a WebAuthn + // navigator.credentials.create() call. + dictionary CreateRequest { + // An opaque identifier for the request. + long requestId; + + // The PublicKeyCredentialCreationOptions passed to + // navigator.credentials.create(), serialized as a JSON + // string. The serialization format is compatible with + // PublicKeyCredential.parseCreationOptionsFromJSON(). + DOMString requestDetailsJson; + }; + + // An object representing a WebAuthn navigator.credentials.get() + // call. + dictionary GetRequest { + // An opaque identifier for the request. + long requestId; + + // The PublicKeyCredentialRequestOptions passed to + // navigator.credentials.get(), serialized as a JSON string. + // The serialization format is compatible with + // PublicKeyCredential.parseRequestOptionsFromJSON(). + DOMString requestDetailsJson; + }; + + // This interface defines Events that fire when any website makes a WebAuthn + // request. Regular processing of WebAuthn requests in the local Chrome + // instance is disabled when these events are subscribed to. + interface Events { + // A native application associated with this extension can cause this + // event to be fired by writing to a file with a name equal to the + // extension's ID in a directory named + // WebAuthenticationProxyRemoteSessionStateChange inside the + // default + // user data directory + // + // The contents of the file should be empty. I.e., it is not necessary to + // change the contents of the file in order to trigger this event. + // + // The native host application may use this event mechanism to signal a + // possible remote session state change (i.e. from detached to attached, or + // vice versa) while the extension service worker is possibly suspended. In + // the handler for this event, the extension can call the + // attach() or detach() API methods accordingly. + // + // The event listener must be registered synchronously at load time. + static void onRemoteSessionStateChange(); + + // Fires when a WebAuthn navigator.credentials.create() call + // occurs. The extension must supply a response by calling + // completeCreateRequest() with the requestId from + // requestInfo. + static void onCreateRequest(CreateRequest requestInfo); + + // Fires when a WebAuthn navigator.credentials.get() call occurs. The + // extension must supply a response by calling + // completeGetRequest() with the requestId from + // requestInfo + static void onGetRequest(GetRequest requestInfo); + + // Fires when a + // PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() + // call occurs. The extension must supply a response by calling + // completeIsUvpaaRequest() with the requestId + // from requestInfo + static void onIsUvpaaRequest(IsUvpaaRequest requestInfo); + + // Fires when a onCreateRequest or onGetRequest + // event is canceled (because the WebAuthn request was aborted by the + // caller, or because it timed out). When receiving this event, the + // extension should cancel processing of the corresponding request on the + // client side. Extensions cannot complete a request once it has been + // canceled. + static void onRequestCanceled(long requestId); + }; + + callback ErrorCallback = void(optional DOMString error); + callback VoidCallback = void(); + + dictionary DOMExceptionDetails { + DOMString name; + DOMString message; + }; + + dictionary CreateResponseDetails { + // The requestId of the CreateRequest. + long requestId; + + // The DOMException yielded by the remote request, if any. + DOMExceptionDetails? error; + + // The PublicKeyCredential, yielded by the remote request, if + // any, serialized as a JSON string by calling + // href="https://w3c.github.io/webauthn/#dom-publickeycredential-tojson"> + // PublicKeyCredential.toJSON(). + DOMString? responseJson; + }; + + dictionary GetResponseDetails { + // The requestId of the CreateRequest. + long requestId; + + // The DOMException yielded by the remote request, if any. + DOMExceptionDetails? error; + + // The PublicKeyCredential, yielded by the remote request, if + // any, serialized as a JSON string by calling + // href="https://w3c.github.io/webauthn/#dom-publickeycredential-tojson"> + // PublicKeyCredential.toJSON(). + DOMString? responseJson; + }; + + dictionary IsUvpaaResponseDetails { + long requestId; + boolean isUvpaa; + }; + + interface Functions { + // Reports the result of a navigator.credentials.create() + // call. The extension must call this for every + // onCreateRequest event it has received, unless the request + // was canceled (in which case, an onRequestCanceled event is + // fired). + static void completeCreateRequest( + CreateResponseDetails details, + VoidCallback callback); + + // Reports the result of a navigator.credentials.get() call. + // The extension must call this for every onGetRequest event + // it has received, unless the request was canceled (in which case, an + // onRequestCanceled event is fired). + static void completeGetRequest( + GetResponseDetails details, + VoidCallback callback); + + // Reports the result of a + // PublicKeyCredential.isUserVerifyingPlatformAuthenticator() + // call. The extension must call this for every + // onIsUvpaaRequest event it has received. + static void completeIsUvpaaRequest( + IsUvpaaResponseDetails details, + VoidCallback callback); + + // Makes this extension the active Web Authentication API request proxy. + // + // Remote desktop extensions typically call this method after detecting + // attachment of a remote session to this host. Once this method returns + // without error, regular processing of WebAuthn requests is suspended, and + // events from this extension API are raised. + // + // This method fails with an error if a different extension is already + // attached. + // + // The attached extension must call detach() once the remote + // desktop session has ended in order to resume regular WebAuthn request + // processing. Extensions automatically become detached if they are + // unloaded. + // + // Refer to the onRemoteSessionStateChange event for signaling + // a change of remote session attachment from a native application to to + // the (possibly suspended) extension. + static void attach(ErrorCallback callback); + + // Removes this extension from being the active Web Authentication API + // request proxy. + // + // This method is typically called when the extension detects that a remote + // desktop session was terminated. Once this method returns, the extension + // ceases to be the active Web Authentication API request proxy. + // + // Refer to the onRemoteSessionStateChange event for signaling + // a change of remote session attachment from a native application to to + // the (possibly suspended) extension. + static void detach(ErrorCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/webrtc_audio_private.idl b/tools/under-control/src/chrome/common/extensions/api/webrtc_audio_private.idl new file mode 100755 index 000000000..ad41331d8 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/webrtc_audio_private.idl @@ -0,0 +1,64 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.webrtcAudioPrivate API allows enumeration +// of audio output (sink) devices. +// +// Note that device IDs as used in this API are opaque (i.e. they are +// not the hardware identifier of the device) and while they are +// unique and persistent across sessions, they are valid only to the +// extension calling this API (i.e. they cannot be shared between +// extensions). +// +// See http://goo.gl/8rOmgk for further documentation of this API. + +namespace webrtcAudioPrivate { + + dictionary SinkInfo { + // The opaque identifier of the audio sink device, which is unique + // and static for the extension calling the API but invalid for + // others. + DOMString sinkId; + // The user-friendly name (e.g. "Bose Amplifier"). + DOMString sinkLabel; + // Current sample rate of the device, in Hz. Useful e.g. to know + // if the remote side should be asked to send a lower sampling + // rate. + long sampleRate; + // True if the device is ready to play out audio. E.g. if it is a + // device that takes an audio jack, whether a jack is plugged in. + // + // TODO(joi): Do unplugged devices even get included in enumeration? + boolean isReady; + // True if this device is the default audio sink device on the + // machine. + boolean isDefault; + }; + + callback GetSinksCallback = void(SinkInfo[] sinkInfo); + callback SinkIdCallback = void(DOMString sinkId); + + interface Functions { + // Retrieves a list of available audio sink devices. + static void getSinks(GetSinksCallback callback); + + // Given a security origin and an input device ID valid for that + // security origin, retrieve an audio sink ID valid for the + // extension, or the empty string if there is no associated audio + // sink. + // + // The associated sink ID can be used as a sink ID for + // setActiveSink. It is valid irrespective of which process you are + // setting the active sink for. + static void getAssociatedSink( + DOMString securityOrigin, + DOMString sourceIdInOrigin, + SinkIdCallback callback); + }; + + interface Events { + // Fired when audio sink devices are added or removed. + static void onSinksChanged(); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/webrtc_desktop_capture_private.idl b/tools/under-control/src/chrome/common/extensions/api/webrtc_desktop_capture_private.idl new file mode 100755 index 000000000..a7463aa60 --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/webrtc_desktop_capture_private.idl @@ -0,0 +1,34 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.webrtcDesktopCapturePrivate API to capture +// desktop media requested from a WebView. +namespace webrtcDesktopCapturePrivate { + dictionary RequestInfo { + // The guest process id for the requester. + long guestProcessId; + + // The webview render frame id for the requester. + long guestRenderFrameId; + }; + + enum DesktopCaptureSourceType { + screen, + window, + tab + }; + + callback chooseDesktopMediaCallback = void (DOMString streamId); + + interface Functions { + // Shows desktop media picker UI with the specified set of sources. + [doesNotSupportPromises="Synchronous return and callback crbug.com/1143032"] + static long chooseDesktopMedia(DesktopCaptureSourceType[] sources, + RequestInfo request, + chooseDesktopMediaCallback callback); + + // Hides desktop media picker dialog shown by chooseDesktopMedia(). + static void cancelChooseDesktopMedia(long desktopMediaRequestId); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/webrtc_logging_private.idl b/tools/under-control/src/chrome/common/extensions/api/webrtc_logging_private.idl new file mode 100755 index 000000000..fca8e3ddd --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/webrtc_logging_private.idl @@ -0,0 +1,186 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.webrtcLoggingPrivate API to control diagnostic +// WebRTC logging. +namespace webrtcLoggingPrivate { + dictionary MetaDataEntry { + // The meta data entry key. + DOMString key; + + // The meta data entry value. + DOMString value; + }; + + dictionary UploadResult { + // The report ID for the uploaded log. Will be empty if not successful. + DOMString reportId; + }; + + dictionary RequestInfo { + // The tab identifier from the chrome.tabs API, if the request is from a + // tab. + long? tabId; + + // The guest process id for the requester, if the request is from a + // webview. + long? guestProcessId; + + // Use the render process of the webview in the current page. This allows an + // app to make a request for a webview it contains. If there are more or + // less than 1 webview, this will fail with a runtime error. + boolean? targetWebview; + }; + + // This contains information about the result of audio debug recordings. + dictionary RecordingInfo { + // Absolute path prefix for the files with the audio debug recordings. + DOMString prefixPath; + + // Indicates if recording was stopped (either by a timed callback after the + // time limit has elapsed, or by a manual call). + boolean didStop; + + // Indicates if recording was stopped manually through a + // stopAudioDebugRecordings() call. + boolean didManualStop; + }; + + dictionary StartEventLoggingResult { + // The log ID. Non-empty if and only if StartEventLogging() was successful. + DOMString logId; + }; + + callback GenericDoneCallback = void (); + callback RecordingDoneCallback = void (RecordingInfo info); + callback UploadDoneCallback = void (UploadResult result); + callback GetLogsDirectoryCallback = void ([instanceOf = DirectoryEntry] object entry); + callback StartEventLoggingCallback = void (StartEventLoggingResult result); + + interface Functions { + // For all functions, |request| determines which render process to apply + // the operation on. |request| identifies the requesting process. + // |securityOrigin| is the security origin for the tab identified by |tabId| + // and is used for verifying that the tab is the correct one and has not + // been navigated away from. + + // Sets additional custom meta data that will be uploaded along with the + // log. |metaData| is a dictionary of the metadata (key, value). + static void setMetaData(RequestInfo request, + DOMString securityOrigin, + MetaDataEntry[] metaData, + GenericDoneCallback callback); + + // Starts logging. If logging has already been started for this render + // process, the call will be ignored. |appSessionId| is the unique session + // ID which will be added to the log. + static void start(RequestInfo request, + DOMString securityOrigin, + GenericDoneCallback callback); + + // Sets whether the log should be uploaded automatically for the case when + // the render process goes away (tab is closed or crashes) and stop has not + // been called before that. If |shouldUpload| is true it will be uploaded, + // otherwise it will be discarded. The default setting is to discard it. + static void setUploadOnRenderClose(RequestInfo request, + DOMString securityOrigin, + boolean shouldUpload); + + // Stops logging. After stop has finished, either upload() or discard() + // should be called, otherwise the log will be kept in memory until the + // render process is closed or logging restarted. + static void stop(RequestInfo request, + DOMString securityOrigin, + GenericDoneCallback callback); + + // Stores the current log without uploading. The log may stay around for + // as much as 5 days. The application has the option of supplying an id + // for uniquely identifying the log for later upload via a call to + // uploadStored(). + static void store(RequestInfo request, + DOMString securityOrigin, + DOMString logId, + GenericDoneCallback callback); + + // Uploads a previously kept log that was stored via a call to store(). + // The caller needs to know the logId as was originally provided in the + // call to store(). + static void uploadStored(RequestInfo request, + DOMString securityOrigin, + DOMString logId, + UploadDoneCallback callback); + + // Uploads the log and the RTP dumps, if they exist. Logging and RTP dumping + // must be stopped before this function is called. + static void upload(RequestInfo request, + DOMString securityOrigin, + UploadDoneCallback callback); + + // Discards the log. Logging must be stopped before this function is called. + static void discard(RequestInfo request, + DOMString securityOrigin, + GenericDoneCallback callback); + + // Starts RTP dumping. If it has already been started for this render + // process, the call will be ignored. + static void startRtpDump(RequestInfo request, + DOMString securityOrigin, + boolean incoming, + boolean outgoing, + GenericDoneCallback callback); + + // Stops RTP dumping. After stop has finished, the dumps will be + // uploaded with the log if upload is called. Otherwise, the dumps will be + // discarded. + static void stopRtpDump(RequestInfo request, + DOMString securityOrigin, + boolean incoming, + boolean outgoing, + GenericDoneCallback callback); + + // Starts audio debug recordings. + // |seconds| indicates how many seconds of audio to record. |callback| + // is invoked once recording stops. + // If |seconds| is zero, recording will continue until + // stopAudioDebugRecordings() is explicitly called. In this case, + // |callback| is invoked once recording starts and will report + // that recording has not stopped. + // If |seconds| is negative, startAudioDebugRecordings() fails. + static void startAudioDebugRecordings(RequestInfo request, + DOMString securityOrigin, + long seconds, + RecordingDoneCallback callback); + + // Stops audio debug recordings. |callback| is invoked once recording + // stops. If there is no recording in progress, stopAudioDebugRecordings() + // fails. + static void stopAudioDebugRecordings(RequestInfo request, + DOMString securityOrigin, + RecordingDoneCallback callback); + + // Start remote-bound event logging for a specific peer connection, + // indicated by its session description's ID. + // If successful, the callback will carry the ID of the log. + // * |webAppId| must be a number between 1 and 99 (inclusive), which will be + // incorporated into the uploaded log, so as to help distinugish logs + // captured by different web-apps. + // * |outputPeriodMs| refers to the time between emissions of logs. + // Only non-negative values are allowed. If set to zero, logs will be + // produced as soon as an event occurs. If positive, events will be + // batched together and emitted approximately every |outputPeriodMs| ms. + static void startEventLogging(RequestInfo request, + DOMString securityOrigin, + DOMString sessionId, + long maxLogSizeBytes, + long outputPeriodMs, + long webAppId, + StartEventLoggingCallback callback); + + // Returns the directory entry for the "WebRTC Logs" directory. If the + // directory doesn't exist yet, this will create it. If the directory + // cannot be created, this call will fail with a runtime error. + [doesNotSupportPromises="Custom hook sets lastError crbug.com/1504349"] + static void getLogsDirectory(GetLogsDirectoryCallback callback); + }; +}; diff --git a/tools/under-control/src/chrome/common/extensions/api/wm_desks_private.idl b/tools/under-control/src/chrome/common/extensions/api/wm_desks_private.idl new file mode 100755 index 000000000..90c19807f --- /dev/null +++ b/tools/under-control/src/chrome/common/extensions/api/wm_desks_private.idl @@ -0,0 +1,145 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Private API for trusted extensions/apps to do desk related operations. +[platforms=("chromeos","lacros"), + implemented_in="chrome/browser/chromeos/extensions/wm/wm_desks_private_api.h"] +namespace wmDesksPrivate { + enum SavedDeskType { + // Desk saved for regular desk template. + kTemplate, + + // Desk saved for Save & Recall. + kSaveAndRecall, + + // Unknown desk type. + kUnknown + }; + + dictionary RemoveDeskOptions { + // Define whether close all windows on the desk and combine them to the + // active desk to the left. + boolean combineDesks; + + // Define whether removed desk is retrievable. + boolean? allowUndo; + }; + + dictionary Desk { + // Unique ID for a desk. + DOMString deskUuid; + + // User readable name of the desk. + DOMString deskName; + }; + + dictionary SavedDesk { + // Unique ID for a saved desk. + DOMString savedDeskUuid; + + // User readable name of the saved desk. + DOMString savedDeskName; + + // Saved desk type. + SavedDeskType savedDeskType; + }; + + // Launch desk options + dictionary LaunchOptions { + // User readable name of the desk. + DOMString? deskName; + }; + + // Window properties + dictionary WindowProperties { + // If window show up on all desks. + boolean allDesks; + }; + + callback DeskIdCallback = void (DOMString deskId); + callback VoidCallback = void (); + callback GetDeskTemplateJsonCallback = void (DOMString templateJson); + callback GetAllDesksCallback = void (Desk[] desks); + callback GetSavedDesksCallback = void (SavedDesk[] saveDesks); + callback SaveActiveDeskCallback = void (SavedDesk desk); + callback GetDeskByIDCallback = void (Desk desk); + + interface Functions { + // Returns all available previously-saved desks. + static void getSavedDesks( + GetSavedDesksCallback callback); + + // Launches a desk, if `templateUuid` is present in the options, launches a + // desk template, otherwise launches an empty desk. If `deskName` is present + // in the options, using provided name as desk name, otherwise launches with + // auto generated name. + static void launchDesk( + LaunchOptions launchOptions, + DeskIdCallback callback); + + // Gets the template associated with the templateUuid and returns its JSON + // representation. Returns an error if either the template could not be + // found or the user profile is not valid. + static void getDeskTemplateJson( + DOMString templateUuid, + GetDeskTemplateJsonCallback callback); + + // Removes a desk as specified in `deskId`. If `combineDesks` of + // `RemoveDeskOptions` is present or set to true, remove the desk and + // combine windows to the active desk to the left. If `allowUndo` is + // present or set to true, prompt the user with a notification allowing for + // the desk to be retrieved. Otherwise close all windows on the desk. + static void removeDesk( + DOMString deskId, + optional RemoveDeskOptions removeDeskOptions, + optional VoidCallback callback); + + // Returns all available desks. + static void getAllDesks(GetAllDesksCallback callback); + + // Sets the window properties for window identified by the `windowId`. + static void setWindowProperties( + long windowId, + WindowProperties windowProperties, + optional VoidCallback callback); + + // Saves the current active desk to the library and remove it from the desk + // bar. + static void saveActiveDesk( + SaveActiveDeskCallback callback); + + // Deletes the saved desk from the library. + static void deleteSavedDesk( + DOMString savedDeskUuid, + optional VoidCallback callback); + + // Launches a saved desk from the library back to active desk. + static void recallSavedDesk( + DOMString savedDeskUuid, + DeskIdCallback callback); + + // Retrieves the UUID of the current active desk. + static void getActiveDesk(DeskIdCallback callback); + + // Switches to the target desk. + static void switchDesk( + DOMString deskUuid, VoidCallback callback); + + // Retrieves desk by the desk UUID. + static void getDeskByID( + DOMString deskUuid, GetDeskByIDCallback callback); + }; + + interface Events { + // Fires when new desks is added. + static void OnDeskAdded(DOMString deskId, boolean fromUndo); + + // Fires when desk removal is finalized. + static void OnDeskRemoved(DOMString deskId); + + // Fires when desk activation changed. + static void OnDeskSwitched(DOMString activated, DOMString deactivated); + }; + +}; diff --git a/tools/under-control/src/chrome/renderer/chrome_content_renderer_client.cc b/tools/under-control/src/chrome/renderer/chrome_content_renderer_client.cc new file mode 100755 index 000000000..13f354e79 --- /dev/null +++ b/tools/under-control/src/chrome/renderer/chrome_content_renderer_client.cc @@ -0,0 +1,1881 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/renderer/chrome_content_renderer_client.h" + +#include +#include +#include +#include +#include + +#include "base/check_op.h" +#include "base/command_line.h" +#include "base/debug/crash_logging.h" +#include "base/functional/bind.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/user_metrics_action.h" +#include "base/no_destructor.h" +#include "base/notreached.h" +#include "base/process/current_process.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task/single_thread_task_runner.h" +#include "base/time/time.h" +#include "base/values.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "chrome/common/buildflags.h" +#include "chrome/common/channel_info.h" +#include "chrome/common/chrome_content_client.h" +#include "chrome/common/chrome_features.h" +#include "chrome/common/chrome_isolated_world_ids.h" +#include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/crash_keys.h" +#include "chrome/common/pepper_permission_util.h" +#include "chrome/common/ppapi_utils.h" +#include "chrome/common/profiler/thread_profiler.h" +#include "chrome/common/profiler/unwind_util.h" +#include "chrome/common/secure_origin_allowlist.h" +#include "chrome/common/url_constants.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/grit/branded_strings.h" +#include "chrome/grit/generated_resources.h" +#include "chrome/grit/renderer_resources.h" +#include "chrome/renderer/benchmarking_extension.h" +#include "chrome/renderer/browser_exposed_renderer_interfaces.h" +#include "chrome/renderer/cart/commerce_hint_agent.h" +#include "chrome/renderer/chrome_content_settings_agent_delegate.h" +#include "chrome/renderer/chrome_render_frame_observer.h" +#include "chrome/renderer/chrome_render_thread_observer.h" +#include "chrome/renderer/controlled_frame/controlled_frame_extensions_renderer_api_provider.h" +#include "chrome/renderer/google_accounts_private_api_extension.h" +#include "chrome/renderer/loadtimes_extension_bindings.h" +#include "chrome/renderer/media/flash_embed_rewrite.h" +#include "chrome/renderer/media/webrtc_logging_agent_impl.h" +#include "chrome/renderer/net/net_error_helper.h" +#include "chrome/renderer/net_benchmarking_extension.h" +#include "chrome/renderer/plugins/non_loadable_plugin_placeholder.h" +#include "chrome/renderer/plugins/pdf_plugin_placeholder.h" +#include "chrome/renderer/supervised_user/supervised_user_error_page_controller_delegate_impl.h" +#include "chrome/renderer/trusted_vault_encryption_keys_extension.h" +#include "chrome/renderer/url_loader_throttle_provider_impl.h" +#include "chrome/renderer/v8_unwinder.h" +#include "chrome/renderer/web_link_preview_triggerer_impl.h" +#include "chrome/renderer/websocket_handshake_throttle_provider_impl.h" +#include "chrome/renderer/worker_content_settings_client.h" +#include "chrome/services/speech/buildflags/buildflags.h" +#include "components/autofill/content/renderer/autofill_agent.h" +#include "components/autofill/content/renderer/password_autofill_agent.h" +#include "components/autofill/content/renderer/password_generation_agent.h" +#include "components/autofill/core/common/autofill_features.h" +#include "components/commerce/content/renderer/commerce_web_extractor.h" +#include "components/commerce/core/commerce_feature_list.h" +#include "components/content_capture/common/content_capture_features.h" +#include "components/content_capture/renderer/content_capture_sender.h" +#include "components/content_settings/core/common/content_settings_pattern.h" +#include "components/continuous_search/renderer/search_result_extractor_impl.h" +#include "components/country_codes/country_codes.h" +#include "components/dom_distiller/content/renderer/distillability_agent.h" +#include "components/dom_distiller/content/renderer/distiller_js_render_frame_observer.h" +#include "components/dom_distiller/core/dom_distiller_features.h" +#include "components/dom_distiller/core/dom_distiller_switches.h" +#include "components/dom_distiller/core/url_constants.h" +#include "components/error_page/common/error.h" +#include "components/error_page/common/localized_error.h" +#include "components/feed/buildflags.h" +#include "components/feed/feed_feature_list.h" +#include "components/grit/components_scaled_resources.h" +#include "components/heap_profiling/in_process/heap_profiler_controller.h" +#include "components/history_clusters/core/config.h" +#include "components/metrics/call_stacks/call_stack_profile_builder.h" +#include "components/network_hints/renderer/web_prescient_networking_impl.h" +#include "components/no_state_prefetch/renderer/no_state_prefetch_client.h" +#include "components/no_state_prefetch/renderer/no_state_prefetch_helper.h" +#include "components/no_state_prefetch/renderer/no_state_prefetch_utils.h" +#include "components/no_state_prefetch/renderer/prerender_render_frame_observer.h" +#include "components/optimization_guide/core/optimization_guide_features.h" +#include "components/page_content_annotations/core/page_content_annotations_features.h" +#include "components/page_load_metrics/renderer/metrics_render_frame_observer.h" +#include "components/paint_preview/buildflags/buildflags.h" +#include "components/password_manager/core/common/password_manager_features.h" +#include "components/pdf/common/constants.h" +#include "components/pdf/common/pdf_util.h" +#include "components/permissions/features.h" +#include "components/safe_browsing/buildflags.h" +#include "components/safe_browsing/content/renderer/threat_dom_details.h" +#include "components/spellcheck/spellcheck_buildflags.h" +#include "components/subresource_filter/content/renderer/subresource_filter_agent.h" +#include "components/subresource_filter/content/renderer/unverified_ruleset_dealer.h" +#include "components/subresource_filter/core/common/common_features.h" +#include "components/variations/net/variations_http_headers.h" +#include "components/variations/variations_switches.h" +#include "components/version_info/version_info.h" +#include "components/visitedlink/renderer/visitedlink_reader.h" +#include "components/web_cache/renderer/web_cache_impl.h" +#include "components/webapps/renderer/web_page_metadata_agent.h" +#include "content/public/common/content_constants.h" +#include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/page_visibility_state.h" +#include "content/public/common/url_constants.h" +#include "content/public/common/webplugininfo.h" +#include "content/public/renderer/render_frame.h" +#include "content/public/renderer/render_frame_visitor.h" +#include "extensions/buildflags/buildflags.h" +#include "extensions/renderer/extensions_renderer_api_provider.h" +#include "ipc/ipc_sync_channel.h" +#include "media/base/media_switches.h" +#include "media/media_buildflags.h" +#include "mojo/public/cpp/bindings/generic_pending_receiver.h" +#include "mojo/public/cpp/bindings/remote.h" +#include "net/base/net_errors.h" +#include "pdf/buildflags.h" +#include "ppapi/buildflags/buildflags.h" +#include "printing/buildflags/buildflags.h" +#include "services/network/public/cpp/is_potentially_trustworthy.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "services/tracing/public/cpp/stack_sampling/tracing_sampler_profiler.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h" +#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/scheduler/web_renderer_process_type.h" +#include "third_party/blink/public/platform/url_conversion.h" +#include "third_party/blink/public/platform/web_cache.h" +#include "third_party/blink/public/platform/web_content_security_policy_struct.h" +#include "third_party/blink/public/platform/web_runtime_features.h" +#include "third_party/blink/public/platform/web_security_origin.h" +#include "third_party/blink/public/platform/web_string.h" +#include "third_party/blink/public/platform/web_url.h" +#include "third_party/blink/public/platform/web_url_error.h" +#include "third_party/blink/public/platform/web_url_request.h" +#include "third_party/blink/public/platform/web_url_response.h" +#include "third_party/blink/public/web/web_document.h" +#include "third_party/blink/public/web/web_element.h" +#include "third_party/blink/public/web/web_heap.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/blink/public/web/web_origin_trials.h" +#include "third_party/blink/public/web/web_plugin.h" +#include "third_party/blink/public/web/web_plugin_container.h" +#include "third_party/blink/public/web/web_plugin_params.h" +#include "third_party/blink/public/web/web_script_controller.h" +#include "third_party/blink/public/web/web_security_policy.h" +#include "third_party/blink/public/web/web_view.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/webui/jstemplate_builder.h" +#include "url/origin.h" +#include "v8/include/v8-isolate.h" + +#if BUILDFLAG(IS_ANDROID) +#include "chrome/renderer/sandbox_status_extension_android.h" +#include "chrome/renderer/wallet/boarding_pass_extractor.h" +#include "components/facilitated_payments/content/renderer/facilitated_payments_agent.h" +#include "components/facilitated_payments/core/features/features.h" +#else +#include "chrome/renderer/searchbox/searchbox.h" +#include "chrome/renderer/searchbox/searchbox_extension.h" +#include "components/search/ntp_features.h" // nogncheck +#endif + +#if BUILDFLAG(ENABLE_SPEECH_SERVICE) +#include "chrome/renderer/media/chrome_speech_recognition_client.h" +#endif // BUILDFLAG(ENABLE_SPEECH_SERVICE) + +#if BUILDFLAG(IS_WIN) +#include "chrome/renderer/render_frame_font_family_accessor.h" +#endif + +#if BUILDFLAG(ENABLE_FEED_V2) +#include "components/feed/content/renderer/rss_link_reader.h" +#include "components/feed/feed_feature_list.h" +#endif + +#if BUILDFLAG(ENABLE_NACL) +#include "components/nacl/common/nacl_constants.h" +#include "components/nacl/renderer/nacl_helper.h" +#endif + +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "chrome/common/initialize_extensions_client.h" +#include "chrome/renderer/extensions/api/chrome_extensions_renderer_api_provider.h" +#include "chrome/renderer/extensions/chrome_extensions_renderer_client.h" +#include "extensions/common/constants.h" +#include "extensions/common/context_data.h" +#include "extensions/common/extension_urls.h" +#include "extensions/common/manifest_handlers/csp_info.h" +#include "extensions/common/manifest_handlers/web_accessible_resources_info.h" +#include "extensions/common/switches.h" +#include "extensions/renderer/api/core_extensions_renderer_api_provider.h" +#include "extensions/renderer/dispatcher.h" +#include "extensions/renderer/guest_view/mime_handler_view/mime_handler_view_container_manager.h" +#include "extensions/renderer/renderer_extension_registry.h" +#include "third_party/blink/public/mojom/css/preferred_color_scheme.mojom.h" +#include "third_party/blink/public/web/web_settings.h" +#endif + +#if BUILDFLAG(ENABLE_PDF) +#include "chrome/renderer/pdf/chrome_pdf_internal_plugin_delegate.h" +#include "components/pdf/renderer/internal_plugin_renderer_helpers.h" +#endif // BUILDFLAG(ENABLE_PDF) + +#if BUILDFLAG(ENABLE_PLUGINS) +#include "chrome/renderer/plugins/chrome_plugin_placeholder.h" +#endif // BUILDFLAG(ENABLE_PLUGINS) + +#if BUILDFLAG(ENABLE_PPAPI) +#include "chrome/renderer/pepper/pepper_helper.h" +#include "ppapi/shared_impl/ppapi_switches.h" // nogncheck crbug.com/1125897 +#endif + +#if BUILDFLAG(ENABLE_PRINTING) +#include "chrome/renderer/printing/chrome_print_render_frame_helper_delegate.h" +#include "components/printing/renderer/print_render_frame_helper.h" // nogncheck +#include "printing/metafile_agent.h" // nogncheck +#endif + +#if BUILDFLAG(ENABLE_PAINT_PREVIEW) +#include "components/paint_preview/renderer/paint_preview_recorder_impl.h" // nogncheck +#endif + +#if BUILDFLAG(ENABLE_SPELLCHECK) +#include "components/spellcheck/renderer/spellcheck.h" +#include "components/spellcheck/renderer/spellcheck_provider.h" + +#if BUILDFLAG(HAS_SPELLCHECK_PANEL) +#include "components/spellcheck/renderer/spellcheck_panel.h" +#endif // BUILDFLAG(HAS_SPELLCHECK_PANEL) +#endif // BUILDFLAG(ENABLE_SPELLCHECK) + +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) +#include "chrome/renderer/media/chrome_key_systems.h" +#endif + +using autofill::AutofillAgent; +using autofill::PasswordAutofillAgent; +using autofill::PasswordGenerationAgent; +using base::ASCIIToUTF16; +using base::UserMetricsAction; +using blink::WebCache; +using blink::WebConsoleMessage; +using blink::WebDocument; +using blink::WebFrame; +using blink::WebLocalFrame; +using blink::WebPlugin; +using blink::WebPluginParams; +using blink::WebSecurityOrigin; +using blink::WebSecurityPolicy; +using blink::WebString; +using blink::WebURL; +using blink::WebURLError; +using blink::WebURLRequest; +using blink::WebURLResponse; +using blink::WebVector; +using blink::mojom::FetchCacheMode; +using content::RenderFrame; +using content::RenderThread; +using content::WebPluginInfo; +using content::WebPluginMimeType; +using ExtractAllDatalists = autofill::AutofillAgent::ExtractAllDatalists; +using FocusRequiresScroll = autofill::AutofillAgent::FocusRequiresScroll; +using QueryPasswordSuggestions = + autofill::AutofillAgent::QueryPasswordSuggestions; +using SecureContextRequired = autofill::AutofillAgent::SecureContextRequired; +using UserGestureRequired = autofill::AutofillAgent::UserGestureRequired; +using UsesKeyboardAccessoryForSuggestions = + autofill::AutofillAgent::UsesKeyboardAccessoryForSuggestions; +using EnableHeavyFormDataScraping = + autofill::PasswordAutofillAgent::EnableHeavyFormDataScraping; + +namespace { + +// Allow PPAPI for Android Runtime for Chromium. (See crbug.com/383937) +#if BUILDFLAG(ENABLE_PLUGINS) +const char* const kPredefinedAllowedCameraDeviceOrigins[] = { + "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F", + "4EB74897CB187C7633357C2FE832E0AD6A44883A"}; +#endif + +#if BUILDFLAG(ENABLE_PLUGINS) +void AppendParams( + const std::vector& additional_params, + WebVector* existing_names, + WebVector* existing_values) { + DCHECK(existing_names->size() == existing_values->size()); + size_t existing_size = existing_names->size(); + size_t total_size = existing_size + additional_params.size(); + + WebVector names(total_size); + WebVector values(total_size); + + for (size_t i = 0; i < existing_size; ++i) { + names[i] = (*existing_names)[i]; + values[i] = (*existing_values)[i]; + } + + for (size_t i = 0; i < additional_params.size(); ++i) { + names[existing_size + i] = WebString::FromUTF16(additional_params[i].name); + values[existing_size + i] = + WebString::FromUTF16(additional_params[i].value); + } + + existing_names->swap(names); + existing_values->swap(values); +} +#endif // BUILDFLAG(ENABLE_PLUGINS) + +bool IsStandaloneContentExtensionProcess() { +#if !BUILDFLAG(ENABLE_EXTENSIONS) + return false; +#else + return base::CommandLine::ForCurrentProcess()->HasSwitch( + extensions::switches::kExtensionProcess); +#endif +} + +std::unique_ptr CreateV8Unwinder(v8::Isolate* isolate) { + return std::make_unique(isolate); +} + +// Web Share is conditionally enabled here in chrome/, to avoid it being +// made available in other clients of content/ that do not have a Web Share +// Mojo implementation (e.g. WebView). +void MaybeEnableWebShare() { +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) + if (base::FeatureList::IsEnabled(features::kWebShare)) +#endif +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || \ + BUILDFLAG(IS_ANDROID) + blink::WebRuntimeFeatures::EnableWebShare(true); +#endif +} + +#if BUILDFLAG(ENABLE_NACL) && BUILDFLAG(ENABLE_EXTENSIONS) && \ + BUILDFLAG(IS_CHROMEOS_ASH) +bool IsTerminalSystemWebAppNaClPage(GURL url) { + GURL::Replacements replacements; + replacements.ClearQuery(); + replacements.ClearRef(); + url = url.ReplaceComponents(replacements); + return url == "chrome-untrusted://terminal/html/terminal_ssh.html"; +} +#endif + +} // namespace + +ChromeContentRendererClient::ChromeContentRendererClient() + : +#if BUILDFLAG(IS_WIN) + remote_module_watcher_(nullptr, base::OnTaskRunnerDeleter(nullptr)), +#endif + main_thread_profiler_( +#if BUILDFLAG(IS_CHROMEOS) + // The profiler can't start before the sandbox is initialized on + // ChromeOS due to ChromeOS's sandbox initialization code's use of + // AssertSingleThreaded(). + nullptr +#else + ThreadProfiler::CreateAndStartOnMainThread() +#endif + ) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + EnsureExtensionsClientInitialized(); + extensions::ExtensionsRendererClient::Set( + ChromeExtensionsRendererClient::GetInstance()); +#endif +#if BUILDFLAG(ENABLE_PLUGINS) + for (const char* origin : kPredefinedAllowedCameraDeviceOrigins) + allowed_camera_device_origins_.insert(origin); +#endif +} + +ChromeContentRendererClient::~ChromeContentRendererClient() {} + +void ChromeContentRendererClient::RenderThreadStarted() { + RenderThread* thread = RenderThread::Get(); + + main_thread_profiler_->SetAuxUnwinderFactory(base::BindRepeating( + &CreateV8Unwinder, base::Unretained(v8::Isolate::GetCurrent()))); + + // In the case of single process mode, the v8 unwinding will not work. + tracing::TracingSamplerProfiler::SetAuxUnwinderFactoryOnMainThread( + base::BindRepeating(&CreateV8Unwinder, + base::Unretained(v8::Isolate::GetCurrent()))); + + const bool is_extension = IsStandaloneContentExtensionProcess(); + + thread->SetRendererProcessType( + is_extension + ? blink::scheduler::WebRendererProcessType::kExtensionRenderer + : blink::scheduler::WebRendererProcessType::kRenderer); + + if (is_extension) { + // The process name was set to "Renderer" in RendererMain(). Update it to + // "Extension Renderer" to highlight that it's hosting an extension. + base::CurrentProcess::GetInstance().SetProcessType( + base::CurrentProcessType::PROCESS_RENDERER_EXTENSION); + } + +#if BUILDFLAG(IS_WIN) + mojo::PendingRemote module_event_sink; + thread->BindHostReceiver(module_event_sink.InitWithNewPipeAndPassReceiver()); + remote_module_watcher_ = RemoteModuleWatcher::Create( + thread->GetIOTaskRunner(), std::move(module_event_sink)); +#endif + + browser_interface_broker_ = + blink::Platform::Current()->GetBrowserInterfaceBroker(); + + chrome_observer_ = std::make_unique(); + web_cache_impl_ = std::make_unique(); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient* chrome_extensions_renderer_client = + ChromeExtensionsRendererClient::GetInstance(); + chrome_extensions_renderer_client->AddAPIProvider( + std::make_unique()); + chrome_extensions_renderer_client->AddAPIProvider( + std::make_unique()); + chrome_extensions_renderer_client->AddAPIProvider( + std::make_unique< + controlled_frame::ControlledFrameExtensionsRendererAPIProvider>()); + chrome_extensions_renderer_client->RenderThreadStarted(); + WebSecurityPolicy::RegisterURLSchemeAsExtension( + WebString::FromASCII(extensions::kExtensionScheme)); + WebSecurityPolicy::RegisterURLSchemeAsCodeCacheWithHashing( + WebString::FromASCII(extensions::kExtensionScheme)); +#endif + +#if BUILDFLAG(ENABLE_SPELLCHECK) + if (!spellcheck_) + InitSpellCheck(); +#endif + + subresource_filter_ruleset_dealer_ = + std::make_unique(); + + phishing_model_setter_ = + std::make_unique(); + + thread->AddObserver(chrome_observer_.get()); + thread->AddObserver(subresource_filter_ruleset_dealer_.get()); + thread->AddObserver(phishing_model_setter_.get()); + + blink::WebScriptController::RegisterExtension( + extensions_v8::LoadTimesExtension::Get()); + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(variations::switches::kEnableBenchmarking)) { + blink::WebScriptController::RegisterExtension( + extensions_v8::BenchmarkingExtension::Get()); + } + + if (command_line->HasSwitch(switches::kEnableNetBenchmarking)) { + blink::WebScriptController::RegisterExtension( + extensions_v8::NetBenchmarkingExtension::Get()); + } + + // chrome: is also to be permitted to embeds https:// things and have them + // treated as first-party. + // See + // ChromeContentBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel + WebString chrome_scheme(WebString::FromASCII(content::kChromeUIScheme)); + WebSecurityPolicy::RegisterURLSchemeAsFirstPartyWhenTopLevelEmbeddingSecure( + chrome_scheme); + + // chrome-native: is a scheme used for placeholder navigations that allow + // UIs to be drawn with platform native widgets instead of HTML. These pages + // should not be accessible. No code should be runnable in these pages, + // so it should not need to access anything nor should it allow javascript + // URLs since it should never be visible to the user. + // See also ChromeContentClient::AddAdditionalSchemes that adds it as an + // empty document scheme. + WebString native_scheme(WebString::FromASCII(chrome::kChromeNativeScheme)); + WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(native_scheme); + WebSecurityPolicy::RegisterURLSchemeAsNotAllowingJavascriptURLs( + native_scheme); + + // chrome-search: and chrome-distiller: pages should not be accessible by + // normal content, and should also be unable to script anything but themselves + // (to help limit the damage that a corrupt page could cause). + WebString chrome_search_scheme( + WebString::FromASCII(chrome::kChromeSearchScheme)); + + // IWAs can be enabled by either the feature flag or by enterprise + // policy. In either case the kEnableIsolatedWebAppsInRenderer flag is passed + // to the renderer process. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableIsolatedWebAppsInRenderer)) { + // isolated-app: is the scheme used for Isolated Web Apps, which are web + // applications packaged in Signed Web Bundles. + WebString isolated_app_scheme( + WebString::FromASCII(chrome::kIsolatedAppScheme)); + // Resources contained in Isolated Web Apps are HTTP-like and safe to expose + // to the fetch API. + WebSecurityPolicy::RegisterURLSchemeAsSupportingFetchAPI( + isolated_app_scheme); + WebSecurityPolicy::RegisterURLSchemeAsAllowingServiceWorkers( + isolated_app_scheme); + WebSecurityPolicy::RegisterURLSchemeAsAllowedForReferrer( + isolated_app_scheme); + } + + // The Instant process can only display the content but not read it. Other + // processes can't display it or read it. + if (!command_line->HasSwitch(switches::kInstantProcess)) + WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(chrome_search_scheme); + + WebString dom_distiller_scheme( + WebString::FromASCII(dom_distiller::kDomDistillerScheme)); + // TODO(nyquist): Add test to ensure this happens when the flag is set. + WebSecurityPolicy::RegisterURLSchemeAsDisplayIsolated(dom_distiller_scheme); + +#if BUILDFLAG(IS_ANDROID) + WebSecurityPolicy::RegisterURLSchemeAsAllowedForReferrer( + WebString::FromUTF8(content::kAndroidAppScheme)); +#endif + + // chrome-search: pages should not be accessible by bookmarklets + // or javascript: URLs typed in the omnibox. + WebSecurityPolicy::RegisterURLSchemeAsNotAllowingJavascriptURLs( + chrome_search_scheme); + + for (auto& scheme : + secure_origin_allowlist::GetSchemesBypassingSecureContextCheck()) { + WebSecurityPolicy::AddSchemeToSecureContextSafelist( + WebString::FromASCII(scheme)); + } + + // This doesn't work in single-process mode. + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSingleProcess)) { + const auto* heap_profiler_controller = + heap_profiling::HeapProfilerController::GetInstance(); + // The HeapProfilerController should have been created in + // ChromeMainDelegate::PostEarlyInitialization. + CHECK(heap_profiler_controller); + if (ThreadProfiler::ShouldCollectProfilesForChildProcess() || + heap_profiler_controller->IsEnabled()) { + ThreadProfiler::SetMainThreadTaskRunner( + base::SingleThreadTaskRunner::GetCurrentDefault()); + mojo::PendingRemote collector; + thread->BindHostReceiver(collector.InitWithNewPipeAndPassReceiver()); + metrics::CallStackProfileBuilder:: + SetParentProfileCollectorForChildProcess(std::move(collector)); + } + } +} + +void ChromeContentRendererClient::ExposeInterfacesToBrowser( + mojo::BinderMap* binders) { + // NOTE: Do not add binders directly within this method. Instead, modify the + // definition of |ExposeChromeRendererInterfacesToBrowser()| to ensure + // security review coverage. + ExposeChromeRendererInterfacesToBrowser(this, binders); +} + +void ChromeContentRendererClient::RenderFrameCreated( + content::RenderFrame* render_frame) { + ChromeRenderFrameObserver* render_frame_observer = + new ChromeRenderFrameObserver(render_frame, web_cache_impl_.get()); + service_manager::BinderRegistry* registry = render_frame_observer->registry(); + + new prerender::PrerenderRenderFrameObserver(render_frame); + + bool should_allow_for_content_settings = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kInstantProcess); + auto content_settings_delegate = + std::make_unique(render_frame); +#if BUILDFLAG(ENABLE_EXTENSIONS) + content_settings_delegate->SetExtensionDispatcher( + ChromeExtensionsRendererClient::GetInstance()->extension_dispatcher()); +#endif + content_settings::ContentSettingsAgentImpl* content_settings = + new content_settings::ContentSettingsAgentImpl( + render_frame, should_allow_for_content_settings, + std::move(content_settings_delegate)); + if (chrome_observer_.get()) { + if (chrome_observer_->content_settings_manager()) { + mojo::Remote manager; + chrome_observer_->content_settings_manager()->Clone( + manager.BindNewPipeAndPassReceiver()); + content_settings->SetContentSettingsManager(std::move(manager)); + } + } + +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient::GetInstance()->RenderFrameCreated( + render_frame, registry); +#endif + +#if BUILDFLAG(ENABLE_PPAPI) + new PepperHelper(render_frame); +#endif + +#if BUILDFLAG(ENABLE_NACL) + new nacl::NaClHelper(render_frame); +#endif + +#if BUILDFLAG(SAFE_BROWSING_DB_LOCAL) || BUILDFLAG(SAFE_BROWSING_DB_REMOTE) + safe_browsing::ThreatDOMDetails::Create(render_frame, registry); +#endif + +#if BUILDFLAG(ENABLE_PRINTING) + new printing::PrintRenderFrameHelper( + render_frame, std::make_unique()); +#endif + +#if BUILDFLAG(ENABLE_PAINT_PREVIEW) + new paint_preview::PaintPreviewRecorderImpl(render_frame); +#endif + +#if BUILDFLAG(IS_ANDROID) + SandboxStatusExtension::Create(render_frame); +#endif + + TrustedVaultEncryptionKeysExtension::Create(render_frame); + GoogleAccountsPrivateApiExtension::Create(render_frame); + + if (render_frame->IsMainFrame()) + new webapps::WebPageMetadataAgent(render_frame); + + const bool search_result_extractor_enabled = + render_frame->IsMainFrame() && + page_content_annotations::features::ShouldExtractRelatedSearches(); + if (search_result_extractor_enabled) { + continuous_search::SearchResultExtractorImpl::Create(render_frame); + } + + new NetErrorHelper(render_frame); + + new SupervisedUserErrorPageControllerDelegateImpl(render_frame); + + if (!render_frame->IsMainFrame()) { + auto* main_frame_no_state_prefetch_helper = + prerender::NoStatePrefetchHelper::Get( + render_frame->GetMainRenderFrame()); + if (main_frame_no_state_prefetch_helper) { + // Avoid any race conditions from having the browser tell subframes that + // they're no-state prefetching. + new prerender::NoStatePrefetchHelper( + render_frame, + main_frame_no_state_prefetch_helper->histogram_prefix()); + } + } + + // Set up a render frame observer to test if this page is a distiller page. + new dom_distiller::DistillerJsRenderFrameObserver( + render_frame, ISOLATED_WORLD_ID_CHROME_INTERNAL); + + if (dom_distiller::ShouldStartDistillabilityService()) { + // Create DistillabilityAgent to send distillability updates to + // DistillabilityDriver in the browser process. + new dom_distiller::DistillabilityAgent(render_frame, DCHECK_IS_ON()); + } + + blink::AssociatedInterfaceRegistry* associated_interfaces = + render_frame_observer->associated_interfaces(); + + if (!render_frame->IsInFencedFrameTree() || + base::FeatureList::IsEnabled(blink::features::kFencedFramesAPIChanges)) { + auto password_autofill_agent = std::make_unique( + render_frame, associated_interfaces, + EnableHeavyFormDataScraping( + chrome::GetChannel() == version_info::Channel::CANARY || + chrome::GetChannel() == version_info::Channel::DEV)); + auto password_generation_agent = std::make_unique( + render_frame, password_autofill_agent.get(), associated_interfaces); + new AutofillAgent( + render_frame, + {ExtractAllDatalists(false), FocusRequiresScroll(true), + QueryPasswordSuggestions(false), SecureContextRequired(false), + UserGestureRequired(true), + UsesKeyboardAccessoryForSuggestions(BUILDFLAG(IS_ANDROID))}, + std::move(password_autofill_agent), + std::move(password_generation_agent), associated_interfaces); + +#if BUILDFLAG(IS_ANDROID) + if (render_frame->IsMainFrame() && + base::FeatureList::IsEnabled( + payments::facilitated::kEnablePixDetection)) { + new payments::facilitated::FacilitatedPaymentsAgent( + render_frame, associated_interfaces); + } +#endif + } + + if (content_capture::features::IsContentCaptureEnabled()) { + new content_capture::ContentCaptureSender(render_frame, + associated_interfaces); + } + +#if BUILDFLAG(ENABLE_EXTENSIONS) + associated_interfaces + ->AddInterface( + base::BindRepeating( + &extensions::MimeHandlerViewContainerManager::BindReceiver, + base::Unretained(render_frame))); +#endif + + // Owned by |render_frame|. + new page_load_metrics::MetricsRenderFrameObserver(render_frame); + // There is no render thread, thus no UnverifiedRulesetDealer in + // ChromeRenderViewTests. + if (subresource_filter_ruleset_dealer_) { + auto* subresource_filter_agent = + new subresource_filter::SubresourceFilterAgent( + render_frame, subresource_filter_ruleset_dealer_.get()); + subresource_filter_agent->Initialize(); + } + +#if !BUILDFLAG(IS_ANDROID) + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kInstantProcess) && + render_frame->IsMainFrame()) { + new SearchBox(render_frame); + } +#endif + +// We should create CommerceHintAgent only for a main frame except a fenced +// frame that is the main frame as well, so we should check if |render_frame| +// is the fenced frame. +#if !BUILDFLAG(IS_ANDROID) + if (command_line->HasSwitch(commerce::switches::kEnableChromeCart) && +#else + if (base::FeatureList::IsEnabled(commerce::kCommerceHintAndroid) && +#endif // !BUILDFLAG(IS_ANDROID) + render_frame->GetWebFrame()->IsOutermostMainFrame()) { + new cart::CommerceHintAgent(render_frame); + } + +#if BUILDFLAG(ENABLE_SPELLCHECK) + new SpellCheckProvider(render_frame, spellcheck_.get()); + +#if BUILDFLAG(HAS_SPELLCHECK_PANEL) + new SpellCheckPanel(render_frame, registry, this); +#endif // BUILDFLAG(HAS_SPELLCHECK_PANEL) +#endif +#if BUILDFLAG(ENABLE_FEED_V2) + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(feed::switches::kEnableRssLinkReader) && + render_frame->IsMainFrame()) { + new feed::RssLinkReader(render_frame, registry); + } +#endif + +#if BUILDFLAG(IS_WIN) + if (render_frame->IsMainFrame()) { + associated_interfaces + ->AddInterface( + base::BindRepeating(&RenderFrameFontFamilyAccessor::Bind, + render_frame)); + } +#endif + + if (render_frame->IsMainFrame()) { + new commerce::CommerceWebExtractor(render_frame, registry); + } + +#if BUILDFLAG(IS_ANDROID) + if (base::FeatureList::IsEnabled(features::kBoardingPassDetector) && + render_frame->IsMainFrame()) { + new wallet::BoardingPassExtractor(render_frame, registry); + } +#endif +} + +void ChromeContentRendererClient::WebViewCreated( + blink::WebView* web_view, + bool was_created_by_renderer, + const url::Origin* outermost_origin) { + new prerender::NoStatePrefetchClient(web_view); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient::GetInstance()->WebViewCreated( + web_view, outermost_origin); +#endif +} + +SkBitmap* ChromeContentRendererClient::GetSadPluginBitmap() { + return const_cast(ui::ResourceBundle::GetSharedInstance() + .GetImageNamed(IDR_SAD_PLUGIN) + .ToSkBitmap()); +} + +SkBitmap* ChromeContentRendererClient::GetSadWebViewBitmap() { + return const_cast(ui::ResourceBundle::GetSharedInstance() + .GetImageNamed(IDR_SAD_WEBVIEW) + .ToSkBitmap()); +} + +bool ChromeContentRendererClient::IsPluginHandledExternally( + content::RenderFrame* render_frame, + const blink::WebElement& plugin_element, + const GURL& original_url, + const std::string& mime_type) { +#if BUILDFLAG(ENABLE_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS) + DCHECK(plugin_element.HasHTMLTagName("object") || + plugin_element.HasHTMLTagName("embed")); + + mojo::AssociatedRemote plugin_info_host; + render_frame->GetRemoteAssociatedInterfaces()->GetInterface( + &plugin_info_host); + // Blink will next try to load a WebPlugin which would end up in + // OverrideCreatePlugin, sending another IPC only to find out the plugin is + // not supported. Here it suffices to return false but there should perhaps be + // a more unified approach to avoid sending the IPC twice. + chrome::mojom::PluginInfoPtr plugin_info = chrome::mojom::PluginInfo::New(); + plugin_info_host->GetPluginInfo( + original_url, render_frame->GetWebFrame()->Top()->GetSecurityOrigin(), + mime_type, &plugin_info); + // TODO(ekaramad): Not continuing here due to a disallowed status should take + // us to CreatePlugin. See if more in depths investigation of |status| is + // necessary here (see https://crbug.com/965747). For now, returning false + // should take us to CreatePlugin after HTMLPlugInElement which is called + // through HTMLPlugInElement::LoadPlugin code path. + if (plugin_info->status != chrome::mojom::PluginStatus::kAllowed && + plugin_info->status != + chrome::mojom::PluginStatus::kPlayImportantContent) { + // We could get here when a MimeHandlerView is loaded inside a + // which is using permissions API (see WebViewPluginTests). + ChromeExtensionsRendererClient::DidBlockMimeHandlerViewForDisallowedPlugin( + plugin_element); + return false; + } +#if BUILDFLAG(ENABLE_PDF) + if (plugin_info->actual_mime_type == pdf::kInternalPluginMimeType) { + // Only actually treat the internal PDF plugin as externally handled if + // used within an origin allowed to create the internal PDF plugin; + // otherwise, let Blink try to create the in-process PDF plugin. + if (IsPdfInternalPluginAllowedOrigin( + render_frame->GetWebFrame()->GetSecurityOrigin())) { + return true; + } + } +#endif // BUILDFLAG(ENABLE_PDF) + return ChromeExtensionsRendererClient::MaybeCreateMimeHandlerView( + plugin_element, original_url, plugin_info->actual_mime_type, + plugin_info->plugin); +#else // !(BUILDFLAG(ENABLE_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS)) + return false; +#endif // BUILDFLAG(ENABLE_EXTENSIONS) && BUILDFLAG(ENABLE_PLUGINS) +} + +bool ChromeContentRendererClient::IsDomStorageDisabled() const { + if (!base::FeatureList::IsEnabled(features::kPdfEnforcements)) { + return false; + } + +#if BUILDFLAG(ENABLE_PDF) && BUILDFLAG(ENABLE_EXTENSIONS) + // PDF renderers shouldn't need to access DOM storage interfaces. Note that + // it's still possible to access localStorage or sessionStorage in a PDF + // document's context via DevTools; returning false here ensures that these + // objects are just seen as null by JavaScript (similarly to what happens for + // opaque origins). This avoids a renderer kill by the browser process which + // isn't expecting PDF renderer processes to ever use DOM storage + // interfaces. See https://crbug.com/357014503. + return pdf::IsPdfRenderer(); +#else + return false; +#endif +} + +v8::Local ChromeContentRendererClient::GetScriptableObject( + const blink::WebElement& plugin_element, + v8::Isolate* isolate) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeExtensionsRendererClient::GetInstance()->GetScriptableObject( + plugin_element, isolate); +#else + return v8::Local(); +#endif +} + +bool ChromeContentRendererClient::OverrideCreatePlugin( + content::RenderFrame* render_frame, + const WebPluginParams& params, + WebPlugin** plugin) { + std::string orig_mime_type = params.mime_type.Utf8(); +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (!ChromeExtensionsRendererClient::GetInstance()->OverrideCreatePlugin( + render_frame, params)) { + return false; + } +#endif + + GURL url(params.url); +#if BUILDFLAG(ENABLE_PLUGINS) + mojo::AssociatedRemote plugin_info_host; + render_frame->GetRemoteAssociatedInterfaces()->GetInterface( + &plugin_info_host); + + chrome::mojom::PluginInfoPtr plugin_info = chrome::mojom::PluginInfo::New(); + plugin_info_host->GetPluginInfo( + url, render_frame->GetWebFrame()->Top()->GetSecurityOrigin(), + orig_mime_type, &plugin_info); + *plugin = CreatePlugin(render_frame, params, *plugin_info); +#else // !BUILDFLAG(ENABLE_PLUGINS) + if (orig_mime_type == pdf::kPDFMimeType) { + ReportPDFLoadStatus( + PDFLoadStatus::kShowedDisabledPluginPlaceholderForEmbeddedPdf); + + PDFPluginPlaceholder* placeholder = + PDFPluginPlaceholder::CreatePDFPlaceholder(render_frame, params); + *plugin = placeholder->plugin(); + return true; + } + auto* placeholder = NonLoadablePluginPlaceholder::CreateNotSupportedPlugin( + render_frame, params); + *plugin = placeholder->plugin(); + +#endif // BUILDFLAG(ENABLE_PLUGINS) + return true; +} + +#if BUILDFLAG(ENABLE_PLUGINS) +WebPlugin* ChromeContentRendererClient::CreatePluginReplacement( + content::RenderFrame* render_frame, + const base::FilePath& plugin_path) { + auto* placeholder = NonLoadablePluginPlaceholder::CreateErrorPlugin( + render_frame, plugin_path); + return placeholder->plugin(); +} +#endif // BUILDFLAG(ENABLE_PLUGINS) + +bool ChromeContentRendererClient::DeferMediaLoad( + content::RenderFrame* render_frame, + bool has_played_media_before, + base::OnceClosure closure) { + return prerender::DeferMediaLoad(render_frame, has_played_media_before, + std::move(closure)); +} + +#if BUILDFLAG(ENABLE_PLUGINS) + +// static +WebPlugin* ChromeContentRendererClient::CreatePlugin( + content::RenderFrame* render_frame, + const WebPluginParams& original_params, + const chrome::mojom::PluginInfo& plugin_info) { + const WebPluginInfo& info = plugin_info.plugin; + const std::string& actual_mime_type = plugin_info.actual_mime_type; + const std::u16string& group_name = plugin_info.group_name; + const std::string& identifier = plugin_info.group_identifier; + chrome::mojom::PluginStatus status = plugin_info.status; + GURL url(original_params.url); + std::string orig_mime_type = original_params.mime_type.Utf8(); + ChromePluginPlaceholder* placeholder = nullptr; + + // If the browser plugin is to be enabled, this should be handled by the + // renderer, so the code won't reach here due to the early exit in + // OverrideCreatePlugin. + if (status == chrome::mojom::PluginStatus::kNotFound || + orig_mime_type == content::kBrowserPluginMimeType) { + // Flash has been thoroughly removed in M88+, so we need to have a special + // case here to display a deprecated message instead of a generic + // plugin-missing message. + if (orig_mime_type == "application/x-shockwave-flash" || + orig_mime_type == "application/futuresplash") { + return NonLoadablePluginPlaceholder::CreateFlashDeprecatedPlaceholder( + render_frame, original_params) + ->plugin(); + } else { + placeholder = ChromePluginPlaceholder::CreateLoadableMissingPlugin( + render_frame, original_params); + } + } else { + // TODO(bauerb): This should be in content/. + WebPluginParams params(original_params); + for (const auto& mime_type : info.mime_types) { + if (mime_type.mime_type == actual_mime_type) { + AppendParams(mime_type.additional_params, ¶ms.attribute_names, + ¶ms.attribute_values); + break; + } + } + if (params.mime_type.IsNull() && (actual_mime_type.size() > 0)) { + // Webkit might say that mime type is null while we already know the + // actual mime type via ChromeViewHostMsg_GetPluginInfo. In that case + // we should use what we know since WebpluginDelegateProxy does some + // specific initializations based on this information. + params.mime_type = WebString::FromUTF8(actual_mime_type); + } + + auto* content_settings_agent = + content_settings::ContentSettingsAgentImpl::Get(render_frame); + auto* content_settings_agent_delegate = + ChromeContentSettingsAgentDelegate::Get(render_frame); + + const ContentSettingsType content_type = ContentSettingsType::JAVASCRIPT; + + if ((status == chrome::mojom::PluginStatus::kUnauthorized || + status == chrome::mojom::PluginStatus::kBlocked) && + content_settings_agent_delegate->IsPluginTemporarilyAllowed( + identifier)) { + status = chrome::mojom::PluginStatus::kAllowed; + } + + auto create_blocked_plugin = [&render_frame, ¶ms, &info, &identifier, + &group_name](int template_id, + const std::u16string& message) { + return ChromePluginPlaceholder::CreateBlockedPlugin( + render_frame, params, info, identifier, group_name, template_id, + message); + }; + switch (status) { + case chrome::mojom::PluginStatus::kNotFound: { + NOTREACHED_IN_MIGRATION(); + break; + } + case chrome::mojom::PluginStatus::kAllowed: + case chrome::mojom::PluginStatus::kPlayImportantContent: { +#if BUILDFLAG(ENABLE_NACL) && BUILDFLAG(ENABLE_EXTENSIONS) + WebLocalFrame* frame = render_frame->GetWebFrame(); + const bool is_nacl_plugin = + info.name == ASCIIToUTF16(nacl::kNaClPluginName); + const bool is_nacl_mime_type = + actual_mime_type == nacl::kNaClPluginMimeType; + const bool is_pnacl_mime_type = + actual_mime_type == nacl::kPnaclPluginMimeType; + if (is_nacl_plugin || is_nacl_mime_type || is_pnacl_mime_type) { + bool has_enable_nacl_switch = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableNaCl); + bool is_nacl_unrestricted = + has_enable_nacl_switch || is_pnacl_mime_type; + GURL manifest_url; + GURL app_url; + if (is_nacl_mime_type || is_pnacl_mime_type) { + // Normal NaCl/PNaCl embed. The app URL is the page URL. + manifest_url = url; + app_url = frame->GetDocument().Url(); + } else { + // NaCl is being invoked as a content handler. Look up the NaCl + // module using the MIME type. The app URL is the manifest URL. + manifest_url = GetNaClContentHandlerURL(actual_mime_type, info); + app_url = manifest_url; + } + bool is_module_allowed = false; + const extensions::Extension* extension = + extensions::RendererExtensionRegistry::Get() + ->GetExtensionOrAppByURL(manifest_url); + if (IsNaclAllowed()) { + if (extension) { + is_module_allowed = + IsNativeNaClAllowed(app_url, is_nacl_unrestricted, extension); +#if BUILDFLAG(IS_CHROMEOS_ASH) + // Allow Terminal System App to load the SSH extension NaCl + // module. + } else if (IsTerminalSystemWebAppNaClPage(app_url)) { + is_module_allowed = true; +#endif + } else { + WebDocument document = frame->GetDocument(); + is_module_allowed = + has_enable_nacl_switch || + (is_pnacl_mime_type && + blink::WebOriginTrials::isTrialEnabled(&document, "PNaCl")); + } + } + if (!is_module_allowed) { + WebString error_message; + if (!IsNaclAllowed()) { + error_message = "NaCl is disabled."; + } else if (is_nacl_mime_type) { + error_message = + "Only unpacked extensions and apps installed from the Chrome " + "Web Store can load NaCl modules without enabling Native " + "Client in about:flags."; + } else if (is_pnacl_mime_type) { + error_message = + "PNaCl modules can only be used on the open web (non-app/" + "extension) when the PNaCl Origin Trial is enabled"; + } + frame->AddMessageToConsole(WebConsoleMessage( + blink::mojom::ConsoleMessageLevel::kError, error_message)); + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, +#if BUILDFLAG(IS_CHROMEOS_ASH) + l10n_util::GetStringUTF16(IDS_NACL_PLUGIN_BLOCKED)); +#else + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name)); +#endif + break; + } + ReportNaClAppType(is_pnacl_mime_type, extension); + } +#endif // BUILDFLAG(ENABLE_NACL) && BUILDFLAG(ENABLE_EXTENSIONS) + + if (info.path.value() == ChromeContentClient::kPDFExtensionPluginPath) { + // Report PDF load metrics. Since the PDF plugin is comprised of an + // extension that loads a second plugin, avoid double counting by + // ignoring the creation of the second plugin. + bool is_main_frame_plugin_document = + render_frame->IsMainFrame() && + render_frame->GetWebFrame()->GetDocument().IsPluginDocument(); + ReportPDFLoadStatus( + is_main_frame_plugin_document + ? PDFLoadStatus::kLoadedFullPagePdfWithPdfium + : PDFLoadStatus::kLoadedEmbeddedPdfWithPdfium); + } + + // Delay loading plugins if no-state prefetching. + // TODO(mmenke): In the case of NoStatePrefetch, feed into + // ChromeContentRendererClient::CreatePlugin instead, to + // reduce the chance of future regressions. + bool is_no_state_prefetching = + prerender::NoStatePrefetchHelper::IsPrefetching(render_frame); + + if (is_no_state_prefetching) { + placeholder = ChromePluginPlaceholder::CreateBlockedPlugin( + render_frame, params, info, identifier, group_name, + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name)); + placeholder->set_blocked_for_prerendering(is_no_state_prefetching); + placeholder->AllowLoading(); + break; + } + +#if BUILDFLAG(ENABLE_PDF) + if (info.path.value() == ChromeContentClient::kPDFInternalPluginPath) { + return pdf::CreateInternalPlugin( + std::move(params), render_frame, + std::make_unique()); + } +#endif // BUILDFLAG(ENABLE_PDF) + + return render_frame->CreatePlugin(info, params); + } + case chrome::mojom::PluginStatus::kDisabled: { + if (info.path.value() == ChromeContentClient::kPDFExtensionPluginPath) { + ReportPDFLoadStatus( + PDFLoadStatus::kShowedDisabledPluginPlaceholderForEmbeddedPdf); + + return PDFPluginPlaceholder::CreatePDFPlaceholder(render_frame, + params) + ->plugin(); + } + + placeholder = create_blocked_plugin( + IDR_DISABLED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_DISABLED, group_name)); + break; + } + case chrome::mojom::PluginStatus::kUnauthorized: { + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED, group_name)); + placeholder->AllowLoading(); + mojo::AssociatedRemote plugin_auth_host; + render_frame->GetRemoteAssociatedInterfaces()->GetInterface( + plugin_auth_host.BindNewEndpointAndPassReceiver()); + plugin_auth_host->BlockedUnauthorizedPlugin(group_name, identifier); + content_settings_agent->DidBlockContentType(content_type); + break; + } + case chrome::mojom::PluginStatus::kBlocked: { + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED, group_name)); + placeholder->AllowLoading(); + RenderThread::Get()->RecordAction(UserMetricsAction("Plugin_Blocked")); + content_settings_agent->DidBlockContentType(content_type); + break; + } + case chrome::mojom::PluginStatus::kBlockedByPolicy: { + placeholder = create_blocked_plugin( + IDR_BLOCKED_PLUGIN_HTML, + l10n_util::GetStringFUTF16(IDS_PLUGIN_BLOCKED_BY_POLICY, + group_name)); + RenderThread::Get()->RecordAction( + UserMetricsAction("Plugin_BlockedByPolicy")); + content_settings_agent->DidBlockContentType(content_type); + break; + } + } + } + placeholder->SetStatus(status); + return placeholder->plugin(); +} +#endif // BUILDFLAG(ENABLE_PLUGINS) + +// For NaCl content handling plugins, the NaCl manifest is stored in an +// additonal 'nacl' param associated with the MIME type. +// static +GURL ChromeContentRendererClient::GetNaClContentHandlerURL( + const std::string& actual_mime_type, + const content::WebPluginInfo& plugin) { + // Look for the manifest URL among the MIME type's additonal parameters. + for (const auto& mime_type : plugin.mime_types) { + if (mime_type.mime_type == actual_mime_type) { + for (const auto& p : mime_type.additional_params) { + if (p.name == u"nacl") + return GURL(p.value); + } + break; + } + } + return GURL(); +} + +void ChromeContentRendererClient::GetInterface( + const std::string& interface_name, + mojo::ScopedMessagePipeHandle interface_pipe) { + // TODO(crbug.com/40633267): Get rid of the use of this implementation of + // |service_manager::LocalInterfaceProvider|. This was done only to avoid + // churning spellcheck code while eliminting the "chrome" and + // "chrome_renderer" services. Spellcheck is (and should remain) the only + // consumer of this implementation. + RenderThread::Get()->BindHostReceiver( + mojo::GenericPendingReceiver(interface_name, std::move(interface_pipe))); +} + +#if BUILDFLAG(ENABLE_NACL) +// static +bool ChromeContentRendererClient::IsNativeNaClAllowed( + const GURL& app_url, + bool is_nacl_unrestricted, + const extensions::Extension* extension) { + bool is_invoked_by_webstore_installed_extension = false; + bool is_extension_unrestricted = false; + bool is_extension_force_installed = false; +#if BUILDFLAG(ENABLE_EXTENSIONS) + bool is_extension_from_webstore = extension && extension->from_webstore(); + + bool is_invoked_by_extension = app_url.SchemeIs(extensions::kExtensionScheme); + bool is_invoked_by_hosted_app = extension && extension->is_hosted_app() && + extension->web_extent().MatchesURL(app_url); + + is_invoked_by_webstore_installed_extension = + is_extension_from_webstore && + (is_invoked_by_extension || is_invoked_by_hosted_app); + + // Allow built-in extensions and developer mode extensions. + is_extension_unrestricted = + extension && + (extensions::Manifest::IsUnpackedLocation(extension->location()) || + extensions::Manifest::IsComponentLocation(extension->location())); + // Allow extensions force installed by admin policy. + is_extension_force_installed = + extension && + extensions::Manifest::IsPolicyLocation(extension->location()); +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + + // Allow NaCl under any of the following circumstances: + // 1) An extension is loaded unpacked or built-in (component) to Chrome. + // 2) An extension is force installed by policy. + // 3) An extension is installed from the webstore, and invoked in that + // context (hosted app URL or chrome-extension:// scheme). + // 4) --enable-nacl is set. + bool is_nacl_allowed_by_location = is_extension_unrestricted || + is_extension_force_installed || + is_invoked_by_webstore_installed_extension; + bool is_nacl_allowed = is_nacl_allowed_by_location || is_nacl_unrestricted; + return is_nacl_allowed; +} + +// static +void ChromeContentRendererClient::ReportNaClAppType( + bool is_pnacl, + const extensions::Extension* extension) { + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. + enum class NaClAppType { + kPNaClOpenWeb = 0, + kPNaClHostedApp = 1, + kPNaClPlatformApp = 2, + kPNaClLegacyPackagedApp = 3, + kPNaClMv2Extension = 4, + kPNaClMv3Extension = 5, + kPNaClLoginScreenMv2Extension = 6, + kPNaClLoginScreenMv3Extension = 7, + kNaClOpenWeb = 8, + kNaClHostedApp = 9, + kNaClPlatformApp = 10, + kNaClLegacyPackagedApp = 11, + kNaClMv2Extension = 12, + kNaClMv3Extension = 13, + kNaClLoginScreenMv2Extension = 14, + kNaClLoginScreenMv3Extension = 15, + kMaxValue = kNaClLoginScreenMv3Extension + }; + + // Not all combinations are allowed by default (e.g. kNaClOpenWeb), but they + // can be used with the --enable-nacl flag. + NaClAppType app_type = + is_pnacl ? NaClAppType::kPNaClOpenWeb : NaClAppType::kNaClOpenWeb; + if (extension) { + if (extension->is_extension()) { + if (extension->manifest_version() >= 3) { + app_type = is_pnacl ? NaClAppType::kPNaClMv3Extension + : NaClAppType::kNaClMv3Extension; + } else { + app_type = is_pnacl ? NaClAppType::kPNaClMv2Extension + : NaClAppType::kNaClMv2Extension; + } + } else if (extension->is_hosted_app()) { + app_type = + is_pnacl ? NaClAppType::kPNaClHostedApp : NaClAppType::kNaClHostedApp; + } else if (extension->is_legacy_packaged_app()) { + app_type = is_pnacl ? NaClAppType::kPNaClLegacyPackagedApp + : NaClAppType::kNaClLegacyPackagedApp; + } else if (extension->is_platform_app()) { + app_type = is_pnacl ? NaClAppType::kPNaClPlatformApp + : NaClAppType::kNaClPlatformApp; + } else if (extension->is_login_screen_extension()) { + if (extension->manifest_version() >= 3) { + app_type = is_pnacl ? NaClAppType::kPNaClLoginScreenMv3Extension + : NaClAppType::kNaClLoginScreenMv3Extension; + } else { + app_type = is_pnacl ? NaClAppType::kPNaClLoginScreenMv2Extension + : NaClAppType::kNaClLoginScreenMv2Extension; + } + } else { + // We found an extension that is not covered by any metric + NOTREACHED_IN_MIGRATION() + << "Invalid NaCl usage in extension. Extension name: " + << extension->name() << ", type: " << extension->GetType(); + } + } + + base::UmaHistogramEnumeration("NaCl.EmbedderType", app_type); +} +#endif // BUILDFLAG(ENABLE_NACL) + +void ChromeContentRendererClient::PrepareErrorPage( + content::RenderFrame* render_frame, + const blink::WebURLError& web_error, + const std::string& http_method, + content::mojom::AlternativeErrorPageOverrideInfoPtr + alternative_error_page_info, + std::string* error_html) { + NetErrorHelper::Get(render_frame) + ->PrepareErrorPage( + error_page::Error::NetError( + web_error.url(), web_error.reason(), web_error.extended_reason(), + web_error.resolve_error_info(), web_error.has_copy_in_cache()), + http_method == "POST", std::move(alternative_error_page_info), + error_html); + + SupervisedUserErrorPageControllerDelegateImpl::Get(render_frame) + ->PrepareForErrorPage(); +} + +void ChromeContentRendererClient::PrepareErrorPageForHttpStatusError( + content::RenderFrame* render_frame, + const blink::WebURLError& error, + const std::string& http_method, + int http_status, + content::mojom::AlternativeErrorPageOverrideInfoPtr + alternative_error_page_info, + std::string* error_html) { + NetErrorHelper::Get(render_frame) + ->PrepareErrorPage(error_page::Error::HttpError(error.url(), http_status), + http_method == "POST", + std::move(alternative_error_page_info), error_html); +} + +void ChromeContentRendererClient::PostSandboxInitialized() { +#if BUILDFLAG(IS_CHROMEOS) + DCHECK(!main_thread_profiler_); + main_thread_profiler_ = ThreadProfiler::CreateAndStartOnMainThread(); +#endif // BUILDFLAG(IS_CHROMEOS) +} + +void ChromeContentRendererClient::PostIOThreadCreated( + base::SingleThreadTaskRunner* io_thread_task_runner) { + io_thread_task_runner->PostTask( + FROM_HERE, base::BindOnce(&ThreadProfiler::StartOnChildThread, + metrics::CallStackProfileParams::Thread::kIo)); +} + +void ChromeContentRendererClient::PostCompositorThreadCreated( + base::SingleThreadTaskRunner* compositor_thread_task_runner) { + compositor_thread_task_runner->PostTask( + FROM_HERE, + base::BindOnce(&ThreadProfiler::StartOnChildThread, + metrics::CallStackProfileParams::Thread::kCompositor)); + // Enable stack sampling for tracing. + // We pass in CreateCoreUnwindersFactory here since it lives in the chrome/ + // layer while TracingSamplerProfiler is outside of chrome/. + compositor_thread_task_runner->PostTask( + FROM_HERE, + base::BindOnce(&tracing::TracingSamplerProfiler:: + CreateOnChildThreadWithCustomUnwinders, +#if BUILDFLAG(IS_ANDROID) + base::BindRepeating(&CreateCoreUnwindersFactory, false))); +#else + base::BindRepeating(&CreateCoreUnwindersFactory))); +#endif // BUILDFLAG(IS_ANDROID) +} + +bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kInitIsolateAsForeground) || + !IsStandaloneContentExtensionProcess(); +} + +bool ChromeContentRendererClient::AllowPopup() { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeExtensionsRendererClient::GetInstance()->AllowPopup(); +#else + return false; +#endif +} + +bool ChromeContentRendererClient::ShouldNotifyServiceWorkerOnWebSocketActivity( + v8::Local context) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return extensions::Dispatcher::ShouldNotifyServiceWorkerOnWebSocketActivity( + context); +#else + return false; +#endif +} + +blink::ProtocolHandlerSecurityLevel +ChromeContentRendererClient::GetProtocolHandlerSecurityLevel( + const url::Origin& origin) { + if (origin.scheme() == chrome::kIsolatedAppScheme) { + return blink::ProtocolHandlerSecurityLevel::kSameOrigin; + } +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeExtensionsRendererClient::GetInstance() + ->GetProtocolHandlerSecurityLevel(); +#else + return blink::ProtocolHandlerSecurityLevel::kStrict; +#endif +} + +void ChromeContentRendererClient::WillSendRequest( + WebLocalFrame* frame, + ui::PageTransition transition_type, + const blink::WebURL& upstream_url, + const blink::WebURL& target_url, + const net::SiteForCookies& site_for_cookies, + const url::Origin* initiator_origin, + GURL* new_url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + // Check whether the request should be allowed. If not allowed, we reset the + // URL to something invalid to prevent the request and cause an error. + ChromeExtensionsRendererClient::GetInstance()->WillSendRequest( + frame, transition_type, upstream_url, target_url, site_for_cookies, + initiator_origin, new_url); + if (!new_url->is_empty()) + return; +#endif + + if (!target_url.ProtocolIs(chrome::kChromeSearchScheme)) { + return; + } + +#if !BUILDFLAG(IS_ANDROID) + SearchBox* search_box = + SearchBox::Get(content::RenderFrame::FromWebFrame(frame->LocalRoot())); + if (search_box) { + // Note: this GURL copy could be avoided if host() were added to WebURL. + GURL gurl(target_url); + if (gurl.host_piece() == chrome::kChromeUIFaviconHost) + search_box->GenerateImageURLFromTransientURL(target_url, new_url); + } +#endif // !BUILDFLAG(IS_ANDROID) +} + +bool ChromeContentRendererClient::IsPrefetchOnly( + content::RenderFrame* render_frame) { + return prerender::NoStatePrefetchHelper::IsPrefetching(render_frame); +} + +uint64_t ChromeContentRendererClient::VisitedLinkHash( + std::string_view canonical_url) { + return chrome_observer_->visited_link_reader()->ComputeURLFingerprint( + canonical_url); +} + +uint64_t ChromeContentRendererClient::PartitionedVisitedLinkFingerprint( + std::string_view canonical_link_url, + const net::SchemefulSite& top_level_site, + const url::Origin& frame_origin) { + return chrome_observer_->visited_link_reader()->ComputePartitionedFingerprint( + canonical_link_url, top_level_site, frame_origin); +} + +bool ChromeContentRendererClient::IsLinkVisited(uint64_t link_hash) { + return chrome_observer_->visited_link_reader()->IsVisited(link_hash); +} + +void ChromeContentRendererClient::AddOrUpdateVisitedLinkSalt( + const url::Origin& origin, + uint64_t salt) { + base::UmaHistogramBoolean( + "Blink.History.VisitedLinks.IsSaltFromNavigationThrottle", true); + return chrome_observer_->visited_link_reader()->AddOrUpdateSalt(origin, salt); +} + +std::unique_ptr +ChromeContentRendererClient::CreatePrescientNetworking( + content::RenderFrame* render_frame) { + return std::make_unique( + render_frame); +} + +bool ChromeContentRendererClient::IsExternalPepperPlugin( + const std::string& module_name) { + // TODO(bbudge) remove this when the trusted NaCl plugin has been removed. + // We must defer certain plugin events for NaCl instances since we switch + // from the in-process to the out-of-process proxy after instantiating them. + return module_name == "Native Client"; +} + +bool ChromeContentRendererClient::IsOriginIsolatedPepperPlugin( + const base::FilePath& plugin_path) { + // Hosting plugins in-process is inherently incompatible with attempting to + // process-isolate plugins from different origins. + auto* cmdline = base::CommandLine::ForCurrentProcess(); + if (cmdline->HasSwitch(switches::kPpapiInProcess)) { + // The kPpapiInProcess switch should only be used by tests. In particular, + // we expect that the PDF plugin should always be isolated in the product + // (and that the switch won't interfere with PDF isolation). + CHECK_NE(ChromeContentClient::kPDFInternalPluginPath, plugin_path.value()); + + return false; + } + +#if BUILDFLAG(ENABLE_NACL) + // Don't isolate the NaCl plugin (preserving legacy behavior). + if (plugin_path.value() == nacl::kInternalNaClPluginFileName) + return false; +#endif + + // Isolate all the other plugins (including the PDF plugin + test plugins). + return true; +} + +#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS) +bool ChromeContentRendererClient::IsExtensionOrSharedModuleAllowed( + const GURL& url, + const std::set& allowlist) { + const extensions::ExtensionSet* extension_set = + extensions::RendererExtensionRegistry::Get()->GetMainThreadExtensionSet(); + return ::IsExtensionOrSharedModuleAllowed(url, extension_set, allowlist); +} +#endif + +#if BUILDFLAG(ENABLE_SPELLCHECK) +void ChromeContentRendererClient::InitSpellCheck() { + spellcheck_ = std::make_unique(this); +} +#endif + +ChromeRenderThreadObserver* ChromeContentRendererClient::GetChromeObserver() + const { + return chrome_observer_.get(); +} + +web_cache::WebCacheImpl* ChromeContentRendererClient::GetWebCache() { + return web_cache_impl_.get(); +} + +chrome::WebRtcLoggingAgentImpl* +ChromeContentRendererClient::GetWebRtcLoggingAgent() { + if (!webrtc_logging_agent_impl_) { + webrtc_logging_agent_impl_ = + std::make_unique(); + } + return webrtc_logging_agent_impl_.get(); +} + +#if BUILDFLAG(ENABLE_SPELLCHECK) +SpellCheck* ChromeContentRendererClient::GetSpellCheck() { + return spellcheck_.get(); +} +#endif // BUILDFLAG(ENABLE_SPELLCHECK) + +std::unique_ptr +ChromeContentRendererClient::CreateWebSocketHandshakeThrottleProvider() { + return std::make_unique( + browser_interface_broker_.get()); +} + +std::unique_ptr +ChromeContentRendererClient::GetSupportedKeySystems( + content::RenderFrame* render_frame, + media::GetSupportedKeySystemsCB cb) { +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) || BUILDFLAG(IS_WIN) || BUILDFLAG(IS_ANDROID) + return GetChromeKeySystems(render_frame, std::move(cb)); +#else + std::move(cb).Run({}); + return nullptr; +#endif +} + +bool ChromeContentRendererClient::ShouldReportDetailedMessageForSource( + const std::u16string& source) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return extensions::IsSourceFromAnExtension(source); +#else + return false; +#endif +} + +std::unique_ptr +ChromeContentRendererClient::CreateWorkerContentSettingsClient( + content::RenderFrame* render_frame) { + return std::make_unique(render_frame); +} + +#if BUILDFLAG(ENABLE_SPEECH_SERVICE) +std::unique_ptr +ChromeContentRendererClient::CreateSpeechRecognitionClient( + content::RenderFrame* render_frame) { + return std::make_unique(render_frame); +} +#endif // BUILDFLAG(ENABLE_SPEECH_SERVICE) + +bool ChromeContentRendererClient::IsPluginAllowedToUseCameraDeviceAPI( + const GURL& url) { +#if BUILDFLAG(ENABLE_PLUGINS) && BUILDFLAG(ENABLE_EXTENSIONS) +#if BUILDFLAG(ENABLE_PPAPI) + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnablePepperTesting)) + return true; +#endif // BUILDFLAG(ENABLE_PPAPI) + + if (IsExtensionOrSharedModuleAllowed(url, allowed_camera_device_origins_)) + return true; +#endif + + return false; +} + +void ChromeContentRendererClient::RunScriptsAtDocumentStart( + content::RenderFrame* render_frame) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient::GetInstance()->RunScriptsAtDocumentStart( + render_frame); + // |render_frame| might be dead by now. +#endif +} + +void ChromeContentRendererClient::RunScriptsAtDocumentEnd( + content::RenderFrame* render_frame) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient::GetInstance()->RunScriptsAtDocumentEnd( + render_frame); + // |render_frame| might be dead by now. +#endif +} + +void ChromeContentRendererClient::RunScriptsAtDocumentIdle( + content::RenderFrame* render_frame) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient::GetInstance()->RunScriptsAtDocumentIdle( + render_frame); + // |render_frame| might be dead by now. +#endif +} + +void ChromeContentRendererClient:: + SetRuntimeFeaturesDefaultsBeforeBlinkInitialization() { + // The performance manager service interfaces are provided by the chrome + // embedder only. + blink::WebRuntimeFeatures::EnablePerformanceManagerInstrumentation(true); + + MaybeEnableWebShare(); + + if (base::FeatureList::IsEnabled( + autofill::features::kAutofillSharedAutofill)) { + blink::WebRuntimeFeatures::EnableSharedAutofill(true); + } + + if (base::FeatureList::IsEnabled(subresource_filter::kAdTagging)) + blink::WebRuntimeFeatures::EnableAdTagging(true); + +#if BUILDFLAG(ENABLE_EXTENSIONS) + // WebHID and WebUSB on service workers is only available in extensions. + if (IsStandaloneContentExtensionProcess()) { + if (base::FeatureList::IsEnabled( + features::kEnableWebUsbOnExtensionServiceWorker)) { + blink::WebRuntimeFeatures::EnableWebUSBOnServiceWorkers(true); + } +#if !BUILDFLAG(IS_ANDROID) + blink::WebRuntimeFeatures::EnableWebHIDOnServiceWorkers(true); +#endif // !BUILDFLAG(IS_ANDROID) + } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) +} + +bool ChromeContentRendererClient::AllowScriptExtensionForServiceWorker( + const url::Origin& script_origin) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return script_origin.scheme() == extensions::kExtensionScheme; +#else + return false; +#endif +} + +void ChromeContentRendererClient:: + WillInitializeServiceWorkerContextOnWorkerThread() { + // This is called on the service worker thread. + ThreadProfiler::StartOnChildThread( + metrics::CallStackProfileParams::Thread::kServiceWorker); +} + +void ChromeContentRendererClient:: + DidInitializeServiceWorkerContextOnWorkerThread( + blink::WebServiceWorkerContextProxy* context_proxy, + const GURL& service_worker_scope, + const GURL& script_url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient::GetInstance() + ->extension_dispatcher() + ->DidInitializeServiceWorkerContextOnWorkerThread( + context_proxy, service_worker_scope, script_url); +#endif +} + +void ChromeContentRendererClient::WillEvaluateServiceWorkerOnWorkerThread( + blink::WebServiceWorkerContextProxy* context_proxy, + v8::Local v8_context, + int64_t service_worker_version_id, + const GURL& service_worker_scope, + const GURL& script_url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient::GetInstance() + ->extension_dispatcher() + ->WillEvaluateServiceWorkerOnWorkerThread( + context_proxy, v8_context, service_worker_version_id, + service_worker_scope, script_url); +#endif +} + +void ChromeContentRendererClient::DidStartServiceWorkerContextOnWorkerThread( + int64_t service_worker_version_id, + const GURL& service_worker_scope, + const GURL& script_url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient::GetInstance() + ->extension_dispatcher() + ->DidStartServiceWorkerContextOnWorkerThread( + service_worker_version_id, service_worker_scope, script_url); +#endif +} + +void ChromeContentRendererClient::WillDestroyServiceWorkerContextOnWorkerThread( + v8::Local context, + int64_t service_worker_version_id, + const GURL& service_worker_scope, + const GURL& script_url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + ChromeExtensionsRendererClient::GetInstance() + ->extension_dispatcher() + ->WillDestroyServiceWorkerContextOnWorkerThread( + context, service_worker_version_id, service_worker_scope, script_url); +#endif +} + +// If we're in an extension, there is no need disabling multiple routes as +// chrome.system.network.getNetworkInterfaces provides the same +// information. Also, the enforcement of sending and binding UDP is already done +// by chrome extension permission model. +bool ChromeContentRendererClient::ShouldEnforceWebRTCRoutingPreferences() { + return !IsStandaloneContentExtensionProcess(); +} + +GURL ChromeContentRendererClient::OverrideFlashEmbedWithHTML(const GURL& url) { + if (!url.is_valid()) + return GURL(); + + return FlashEmbedRewrite::RewriteFlashEmbedURL(url); +} + +std::unique_ptr +ChromeContentRendererClient::CreateURLLoaderThrottleProvider( + blink::URLLoaderThrottleProviderType provider_type) { + return URLLoaderThrottleProviderImpl::Create(provider_type, this, + browser_interface_broker_.get()); +} + +blink::WebFrame* ChromeContentRendererClient::FindFrame( + blink::WebLocalFrame* relative_to_frame, + const std::string& name) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + return ChromeExtensionsRendererClient::FindFrame(relative_to_frame, name); +#else + return nullptr; +#endif // BUILDFLAG(ENABLE_EXTENSIONS) +} + +bool ChromeContentRendererClient::IsSafeRedirectTarget(const GURL& upstream_url, + const GURL& target_url) { +#if BUILDFLAG(ENABLE_EXTENSIONS) + if (target_url.SchemeIs(extensions::kExtensionScheme)) { + const extensions::Extension* extension = + extensions::RendererExtensionRegistry::Get()->GetByID( + target_url.host()); + if (!extension) { + return false; + } + // TODO(solomonkinard): Use initiator_origin and add tests. + if (extensions::WebAccessibleResourcesInfo::IsResourceWebAccessibleRedirect( + extension, target_url, /*initiator_origin=*/std::nullopt, + upstream_url)) { + return true; + } + return extension->guid() == upstream_url.host(); + } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + return true; +} + +void ChromeContentRendererClient::DidSetUserAgent( + const std::string& user_agent) { +#if BUILDFLAG(ENABLE_PRINTING) + printing::SetAgent(user_agent); +#endif +} + +void ChromeContentRendererClient::AppendContentSecurityPolicy( + const blink::WebURL& url, + blink::WebVector* csp) { +#if BUILDFLAG(ENABLE_EXTENSIONS) +#if BUILDFLAG(ENABLE_PDF) + // Don't apply default CSP to PDF renderers. + // TODO(crbug.com/40792950): Lock down the CSP once style and script are no + // longer injected inline by `pdf::PluginResponseWriter`. That class may be a + // better place to define such CSP, or we may continue doing so here. + if (pdf::IsPdfRenderer()) + return; +#endif // BUILDFLAG(ENABLE_PDF) + + DCHECK(csp); + GURL gurl(url); + const extensions::Extension* extension = + extensions::RendererExtensionRegistry::Get()->GetExtensionOrAppByURL( + gurl); + if (!extension) + return; + + // Append a minimum CSP to ensure the extension can't relax the default + // applied CSP through means like Service Worker. + const std::string* default_csp = + extensions::CSPInfo::GetMinimumCSPToAppend(*extension, gurl.path()); + if (!default_csp) + return; + + csp->push_back({blink::WebString::FromUTF8(*default_csp), + network::mojom::ContentSecurityPolicyType::kEnforce, + network::mojom::ContentSecurityPolicySource::kHTTP}); +#endif +} + +std::unique_ptr +ChromeContentRendererClient::CreateLinkPreviewTriggerer() { + return ::CreateWebLinkPreviewTriggerer(); +} diff --git a/tools/under-control/src/content/browser/web_contents/web_contents_impl.cc b/tools/under-control/src/content/browser/web_contents/web_contents_impl.cc new file mode 100755 index 000000000..b66f7c515 --- /dev/null +++ b/tools/under-control/src/content/browser/web_contents/web_contents_impl.cc @@ -0,0 +1,11146 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/web_contents/web_contents_impl.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "base/allocator/partition_allocator/src/partition_alloc/buildflags.h" +#include "base/check_op.h" +#include "base/command_line.h" +#include "base/containers/contains.h" +#include "base/containers/flat_set.h" +#include "base/feature_list.h" +#include "base/files/file_path.h" +#include "base/functional/bind.h" +#include "base/functional/callback_helpers.h" +#include "base/lazy_instance.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/ref_counted.h" +#include "base/metrics/field_trial.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "base/metrics/user_metrics.h" +#include "base/no_destructor.h" +#include "base/observer_list.h" +#include "base/process/process.h" +#include "base/ranges/algorithm.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/system/sys_info.h" +#include "base/task/single_thread_task_runner.h" +#include "base/time/time.h" +#include "base/timer/elapsed_timer.h" +#include "base/trace_event/optional_trace_event.h" +#include "base/trace_event/trace_event.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "cc/input/browser_controls_offset_tags_info.h" +#include "components/attribution_reporting/features.h" +#include "components/download/public/common/download_stats.h" +#include "components/input/cursor_manager.h" +#include "components/input/render_widget_host_input_event_router.h" +#include "components/url_formatter/url_formatter.h" +#include "components/viz/common/features.h" +#include "components/viz/host/host_frame_sink_manager.h" +#include "content/browser/accessibility/browser_accessibility.h" +#include "content/browser/accessibility/browser_accessibility_state_impl.h" +#include "content/browser/attribution_reporting/attribution_host.h" +#include "content/browser/attribution_reporting/attribution_manager.h" +#include "content/browser/attribution_reporting/attribution_os_level_manager.h" +#include "content/browser/bad_message.h" +#include "content/browser/browser_context_impl.h" +#include "content/browser/browser_main_loop.h" +#include "content/browser/browser_plugin/browser_plugin_embedder.h" +#include "content/browser/browser_plugin/browser_plugin_guest.h" +#include "content/browser/child_process_security_policy_impl.h" +#include "content/browser/closewatcher/close_listener_manager.h" +#include "content/browser/compositor/surface_utils.h" +#include "content/browser/device_posture/device_posture_provider_impl.h" +#include "content/browser/devtools/protocol/page_handler.h" +#include "content/browser/devtools/render_frame_devtools_agent_host.h" +#include "content/browser/display_cutout/display_cutout_host_impl.h" +#include "content/browser/dom_storage/dom_storage_context_wrapper.h" +#include "content/browser/dom_storage/session_storage_namespace_impl.h" +#include "content/browser/download/mhtml_generation_manager.h" +#include "content/browser/download/save_package.h" +#include "content/browser/fenced_frame/fenced_frame.h" +#include "content/browser/find_request_manager.h" +#include "content/browser/gpu/gpu_data_manager_impl.h" +#include "content/browser/host_zoom_map_impl.h" +#include "content/browser/media/audio_stream_monitor.h" +#include "content/browser/media/media_web_contents_observer.h" +#include "content/browser/permissions/permission_controller_impl.h" +#include "content/browser/permissions/permission_util.h" +#include "content/browser/preloading/prefetch/prefetch_service.h" +#include "content/browser/preloading/preloading.h" +#include "content/browser/preloading/prerender/prerender_final_status.h" +#include "content/browser/preloading/prerender/prerender_host_registry.h" +#include "content/browser/preloading/prerender/prerender_metrics.h" +#include "content/browser/preloading/prerender/prerender_new_tab_handle.h" +#include "content/browser/renderer_host/agent_scheduling_group_host.h" +#include "content/browser/renderer_host/cross_process_frame_connector.h" +#include "content/browser/renderer_host/frame_token_message_queue.h" +#include "content/browser/renderer_host/frame_tree_node.h" +#include "content/browser/renderer_host/input/touch_emulator_impl.h" +#include "content/browser/renderer_host/media/media_stream_manager.h" +#include "content/browser/renderer_host/navigation_entry_impl.h" +#include "content/browser/renderer_host/navigation_request.h" +#include "content/browser/renderer_host/page_impl.h" +#include "content/browser/renderer_host/render_frame_host_impl.h" +#include "content/browser/renderer_host/render_frame_proxy_host.h" +#include "content/browser/renderer_host/render_process_host_impl.h" +#include "content/browser/renderer_host/render_view_host_delegate_view.h" +#include "content/browser/renderer_host/render_view_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_factory.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" +#include "content/browser/renderer_host/render_widget_host_view_base.h" +#include "content/browser/renderer_host/render_widget_host_view_child_frame.h" +#include "content/browser/renderer_host/text_input_manager.h" +#include "content/browser/renderer_host/visible_time_request_trigger.h" +#include "content/browser/screen_details/screen_change_monitor.h" +#include "content/browser/screen_orientation/screen_orientation_provider.h" +#include "content/browser/shared_storage/shared_storage_budget_charger.h" +#include "content/browser/site_instance_impl.h" +#include "content/browser/wake_lock/wake_lock_context_host.h" +#include "content/browser/web_contents/java_script_dialog_commit_deferring_condition.h" +#include "content/browser/web_contents/web_contents_view.h" +#include "content/browser/web_contents/web_contents_view_child_frame.h" +#include "content/browser/webui/web_ui_controller_factory_registry.h" +#include "content/browser/webui/web_ui_impl.h" +#include "content/common/content_switches_internal.h" +#include "content/common/features.h" +#include "content/public/browser/ax_inspect_factory.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_plugin_guest_manager.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/color_chooser.h" +#include "content/public/browser/content_browser_client.h" +#include "content/public/browser/context_menu_params.h" +#include "content/public/browser/device_service.h" +#include "content/public/browser/disallow_activation_reason.h" +#include "content/public/browser/download_manager.h" +#include "content/public/browser/file_select_listener.h" +#include "content/public/browser/focused_node_details.h" +#include "content/public/browser/frame_type.h" +#include "content/public/browser/global_routing_id.h" +#include "content/public/browser/invalidate_type.h" +#include "content/public/browser/javascript_dialog_manager.h" +#include "content/public/browser/keyboard_event_processing_result.h" +#include "content/public/browser/navigation_details.h" +#include "content/public/browser/preview_cancel_reason.h" +#include "content/public/browser/render_widget_host_iterator.h" +#include "content/public/browser/render_widget_host_observer.h" +#include "content/public/browser/restore_type.h" +#include "content/public/browser/scoped_accessibility_mode.h" +#include "content/public/browser/site_isolation_policy.h" +#include "content/public/browser/ssl_status.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/web_contents_delegate.h" +#include "content/public/browser/web_contents_view_delegate.h" +#include "content/public/browser/web_ui_controller.h" +#include "content/public/common/content_client.h" +#include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/referrer_type_converters.h" +#include "content/public/common/url_constants.h" +#include "media/base/media_switches.h" +#include "media/base/user_input_monitor.h" +#include "net/base/url_util.h" +#include "net/http/http_util.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "ppapi/buildflags/buildflags.h" +#include "services/device/public/mojom/wake_lock.mojom.h" +#include "services/network/public/cpp/request_destination.h" +#include "services/network/public/cpp/web_sandbox_flags.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "third_party/abseil-cpp/absl/cleanup/cleanup.h" +#include "third_party/blink/public/common/custom_handlers/protocol_handler_utils.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/loader/resource_type_util.h" +#include "third_party/blink/public/common/mime_util/mime_util.h" +#include "third_party/blink/public/common/page/page_zoom.h" +#include "third_party/blink/public/common/page_state/page_state.h" +#include "third_party/blink/public/common/permissions/permission_utils.h" +#include "third_party/blink/public/common/security/protocol_handler_security_level.h" +#include "third_party/blink/public/common/switches.h" +#include "third_party/blink/public/common/web_preferences/web_preferences.h" +#include "third_party/blink/public/common/widget/constants.h" +#include "third_party/blink/public/mojom/frame/frame.mojom.h" +#include "third_party/blink/public/mojom/frame/fullscreen.mojom.h" +#include "third_party/blink/public/mojom/image_downloader/image_downloader.mojom.h" +#include "third_party/blink/public/mojom/input/input_handler.mojom-shared.h" +#include "third_party/blink/public/mojom/mediastream/media_stream.mojom-shared.h" +#include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h" +#include "third_party/blink/public/mojom/page/draggable_region.mojom.h" +#include "third_party/blink/public/mojom/window_features/window_features.mojom.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/accessibility/ax_tree_combiner.h" +#include "ui/base/ime/mojom/virtual_keyboard_types.mojom.h" +#include "ui/base/pointer/pointer_device.h" +#include "ui/base/ui_base_types.h" +#include "ui/base/window_open_disposition.h" +#include "ui/color/color_provider_key.h" +#include "ui/color/color_provider_manager.h" +#include "ui/color/color_provider_utils.h" +#include "ui/compositor/compositor.h" +#include "ui/display/screen.h" +#include "ui/display/types/display_constants.h" +#include "ui/events/base_event_utils.h" +#include "ui/gfx/animation/animation.h" + +#if BUILDFLAG(IS_WIN) +#include "base/threading/thread_restrictions.h" +#include "content/browser/renderer_host/dip_util.h" +#include "ui/gfx/geometry/dip_util.h" +#endif + +#if BUILDFLAG(IS_ANDROID) +#include "content/browser/android/java_interfaces_impl.h" +#include "content/browser/android/nfc_host.h" +#include "content/browser/navigation_transitions/back_forward_transition_animation_manager_android.h" +#include "content/browser/web_contents/web_contents_android.h" +#include "content/browser/web_contents/web_contents_view_android.h" +#include "services/device/public/mojom/nfc.mojom.h" +#include "services/service_manager/public/cpp/interface_provider.h" +#include "ui/android/view_android.h" +#include "ui/base/device_form_factor.h" +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) +#include "content/browser/date_time_chooser/date_time_chooser.h" +#endif + +#if BUILDFLAG(ENABLE_PPAPI) +#include "content/browser/media/session/pepper_playback_observer.h" +#endif + +#if BUILDFLAG(ENABLE_VR) +#include "content/browser/xr/service/xr_runtime_manager_impl.h" +#endif + +#if defined(USE_AURA) +#include "ui/aura/window.h" +#include "ui/wm/core/window_util.h" +#endif + +#if !BUILDFLAG(IS_ANDROID) +#include "content/public/browser/document_picture_in_picture_window_controller.h" +#include "content/public/browser/picture_in_picture_window_controller.h" +#endif // !BUILDFLAG(IS_ANDROID) + +namespace content { + +namespace { + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class AllPointerTypes { + kNone = 0, + kCoarse = 1, + kFine = 2, + kBoth = 3, + kMaxValue = kBoth +}; + +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class PrimaryPointerType { + kNone = 0, + kCoarse = 1, + kFine = 2, + kMaxValue = kFine +}; + +// The window which we dobounce load info updates in. +constexpr auto kUpdateLoadStatesInterval = base::Milliseconds(250); + +// Kill switch for crash immediately on dangling BrowserContext. +BASE_FEATURE(kCrashOnDanglingBrowserContext, + "CrashOnDanglingBrowserContext", + base::FEATURE_ENABLED_BY_DEFAULT); + +// Kill switch for inner WebContents visibility updates. +BASE_FEATURE(kUpdateInnerWebContentsVisibility, + "UpdateInnerWebContentsVisibility", + base::FEATURE_ENABLED_BY_DEFAULT); + +using LifecycleState = RenderFrameHost::LifecycleState; +using LifecycleStateImpl = RenderFrameHostImpl::LifecycleStateImpl; +using AttributionReportingOsRegistrar = + ContentBrowserClient::AttributionReportingOsRegistrar; + +base::LazyInstance>:: + DestructorAtExit g_created_callbacks = LAZY_INSTANCE_INITIALIZER; + +bool HasMatchingWidgetHost(FrameTree* tree, RenderWidgetHostImpl* host) { + // This method scans the frame tree rather than checking whether + // host->delegate() == this, which allows it to return false when the host + // for a frame that is pending or pending deletion. + if (!host) { + return false; + } + + for (FrameTreeNode* node : tree->NodesIncludingInnerTreeNodes()) { + // We might cross a WebContents boundary here, but it's fine as we are only + // comparing the RWHI with the given `host`, which is always guaranteed to + // belong to the same WebContents as `tree`. + if (node->current_frame_host()->GetRenderWidgetHost() == host) { + DCHECK_EQ(WebContentsImpl::FromFrameTreeNode(node), + WebContentsImpl::FromRenderWidgetHostImpl(host)); + return true; + } + } + return false; +} + +RenderFrameHostImpl* FindOpenerRFH(const WebContents::CreateParams& params) { + RenderFrameHostImpl* opener_rfh = nullptr; + if (params.opener_render_frame_id != MSG_ROUTING_NONE) { + opener_rfh = RenderFrameHostImpl::FromID(params.opener_render_process_id, + params.opener_render_frame_id); + } + return opener_rfh; +} + +// Returns |true| if |type| is the kind of user input that should trigger the +// user interaction observers. +bool IsUserInteractionInputType(blink::WebInputEvent::Type type) { + // TODO(mustaq): This list should be based off the HTML spec: + // https://html.spec.whatwg.org/multipage/interaction.html#tracking-user-activation, + // and kGestureScrollBegin is a clear outlier. + return type == blink::WebInputEvent::Type::kMouseDown || + type == blink::WebInputEvent::Type::kGestureScrollBegin || + type == blink::WebInputEvent::Type::kTouchStart || + type == blink::WebInputEvent::Type::kRawKeyDown; +} + +// Ensures that OnDialogClosed is only called once. +class CloseDialogCallbackWrapper + : public base::RefCountedThreadSafe { + public: + using CloseCallback = + base::OnceCallback; + + explicit CloseDialogCallbackWrapper(CloseCallback callback) + : callback_(std::move(callback)) {} + + void Run(bool dialog_was_suppressed, + bool success, + const std::u16string& user_input) { + if (callback_.is_null()) { + return; + } + std::move(callback_).Run(dialog_was_suppressed, success, user_input); + } + + private: + friend class base::RefCountedThreadSafe; + ~CloseDialogCallbackWrapper() = default; + + CloseCallback callback_; +}; + +bool FrameCompareDepth(RenderFrameHostImpl* a, RenderFrameHostImpl* b) { + return a->GetFrameDepth() < b->GetFrameDepth(); +} + +bool AreValidRegisterProtocolHandlerArguments( + const std::string& protocol, + const GURL& url, + const url::Origin& origin, + blink::ProtocolHandlerSecurityLevel security_level) { + ChildProcessSecurityPolicyImpl* policy = + ChildProcessSecurityPolicyImpl::GetInstance(); + if (policy->IsPseudoScheme(protocol)) { + return false; + } + + // Implementation of the protocol handler arguments normalization steps + // defined in the spec. + // https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters + // + // Verify custom handler schemes for errors as described in steps 1 and 2 + if (!blink::IsValidCustomHandlerScheme(protocol, security_level)) { + return false; + } + + blink::URLSyntaxErrorCode code = + blink::IsValidCustomHandlerURLSyntax(url, url.spec()); + if (code != blink::URLSyntaxErrorCode::kNoError) { + return false; + } + + // Verify custom handler URL security as described in steps 6 and 7 + if (!blink::IsAllowedCustomHandlerURL(url, security_level)) { + return false; + } + url::Origin url_origin = url::Origin::Create(url); + if (url_origin.opaque()) { + return false; + } + if (security_level < blink::ProtocolHandlerSecurityLevel::kUntrustedOrigins && + !origin.IsSameOriginWith(url)) { + return false; + } + + return true; +} + +void RecordMaxFrameCountUMA(size_t max_frame_count) { + UMA_HISTOGRAM_COUNTS_10000("Navigation.MainFrame.MaxFrameCount", + max_frame_count); +} + +// Returns the set of all WebContentses that are reachable from |web_contents| +// by applying some combination of +// WebContents::GetFirstWebContentsInLiveOriginalOpenerChain() and +// WebContents::GetOuterWebContents(). The |web_contents| parameter will be +// included in the returned set. +base::flat_set GetAllOpeningWebContents( + WebContentsImpl* web_contents) { + base::flat_set result; + base::flat_set current; + + current.insert(web_contents); + + while (!current.empty()) { + WebContentsImpl* current_contents = *current.begin(); + current.erase(current.begin()); + auto insert_result = result.insert(current_contents); + + if (insert_result.second) { + if (WebContents* opener_contents = + current_contents + ->GetFirstWebContentsInLiveOriginalOpenerChain()) { + current.insert(static_cast(opener_contents)); + } + + WebContentsImpl* outer_contents = current_contents->GetOuterWebContents(); + if (outer_contents) { + current.insert(outer_contents); + } + } + } + + return result; +} + +#if BUILDFLAG(IS_ANDROID) +float GetDeviceScaleAdjustment(int min_width) { + static const float kMinFSM = 1.05f; + static const int kWidthForMinFSM = 320; + static const float kMaxFSM = 1.3f; + static const int kWidthForMaxFSM = 800; + + if (min_width <= kWidthForMinFSM) { + return kMinFSM; + } + if (min_width >= kWidthForMaxFSM) { + return kMaxFSM; + } + + // The font scale multiplier varies linearly between kMinFSM and kMaxFSM. + float ratio = static_cast(min_width - kWidthForMinFSM) / + (kWidthForMaxFSM - kWidthForMinFSM); + return ratio * (kMaxFSM - kMinFSM) + kMinFSM; +} +#endif + +// Store a set of fullscreen WebContents and metadata for the browser context. +// Storing this information on the browser context is done for two reasons. One, +// related WebContentses must necessarily share a browser context, so this saves +// lookup time by restricting to one specific browser context. Two, separating +// by browser context is preemptive paranoia about keeping things separate. +class FullscreenUserData : public base::SupportsUserData::Data { + public: + FullscreenUserData() = default; + ~FullscreenUserData() override = default; + + FullscreenUserData(const FullscreenUserData&) = delete; + FullscreenUserData& operator=(const FullscreenUserData&) = delete; + + base::flat_set>* set() { + return &set_; + } + + std::map* last_exits() { return &last_exits_; } + + private: + base::flat_set> set_; + // Track latest exits by origin to briefly block re-entry without a gesture. + std::map last_exits_; +}; + +const char kFullscreenUserData[] = "fullscreen-user-data"; + +FullscreenUserData* GetFullscreenUserData(BrowserContext* browser_context) { + auto* set_holder = static_cast( + browser_context->GetUserData(kFullscreenUserData)); + if (!set_holder) { + auto new_holder = std::make_unique(); + set_holder = new_holder.get(); + browser_context->SetUserData(kFullscreenUserData, std::move(new_holder)); + } + return set_holder; +} + +base::flat_set>* +FullscreenContentsSet(BrowserContext* browser_context) { + return GetFullscreenUserData(browser_context)->set(); +} + +// Returns true if `host` has the Window Management permission granted. +bool IsWindowManagementGranted(RenderFrameHost* host) { + content::PermissionController* permission_controller = + host->GetBrowserContext()->GetPermissionController(); + CHECK(permission_controller); + + return permission_controller->GetPermissionStatusForCurrentDocument( + blink::PermissionType::WINDOW_MANAGEMENT, host) == + blink::mojom::PermissionStatus::GRANTED; +} + +// Returns true if `host` has the Automatic Fullscreen permission granted. +bool IsAutomaticFullscreenGranted(RenderFrameHost* host) { + if (!base::FeatureList::IsEnabled( + blink::features::kAutomaticFullscreenPermissionsQuery)) { + return false; + } + content::PermissionController* permission_controller = + host->GetBrowserContext()->GetPermissionController(); + CHECK(permission_controller); + + return permission_controller->GetPermissionStatusForCurrentDocument( + blink::PermissionType::AUTOMATIC_FULLSCREEN, host) == + blink::mojom::PermissionStatus::GRANTED; +} + +// Adjust the requested `rect` for opening or placing a window and return the id +// of the display where the window will be placed. The bounds may not extend +// outside a single screen's work area, and the `host` requires permission to +// specify bounds on a screen other than its current screen. +// TODO(crbug.com/40092782): These adjustments are inaccurate for window.open(), +// which specifies the inner content size, and for window.moveTo, resizeTo, etc. +// calls on newly created windows, which may pass empty sizes or positions to +// indicate uninitialized placement information in the renderer. Constraints +// enforced later should resolve most inaccuracies, but this early enforcement +// is needed to ensure bounds indicate the appropriate display. +int64_t AdjustWindowRectForDisplay(gfx::Rect* rect, RenderFrameHost* host) { + auto* screen = display::Screen::GetScreen(); + auto display = screen->GetDisplayMatching(*rect); + + // Check, but do not prompt, for permission to place windows on other screens. + // Sites generally need permission to get such bounds in the first place. + // Also clamp offscreen bounds to the window's current screen. + if (!rect->Intersects(display.bounds()) || !IsWindowManagementGranted(host)) { + // Use the main frame's NativeView; cross-origin iframes yield null. + gfx::NativeView view = host->GetOutermostMainFrame()->GetNativeView(); + display = screen->GetDisplayNearestView(view); + } + rect->AdjustToFit(display.work_area()); + return display.id(); +} + +// Adjusts the bounds to the minimum window size provided. Defaults to +// `blink::kMinimumWindowSize` but can be overridden, e.g. for borderless apps. +void AdjustWindowRectForMinimum(gfx::Rect* bounds, + int minimum_size = blink::kMinimumWindowSize) { + // Size 0 indicates default size, not minimum. + if (bounds->width()) { + bounds->set_width(std::max(minimum_size, bounds->width())); + } + if (bounds->height()) { + bounds->set_height(std::max(minimum_size, bounds->height())); + } +} + +// A ColorProviderSource used when one has not been explicitly set. This source +// only reflects theme information present in the web NativeTheme singleton. +// Keep this an implementation detail of WebContentsImpl as we should not be +// exposing a default ColorProviderSource generally. +class DefaultColorProviderSource : public ui::ColorProviderSource, + public ui::NativeThemeObserver { + public: + DefaultColorProviderSource() { + native_theme_observation_.Observe(ui::NativeTheme::GetInstanceForWeb()); + } + DefaultColorProviderSource(const DefaultColorProviderSource&) = delete; + DefaultColorProviderSource& operator=(const DefaultColorProviderSource&) = + delete; + ~DefaultColorProviderSource() override = default; + + static DefaultColorProviderSource* GetInstance() { + static base::NoDestructor instance; + return instance.get(); + } + + // ui::ColorProviderSource: + const ui::ColorProvider* GetColorProvider() const override { + return ui::ColorProviderManager::Get().GetColorProviderFor( + GetColorProviderKey()); + } + + ui::RendererColorMap GetRendererColorMap( + ui::ColorProviderKey::ColorMode color_mode, + ui::ColorProviderKey::ForcedColors forced_colors) const override { + auto key = GetColorProviderKey(); + key.color_mode = color_mode; + key.forced_colors = forced_colors; + ui::ColorProvider* color_provider = + ui::ColorProviderManager::Get().GetColorProviderFor(key); + CHECK(color_provider); + + return ui::CreateRendererColorMap(*color_provider); + } + + // ui::NativeThemeObserver: + void OnNativeThemeUpdated(ui::NativeTheme* observed_theme) override { + DCHECK(native_theme_observation_.IsObservingSource(observed_theme)); + NotifyColorProviderChanged(); + } + + protected: + // ui::ColorProviderSource: + ui::ColorProviderKey GetColorProviderKey() const override { + return ui::NativeTheme::GetInstanceForWeb()->GetColorProviderKey(nullptr); + } + + private: + base::ScopedObservation + native_theme_observation_{this}; +}; + +size_t GetFrameTreeSize(FrameTree* frame_tree) { + size_t tree_size = 0; + FrameTree::NodeRange node_range = frame_tree->NodesIncludingInnerTreeNodes(); + FrameTree::NodeIterator node_iter = node_range.begin(); + while (node_iter != node_range.end()) { + // Skip over collapsed frame trees. + if ((*node_iter)->is_collapsed()) { + node_iter.AdvanceSkippingChildren(); + } else { + ++tree_size; + ++node_iter; + } + } + return tree_size; +} + +using RenderWidgetHostAtPointCallback = + base::OnceCallback, + std::optional)>; + +void RunCallback(RenderWidgetHostAtPointCallback callback, + base::WeakPtr view, + std::optional point) { + auto* target = static_cast(view.get()); + if (!callback.is_null()) { + std::move(callback).Run(target ? target->GetWeakPtr() : nullptr, point); + } +} + +} // namespace + +// This is a small helper class created while a JavaScript dialog is showing +// and destroyed when it's dismissed. Clients can register callbacks to receive +// a notification when the dialog is dismissed. +class JavaScriptDialogDismissNotifier { + public: + JavaScriptDialogDismissNotifier() = default; + + JavaScriptDialogDismissNotifier(const JavaScriptDialogDismissNotifier&) = + delete; + JavaScriptDialogDismissNotifier& operator=( + const JavaScriptDialogDismissNotifier&) = delete; + + ~JavaScriptDialogDismissNotifier() { + for (auto& callback : callbacks_) { + std::move(callback).Run(); + } + } + + void NotifyOnDismiss(base::OnceClosure callback) { + callbacks_.push_back(std::move(callback)); + } + + private: + std::vector callbacks_; +}; + +CreatedWindow::CreatedWindow() = default; +CreatedWindow::CreatedWindow(std::unique_ptr contents, + GURL target_url) + : contents(std::move(contents)), target_url(std::move(target_url)) {} +CreatedWindow::~CreatedWindow() = default; +CreatedWindow::CreatedWindow(CreatedWindow&&) = default; +CreatedWindow& CreatedWindow::operator=(CreatedWindow&&) = default; + +std::unique_ptr WebContents::Create( + const WebContents::CreateParams& params) { + return WebContentsImpl::Create(params); +} + +std::unique_ptr WebContentsImpl::Create( + const CreateParams& params) { + return CreateWithOpener(params, FindOpenerRFH(params)); +} + +std::unique_ptr WebContents::CreateWithSessionStorage( + const WebContents::CreateParams& params, + const SessionStorageNamespaceMap& session_storage_namespace_map) { + OPTIONAL_TRACE_EVENT0("content", "WebContents::CreateWithSessionStorage"); + std::unique_ptr new_contents( + new WebContentsImpl(params.browser_context)); + RenderFrameHostImpl* opener_rfh = FindOpenerRFH(params); + FrameTreeNode* opener = nullptr; + if (opener_rfh) { + opener = opener_rfh->frame_tree_node(); + } + new_contents->SetOpenerForNewContents(opener, params.opener_suppressed); + + for (const auto& it : session_storage_namespace_map) { + new_contents->GetController().SetSessionStorageNamespace(it.first, + it.second.get()); + } + + WebContentsImpl* outer_web_contents = nullptr; + if (params.guest_delegate) { + // This makes |new_contents| act as a guest. + // For more info, see comment above class BrowserPluginGuest. + BrowserPluginGuest::CreateInWebContents(new_contents.get(), + params.guest_delegate); + outer_web_contents = static_cast( + params.guest_delegate->GetOwnerWebContents()); + } + + new_contents->Init(params, blink::FramePolicy()); + if (outer_web_contents) { + outer_web_contents->InnerWebContentsCreated(new_contents.get()); + } + return new_contents; +} + +base::CallbackListSubscription +WebContentsImpl::FriendWrapper::AddCreatedCallbackForTesting( + const CreatedCallback& callback) { + return g_created_callbacks.Get().Add(callback); +} + +WebContents* WebContents::FromRenderViewHost(RenderViewHost* rvh) { + OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContents::FromRenderViewHost", "render_view_host", + rvh); + if (!rvh) { + return nullptr; + } + return static_cast( + static_cast(rvh)->GetDelegate()); +} + +WebContents* WebContents::FromRenderFrameHost(RenderFrameHost* rfh) { + OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContents::FromRenderFrameHost", "render_frame_host", + rfh); + return WebContentsImpl::FromRenderFrameHostImpl( + static_cast(rfh)); +} + +WebContentsImpl* WebContentsImpl::FromRenderFrameHostImpl( + RenderFrameHostImpl* rfh) { + OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::FromRenderFrameHostImpl", + "render_frame_host", rfh); + if (!rfh) { + return nullptr; + } + return static_cast(rfh->delegate()); +} + +WebContents* WebContents::FromFrameTreeNodeId(int frame_tree_node_id) { + OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContents::FromFrameTreeNodeId", + "frame_tree_node_id", frame_tree_node_id); + FrameTreeNode* frame_tree_node = + FrameTreeNode::GloballyFindByID(frame_tree_node_id); + if (!frame_tree_node) { + return nullptr; + } + return WebContentsImpl::FromFrameTreeNode(frame_tree_node); +} + +WebContentsImpl* WebContentsImpl::FromRenderWidgetHostImpl( + RenderWidgetHostImpl* rwh) { + if (!rwh) { + return nullptr; + } + return static_cast(rwh->delegate()); +} + +std::optional WebContentsImpl::AdjustedChildZoom( + const RenderWidgetHostViewChildFrame* render_widget) { + // permits zoom level to be set programmatically by script: + // https://developer.chrome.com/docs/apps/reference/webviewTag#method-setZoom + if (IsGuest() && GetRenderWidgetHostView() == render_widget) { + return GetPendingPageZoomLevel(); + } + + // Signals zoom level should be inherited from the parent + return std::nullopt; +} + +bool WebContentsImpl::IsPopup() const { + return is_popup_; +} + +void WebContents::SetScreenOrientationDelegate( + ScreenOrientationDelegate* delegate) { + ScreenOrientationProvider::SetDelegate(delegate); +} + +// WebContentsImpl::RenderWidgetHostDestructionObserver ----------------------- + +class WebContentsImpl::RenderWidgetHostDestructionObserver + : public RenderWidgetHostObserver { + public: + RenderWidgetHostDestructionObserver(WebContentsImpl* owner, + RenderWidgetHost* watched_host) + : owner_(owner), watched_host_(watched_host) { + watched_host_->AddObserver(this); + } + + RenderWidgetHostDestructionObserver( + const RenderWidgetHostDestructionObserver&) = delete; + RenderWidgetHostDestructionObserver& operator=( + const RenderWidgetHostDestructionObserver&) = delete; + + ~RenderWidgetHostDestructionObserver() override { + watched_host_->RemoveObserver(this); + } + + // RenderWidgetHostObserver: + void RenderWidgetHostDestroyed(RenderWidgetHost* widget_host) override { + owner_->OnRenderWidgetHostDestroyed(widget_host); + } + + private: + raw_ptr owner_; + raw_ptr watched_host_; +}; + +// WebContentsImpl::WebContentsDestructionObserver ---------------------------- + +class WebContentsImpl::WebContentsDestructionObserver + : public WebContentsObserver { + public: + WebContentsDestructionObserver(WebContentsImpl* owner, + WebContents* watched_contents) + : WebContentsObserver(watched_contents), owner_(owner) {} + + WebContentsDestructionObserver(const WebContentsDestructionObserver&) = + delete; + WebContentsDestructionObserver& operator=( + const WebContentsDestructionObserver&) = delete; + + // WebContentsObserver: + void WebContentsDestroyed() override { + owner_->OnWebContentsDestroyed( + static_cast(web_contents())); + } + + private: + raw_ptr owner_; +}; + +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) +// TODO(sreejakshetty): Make |WebContentsImpl::ColorChooserHolder| per-frame +// instead of WebContents-owned. +// WebContentsImpl::ColorChooserHolder ----------------------------------------- +class WebContentsImpl::ColorChooserHolder : public blink::mojom::ColorChooser { + public: + ColorChooserHolder( + mojo::PendingReceiver receiver, + mojo::PendingRemote client) + : receiver_(this, std::move(receiver)), client_(std::move(client)) {} + + ~ColorChooserHolder() override { + if (chooser_) { + chooser_->End(); + } + } + + void SetChooser(std::unique_ptr chooser) { + chooser_ = std::move(chooser); + if (chooser_) { + receiver_.set_disconnect_handler( + base::BindOnce([](content::ColorChooser* chooser) { chooser->End(); }, + base::Unretained(chooser_.get()))); + } + } + + void SetSelectedColor(SkColor color) override { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::ColorChooserHolder::SetSelectedColor"); + if (chooser_) { + chooser_->SetSelectedColor(color); + } + } + + void DidChooseColorInColorChooser(SkColor color) { + OPTIONAL_TRACE_EVENT0( + "content", + "WebContentsImpl::ColorChooserHolder::DidChooseColorInColorChooser"); + client_->DidChooseColor(color); + } + + private: + // Color chooser that was opened by this tab. + std::unique_ptr chooser_; + + // mojo receiver. + mojo::Receiver receiver_; + + // mojo renderer client. + mojo::Remote client_; +}; +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) + +// WebContentsImpl::WebContentsTreeNode ---------------------------------------- +WebContentsImpl::WebContentsTreeNode::WebContentsTreeNode( + WebContentsImpl* current_web_contents) + : current_web_contents_(current_web_contents), + outer_web_contents_(nullptr), + outer_contents_frame_tree_node_id_( + FrameTreeNode::kFrameTreeNodeInvalidId) {} + +WebContentsImpl::WebContentsTreeNode::~WebContentsTreeNode() = default; + +void WebContentsImpl::WebContentsTreeNode::AttachInnerWebContents( + std::unique_ptr inner_web_contents, + RenderFrameHostImpl* render_frame_host) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsTreeNode::AttachInnerWebContents"); + WebContentsImpl* inner_web_contents_impl = + static_cast(inner_web_contents.get()); + WebContentsTreeNode& inner_web_contents_node = inner_web_contents_impl->node_; + + inner_web_contents_node.outer_web_contents_ = current_web_contents_; + inner_web_contents_node.outer_contents_frame_tree_node_id_ = + render_frame_host->frame_tree_node()->frame_tree_node_id(); + + if (inner_web_contents) { + inner_web_contents->SetOwnerLocationForDebug(FROM_HERE); + } + inner_web_contents_.push_back(std::move(inner_web_contents)); + + render_frame_host->frame_tree_node()->AddObserver(&inner_web_contents_node); + current_web_contents_->InnerWebContentsAttached(inner_web_contents_impl); +} + +std::unique_ptr +WebContentsImpl::WebContentsTreeNode::DetachInnerWebContents( + WebContentsImpl* inner_web_contents) { + OPTIONAL_TRACE_EVENT0( + "content", + "WebContentsImpl::WebContentsTreeNode::DetachInnerWebContents"); + std::unique_ptr detached_contents; + for (std::unique_ptr& web_contents : inner_web_contents_) { + if (web_contents.get() == inner_web_contents) { + detached_contents = std::move(web_contents); + std::swap(web_contents, inner_web_contents_.back()); + inner_web_contents_.pop_back(); + current_web_contents_->InnerWebContentsDetached(inner_web_contents); + if (detached_contents) { + detached_contents->SetOwnerLocationForDebug(std::nullopt); + } + return detached_contents; + } + } + + NOTREACHED_IN_MIGRATION(); + return nullptr; +} + +FrameTreeNode* +WebContentsImpl::WebContentsTreeNode::OuterContentsFrameTreeNode() const { + return FrameTreeNode::GloballyFindByID(outer_contents_frame_tree_node_id_); +} + +void WebContentsImpl::WebContentsTreeNode::OnFrameTreeNodeDestroyed( + FrameTreeNode* node) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsTreeNode::OnFrameTreeNodeDestroyed"); + DCHECK_EQ(outer_contents_frame_tree_node_id_, node->frame_tree_node_id()) + << "WebContentsTreeNode should only receive notifications for the " + "FrameTreeNode in its outer WebContents that hosts it."; + + node->RemoveObserver(this); + // Deletes |this| too. + outer_web_contents_->node_.DetachInnerWebContents(current_web_contents_); +} + +FrameTree* WebContentsImpl::WebContentsTreeNode::focused_frame_tree() { + CHECK(focused_frame_tree_); + return focused_frame_tree_; +} + +void WebContentsImpl::WebContentsTreeNode::SetFocusedFrameTree( + FrameTree* frame_tree) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsTreeNode::SetFocusedFrameTree"); + DCHECK(!outer_web_contents()) + << "Only the outermost WebContents tracks focus."; + focused_frame_tree_ = frame_tree; +} + +WebContentsImpl* +WebContentsImpl::WebContentsTreeNode::GetInnerWebContentsInFrame( + const FrameTreeNode* frame) { + auto ftn_id = frame->frame_tree_node_id(); + for (auto& contents : inner_web_contents_) { + WebContentsImpl* impl = static_cast(contents.get()); + if (impl->node_.outer_contents_frame_tree_node_id() == ftn_id) { + return impl; + } + } + return nullptr; +} + +std::vector +WebContentsImpl::WebContentsTreeNode::GetInnerWebContents() const { + std::vector inner_web_contents; + for (auto& contents : inner_web_contents_) { + inner_web_contents.push_back(static_cast(contents.get())); + } + + return inner_web_contents; +} + +// WebContentsObserverList ----------------------------------------------------- +WebContentsImpl::WebContentsObserverList::WebContentsObserverList() = default; +WebContentsImpl::WebContentsObserverList::~WebContentsObserverList() = default; + +void WebContentsImpl::WebContentsObserverList::AddObserver( + WebContentsObserver* observer) { + observers_.AddObserver(observer); +} + +void WebContentsImpl::WebContentsObserverList::RemoveObserver( + WebContentsObserver* observer) { + observers_.RemoveObserver(observer); +} + +// WebContentsImpl ------------------------------------------------------------- + +namespace { + +// A helper for ensuring that WebContents are closed (or otherwise destroyed) +// *before* their BrowserContext is destroyed. +class WebContentsOfBrowserContext : public base::SupportsUserData::Data { + public: + static void Attach(WebContentsImpl& web_contents) { + WebContentsOfBrowserContext* self = + GetOrCreate(*web_contents.GetBrowserContext()); + self->web_contents_set_.insert(&web_contents); + } + + static void Detach(WebContentsImpl& web_contents) { + WebContentsOfBrowserContext* self = + GetOrCreate(*web_contents.GetBrowserContext()); + self->web_contents_set_.erase(&web_contents); + } + + ~WebContentsOfBrowserContext() override { + // The ~WebContentsOfBrowserContext destructor is called when the + // BrowserContext (and its UserData) gets destroyed. At this point + // in time all the WebContents of this BrowserContext should have been + // already closed (i.e. we expect the `web_contents_set_` set to be empty at + // this point - emptied by calls to the `Detach` method above). + if (web_contents_set_.empty()) { + return; // Everything is okay - nothing to warn about. + } + +#if BUILDFLAG(IS_ANDROID) + JNIEnv* env = base::android::AttachCurrentThread(); +#endif // BUILDFLAG(IS_ANDROID) + + // Any remaining WebContents contain dangling pointers to the + // BrowserContext being destroyed. Such WebContents (and their + // RenderFrameHosts, SiteInstances, etc.) risk causing + // use-after-free bugs. For more discussion about managing the + // lifetime of WebContents please see https://crbug.com/1376879#c44. + for (WebContentsImpl* web_contents_with_dangling_ptr_to_browser_context : + web_contents_set_) { + std::string creator = web_contents_with_dangling_ptr_to_browser_context + ->GetCreatorLocation() + .ToString(); + SCOPED_CRASH_KEY_STRING256("shutdown", "web_contents/creator", creator); + + const std::optional& ownership_location = + web_contents_with_dangling_ptr_to_browser_context + ->ownership_location(); + std::string owner; + if (ownership_location) { + if (ownership_location->has_source_info()) { + owner = std::string(ownership_location->function_name()) + "@" + + ownership_location->file_name(); + } else { + owner = "no_source_info"; + } + } else { + owner = "unknown"; + } + SCOPED_CRASH_KEY_STRING256("shutdown", "web_contents/owner", owner); + +#if BUILDFLAG(IS_ANDROID) + // On Android, also report the Java stack trace from WebContents's + // creation. + WebContentsAndroid::ReportDanglingPtrToBrowserContext( + env, web_contents_with_dangling_ptr_to_browser_context); +#endif // BUILDFLAG(IS_ANDROID) + + if (base::FeatureList::IsEnabled(kCrashOnDanglingBrowserContext)) { + LOG(FATAL) + << "BrowserContext is getting destroyed without first closing all " + << "WebContents (for more info see https://crbug.com/1376879#c44); " + << "creator = " << creator; + } else { + NOTREACHED_IN_MIGRATION() + << "BrowserContext is getting destroyed without first closing all " + << "WebContents (for more info see https://crbug.com/1376879#c44); " + << "creator = " << creator; + base::debug::DumpWithoutCrashing(); + } + } + } + + std::unique_ptr Clone() override { + // Indicate to `SupportsUserData` / `BrowserContext` that cloning is not + // supported. + return nullptr; + } + + private: + WebContentsOfBrowserContext() = default; + + // Gets WebContentsOfBrowserContext associated with the given + // `browser_context` (creating a new WebContentsOfBrowserContext if + // necessary - if one hasn't been created yet). + static WebContentsOfBrowserContext* GetOrCreate( + BrowserContext& browser_context) { + static const char* kUserDataKey = "WebContentsOfBrowserContext/UserDataKey"; + WebContentsOfBrowserContext* result = + static_cast( + browser_context.GetUserData(kUserDataKey)); + if (!result) { + result = new WebContentsOfBrowserContext(); + browser_context.SetUserData(kUserDataKey, base::WrapUnique(result)); + } + return result; + } + + // Set of all `WebContents` within the tracked `BrowserContext`. + // + // Usage of `raw_ptr` below is okay (i.e. it shouldn't dangle), because + // when `WebContentsImpl`'s destructor runs, then it removes the set entry + // (by calling `Detach`). + std::set> web_contents_set_; +}; + +} // namespace + +WebContentsImpl::WebContentsImpl(BrowserContext* browser_context) + : ColorProviderSourceObserver(DefaultColorProviderSource::GetInstance()), + delegate_(nullptr), + render_view_host_delegate_view_(nullptr), + opened_by_another_window_(false), + node_(this), + primary_frame_tree_(browser_context, + this, + this, + this, + this, + this, + this, + this, + this, + FrameTree::Type::kPrimary), + primary_main_frame_process_status_( + base::TERMINATION_STATUS_STILL_RUNNING), + primary_main_frame_process_error_code_(0), + load_state_(net::LOAD_STATE_IDLE, std::u16string()), + upload_size_(0), + upload_position_(0), + is_resume_pending_(false), + notify_disconnection_(false), + dialog_manager_(nullptr), + is_showing_before_unload_dialog_(false), + last_active_time_(base::TimeTicks::Now()), + closed_by_user_gesture_(false), + minimum_zoom_percent_( + static_cast(blink::kMinimumBrowserZoomFactor * 100)), + maximum_zoom_percent_( + static_cast(blink::kMaximumBrowserZoomFactor * 100)), + zoom_scroll_remainder_(0), + force_disable_overscroll_content_(false), + last_dialog_suppressed_(false), + accessibility_mode_( + BrowserAccessibilityState::GetInstance() + ->GetAccessibilityModeForBrowserContext(browser_context)), + audio_stream_monitor_(this), + media_web_contents_observer_( + std::make_unique(this)), + is_overlay_content_(false), + showing_context_menu_(false), + prerender_host_registry_(std::make_unique(*this)) { + TRACE_EVENT0("content", "WebContentsImpl::WebContentsImpl"); + WebContentsOfBrowserContext::Attach(*this); + node_.SetFocusedFrameTree(&primary_frame_tree_); +#if BUILDFLAG(ENABLE_PPAPI) + pepper_playback_observer_ = std::make_unique(this); +#endif + +#if BUILDFLAG(IS_ANDROID) + safe_area_insets_host_ = SafeAreaInsetsHost::Create(this); +#endif + + ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForWeb(); + native_theme_observation_.Observe(native_theme); + using_dark_colors_ = native_theme->ShouldUseDarkColors(); + in_forced_colors_ = native_theme->InForcedColorsMode(); + preferred_color_scheme_ = native_theme->GetPreferredColorScheme(); + preferred_contrast_ = native_theme->GetPreferredContrast(); + prefers_reduced_transparency_ = native_theme->GetPrefersReducedTransparency(); + inverted_colors_ = native_theme->GetInvertedColors(); + renderer_preferences_.caret_blink_interval = + native_theme->GetCaretBlinkInterval(); + + screen_change_monitor_ = + std::make_unique(base::BindRepeating( + &WebContentsImpl::OnScreensChange, base::Unretained(this))); + + if (base::FeatureList::IsEnabled(blink::features::kSharedStorageAPI)) { + SharedStorageBudgetCharger::CreateForWebContents(this); + } +} + +WebContentsImpl::~WebContentsImpl() { + TRACE_EVENT0("content", "WebContentsImpl::~WebContentsImpl"); + WebContentsOfBrowserContext::Detach(*this); + + // Imperfect sanity check against double free, given some crashes unexpectedly + // observed in the wild. + CHECK(!IsBeingDestroyed()); + + // We generally keep track of is_being_destroyed_ to let other features know + // to avoid certain actions during destruction. + is_being_destroyed_ = true; + + // A WebContents should never be deleted while it is notifying observers, + // since this will lead to a use-after-free as it continues to notify later + // observers. + CHECK(!observers_.is_notifying_observers()); + // This is used to watch for one-off observers (i.e. non-WebContentsObservers) + // destroying WebContents, which they should not do. + CHECK(!prevent_destruction_); + + // We usually record `max_loaded_frame_count_` in `DidFinishNavigation()` + // for pages the user navigated away from other than the last one. We record + // it for the last page here. + if (first_primary_navigation_completed_) { + RecordMaxFrameCountUMA(max_loaded_frame_count_); + } + + FullscreenContentsSet(GetBrowserContext())->erase(this); + + touch_emulator_.reset(); + + rwh_input_event_router_.reset(); + + WebContentsImpl* outermost = GetOutermostWebContents(); + if (this != outermost && ContainsOrIsFocusedWebContents()) { + // If the current WebContents is in focus, unset it. + outermost->SetAsFocusedWebContentsIfNecessary(); + } + + if (pointer_lock_widget_) { + pointer_lock_widget_->RejectPointerLockOrUnlockIfNecessary( + blink::mojom::PointerLockResult::kElementDestroyed); + + // Normally, the call above clears mouse_lock_widget_ pointers on the + // entire WebContents chain, since it results in calling LostPointerLock() + // when the mouse lock is already active. However, this doesn't work for + // guests if the mouse lock request is still pending while the + // is destroyed. Hence, ensure that all mouse lock widget + // pointers are cleared. See https://crbug.com/1346245. + for (WebContentsImpl* current = this; current; + current = current->GetOuterWebContents()) { + current->pointer_lock_widget_ = nullptr; + } + } + + for (RenderWidgetHostImpl* widget : created_widgets_) { + widget->DetachDelegate(); + } + created_widgets_.clear(); + + // Clear out any JavaScript state. + if (dialog_manager_) { + dialog_manager_->CancelDialogs(this, /*reset_state=*/true); + } + +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) + color_chooser_holder_.reset(); +#endif + find_request_manager_.reset(); + + // Shutdown the primary FrameTree. + primary_frame_tree_.Shutdown(); + + // Shutdown the non-primary FrameTrees. + // + // Do this here rather than relying on the owner of the FrameTree to shutdown + // on WebContentsDestroyed(), so that all the FrameTrees are shutdown at the + // same time for consistency. Also, destroying a FrameTree results in other + // observer functions like RenderFrameDeleted() being called, which are not + // expected to be called after WebContentsDestroyed(). + // + // Currently the only instances of the non-primary FrameTrees are for + // prerendering. Shutdown them by destructing PrerenderHostRegistry. + prerender_host_registry_.reset(); + + // For historical reasons, it is the requestor's responsibility to reset + // `PrefetchContainer`s that were created by the requestor (= `this`) but have + // not yet started prefetching (Otherwise, they will stay alive forever in + // `PrefetchService`). + // TODO(crbug.com/40946257): Refactor to handle this case better. + if (base::FeatureList::IsEnabled( + features::kPrefetchBrowserInitiatedTriggers)) { + PrefetchService* prefetch_service = + BrowserContextImpl::From(GetBrowserContext())->GetPrefetchService(); + if (prefetch_service) { + for (const auto& prefetch_container : prefetch_containers_) { + if (prefetch_container) { + switch (prefetch_container->GetLoadState()) { + case PrefetchContainer::LoadState::kNotStarted: + case PrefetchContainer::LoadState::kEligible: + case PrefetchContainer::LoadState::kFailedIneligible: + case PrefetchContainer::LoadState::kFailedHeldback: + prefetch_service->ResetPrefetch(prefetch_container); + break; + case PrefetchContainer::LoadState::kStarted: + break; + } + } + } + } + prefetch_containers_.clear(); + } + +#if BUILDFLAG(ENABLE_PPAPI) + // Call this before WebContentsDestroyed() is broadcasted since + // AudioFocusManager will be destroyed after that. + pepper_playback_observer_.reset(); +#endif // defined(ENABLED_PLUGINS) + + // If audio is playing then notify external observers of the audio stream + // disappearing. + if (is_currently_audible_) { + is_currently_audible_ = false; + observers_.NotifyObservers(&WebContentsObserver::OnAudioStateChanged, + false); + if (GetOuterWebContents()) { + GetOuterWebContents()->OnAudioStateChanged(); + } + } + + // |save_package_| is refcounted so make sure we clear the page before + // we toss out our reference. + if (save_package_) { + save_package_->ClearPage(); + } + + observers_.NotifyObservers(&WebContentsObserver::WebContentsDestroyed); + +#if BUILDFLAG(IS_ANDROID) + // Destroy the WebContentsAndroid here, so that its observers still can access + // `this`. + ClearWebContentsAndroid(); +#endif + + observers_.NotifyObservers(&WebContentsObserver::ResetWebContents); + SetDelegate(nullptr); +} + +std::unique_ptr WebContentsImpl::CreateWithOpener( + const WebContents::CreateParams& params, + RenderFrameHostImpl* opener_rfh) { + OPTIONAL_TRACE_EVENT1("browser", "WebContentsImpl::CreateWithOpener", + "opener", opener_rfh); + FrameTreeNode* opener = nullptr; + if (opener_rfh) { + opener = opener_rfh->frame_tree_node(); + } + std::unique_ptr new_contents( + new WebContentsImpl(params.browser_context)); + new_contents->SetOpenerForNewContents(opener, params.opener_suppressed); + + // If the opener is sandboxed, a new popup must inherit the opener's sandbox + // flags, and these flags take effect immediately. An exception is if the + // opener's sandbox flags lack the PropagatesToAuxiliaryBrowsingContexts + // bit (which is controlled by the "allow-popups-to-escape-sandbox" token). + // See https://html.spec.whatwg.org/C/#attr-iframe-sandbox. + FrameTreeNode* new_root = new_contents->GetPrimaryFrameTree().root(); + if (opener) { + network::mojom::WebSandboxFlags opener_flags = + opener_rfh->active_sandbox_flags(); + if (opener_rfh->IsSandboxed(network::mojom::WebSandboxFlags:: + kPropagatesToAuxiliaryBrowsingContexts)) { + new_root->SetPendingFramePolicy({opener_flags, + {} /* container_policy */, + {} /* required_document_policy */}); + } + new_root->SetInitialPopupURL(params.initial_popup_url); + new_root->SetPopupCreatorOrigin(opener_rfh->GetLastCommittedOrigin()); + } + + // Apply starting sandbox flags. + blink::FramePolicy frame_policy(new_root->pending_frame_policy()); + frame_policy.sandbox_flags |= params.starting_sandbox_flags; + new_root->SetPendingFramePolicy(frame_policy); + + // This may be true even when opener is null, such as when opening blocked + // popups. + if (params.opened_by_another_window) { + new_contents->opened_by_another_window_ = true; + } + + WebContentsImpl* outer_web_contents = nullptr; + if (params.guest_delegate) { + // This makes |new_contents| act as a guest. + // For more info, see comment above class BrowserPluginGuest. + BrowserPluginGuest::CreateInWebContents(new_contents.get(), + params.guest_delegate); + outer_web_contents = static_cast( + params.guest_delegate->GetOwnerWebContents()); + } + + // To support multi-network feature in chrome (e.g. want to open a tab over + // a specific network such as Wi-Fi while the current default network is + // cellular connection), a feasible solution would be to associate the target + // network handle to WebContents on creation time and MUST set it before + // WebContents initialization, otherwise the renderer might create a + // URLLoaderFactory that won't load the resources from the target network + // handle during WebContents initialization below, as a result, it will end + // up with a URLLoaderFactory that has not been bound to the target network. + new_contents->target_network_ = params.target_network; + + new_contents->Init(params, frame_policy); + if (outer_web_contents) { + outer_web_contents->InnerWebContentsCreated(new_contents.get()); + } + return new_contents; +} + +// static +std::vector WebContentsImpl::GetAllWebContents() { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::GetAllWebContents"); + std::vector result; + std::unique_ptr widgets( + RenderWidgetHostImpl::GetRenderWidgetHosts()); + while (RenderWidgetHost* rwh = widgets->GetNextHost()) { + RenderViewHost* rvh = RenderViewHost::From(rwh); + if (!rvh) { + continue; + } + WebContents* web_contents = WebContents::FromRenderViewHost(rvh); + if (!web_contents) { + continue; + } + if (web_contents->GetPrimaryMainFrame()->GetRenderViewHost() != rvh) { + continue; + } + // Because a WebContents can only have one current RVH at a time, there will + // be no duplicate WebContents here. + result.push_back(static_cast(web_contents)); + } + return result; +} + +// static +WebContentsImpl* WebContentsImpl::FromFrameTreeNode( + const FrameTreeNode* frame_tree_node) { + OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::FromFrameTreeNode", "frame_tree_node", + static_cast(frame_tree_node)); + return static_cast( + WebContents::FromRenderFrameHost(frame_tree_node->current_frame_host())); +} + +// static +WebContents* WebContentsImpl::FromRenderFrameHostID( + GlobalRenderFrameHostId render_frame_host_id) { + OPTIONAL_TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::FromRenderFrameHostID", "process_id", + render_frame_host_id.child_id, "frame_id", + render_frame_host_id.frame_routing_id); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || + !BrowserThread::IsThreadInitialized(BrowserThread::UI)); + RenderFrameHost* render_frame_host = + RenderFrameHost::FromID(render_frame_host_id); + if (!render_frame_host) { + return nullptr; + } + + return WebContents::FromRenderFrameHost(render_frame_host); +} + +// static +WebContents* WebContentsImpl::FromRenderFrameHostID(int render_process_host_id, + int render_frame_host_id) { + return FromRenderFrameHostID( + GlobalRenderFrameHostId(render_process_host_id, render_frame_host_id)); +} + +// static +WebContentsImpl* WebContentsImpl::FromOuterFrameTreeNode( + const FrameTreeNode* frame_tree_node) { + OPTIONAL_TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::FromOuterFrameTreeNode", + "frame_tree_node", + static_cast(frame_tree_node)); + return WebContentsImpl::FromFrameTreeNode(frame_tree_node) + ->node_.GetInnerWebContentsInFrame(frame_tree_node); +} + +bool WebContentsImpl::OnMessageReceived(RenderFrameHostImpl* render_frame_host, + const IPC::Message& message) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnMessageReceived", + "render_frame_host", render_frame_host); + + for (auto& observer : observers_.observer_list()) { + if (observer.OnMessageReceived(message, render_frame_host)) { + return true; + } + } + + return false; +} + +std::string WebContentsImpl::GetTitleForMediaControls() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GetTitleForMediaControls"); + + if (!delegate_) { + return std::string(); + } + return delegate_->GetTitleForMediaControls(this); +} + +// Returns the NavigationController for the primary FrameTree, i.e. the one +// whose URL is shown in the omnibox. With MPArch we can have multiple +// FrameTrees in one WebContents and each has its own NavigationController. +// TODO(crbug.com/40165692): Make sure callers are aware of this. +NavigationControllerImpl& WebContentsImpl::GetController() { + return primary_frame_tree_.controller(); +} + +BrowserContext* WebContentsImpl::GetBrowserContext() { + return GetController().GetBrowserContext(); +} + +base::WeakPtr WebContentsImpl::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + +const GURL& WebContentsImpl::GetURL() { + return GetVisibleURL(); +} + +const GURL& WebContentsImpl::GetVisibleURL() { + // We may not have a navigation entry yet. + NavigationEntry* entry = GetController().GetVisibleEntry(); + return entry ? entry->GetVirtualURL() : GURL::EmptyGURL(); +} + +const GURL& WebContentsImpl::GetLastCommittedURL() { + // We may not have a navigation entry yet. + NavigationEntry* entry = GetController().GetLastCommittedEntry(); + return entry ? entry->GetVirtualURL() : GURL::EmptyGURL(); +} + +WebContentsDelegate* WebContentsImpl::GetDelegate() { + return delegate_; +} + +void WebContentsImpl::SetDelegate(WebContentsDelegate* delegate) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetDelegate", "delegate", + static_cast(delegate)); + // TODO(cbentzel): remove this debugging code? + if (delegate == delegate_) { + return; + } + const bool had_delegate = !!delegate_; + if (had_delegate) { + delegate_->Detach(this); + } + delegate_ = delegate; + if (delegate_) { + delegate_->Attach(this); + // RenderFrameDevToolsAgentHost should not be told about the WebContents + // until there is a `delegate_`. + if (!had_delegate) { + RenderFrameDevToolsAgentHost::AttachToWebContents(this); + } + } + + // Re-read values from the new delegate and apply them. + if (view_) { + view_->SetOverscrollControllerEnabled(CanOverscrollContent()); + } +} + +const RenderFrameHostImpl* WebContentsImpl::GetPrimaryMainFrame() const { + return primary_frame_tree_.root()->current_frame_host(); +} + +RenderFrameHostImpl* WebContentsImpl::GetPrimaryMainFrame() { + return const_cast( + std::as_const(*this).GetPrimaryMainFrame()); +} + +PageImpl& WebContentsImpl::GetPrimaryPage() { + // We should not be accessing Page during the destruction of this WebContents, + // as the Page has already been cleared. + // + // Please note that IsBeingDestroyed() should be checked to ensure that we + // don't access Page related data that is going to be destroyed. + CHECK(primary_frame_tree_.root()->current_frame_host()); + return primary_frame_tree_.root()->current_frame_host()->GetPage(); +} + +RenderFrameHostImpl* WebContentsImpl::GetFocusedFrame() { + // If this method is called on an inner WebContents, don't return frames from + // outside of the inner WebContents's subtree. + if (GetOuterWebContents() && !ContainsOrIsFocusedWebContents()) { + return nullptr; + } + + FrameTreeNode* focused_node = GetFocusedFrameTree()->GetFocusedFrame(); + if (!focused_node) { + return nullptr; + } + + // If an inner frame tree has focus, we should return a RenderFrameHost from + // the inner frame tree and not the placeholder RenderFrameHost. + DCHECK_EQ( + focused_node->current_frame_host()->inner_tree_main_frame_tree_node_id(), + FrameTreeNode::kFrameTreeNodeInvalidId); + + return focused_node->current_frame_host(); +} + +bool WebContentsImpl::IsPrerenderedFrame(int frame_tree_node_id) { + if (frame_tree_node_id == RenderFrameHost::kNoFrameTreeNodeId) { + return false; + } + + FrameTreeNode* frame_tree_node = + FrameTreeNode::GloballyFindByID(frame_tree_node_id); + if (!frame_tree_node) { + return false; + } + + // In the case of inner frame trees in a prerender, the inner frame tree's + // type, would not be FrameTree::Type::kPrerender. So if this is not the + // outermost frame, we use the lifecycle state of the document that owns this. + // TODO(1196715, 1232528): This relies on the LifecycleState being correct + // in the case of inner frame trees. + if (frame_tree_node->GetParentOrOuterDocumentOrEmbedder()) { + return frame_tree_node->GetParentOrOuterDocumentOrEmbedder() + ->lifecycle_state() == + RenderFrameHostImpl::LifecycleStateImpl::kPrerendering; + } + return frame_tree_node->GetFrameType() == FrameType::kPrerenderMainFrame; +} + +RenderFrameHostImpl* WebContentsImpl::UnsafeFindFrameByFrameTreeNodeId( + int frame_tree_node_id) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::UnsafeFindFrameByFrameTreeNodeId", + "frame_tree_node_id", frame_tree_node_id); + // Beware using this! The RenderFrameHost may have changed since the caller + // obtained frame_tree_node_id. + FrameTreeNode* ftn = FrameTreeNode::GloballyFindByID(frame_tree_node_id); + if (!ftn) { + return nullptr; + } + if (this != WebContents::FromRenderFrameHost(ftn->current_frame_host())) { + return nullptr; + } + return ftn->current_frame_host(); +} + +void WebContentsImpl::ForEachRenderFrameHostWithAction( + base::FunctionRef on_frame) { + ForEachRenderFrameHostWithAction( + [on_frame](RenderFrameHostImpl* rfh) { return on_frame(rfh); }); +} + +void WebContentsImpl::ForEachRenderFrameHost( + base::FunctionRef on_frame) { + ForEachRenderFrameHost( + [on_frame](RenderFrameHostImpl* rfh) { on_frame(rfh); }); +} + +void WebContentsImpl::ForEachRenderFrameHostWithAction( + base::FunctionRef on_frame) { + ForEachRenderFrameHostImpl(on_frame, /* include_speculative */ false); +} + +void WebContentsImpl::ForEachRenderFrameHost( + base::FunctionRef on_frame) { + ForEachRenderFrameHostWithAction([on_frame](RenderFrameHostImpl* rfh) { + on_frame(rfh); + return FrameIterationAction::kContinue; + }); +} + +void WebContentsImpl::ForEachRenderFrameHostIncludingSpeculativeWithAction( + base::FunctionRef on_frame) { + ForEachRenderFrameHostImpl(on_frame, /* include_speculative */ true); +} + +void WebContentsImpl::ForEachRenderFrameHostIncludingSpeculative( + base::FunctionRef on_frame) { + ForEachRenderFrameHostIncludingSpeculativeWithAction( + [on_frame](RenderFrameHostImpl* rfh) { + on_frame(rfh); + return FrameIterationAction::kContinue; + }); +} + +void WebContentsImpl::ForEachRenderFrameHostImpl( + base::FunctionRef on_frame, + bool include_speculative) { + // Since |RenderFrameHostImpl::ForEachRenderFrameHost| will reach the + // RenderFrameHosts descending from a specified root, it is enough to start + // iteration from each of the outermost main frames to reach everything in + // this WebContents. However, if iteration stops early in + // |RenderFrameHostImpl::ForEachRenderFrameHost|, we also need to stop early + // by not iterating over additional outermost main frames. + bool iteration_stopped = false; + auto on_frame_with_termination = + [on_frame, &iteration_stopped](RenderFrameHostImpl* rfh) { + const auto action = on_frame(rfh); + if (action == FrameIterationAction::kStop) { + iteration_stopped = true; + } + return action; + }; + + for (auto* rfh : GetOutermostMainFrames()) { + if (include_speculative) { + rfh->ForEachRenderFrameHostIncludingSpeculativeWithAction( + on_frame_with_termination); + } else { + rfh->ForEachRenderFrameHostWithAction(on_frame_with_termination); + } + + if (iteration_stopped) { + return; + } + } +} + +void WebContentsImpl::ForEachFrameTree( + FrameTreeIterationCallback on_frame_tree) { + // Consider all outermost frame trees, and for each, iterate through their + // FrameTreeNodes to find any inner frame trees. + for (FrameTree* outermost_frame_tree : GetOutermostFrameTrees()) { + FrameTree::NodeRange node_range = + outermost_frame_tree->NodesIncludingInnerTreeNodes(); + FrameTree::NodeIterator node_iter = node_range.begin(); + while (node_iter != node_range.end()) { + FrameTreeNode* node = *node_iter; + if (FromFrameTreeNode(node) != this) { + // Exclude any inner frame trees based on multi-WebContents + // architecture. + node_iter.AdvanceSkippingChildren(); + } else { + if (node->IsMainFrame()) { + on_frame_tree.Run(node->frame_tree()); + } + ++node_iter; + } + } + } +} + +std::vector WebContentsImpl::GetOutermostFrameTrees() { + // If the WebContentsImpl is being destroyed, then we should not + // perform the tree traversal. + if (IsBeingDestroyed()) { + return {}; + } + + std::vector result; + result.push_back(&GetPrimaryFrameTree()); + + const std::vector prerender_frame_trees = + GetPrerenderHostRegistry()->GetPrerenderFrameTrees(); + result.insert(result.end(), prerender_frame_trees.begin(), + prerender_frame_trees.end()); + + return result; +} + +std::vector WebContentsImpl::GetOutermostMainFrames() { + // Do nothing if the WebContents is currently being initialized or destroyed. + if (!GetPrimaryMainFrame()) { + return {}; + } + + std::vector result; + + for (FrameTree* outermost_frame_tree : GetOutermostFrameTrees()) { + DCHECK(outermost_frame_tree->GetMainFrame()); + result.push_back(outermost_frame_tree->GetMainFrame()); + } + + for (const auto& entry : GetController().GetBackForwardCache().GetEntries()) { + result.push_back(entry->render_frame_host()); + } + + // In the case of inner WebContents, we still allow this method to be called, + // but the semantics of the values being returned are "outermost + // within this WebContents" as opposed to truly outermost. We would not expect + // any other outermost pages besides the primary page in the case of inner + // WebContents. + DCHECK(!GetOuterWebContents() || (result.size() == 1)); + + return result; +} + +void WebContentsImpl::ExecutePageBroadcastMethod( + PageBroadcastMethodCallback callback) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::ExecutePageBroadcastMethod"); + primary_frame_tree_.root()->render_manager()->ExecutePageBroadcastMethod( + callback); +} + +void WebContentsImpl::ExecutePageBroadcastMethodForAllPages( + PageBroadcastMethodCallback callback) { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::ExecutePageBroadcastMethodForAllPages"); + ForEachFrameTree(base::BindRepeating( + [](PageBroadcastMethodCallback* callback, FrameTree& frame_tree) { + frame_tree.root()->render_manager()->ExecutePageBroadcastMethod( + *callback); + }, + &callback)); +} + +RenderViewHostImpl* WebContentsImpl::GetRenderViewHost() { + return GetRenderManager()->current_frame_host()->render_view_host(); +} + +void WebContentsImpl::CancelActiveAndPendingDialogs() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::CancelActiveAndPendingDialogs"); + if (dialog_manager_) { + dialog_manager_->CancelDialogs(this, /*reset_state=*/false); + } + if (browser_plugin_embedder_) { + browser_plugin_embedder_->CancelGuestDialogs(); + } +} + +void WebContentsImpl::ClosePage() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ClosePage"); + GetPrimaryMainFrame()->ClosePage( + RenderFrameHostImpl::ClosePageSource::kBrowser); +} + +RenderWidgetHostView* WebContentsImpl::GetRenderWidgetHostView() { + return GetRenderManager()->GetRenderWidgetHostView(); +} + +RenderWidgetHostView* WebContentsImpl::GetTopLevelRenderWidgetHostView() { + if (GetOuterWebContents()) { + return GetOuterWebContents()->GetTopLevelRenderWidgetHostView(); + } + return GetRenderManager()->GetRenderWidgetHostView(); +} + +WebContentsView* WebContentsImpl::GetView() const { + return view_.get(); +} + +void WebContentsImpl::OnScreensChange(bool is_multi_screen_changed) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnScreensChange", + "is_multi_screen_changed", is_multi_screen_changed); + // Allow fullscreen requests shortly after user-generated screens changes. + // TODO(crbug.com/40165350): Mac should not activate this on local process + // display::Screen signals, but via RenderWidgetHostViewMac screen updates. + if (base::FeatureList::IsEnabled( + blink::features::kWindowPlacementFullscreenOnScreensChange)) { + transient_allow_fullscreen_.Activate(); + } + + // Mac display info may originate from a remote process hosting the NSWindow; + // this local process display::Screen signal should not trigger updates. + // TODO(crbug.com/40165350): Unify screen info plumbing, caching, etc. +#if !BUILDFLAG(IS_MAC) + // This updates Screen attributes and fires Screen.change events as needed, + // propagating to all widgets through the VisualProperties update waterfall. + // This is triggered by system changes, not renderer IPC, so explicitly check + // that the RenderWidgetHostView is valid before sending an update. + if (RenderWidgetHostViewBase* view = + GetRenderViewHost()->GetWidget()->GetView()) { + // Only update top-level views, as child frames will have their ScreenInfos + // updated by the visual property flow. + if (!view->IsRenderWidgetHostViewChildFrame()) { + view->UpdateScreenInfo(); + } + } +#endif // !BUILDFLAG(IS_MAC) +} + +void WebContentsImpl::OnScreenOrientationChange() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::OnScreenOrientationChange"); + DCHECK(screen_orientation_provider_); + DidChangeScreenOrientation(); + screen_orientation_provider_->OnOrientationChange(); +} + +std::optional WebContentsImpl::GetThemeColor() { + return GetPrimaryPage().theme_color(); +} + +std::optional WebContentsImpl::GetBackgroundColor() { + return GetPrimaryPage().background_color(); +} + +void WebContentsImpl::SetPageBaseBackgroundColor(std::optional color) { + if (page_base_background_color_ == color) { + return; + } + page_base_background_color_ = color; + ExecutePageBroadcastMethod(base::BindRepeating( + [](std::optional color, RenderViewHostImpl* rvh) { + // Null `broadcast` can happen before view is created on the renderer + // side, in which case this color will be sent in CreateView. + if (auto& broadcast = rvh->GetAssociatedPageBroadcast()) { + broadcast->SetPageBaseBackgroundColor(color); + } + }, + page_base_background_color_)); +} + +void WebContentsImpl::SetColorProviderSource(ui::ColorProviderSource* source) { + ColorProviderSourceObserver::Observe(source); +} + +ui::ColorProviderKey::ColorMode WebContentsImpl::GetColorMode() const { + // A ColorProviderSource should always be set. + auto* source = GetColorProviderSource(); + CHECK(source); + return source->GetColorMode(); +} + +void WebContentsImpl::SetAccessibilityMode(ui::AXMode mode) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetAccessibilityMode", + "mode", mode.ToString(), "previous_mode", + accessibility_mode_.ToString()); + + if (unrecoverable_accessibility_error_) { + DUMP_WILL_BE_CHECK(accessibility_mode_.is_mode_off()); + return; + } + + if (mode == accessibility_mode_) { + return; + } + + // Don't allow accessibility to be enabled for WebContents that are never + // user-visible, like background pages. + if (IsNeverComposited()) { + return; + } + + accessibility_mode_ = mode; + + // Update state for all frames in this tree and inner trees, including + // speculative frame hosts and those in the back-forward cache. Take care not + // to touch frame hosts that belong to another WebContents (e.g., guest views) + // -- it is the responsibility of other WebContents' to update their own + // frames. Note that content::BrowserAccessibilityState will propagate mode + // flag changes that target the whole process (CreateScopedModeForProcess) or + // a BrowserContext (CreateScopedModeForBrowserContext) to all relevant + // WebContents, so inner WebContents will automatically receive the same mode + // flag changes. In cases where mode flag changes apply to a specific + // WebContents (via CreateScopedModeForWebContents), it is the responsibility + // of the owner of the ScopedAccessibilityMode to choose whether or not to + // create scopers for inner WebContents. + ForEachRenderFrameHostIncludingSpeculativeWithAction( + [this](RenderFrameHostImpl* frame_host) { + if (WebContentsImpl::FromRenderFrameHostImpl(frame_host) == this) { + frame_host->UpdateAccessibilityMode(); + return FrameIterationAction::kContinue; + } + return FrameIterationAction::kSkipChildren; + }); +} + +void WebContentsImpl::DidCapturedSurfaceControl() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + observers_.NotifyObservers(&WebContentsObserver::OnCapturedSurfaceControl); +} + +void WebContentsImpl::ResetAccessibility() { + // In contrast to the above, do not bother with frames in the back-forward + // cache since the reset is intended to generate new trees for observers of + // active frames. + GetPrimaryMainFrame()->ForEachRenderFrameHostIncludingSpeculative( + [this](RenderFrameHostImpl* frame_host) { + if (WebContentsImpl::FromRenderFrameHostImpl(frame_host) == this) { + frame_host->AccessibilityReset(); + } + }); +} + +void WebContentsImpl::AddAccessibilityModeForTesting(ui::AXMode mode) { + ui::AXMode new_mode(accessibility_mode_); + new_mode |= mode; + SetAccessibilityMode(new_mode); +} + +// Helper class used by WebContentsImpl::RequestAXTreeSnapshot. +// Handles the callbacks from parallel snapshot requests to each frame, +// and feeds the results to an AXTreeCombiner, which converts them into a +// single combined accessibility tree. +class AXTreeSnapshotCombiner : public base::RefCounted { + public: + AXTreeSnapshotCombiner(WebContents::AXTreeSnapshotCallback callback, + mojom::SnapshotAccessibilityTreeParamsPtr params) + : callback_(std::move(callback)), params_(std::move(params)) {} + + WebContents::AXTreeSnapshotCallback AddFrame(bool is_root) { + // Adds a reference to |this|. + return base::BindOnce(&AXTreeSnapshotCombiner::ReceiveSnapshot, this, + is_root); + } + + void ReceiveSnapshot(bool is_root, const ui::AXTreeUpdate& snapshot) { + combiner_.AddTree(snapshot, is_root); + } + + void AXTreeSnapshotOnFrame(RenderFrameHostImpl* rfhi) { + OPTIONAL_TRACE_EVENT0("content", + "AXTreeSnapshotCombiner::AXTreeSnapshotOnFrame"); + bool is_root = rfhi->AccessibilityIsRootFrame(); + rfhi->RequestAXTreeSnapshot(AddFrame(is_root), params_.Clone()); + } + + private: + friend class base::RefCounted; + + // This is called automatically after the last call to ReceiveSnapshot + // when there are no more references to this object. + ~AXTreeSnapshotCombiner() { + combiner_.Combine(); + std::move(callback_).Run(combiner_.combined()); + } + + ui::AXTreeCombiner combiner_; + WebContents::AXTreeSnapshotCallback callback_; + mojom::SnapshotAccessibilityTreeParamsPtr params_; +}; + +void WebContentsImpl::RequestAXTreeSnapshot(AXTreeSnapshotCallback callback, + ui::AXMode ax_mode, + size_t max_nodes, + base::TimeDelta timeout, + AXTreeSnapshotPolicy policy) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RequestAXTreeSnapshot", + "mode", ax_mode.ToString()); + // Send a request to each of the frames in parallel. Each one will return + // an accessibility tree snapshot, and AXTreeSnapshotCombiner will combine + // them into a single tree and call |callback| with that result, then + // delete |combiner|. + auto params = mojom::SnapshotAccessibilityTreeParams::New(); + params->ax_mode = ax_mode.flags(); + params->max_nodes = max_nodes; + params->timeout = timeout; + + auto combiner = base::MakeRefCounted( + std::move(callback), std::move(params)); + GetPrimaryMainFrame()->ForEachRenderFrameHostWithAction( + [this, &combiner, policy](RenderFrameHostImpl* rfh) { + switch (policy) { + case AXTreeSnapshotPolicy::kAll: + break; + case AXTreeSnapshotPolicy::kSameOriginDirectDescendants: + if (GetPrimaryMainFrame()->GetSiteInstance() != + rfh->GetSiteInstance() || + rfh->IsFencedFrameRoot() || + !GetPrimaryMainFrame() + ->GetLastCommittedOrigin() + .IsSameOriginWith(rfh->GetLastCommittedOrigin())) { + return FrameIterationAction::kSkipChildren; + } + break; + } + combiner->AXTreeSnapshotOnFrame(rfh); + return FrameIterationAction::kContinue; + }); +} + +void WebContentsImpl::NotifyViewportFitChanged( + blink::mojom::ViewportFit value) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::NotifyViewportFitChanged", + "value", static_cast(value)); + observers_.NotifyObservers(&WebContentsObserver::ViewportFitChanged, value); +} + +FindRequestManager* WebContentsImpl::GetFindRequestManagerForTesting() { + return GetOrCreateFindRequestManager(); +} + +void WebContentsImpl::UpdateZoom() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::UpdateZoom"); + RenderWidgetHostImpl* rwh = GetRenderViewHost()->GetWidget(); + if (rwh->GetView()) { + rwh->SynchronizeVisualProperties(); + } +} + +void WebContentsImpl::UpdateZoomIfNecessary(const std::string& scheme, + const std::string& host) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::UpdateZoomIfNecessary", + "scheme", scheme, "host", host); + NavigationEntry* entry = GetController().GetLastCommittedEntry(); + if (!entry) { + return; + } + + GURL url = HostZoomMap::GetURLFromEntry(entry); + if (host != net::GetHostOrSpecFromURL(url) || + (!scheme.empty() && !url.SchemeIs(scheme))) { + return; + } + + UpdateZoom(); +} + +std::vector WebContentsImpl::GetWebContentsAndAllInner() { + std::vector all_contents(1, this); + + for (size_t i = 0; i != all_contents.size(); ++i) { + for (auto* inner_contents : all_contents[i]->GetInnerWebContents()) { + all_contents.push_back(static_cast(inner_contents)); + } + } + + return all_contents; +} + +void WebContentsImpl::OnManifestUrlChanged(PageImpl& page) { + std::optional manifest_url = page.GetManifestUrl(); + if (!manifest_url.has_value()) { + return; + } + + if (!page.IsPrimary()) { + return; + } + + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::NotifyManifestUrlChanged", + "render_frame_host", &page.GetMainDocument(), + "manifest_url", manifest_url); + observers_.NotifyObservers(&WebContentsObserver::DidUpdateWebManifestURL, + &page.GetMainDocument(), *manifest_url); +} + +WebUI* WebContentsImpl::GetWebUI() { + return primary_frame_tree_.root()->current_frame_host()->web_ui(); +} + +void WebContentsImpl::SetAlwaysSendSubresourceNotifications() { + if (!base::FeatureList::IsEnabled( + features::kReduceSubresourceResponseStartedIPC)) { + return; + } + + if (GetSendSubresourceNotification()) { + return; + } + + // Updates all the renderers if the user allows certificate error or HTTP + // exception, but doesn't update renderers when all exceptions are revoked + // from all hosts since this causes superfluous IPCs. + for (WebContentsImpl* web_contents : GetAllWebContents()) { + DCHECK(!web_contents->GetSendSubresourceNotification()); + web_contents->renderer_preferences_.send_subresource_notification = true; + web_contents->SyncRendererPrefs(); + } +} + +bool WebContentsImpl::GetSendSubresourceNotification() { + return GetRendererPrefs().send_subresource_notification; +} + +void WebContentsImpl::SetUserAgentOverride( + const blink::UserAgentOverride& ua_override, + bool override_in_new_tabs) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetUserAgentOverride", + "ua_override", ua_override.ua_string_override, + "override_in_new_tabs", override_in_new_tabs); + DCHECK(!ua_override.ua_metadata_override.has_value() || + !ua_override.ua_string_override.empty()); + + if (GetUserAgentOverride() == ua_override) { + return; + } + + if (!ua_override.ua_string_override.empty() && + !net::HttpUtil::IsValidHeaderValue(ua_override.ua_string_override)) { + return; + } + + should_override_user_agent_in_new_tabs_ = override_in_new_tabs; + + // Update any in-flight load requests with overrides for new tabs. + if (delayed_load_url_params_.get()) { + delayed_load_url_params_->override_user_agent = + override_in_new_tabs ? NavigationController::UA_OVERRIDE_TRUE + : NavigationController::UA_OVERRIDE_FALSE; + } + + renderer_preferences_.user_agent_override = ua_override; + + // Send the new override string to all renderers in the current page. + SyncRendererPrefs(); + + // Reload the page if a load is currently in progress to avoid having + // different parts of the page loaded using different user agents. + // No need to reload if the current entry matches that of the + // NavigationRequest supplied to DidStartNavigation() as NavigationRequest + // handles it. + ForEachFrameTree(base::BindRepeating([](FrameTree& frame_tree) { + // For prerendering, we don't want to activate a prerendered page loaded + // with a stale UA and will handle it even if it finishes loading. + if (!frame_tree.IsLoadingIncludingInnerFrameTrees() && + !frame_tree.is_prerendering()) { + return; + } + + NavigationEntry* entry = frame_tree.controller().GetVisibleEntry(); + if (!entry || !entry->GetIsOverridingUserAgent()) { + return; + } + if (frame_tree.root()->navigation_request() && + !frame_tree.root()->navigation_request()->ua_change_requires_reload()) { + return; + } + if (frame_tree.is_prerendering()) { + // Just cancel if the FrameTree is for prerendering, as prerendered + // page may not allow another navigation including a reload, depending + // on conditions. + frame_tree.GetMainFrame()->CancelPrerendering(PrerenderCancellationReason( + PrerenderFinalStatus::kUaChangeRequiresReload)); + } else { + frame_tree.controller().Reload(ReloadType::BYPASSING_CACHE, true); + } + })); + + observers_.NotifyObservers(&WebContentsObserver::UserAgentOverrideSet, + ua_override); +} + +void WebContentsImpl::SetRendererInitiatedUserAgentOverrideOption( + NavigationController::UserAgentOverrideOption option) { + OPTIONAL_TRACE_EVENT0( + "content", + "WebContentsImpl::SetRendererInitiatedUserAgentOverrideOption"); + renderer_initiated_user_agent_override_option_ = option; +} + +const blink::UserAgentOverride& WebContentsImpl::GetUserAgentOverride() { + return renderer_preferences_.user_agent_override; +} + +bool WebContentsImpl::ShouldOverrideUserAgentForRendererInitiatedNavigation() { + NavigationEntryImpl* current_entry = GetController().GetLastCommittedEntry(); + if (!current_entry || current_entry->IsInitialEntry()) { + return should_override_user_agent_in_new_tabs_; + } + + switch (renderer_initiated_user_agent_override_option_) { + case NavigationController::UA_OVERRIDE_INHERIT: + return current_entry->GetIsOverridingUserAgent(); + case NavigationController::UA_OVERRIDE_TRUE: + return true; + case NavigationController::UA_OVERRIDE_FALSE: + return false; + default: + break; + } + return false; +} + +bool WebContentsImpl::IsWebContentsOnlyAccessibilityModeForTesting() { + return accessibility_mode_ == ui::kAXModeWebContentsOnly; +} + +bool WebContentsImpl::IsFullAccessibilityModeForTesting() { + return accessibility_mode_ == ui::kAXModeComplete; +} + +#if BUILDFLAG(IS_ANDROID) + +void WebContentsImpl::SetDisplayCutoutSafeArea(gfx::Insets insets) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetDisplayCutoutSafeArea"); + if (safe_area_insets_host_) { + safe_area_insets_host_->SetDisplayCutoutSafeArea(insets); + } +} + +#endif + +const std::u16string& WebContentsImpl::GetTitle() { + WebUI* our_web_ui = + GetRenderManager()->speculative_frame_host() + ? GetRenderManager()->speculative_frame_host()->web_ui() + : GetRenderManager()->current_frame_host()->web_ui(); + if (our_web_ui) { + // Don't override the title in view source mode. + NavigationEntry* entry = GetController().GetVisibleEntry(); + if (!(entry && entry->IsViewSourceMode())) { + // Give the Web UI the chance to override our title. + const std::u16string& title = our_web_ui->GetOverriddenTitle(); + if (!title.empty()) { + return title; + } + } + } + + return GetNavigationEntryForTitle()->GetTitleForDisplay(); +} + +const std::u16string& WebContentsImpl::GetAppTitle() { + return GetNavigationEntryForTitle()->GetAppTitle(); +} + +SiteInstanceImpl* WebContentsImpl::GetSiteInstance() { + return GetRenderManager()->current_frame_host()->GetSiteInstance(); +} + +bool WebContentsImpl::IsLoading() { + return primary_frame_tree_.IsLoadingIncludingInnerFrameTrees(); +} + +double WebContentsImpl::GetLoadProgress() { + // TODO(crbug.com/40177943): Make this MPArch friendly considering primary + // frame tree and its descendants. + return primary_frame_tree_.GetLoadProgress(); +} + +bool WebContentsImpl::ShouldShowLoadingUI() { + return primary_frame_tree_.GetLoadingState() == + LoadingState::LOADING_UI_REQUESTED; +} + +bool WebContentsImpl::IsDocumentOnLoadCompletedInPrimaryMainFrame() { + // TODO(mparch): This should be moved to Page, and callers should use it + // directly. + return GetPrimaryPage().is_on_load_completed_in_main_document(); +} + +bool WebContentsImpl::IsWaitingForResponse() { + NavigationRequest* ongoing_navigation_request = + primary_frame_tree_.root()->navigation_request(); + + // An ongoing navigation request means we're waiting for a response. + return ongoing_navigation_request != nullptr; +} + +bool WebContentsImpl::HasUncommittedNavigationInPrimaryMainFrame() { + return primary_frame_tree_.root()->HasNavigation(); +} + +const net::LoadStateWithParam& WebContentsImpl::GetLoadState() { + return load_state_; +} + +const std::u16string& WebContentsImpl::GetLoadStateHost() { + return load_state_host_; +} + +uint64_t WebContentsImpl::GetUploadSize() { + return upload_size_; +} + +uint64_t WebContentsImpl::GetUploadPosition() { + return upload_position_; +} + +const std::string& WebContentsImpl::GetEncoding() { + return GetPrimaryPage().GetEncoding(); +} + +bool WebContentsImpl::WasDiscarded() { + return GetPrimaryFrameTree().root()->was_discarded(); +} + +void WebContentsImpl::SetWasDiscarded(bool was_discarded) { + // It's set based on a tab and the setting value is started from a primary + // tree and propagated to all children nodes including a fenced frame node. + GetPrimaryFrameTree().root()->set_was_discarded(); +} + +base::ScopedClosureRunner WebContentsImpl::IncrementCapturerCount( + const gfx::Size& capture_size, + bool stay_hidden, + bool stay_awake, + bool is_activity) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::IncrementCapturerCount"); + DCHECK(!IsBeingDestroyed()); + if (stay_hidden) { + // A hidden capture should not have side effect on the web contents, so it + // should not pass a non-empty |capture_size| which will cause side effect. + DCHECK(capture_size.IsEmpty()); + ++hidden_capturer_count_; + } else { + ++visible_capturer_count_; + } + + if (stay_awake) { + ++stay_awake_capturer_count_; + } + + view_->OnCapturerCountChanged(); + + // Note: This provides a hint to upstream code to size the views optimally + // for quality (e.g., to avoid scaling). + if (!capture_size.IsEmpty() && preferred_size_for_capture_.IsEmpty()) { + preferred_size_for_capture_ = capture_size; + OnPreferredSizeChanged(preferred_size_); + } + + if (!capture_wake_lock_ && stay_awake_capturer_count_) { + if (auto* wake_lock_context = GetWakeLockContext()) { + auto receiver = capture_wake_lock_.BindNewPipeAndPassReceiver(); + wake_lock_context->GetWakeLock( + device::mojom::WakeLockType::kPreventDisplaySleepAllowDimming, + device::mojom::WakeLockReason::kOther, "Capturing", + std::move(receiver)); + } + } + + if (capture_wake_lock_) { + capture_wake_lock_->RequestWakeLock(); + } + + UpdateVisibilityAndNotifyPageAndView(GetVisibility(), is_activity); + + return base::ScopedClosureRunner(base::BindOnce( + &WebContentsImpl::DecrementCapturerCount, weak_factory_.GetWeakPtr(), + stay_hidden, stay_awake, is_activity)); +} + +const blink::mojom::CaptureHandleConfig& +WebContentsImpl::GetCaptureHandleConfig() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + return capture_handle_config_; +} + +bool WebContentsImpl::IsBeingCaptured() { + return visible_capturer_count_ + hidden_capturer_count_ > 0; +} + +bool WebContentsImpl::IsBeingVisiblyCaptured() { + return visible_capturer_count_ > 0; +} + +bool WebContentsImpl::IsAudioMuted() { + return audio_stream_factory_ && audio_stream_factory_->IsMuted(); +} + +void WebContentsImpl::SetAudioMuted(bool mute) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetAudioMuted", "mute", + mute); + DVLOG(1) << "SetAudioMuted(mute=" << mute << "), was " << IsAudioMuted() + << " for WebContentsImpl@" << this; + + if (mute == IsAudioMuted()) { + return; + } + + GetAudioStreamFactory()->SetMuted(mute); + + observers_.NotifyObservers(&WebContentsObserver::DidUpdateAudioMutingState, + mute); + // Notification for UI updates in response to the changed muting state. + NotifyNavigationStateChanged(INVALIDATE_TYPE_AUDIO); +} + +bool WebContentsImpl::IsCurrentlyAudible() { + return is_currently_audible_; +} + +bool WebContentsImpl::IsConnectedToBluetoothDevice() { + return bluetooth_connected_device_count_ > 0; +} + +bool WebContentsImpl::IsScanningForBluetoothDevices() { + return bluetooth_scanning_sessions_count_ > 0; +} + +bool WebContentsImpl::IsConnectedToSerialPort() { + return serial_active_frame_count_ > 0; +} + +bool WebContentsImpl::IsConnectedToHidDevice() { + return hid_active_frame_count_ > 0; +} + +bool WebContentsImpl::IsConnectedToUsbDevice() { + return usb_active_frame_count_ > 0; +} + +bool WebContentsImpl::HasFileSystemAccessHandles() { + return file_system_access_handle_count_ > 0; +} + +bool WebContentsImpl::HasPictureInPictureVideo() { + return has_picture_in_picture_video_; +} + +bool WebContentsImpl::HasPictureInPictureDocument() { + return has_picture_in_picture_document_; +} + +void WebContentsImpl::SetHasPictureInPictureCommon( + bool has_picture_in_picture) { + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + observers_.NotifyObservers(&WebContentsObserver::MediaPictureInPictureChanged, + has_picture_in_picture); + + // Picture-in-picture state can affect how we notify visibility for non- + // visible pages. + if (visibility_ != Visibility::VISIBLE) { + UpdateVisibilityAndNotifyPageAndView(visibility_); + } +} + +void WebContentsImpl::DisallowCustomCursorScopeExpired() { + --disallow_custom_cursor_scope_count_; +} + +void WebContentsImpl::SetHasPictureInPictureVideo( + bool has_picture_in_picture_video) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::SetHasPictureInPictureVideo", + "has_pip_video", has_picture_in_picture_video); + // If status of |this| is already accurate, there is no need to update. + if (has_picture_in_picture_video == has_picture_in_picture_video_) { + return; + } + has_picture_in_picture_video_ = has_picture_in_picture_video; + SetHasPictureInPictureCommon(has_picture_in_picture_video); +} + +void WebContentsImpl::SetHasPictureInPictureDocument( + bool has_picture_in_picture_document) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::SetHasPictureInPictureDocument", + "has_pip_document", has_picture_in_picture_document); + // If status of |this| is already accurate, there is no need to update. + if (has_picture_in_picture_document == has_picture_in_picture_document_) { + return; + } + has_picture_in_picture_document_ = has_picture_in_picture_document; + SetHasPictureInPictureCommon(has_picture_in_picture_document); +} + +bool WebContentsImpl::IsCrashed() { + switch (primary_main_frame_process_status_) { + case base::TERMINATION_STATUS_PROCESS_CRASHED: + case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: + case base::TERMINATION_STATUS_OOM: + case base::TERMINATION_STATUS_LAUNCH_FAILED: +#if BUILDFLAG(IS_CHROMEOS) + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: +#endif +#if BUILDFLAG(IS_ANDROID) + case base::TERMINATION_STATUS_OOM_PROTECTED: +#endif +#if BUILDFLAG(IS_WIN) + case base::TERMINATION_STATUS_INTEGRITY_FAILURE: +#endif + return true; + case base::TERMINATION_STATUS_NORMAL_TERMINATION: + case base::TERMINATION_STATUS_STILL_RUNNING: + return false; + case base::TERMINATION_STATUS_MAX_ENUM: + NOTREACHED_IN_MIGRATION(); + return false; + } + + NOTREACHED_IN_MIGRATION(); + return false; +} + +void WebContentsImpl::SetPrimaryMainFrameProcessStatus( + base::TerminationStatus status, + int error_code) { + OPTIONAL_TRACE_EVENT2("content", + "WebContentsImpl::SetPrimaryMainFrameProcessStatus", + "status", static_cast(status), "old_status", + static_cast(primary_main_frame_process_status_)); + if (status == primary_main_frame_process_status_) { + return; + } + + primary_main_frame_process_status_ = status; + primary_main_frame_process_error_code_ = error_code; + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); +} + +base::TerminationStatus WebContentsImpl::GetCrashedStatus() { + return primary_main_frame_process_status_; +} + +int WebContentsImpl::GetCrashedErrorCode() { + return primary_main_frame_process_error_code_; +} + +bool WebContentsImpl::IsBeingDestroyed() { + return is_being_destroyed_; +} + +void WebContentsImpl::NotifyNavigationStateChanged( + InvalidateTypes changed_flags) { + TRACE_EVENT1("content,navigation", + "WebContentsImpl::NotifyNavigationStateChanged", "changed_flags", + static_cast(changed_flags)); + // Notify the media observer of potential audibility changes. + if (changed_flags & INVALIDATE_TYPE_AUDIO) { + media_web_contents_observer_->MaybeUpdateAudibleState(); + } + + if (delegate_) { + delegate_->NavigationStateChanged(this, changed_flags); + } + + if (GetOuterWebContents()) { + GetOuterWebContents()->NotifyNavigationStateChanged(changed_flags); + } +} + +void WebContentsImpl::OnVerticalScrollDirectionChanged( + viz::VerticalScrollDirection scroll_direction) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::OnVerticalScrollDirectionChanged", + "scroll_direction", static_cast(scroll_direction)); + observers_.NotifyObservers( + &WebContentsObserver::DidChangeVerticalScrollDirection, scroll_direction); +} + +int WebContentsImpl::GetVirtualKeyboardResizeHeight() { + // Only consider a web contents to be insetted by the virtual keyboard if it + // is in the currently active tab. + if (GetVisibility() != Visibility::VISIBLE) { + return 0; + } + + // The only mode where the virtual keyboard causes the web contents to be + // resized is kResizesContent. + if (GetPrimaryPage().virtual_keyboard_mode() != + ui::mojom::VirtualKeyboardMode::kResizesContent) { + return 0; + } + + // The virtual keyboard never resizes content when fullscreened. + if (IsFullscreen()) { + return 0; + } + + return GetDelegate() ? GetDelegate()->GetVirtualKeyboardHeight(this) : 0; +} + +bool WebContentsImpl::ShouldDoLearning() { + return !GetBrowserContext()->IsOffTheRecord(); +} + +void WebContentsImpl::OnAudioStateChanged() { + // This notification can come from any embedded contents or from this + // WebContents' stream monitor. Aggregate these signals to get the actual + // state. + // + // Note that guests may not be attached as inner contents, and so may need to + // be checked separately. This intentionally does not do a recursive search, + // since the state is aggregated in each inner WebContents and reflects that + // whole subtree. + bool is_currently_audible = + audio_stream_monitor_.IsCurrentlyAudible() || + (browser_plugin_embedder_ && + browser_plugin_embedder_->AreAnyGuestsCurrentlyAudible()) || + base::ranges::any_of(GetInnerWebContents(), + [](WebContents* inner_contents) { + return inner_contents->IsCurrentlyAudible(); + }); + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnAudioStateChanged", + "is_currently_audible", is_currently_audible, + "was_audible", is_currently_audible_); + if (is_currently_audible == is_currently_audible_) { + return; + } + + // Update internal state. + is_currently_audible_ = is_currently_audible; + was_ever_audible_ = was_ever_audible_ || is_currently_audible_; + + ExecutePageBroadcastMethod(base::BindRepeating( + [](bool is_currently_audible, RenderViewHostImpl* rvh) { + if (auto& broadcast = rvh->GetAssociatedPageBroadcast()) { + broadcast->AudioStateChanged(is_currently_audible); + } + }, + is_currently_audible_)); + + // Notification for UI updates in response to the changed audio state. + NotifyNavigationStateChanged(INVALIDATE_TYPE_AUDIO); + + // Ensure that audio state changes propagate from innermost to outermost + // WebContents. + if (GetOuterWebContents()) { + GetOuterWebContents()->OnAudioStateChanged(); + } + + observers_.NotifyObservers(&WebContentsObserver::OnAudioStateChanged, + is_currently_audible_); +} + +base::TimeTicks WebContentsImpl::GetLastActiveTime() { + return last_active_time_; +} + +void WebContentsImpl::WasShown() { + TRACE_EVENT0("content", "WebContentsImpl::WasShown"); + UpdateVisibilityAndNotifyPageAndView(Visibility::VISIBLE); +} + +void WebContentsImpl::WasHidden() { + TRACE_EVENT0("content", "WebContentsImpl::WasHidden"); + UpdateVisibilityAndNotifyPageAndView(Visibility::HIDDEN); +} + +bool WebContentsImpl::HasRecentInteraction() { + if (last_interaction_time_.is_null()) { + return false; + } + + static constexpr base::TimeDelta kMaxInterval = base::Seconds(5); + base::TimeDelta delta = ui::EventTimeForNow() - last_interaction_time_; + // Note: the expectation is that the caller is typically expecting an input + // event, e.g. validating that a WebUI message that requires a gesture is + // actually attached to a gesture. + return delta <= kMaxInterval; +} + +WebContents::ScopedIgnoreInputEvents WebContentsImpl::IgnoreInputEvents( + std::optional audit_callback) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::IgnoreInputEvents"); + + uint64_t callback_id = 0; + if (audit_callback.has_value()) { + do { + callback_id = next_web_input_event_audit_callback_id_++; + } while (web_input_event_audit_callbacks_.contains(callback_id)); + web_input_event_audit_callbacks_[callback_id] = std::move(*audit_callback); + } else { + ++ignore_input_events_count_; + } + + // Bind weakly, since the token might outlive us. + return ScopedIgnoreInputEvents(base::BindOnce( + [](base::WeakPtr wc, + std::optional callback_id) { + if (wc) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::IgnoreInputEvents.Release"); + if (callback_id.has_value()) { + CHECK(wc->web_input_event_audit_callbacks_.contains(*callback_id)); + wc->web_input_event_audit_callbacks_.erase(*callback_id); + } else { + --wc->ignore_input_events_count_; + // Reset gesture detection so that we don't continue to generate new + // gestures from suppressed touches. These suppressed gestures would + // otherwise confuse the event stream validator when input is + // re-enabled. + if (wc->ignore_input_events_count_ == 0) { + if (auto* view = wc->GetRenderWidgetHostView()) { + static_cast(view) + ->ResetGestureDetection(); + } + } + } + } + }, + weak_factory_.GetWeakPtr(), + audit_callback.has_value() ? std::make_optional(callback_id) + : std::nullopt)); +} + +bool WebContentsImpl::HasActiveEffectivelyFullscreenVideo() { + return IsFullscreen() && + media_web_contents_observer_->HasActiveEffectivelyFullscreenVideo(); +} + +void WebContentsImpl::WriteIntoTrace(perfetto::TracedValue context) { + auto dict = std::move(context).WriteDictionary(); + dict.Add("root_frame_tree_node_id", + primary_frame_tree_.root()->frame_tree_node_id()); +} + +const base::Location& WebContentsImpl::GetCreatorLocation() { + return creator_location_; +} + +const std::optional& +WebContentsImpl::GetPictureInPictureOptions() const { + return picture_in_picture_options_; +} + +#if BUILDFLAG(IS_ANDROID) +void WebContentsImpl::SetPrimaryMainFrameImportance( + ChildProcessImportance importance) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetMainFrameImportance", + "importance", static_cast(importance)); + GetPrimaryMainFrame()->GetRenderWidgetHost()->SetImportance(importance); +} +#endif + +void WebContentsImpl::WasOccluded() { + TRACE_EVENT0("content", "WebContentsImpl::WasOccluded"); + UpdateVisibilityAndNotifyPageAndView(Visibility::OCCLUDED); +} + +Visibility WebContentsImpl::GetVisibility() { + return visibility_; +} + +bool WebContentsImpl::NeedToFireBeforeUnloadOrUnloadEvents() { + if (!notify_disconnection_) { + return false; + } + + // Don't fire if the main frame indicates that beforeunload and unload have + // already executed (e.g., after receiving a ClosePage ACK) or should be + // ignored. + if (GetPrimaryMainFrame()->IsPageReadyToBeClosed()) { + return false; + } + + // Check whether any frame in the frame tree needs to run beforeunload or + // unload-time event handlers. + for (FrameTreeNode* node : primary_frame_tree_.Nodes()) { + RenderFrameHostImpl* rfh = node->current_frame_host(); + + // No need to run beforeunload/unload-time events if the RenderFrame isn't + // live. + if (!rfh->IsRenderFrameLive()) { + continue; + } + bool should_run_before_unload_handler = + rfh->GetSuddenTerminationDisablerState( + blink::mojom::SuddenTerminationDisablerType::kBeforeUnloadHandler); + bool should_run_unload_handler = rfh->GetSuddenTerminationDisablerState( + blink::mojom::SuddenTerminationDisablerType::kUnloadHandler); + bool should_run_page_hide_handler = rfh->GetSuddenTerminationDisablerState( + blink::mojom::SuddenTerminationDisablerType::kPageHideHandler); + auto* rvh = static_cast(rfh->GetRenderViewHost()); + // If the tab is already hidden, we should not run visibilitychange + // handlers. + bool is_page_visible = rvh->GetPageLifecycleStateManager() + ->CalculatePageLifecycleState() + ->visibility == PageVisibilityState::kVisible; + + bool should_run_visibility_change_handler = + is_page_visible && rfh->GetSuddenTerminationDisablerState( + blink::mojom::SuddenTerminationDisablerType:: + kVisibilityChangeHandler); + if (should_run_before_unload_handler || should_run_unload_handler || + should_run_page_hide_handler || should_run_visibility_change_handler) { + return true; + } + } + + return false; +} + +void WebContentsImpl::DispatchBeforeUnload(bool auto_cancel) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DispatchBeforeUnload", + "auto_cancel", auto_cancel); + auto before_unload_type = + auto_cancel ? RenderFrameHostImpl::BeforeUnloadType::DISCARD + : RenderFrameHostImpl::BeforeUnloadType::TAB_CLOSE; + GetPrimaryMainFrame()->DispatchBeforeUnload(before_unload_type, false); +} + +bool WebContentsImpl::IsInnerWebContentsForGuest() { + return IsGuest(); +} + +void WebContentsImpl::AttachInnerWebContents( + std::unique_ptr inner_web_contents, + RenderFrameHost* render_frame_host, + mojo::PendingAssociatedRemote remote_frame, + mojo::PendingAssociatedReceiver + remote_frame_host_receiver, + bool is_full_page) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::AttachInnerWebContents", + "inner_web_contents", + static_cast(inner_web_contents.get()), + "is_full_page", is_full_page); + WebContentsImpl* inner_web_contents_impl = + static_cast(inner_web_contents.get()); + DCHECK(!inner_web_contents_impl->node_.outer_web_contents()); + auto* render_frame_host_impl = + static_cast(render_frame_host); + DCHECK_EQ(this, WebContents::FromRenderFrameHost(render_frame_host_impl)); + DCHECK(render_frame_host_impl->GetParent()); + + // Inner WebContents aren't supported with prerendering. See + // https://crbug.com/40191159 for details. + CHECK_NE(RenderFrameHostImpl::LifecycleStateImpl::kPrerendering, + render_frame_host_impl->lifecycle_state()); + + RenderFrameHostManager* inner_render_manager = + inner_web_contents_impl->GetRenderManager(); + RenderFrameHostImpl* inner_main_frame = + inner_render_manager->current_frame_host(); + RenderViewHostImpl* inner_render_view_host = + inner_main_frame->render_view_host(); + auto* outer_render_manager = + render_frame_host_impl->frame_tree_node()->render_manager(); + + // Make |render_frame_host_impl| an outer delegate frame. + render_frame_host_impl->set_inner_tree_main_frame_tree_node_id( + inner_main_frame->frame_tree_node()->frame_tree_node_id()); + + // When attaching a WebContents as an inner WebContents, we need to replace + // the Webcontents' view with a WebContentsViewChildFrame. + inner_web_contents_impl->view_ = std::make_unique( + inner_web_contents_impl, + GetContentClient()->browser()->GetWebContentsViewDelegate( + inner_web_contents_impl), + &inner_web_contents_impl->render_view_host_delegate_view_); + // On platforms where destroying the WebContents' view does not also destroy + // the platform RenderWidgetHostView, we need to destroy it if it exists. + // TODO(mcnee): Should all platforms' WebContentsView destroy the platform + // RWHV? + if (RenderWidgetHostViewBase* prev_rwhv = + inner_render_manager->GetRenderWidgetHostView()) { + if (!prev_rwhv->IsRenderWidgetHostViewChildFrame()) { + prev_rwhv->Destroy(); + } + } + + // When the WebContents being initialized has an opener, the browser side + // Render{View,Frame}Host must be initialized and the RenderWidgetHostView + // created. This is needed because the usual initialization happens during + // the first navigation, but when attaching a new window we don't navigate + // before attaching. If the browser side is already initialized, the calls + // below will just early return. + inner_render_manager->InitRenderView( + inner_main_frame->GetSiteInstance()->group(), inner_render_view_host, + nullptr); + if (!inner_render_manager->GetRenderWidgetHostView()) { + inner_web_contents_impl->CreateRenderWidgetHostViewForRenderManager( + inner_render_view_host); + } + + inner_web_contents_impl->RecursivelyUnregisterRenderWidgetHostViews(); + + // Create a link to our outer WebContents. + node_.AttachInnerWebContents(std::move(inner_web_contents), + render_frame_host_impl); + + // Create a proxy in top-level RenderFrameHostManager, pointing to the + // SiteInstanceGroup of the outer WebContents. The proxy will be used to send + // postMessage to the inner WebContents. + auto* proxy = + inner_main_frame->browsing_context_state()->CreateOuterDelegateProxy( + render_frame_host_impl->GetSiteInstance()->group(), + inner_main_frame->frame_tree_node(), blink::RemoteFrameToken()); + if (remote_frame && remote_frame_host_receiver) { + proxy->BindRemoteFrameInterfaces(std::move(remote_frame), + std::move(remote_frame_host_receiver)); + } + + // When attaching a GuestView as an inner WebContents, there should already be + // a live RenderFrame, which has to be swapped. + if (render_frame_host_impl->IsRenderFrameLive()) { + inner_render_manager->SwapOuterDelegateFrame(render_frame_host_impl, proxy); + + inner_web_contents_impl->ReattachToOuterWebContentsFrame(); + } + + if (primary_frame_tree_.GetFocusedFrame() == + render_frame_host_impl->frame_tree_node()) { + inner_web_contents_impl->SetFocusedFrame( + inner_web_contents_impl->primary_frame_tree_.root(), + render_frame_host_impl->GetSiteInstance()->group()); + } + outer_render_manager->set_attach_complete(); + + // If the inner WebContents is full frame, give it focus. + if (is_full_page) { + // There should only ever be one inner WebContents when |is_full_page| is + // true, and it is the one we just attached. + DCHECK_EQ(1u, node_.GetInnerWebContents().size()); + inner_web_contents_impl->SetAsFocusedWebContentsIfNecessary(); + } + + observers_.NotifyObservers(&WebContentsObserver::InnerWebContentsAttached, + inner_web_contents_impl, render_frame_host, + is_full_page); + + // Make sure that the inner web contents and its outer delegate get properly + // linked via the embedding token now that inner web contents are attached. + inner_main_frame->PropagateEmbeddingTokenToParentFrame(); +} + +void WebContentsImpl::RecursivelyRegisterRenderWidgetHostViews() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::RecursivelyRegisterRenderWidgetHostViews"); + + auto* text_input_manager = GetTextInputManager(); + for (auto* view : GetRenderWidgetHostViewsInWebContentsTree()) { + if (text_input_manager) { + // Use RenderWidgetHostView::GetTextInputManager() for its side effects, + // rather than registering the view directly; the view caches the + // TextInputManager. + // + // TODO(crbug.com/40212969): This probably could be made more symmetrical + // with unregistration. Getting rid of lazy registration might also allow + // eliminating some special cases in TextInputManager. + auto* text_input_manager_for_view = view->GetTextInputManager(); + DCHECK_EQ(text_input_manager, text_input_manager_for_view); + } + + if (view->IsRenderWidgetHostViewChildFrame()) { + static_cast(view)->RegisterFrameSinkId(); + } + } +} + +void WebContentsImpl::RecursivelyUnregisterRenderWidgetHostViews() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::RecursivelyUnregisterRenderWidgetHostViews"); + + auto* text_input_manager = GetTextInputManager(); + for (auto* view : GetRenderWidgetHostViewsInWebContentsTree()) { + if (text_input_manager) { + // The RenderWidgetHostView will drop the cached TextInputManager itself. + text_input_manager->Unregister(view); + } + + if (view->IsRenderWidgetHostViewChildFrame()) { + static_cast(view) + ->UnregisterFrameSinkId(); + } + } +} + +void WebContentsImpl::ReattachToOuterWebContentsFrame() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::ReattachToOuterWebContentsFrame"); + DCHECK(node_.outer_web_contents()); + auto* render_manager = GetRenderManager(); + auto* child_rwhv = render_manager->GetRenderWidgetHostView(); + DCHECK(child_rwhv); + DCHECK(child_rwhv->IsRenderWidgetHostViewChildFrame()); + render_manager->SetRWHViewForInnerFrameTree( + static_cast(child_rwhv)); + + RecursivelyRegisterRenderWidgetHostViews(); + GetPrimaryMainFrame()->UpdateAXTreeData(); +} + +void WebContentsImpl::DidActivatePreviewedPage( + base::TimeTicks activation_time) { + TRACE_EVENT1("content", "WebContentsImpl::DidActivatePreviewedPage", + "activation_time", activation_time); + observers_.NotifyObservers(&WebContentsObserver::DidActivatePreviewedPage, + activation_time); + GetDelegate()->DidActivatePreviewedPage(); +} + +void WebContentsImpl::DidChangeVisibleSecurityState() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::DidChangeVisibleSecurityState"); + if (delegate_) { + delegate_->VisibleSecurityStateChanged(this); + } + + SCOPED_UMA_HISTOGRAM_TIMER( + "WebContentsObserver.DidChangeVisibleSecurityState"); + observers_.NotifyObservers( + &WebContentsObserver::DidChangeVisibleSecurityState); +} + +const blink::web_pref::WebPreferences WebContentsImpl::ComputeWebPreferences() { + OPTIONAL_TRACE_EVENT0("browser", "WebContentsImpl::ComputeWebPreferences"); + + blink::web_pref::WebPreferences prefs; + + const base::CommandLine& command_line = + *base::CommandLine::ForCurrentProcess(); + + SetSlowWebPreferences(command_line, &prefs); + + prefs.web_security_enabled = + !command_line.HasSwitch(switches::kDisableWebSecurity); + + prefs.remote_fonts_enabled = + !command_line.HasSwitch(switches::kDisableRemoteFonts); + prefs.local_storage_enabled = + !command_line.HasSwitch(switches::kDisableLocalStorage); + prefs.databases_enabled = + !command_line.HasSwitch(switches::kDisableDatabases); + + prefs.webgl1_enabled = !command_line.HasSwitch(switches::kDisable3DAPIs) && + !command_line.HasSwitch(switches::kDisableWebGL); + prefs.webgl2_enabled = !command_line.HasSwitch(switches::kDisable3DAPIs) && + !command_line.HasSwitch(switches::kDisableWebGL) && + !command_line.HasSwitch(switches::kDisableWebGL2); + + prefs.pepper_3d_enabled = !command_line.HasSwitch(switches::kDisablePepper3d); + + prefs.allow_file_access_from_file_urls = + command_line.HasSwitch(switches::kAllowFileAccessFromFiles); + + prefs.accelerated_2d_canvas_enabled = + !command_line.HasSwitch(switches::kDisableAccelerated2dCanvas); + prefs.canvas_2d_layers_enabled = + command_line.HasSwitch(switches::kEnableCanvas2DLayers) || + base::FeatureList::IsEnabled(features::kEnableCanvas2DLayers); + prefs.antialiased_2d_canvas_disabled = + command_line.HasSwitch(switches::kDisable2dCanvasAntialiasing); + prefs.antialiased_clips_2d_canvas_enabled = + !command_line.HasSwitch(switches::kDisable2dCanvasClipAntialiasing); + + prefs.disable_ipc_flooding_protection = + command_line.HasSwitch(switches::kDisableIpcFloodingProtection) || + command_line.HasSwitch(switches::kDisablePushStateThrottle); + + prefs.accelerated_video_decode_enabled = + !command_line.HasSwitch(switches::kDisableAcceleratedVideoDecode); + + std::string autoplay_policy = media::GetEffectiveAutoplayPolicy(command_line); + if (autoplay_policy == switches::autoplay::kNoUserGestureRequiredPolicy) { + prefs.autoplay_policy = + blink::mojom::AutoplayPolicy::kNoUserGestureRequired; + } else if (autoplay_policy == + switches::autoplay::kUserGestureRequiredPolicy) { + prefs.autoplay_policy = blink::mojom::AutoplayPolicy::kUserGestureRequired; + } else if (autoplay_policy == + switches::autoplay::kDocumentUserActivationRequiredPolicy) { + prefs.autoplay_policy = + blink::mojom::AutoplayPolicy::kDocumentUserActivationRequired; + } else { + NOTREACHED_IN_MIGRATION(); + } + + prefs.dont_send_key_events_to_javascript = + base::FeatureList::IsEnabled(features::kDontSendKeyEventsToJavascript); + +// TODO(dtapuska): Enable barrel button selection drag support on Android. +// crbug.com/758042 +#if BUILDFLAG(IS_WIN) + prefs.barrel_button_for_drag_enabled = true; +#endif // BUILDFLAG(IS_WIN) + + prefs.enable_scroll_animator = + command_line.HasSwitch(switches::kEnableSmoothScrolling) || + (!command_line.HasSwitch(switches::kDisableSmoothScrolling) && + gfx::Animation::ScrollAnimationsEnabledBySystem()); + + prefs.prefers_reduced_motion = gfx::Animation::PrefersReducedMotion(); + prefs.prefers_reduced_transparency = prefers_reduced_transparency_; + prefs.inverted_colors = inverted_colors_; + + if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( + GetRenderViewHost()->GetProcess()->GetID())) { + prefs.loads_images_automatically = true; + prefs.javascript_enabled = true; + } + + prefs.viewport_enabled = command_line.HasSwitch(switches::kEnableViewport); + +#if BUILDFLAG(IS_ANDROID) + // TODO(crbug.com/40925473): GetPrimaryDisplay() won't be correct for + // externally connected displays. Get the display where Chrome is opened + // instead. + display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay(); + gfx::Size size = display.GetSizeInPixel(); + int min_width = size.width() < size.height() ? size.width() : size.height(); + int min_width_in_dp = + static_cast(min_width / display.device_scale_factor()); + if (prefs.viewport_enabled && + base::FeatureList::IsEnabled( + blink::features::kDefaultViewportIsDeviceWidth) && + (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_AUTOMOTIVE || + (min_width_in_dp >= kAndroidMinimumTabletWidthDp && + ui::GetDeviceFormFactor() != ui::DEVICE_FORM_FACTOR_TV))) { + prefs.viewport_style = blink::mojom::ViewportStyle::kDefault; + } +#endif + + if (GetController().GetVisibleEntry() && + GetController().GetVisibleEntry()->GetIsOverridingUserAgent()) { +#if BUILDFLAG(IS_ANDROID) + // Only ignore viewport meta tag when Request Desktop Site is used, but not + // in other situations where embedder changes to arbitrary mobile UA string. + bool is_request_desktop_site = + renderer_preferences_.user_agent_override.ua_metadata_override && + !renderer_preferences_.user_agent_override.ua_metadata_override->mobile; + prefs.viewport_meta_enabled = !is_request_desktop_site; +#else + prefs.viewport_meta_enabled = false; +#endif + } + + prefs.spatial_navigation_enabled = + command_line.HasSwitch(switches::kEnableSpatialNavigation); + + if (is_spatial_navigation_disabled_) { + prefs.spatial_navigation_enabled = false; + } + +#if BUILDFLAG(IS_ANDROID) + prefs.long_press_link_select_text = long_press_link_select_text_; +#endif + + prefs.stylus_handwriting_enabled = stylus_handwriting_enabled_; + + prefs.disable_reading_from_canvas = + command_line.HasSwitch(switches::kDisableReadingFromCanvas); + + prefs.strict_mixed_content_checking = + command_line.HasSwitch(switches::kEnableStrictMixedContentChecking); + + prefs.strict_powerful_feature_restrictions = command_line.HasSwitch( + switches::kEnableStrictPowerfulFeatureRestrictions); + + const std::string blockable_mixed_content_group = + base::FieldTrialList::FindFullName("BlockableMixedContent"); + prefs.strictly_block_blockable_mixed_content = + blockable_mixed_content_group == "StrictlyBlockBlockableMixedContent"; + + const std::string plugin_mixed_content_status = + base::FieldTrialList::FindFullName("PluginMixedContentStatus"); + prefs.block_mixed_plugin_content = + plugin_mixed_content_status == "BlockableMixedContent"; + + prefs.v8_cache_options = GetV8CacheOptions(); + + prefs.user_gesture_required_for_presentation = !command_line.HasSwitch( + switches::kDisableGestureRequirementForPresentation); + + if (is_overlay_content_) { + prefs.hide_download_ui = true; + } + + // `media_controls_enabled` is `true` by default. + if (has_persistent_video_) { + prefs.media_controls_enabled = false; + } + +#if BUILDFLAG(IS_ANDROID) + prefs.device_scale_adjustment = GetDeviceScaleAdjustment(min_width_in_dp); +#endif // BUILDFLAG(IS_ANDROID) + + // GuestViews in the same StoragePartition need to find each other's frames. + prefs.renderer_wide_named_frame_lookup = IsGuest(); + + if (command_line.HasSwitch(switches::kHideScrollbars)) { + prefs.hide_scrollbars = true; + } + + GetContentClient()->browser()->OverrideWebkitPrefs(this, &prefs); + return prefs; +} + +void WebContentsImpl::SetSlowWebPreferences( + const base::CommandLine& command_line, + blink::web_pref::WebPreferences* prefs) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetSlowWebPreferences"); + + if (web_preferences_.get()) { +#define SET_FROM_CACHE(prefs, field) prefs->field = web_preferences_->field + + SET_FROM_CACHE(prefs, touch_event_feature_detection_enabled); + SET_FROM_CACHE(prefs, available_pointer_types); + SET_FROM_CACHE(prefs, available_hover_types); + SET_FROM_CACHE(prefs, primary_pointer_type); + SET_FROM_CACHE(prefs, primary_hover_type); + SET_FROM_CACHE(prefs, pointer_events_max_touch_points); + SET_FROM_CACHE(prefs, number_of_cpu_cores); + +#if BUILDFLAG(IS_ANDROID) + SET_FROM_CACHE(prefs, video_fullscreen_orientation_lock_enabled); + SET_FROM_CACHE(prefs, video_rotate_to_fullscreen_enabled); +#endif + +#undef SET_FROM_CACHE + } else { + // Every prefs->field modified below should have a SET_FROM_CACHE entry + // above. + + // On Android, Touch event feature detection is enabled by default, + // Otherwise default is disabled. + std::string touch_enabled_default_switch = + switches::kTouchEventFeatureDetectionDisabled; +#if BUILDFLAG(IS_ANDROID) + touch_enabled_default_switch = switches::kTouchEventFeatureDetectionEnabled; +#endif // BUILDFLAG(IS_ANDROID) + const std::string touch_enabled_switch = + command_line.HasSwitch(switches::kTouchEventFeatureDetection) + ? command_line.GetSwitchValueASCII( + switches::kTouchEventFeatureDetection) + : touch_enabled_default_switch; + + prefs->touch_event_feature_detection_enabled = + (touch_enabled_switch == switches::kTouchEventFeatureDetectionAuto) + ? (ui::GetTouchScreensAvailability() == + ui::TouchScreensAvailability::ENABLED) + : (touch_enabled_switch.empty() || + touch_enabled_switch == + switches::kTouchEventFeatureDetectionEnabled); + + std::tie(prefs->available_pointer_types, prefs->available_hover_types) = + GetAvailablePointerAndHoverTypes(); + prefs->primary_pointer_type = static_cast( + ui::GetPrimaryPointerType(prefs->available_pointer_types)); + prefs->primary_hover_type = static_cast( + ui::GetPrimaryHoverType(prefs->available_hover_types)); + + prefs->pointer_events_max_touch_points = ui::MaxTouchPoints(); + + prefs->number_of_cpu_cores = base::SysInfo::NumberOfProcessors(); + + AllPointerTypes all_pointer_types = AllPointerTypes::kNone; + if (prefs->available_pointer_types & ui::POINTER_TYPE_COARSE && + prefs->available_pointer_types & ui::POINTER_TYPE_FINE) { + all_pointer_types = AllPointerTypes::kBoth; + } else if (prefs->available_pointer_types & ui::POINTER_TYPE_COARSE) { + all_pointer_types = AllPointerTypes::kCoarse; + } else if (prefs->available_pointer_types & ui::POINTER_TYPE_FINE) { + all_pointer_types = AllPointerTypes::kFine; + } + PrimaryPointerType primary_pointer = PrimaryPointerType::kNone; + if (prefs->primary_pointer_type == + blink::mojom::PointerType::kPointerCoarseType) { + primary_pointer = PrimaryPointerType::kCoarse; + } else if (prefs->primary_pointer_type == + blink::mojom::PointerType::kPointerFineType) { + primary_pointer = PrimaryPointerType::kFine; + } + base::UmaHistogramEnumeration("Input.PointerTypesAll", all_pointer_types); + base::UmaHistogramEnumeration("Input.PointerTypePrimary", primary_pointer); + +#if BUILDFLAG(IS_ANDROID) + const bool device_is_phone = + ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_PHONE; + prefs->video_fullscreen_orientation_lock_enabled = device_is_phone; + prefs->video_rotate_to_fullscreen_enabled = device_is_phone; +#endif + } +} + +void WebContentsImpl::OnWebPreferencesChanged() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnWebPreferencesChanged"); + + // This is defensive code to avoid infinite loops due to code run inside + // SetWebPreferences() accidentally updating more preferences and thus + // calling back into this code. See crbug.com/398751 for one past example. + if (updating_web_preferences_) { + return; + } + updating_web_preferences_ = true; + SetWebPreferences(ComputeWebPreferences()); +#if BUILDFLAG(IS_ANDROID) + for (FrameTreeNode* node : primary_frame_tree_.Nodes()) { + RenderFrameHostImpl* rfh = node->current_frame_host(); + if (rfh->is_local_root()) { + if (auto* rwh = rfh->GetRenderWidgetHost()) { + rwh->SetForceEnableZoom(web_preferences_->force_enable_zoom); + } + } + } +#endif + updating_web_preferences_ = false; +} + +void WebContentsImpl::NotifyPreferencesChanged() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::NotifyPreferencesChanged"); + + // Recompute the WebPreferences based on the current state of the WebContents, + // etc. Note that OnWebPreferencesChanged will also call SetWebPreferences and + // send the updated WebPreferences to all RenderViews for this WebContents. + OnWebPreferencesChanged(); +} + +void WebContentsImpl::SyncRendererPrefs() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SyncRendererPrefs"); + + blink::RendererPreferences renderer_preferences = GetRendererPrefs(); + RenderViewHostImpl::GetPlatformSpecificPrefs(&renderer_preferences); + ExecutePageBroadcastMethodForAllPages(base::BindRepeating( + [](const blink::RendererPreferences& preferences, + RenderViewHostImpl* rvh) { + rvh->SendRendererPreferencesToRenderer(preferences); + }, + renderer_preferences)); +} + +void WebContentsImpl::OnCookiesAccessed(NavigationHandle* navigation, + const CookieAccessDetails& details) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnCookiesAccessed", + "navigation_handle", navigation); + // Use a variable to select between overloads. + void (WebContentsObserver::*func)(NavigationHandle*, + const CookieAccessDetails&) = + &WebContentsObserver::OnCookiesAccessed; + observers_.NotifyObservers(func, navigation, details); +} + +void WebContentsImpl::OnCookiesAccessed(RenderFrameHostImpl* rfh, + const CookieAccessDetails& details) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnCookiesAccessed", + "render_frame_host", rfh); + // Use a variable to select between overloads. + void (WebContentsObserver::*func)(RenderFrameHost*, + const CookieAccessDetails&) = + &WebContentsObserver::OnCookiesAccessed; + observers_.NotifyObservers(func, rfh, details); +} + +void WebContentsImpl::OnTrustTokensAccessed( + NavigationHandle* navigation, + const TrustTokenAccessDetails& details) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnTrustTokensAccessed", + "navigation_handle", navigation); + // Use a variable to select between overloads. + void (WebContentsObserver::*func)(NavigationHandle*, + const TrustTokenAccessDetails&) = + &WebContentsObserver::OnTrustTokensAccessed; + observers_.NotifyObservers(func, navigation, details); +} + +void WebContentsImpl::OnTrustTokensAccessed( + RenderFrameHostImpl* rfh, + const TrustTokenAccessDetails& details) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnTrustTokensAccessed", + "render_frame_host", rfh); + // Use a variable to select between overloads. + void (WebContentsObserver::*func)(RenderFrameHost*, + const TrustTokenAccessDetails&) = + &WebContentsObserver::OnTrustTokensAccessed; + observers_.NotifyObservers(func, rfh, details); +} + +void WebContentsImpl::OnSharedDictionaryAccessed( + NavigationHandle* navigation, + const network::mojom::SharedDictionaryAccessDetails& details) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::OnSharedDictionaryAccessed", + "navigation_handle", navigation); + // Use a variable to select between overloads. + void (WebContentsObserver::*func)( + NavigationHandle*, const network::mojom::SharedDictionaryAccessDetails&) = + &WebContentsObserver::OnSharedDictionaryAccessed; + observers_.NotifyObservers(func, navigation, details); +} + +void WebContentsImpl::OnSharedDictionaryAccessed( + RenderFrameHostImpl* rfh, + const network::mojom::SharedDictionaryAccessDetails& details) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::OnSharedDictionaryAccessed", + "render_frame_host", rfh); + // Use a variable to select between overloads. + void (WebContentsObserver::*func)( + RenderFrameHost*, const network::mojom::SharedDictionaryAccessDetails&) = + &WebContentsObserver::OnSharedDictionaryAccessed; + observers_.NotifyObservers(func, rfh, details); +} + +void WebContentsImpl::NotifyStorageAccessed( + RenderFrameHostImpl* rfh, + blink::mojom::StorageTypeAccessed storage_type, + bool blocked) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::NotifyStorageAccessed", + "render_frame_host", rfh); + observers_.NotifyObservers(&WebContentsObserver::NotifyStorageAccessed, rfh, + storage_type, blocked); +} + +void WebContentsImpl::OnVibrate(RenderFrameHostImpl* rfh) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnVibrate", + "render_frame_host", rfh); + observers_.NotifyObservers(&WebContentsObserver::VibrationRequested); +} + +std::optional +WebContentsImpl::GetPermissionsPolicyForIsolatedWebApp( + RenderFrameHostImpl* source) { + WebExposedIsolationInfo weii = + source->GetSiteInstance()->GetWebExposedIsolationInfo(); + CHECK(weii.is_isolated_application()); + return GetContentClient()->browser()->GetPermissionsPolicyForIsolatedWebApp( + this, weii.origin()); +} + +void WebContentsImpl::Stop() { + TRACE_EVENT0("content", "WebContentsImpl::Stop"); + ForEachFrameTree(base::BindRepeating( + [](FrameTree& frame_tree) { frame_tree.StopLoading(); })); + GetPrerenderHostRegistry()->CancelAllHosts(PrerenderFinalStatus::kStop); + observers_.NotifyObservers(&WebContentsObserver::NavigationStopped); +} + +void WebContentsImpl::SetPageFrozen(bool frozen) { + TRACE_EVENT1("content", "WebContentsImpl::SetPageFrozen", "frozen", frozen); + + // A visible page is never frozen. + DCHECK_NE(Visibility::VISIBLE, GetVisibility()); + + primary_frame_tree_.ForEachRenderViewHost( + [&frozen](RenderViewHostImpl* rvh) { rvh->SetIsFrozen(frozen); }); +} + +std::unique_ptr WebContentsImpl::Clone() { + TRACE_EVENT0("content", "WebContentsImpl::Clone"); + + // We use our current SiteInstance since the cloned entry will use it anyway. + // We pass our own opener so that the cloned page can access it if it was set + // before. + CreateParams create_params(GetBrowserContext(), GetSiteInstance()); + FrameTreeNode* opener = primary_frame_tree_.root()->opener(); + RenderFrameHostImpl* opener_rfh = nullptr; + if (opener) { + opener_rfh = opener->current_frame_host(); + } + std::unique_ptr tc = + CreateWithOpener(create_params, opener_rfh); + tc->GetController().CopyStateFrom(&primary_frame_tree_.controller(), true); + observers_.NotifyObservers(&WebContentsObserver::DidCloneToNewWebContents, + this, tc.get()); + return tc; +} + +void WebContentsImpl::Init(const WebContents::CreateParams& params, + blink::FramePolicy primary_main_frame_policy) { + TRACE_EVENT0("content", "WebContentsImpl::Init"); + + is_in_preview_mode_ = params.preview_mode; + creator_location_ = params.creator_location; +#if BUILDFLAG(IS_ANDROID) + java_creator_location_ = params.java_creator_location; +#endif // BUILDFLAG(IS_ANDROID) + + if (params.picture_in_picture_options.has_value()) { + picture_in_picture_options_ = params.picture_in_picture_options; + if (GetOpener()) { + picture_in_picture_opener_ = + FromRenderFrameHostImpl(GetOpener())->GetWeakPtr(); + } + } + + // This is set before initializing the render manager since + // RenderFrameHostManager::Init calls back into us via its delegate to ask if + // it should be hidden. + visibility_ = + params.initially_hidden ? Visibility::HIDDEN : Visibility::VISIBLE; + + enable_wake_locks_ = params.enable_wake_locks; + + if (!params.last_active_time.is_null()) { + last_active_time_ = params.last_active_time; + } + + scoped_refptr site_instance = + static_cast(params.site_instance.get()); + if (!site_instance) { + site_instance = SiteInstanceImpl::Create(params.browser_context); + } + if (params.desired_renderer_state == CreateParams::kNoRendererProcess) { + site_instance->PreventAssociationWithSpareProcess(); + } + + // Iniitalize the primary FrameTree. + // Note that GetOpener() is used here to get the opener for origin + // inheritance, instead of other similar functions: + // - GetOriginalOpener(), which would always return the main frame of the + // opener, which might be different from the actual opener. + // - FindOpenerRFH(), which will still return the opener frame if the + // opener is suppressed (e.g. due to 'noopener'). The opener should not + // be used for origin inheritance purposes in those cases, so this should + // not pass the opener for those cases. + primary_frame_tree_.Init( + site_instance.get(), params.renderer_initiated_creation, + params.main_frame_name, GetOpener(), primary_main_frame_policy, + base::UnguessableToken::Create()); + + std::unique_ptr delegate = + GetContentClient()->browser()->GetWebContentsViewDelegate(this); + + if (browser_plugin_guest_) { + view_ = std::make_unique( + this, std::move(delegate), &render_view_host_delegate_view_); + } else { + view_ = CreateWebContentsView(this, std::move(delegate), + &render_view_host_delegate_view_); + } + CHECK(render_view_host_delegate_view_); + CHECK(view_.get()); + + view_->CreateView(params.context); + + screen_orientation_provider_ = + std::make_unique(this); + +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) + DateTimeChooser::CreateDateTimeChooser(this); +#endif + + // AttributionHost must be created after `view_->CreateView()` is called as it + // may invoke `WebContentsAndroid::AddObserver()`. + if (base::FeatureList::IsEnabled( + attribution_reporting::features::kConversionMeasurement)) { + AttributionHost::CreateForWebContents(this); + } + + // BrowserPluginGuest::Init needs to be called after this WebContents has + // a RenderWidgetHostViewChildFrame. That is, |view_->CreateView| above. + if (browser_plugin_guest_) { + browser_plugin_guest_->Init(); + } + + g_created_callbacks.Get().Notify(this); + + // Create the renderer process in advance if requested. + if (params.desired_renderer_state == + CreateParams::kInitializeAndWarmupRendererProcess) { + if (!GetRenderManager()->current_frame_host()->IsRenderFrameLive()) { + GetRenderManager()->InitRenderView(site_instance->group(), + GetRenderViewHost(), nullptr); + } + } + + // Let the embedder know about the newly created and initialized WebContents. + GetContentClient()->browser()->OnWebContentsCreated(this); + + // Ensure that observers are notified of the creation of this WebContents's + // main RenderFrameHost. It must be done here for main frames, since the + // NotifySwappedFromRenderManager expects view_ to already be created and that + // happens after RenderFrameHostManager::Init. + NotifySwappedFromRenderManager(nullptr, + GetRenderManager()->current_frame_host()); + + // Checks whether the associated ssl_manager has any certificate error or HTTP + // exceptions for any host and updates the renderer preferences. + if (base::FeatureList::IsEnabled( + features::kReduceSubresourceResponseStartedIPC) && + GetController().ssl_manager()->HasAllowExceptionForAnyHost()) { + renderer_preferences_.send_subresource_notification = true; + SyncRendererPrefs(); + } +} + +void WebContentsImpl::OnWebContentsDestroyed(WebContentsImpl* web_contents) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnWebContentsDestroyed"); + + RemoveWebContentsDestructionObserver(web_contents); + + // Clear a pending contents that has been closed before being shown. + for (auto iter = pending_contents_.begin(); iter != pending_contents_.end(); + ++iter) { + if (iter->second.contents.get() != web_contents) { + continue; + } + + // Someone else has deleted the WebContents. That should never happen! + // TODO(erikchen): Fix semantics here. https://crbug.com/832879. + iter->second.contents.release(); + pending_contents_.erase(iter); + return; + } + NOTREACHED_IN_MIGRATION(); +} + +void WebContentsImpl::OnRenderWidgetHostDestroyed( + RenderWidgetHost* render_widget_host) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnWebContentsDestroyed"); + + RemoveRenderWidgetHostDestructionObserver(render_widget_host); + + // Clear a pending widget that has been closed before being shown. + size_t num_erased = + std::erase_if(pending_widgets_, [render_widget_host](const auto& pair) { + return pair.second == render_widget_host; + }); + DCHECK_EQ(1u, num_erased); +} + +void WebContentsImpl::AddWebContentsDestructionObserver( + WebContentsImpl* web_contents) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::AddWebContentsDestructionObserver"); + + if (!base::Contains(web_contents_destruction_observers_, web_contents)) { + web_contents_destruction_observers_[web_contents] = + std::make_unique(this, web_contents); + } +} + +void WebContentsImpl::RemoveWebContentsDestructionObserver( + WebContentsImpl* web_contents) { + OPTIONAL_TRACE_EVENT0( + TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::RemoveWebContentsDestructionObserver"); + web_contents_destruction_observers_.erase(web_contents); +} + +void WebContentsImpl::AddRenderWidgetHostDestructionObserver( + RenderWidgetHost* render_widget_host) { + OPTIONAL_TRACE_EVENT0( + TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::AddRenderWidgetHostDestructionObserver"); + + DCHECK(!base::Contains(render_widget_host_destruction_observers_, + render_widget_host)); + + render_widget_host_destruction_observers_.insert( + {render_widget_host, + std::make_unique( + this, render_widget_host)}); +} + +void WebContentsImpl::RemoveRenderWidgetHostDestructionObserver( + RenderWidgetHost* render_widget_host) { + OPTIONAL_TRACE_EVENT0( + TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::RemoveRenderWidgetHostDestructionObserver"); + render_widget_host_destruction_observers_.erase(render_widget_host); +} + +void WebContentsImpl::AddObserver(WebContentsObserver* observer) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::AddObserver"); + observers_.AddObserver(observer); +} + +void WebContentsImpl::RemoveObserver(WebContentsObserver* observer) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::RemoveObserver"); + observers_.RemoveObserver(observer); +} + +std::set +WebContentsImpl::GetRenderWidgetHostViewsInWebContentsTree() { + std::set result; + GetPrimaryMainFrame()->ForEachRenderFrameHost([&result]( + RenderFrameHostImpl* rfh) { + if (auto* view = static_cast(rfh->GetView())) { + result.insert(view); + } + }); + return result; +} + +void WebContentsImpl::Activate() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Activate"); + if (delegate_) { + delegate_->ActivateContents(this); + } +} + +void WebContentsImpl::SetTopControlsShownRatio( + RenderWidgetHostImpl* render_widget_host, + float ratio) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetTopControlsShownRatio", + "render_widget_host", render_widget_host, "ratio", + ratio); + if (!delegate_) { + return; + } + + RenderFrameHostImpl* rfh = GetPrimaryMainFrame(); + if (!rfh || render_widget_host != rfh->GetRenderWidgetHost()) { + return; + } + + delegate_->SetTopControlsShownRatio(this, ratio); +} + +void WebContentsImpl::SetTopControlsGestureScrollInProgress(bool in_progress) { + OPTIONAL_TRACE_EVENT1( + "content", "WebContentsImpl::SetTopControlsGestureScrollInProgress", + "in_progress", in_progress); + if (delegate_) { + delegate_->SetTopControlsGestureScrollInProgress(in_progress); + } +} + +void WebContentsImpl::RenderWidgetCreated( + RenderWidgetHostImpl* render_widget_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderWidgetCreated", + "render_widget_host", render_widget_host); + created_widgets_.insert(render_widget_host); +} + +void WebContentsImpl::RenderWidgetDeleted( + RenderWidgetHostImpl* render_widget_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderWidgetDeleted", + "render_widget_host", render_widget_host); + // Note that IsBeingDestroyed() can return true at this point as + // ~WebContentsImpl() calls RFHM::ClearRFHsPendingShutdown(), which might lead + // us here. + created_widgets_.erase(render_widget_host); + + if (IsBeingDestroyed()) { + return; + } + + if (render_widget_host == pointer_lock_widget_) { + LostPointerLock(pointer_lock_widget_); + } + + CancelKeyboardLock(render_widget_host); +} + +void WebContentsImpl::RenderWidgetWasResized( + RenderWidgetHostImpl* render_widget_host, + bool width_changed) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RenderWidgetWasResized", + "render_widget_host", render_widget_host, + "width_changed", width_changed); + RenderFrameHostImpl* rfh = GetPrimaryMainFrame(); + if (!rfh || render_widget_host != rfh->GetRenderWidgetHost()) { + return; + } + + observers_.NotifyObservers(&WebContentsObserver::PrimaryMainFrameWasResized, + width_changed); +} + +KeyboardEventProcessingResult WebContentsImpl::PreHandleKeyboardEvent( + const input::NativeWebKeyboardEvent& event) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::PreHandleKeyboardEvent"); + auto* outermost_contents = GetOutermostWebContents(); + // TODO(wjmaclean): Generalize this to forward all key events to the outermost + // delegate's handler. + if (outermost_contents != this && IsFullscreen() && + event.windows_key_code == ui::VKEY_ESCAPE) { + // When an inner WebContents has focus and is fullscreen, redirect + // key events to the outermost WebContents so it can be handled by that + // WebContents' delegate. + if (outermost_contents->PreHandleKeyboardEvent(event) == + KeyboardEventProcessingResult::HANDLED) { + return KeyboardEventProcessingResult::HANDLED; + } + } + return delegate_ ? delegate_->PreHandleKeyboardEvent(this, event) + : KeyboardEventProcessingResult::NOT_HANDLED; +} + +bool WebContentsImpl::HandleMouseEvent(const blink::WebMouseEvent& event) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::HandleMouseEvent"); + // Handle mouse button back/forward in the browser process after the render + // process is done with the event. This ensures all renderer-initiated history + // navigations can be treated consistently. + if (event.GetType() == blink::WebInputEvent::Type::kMouseUp) { + WebContentsImpl* outermost = GetOutermostWebContents(); + if (event.button == blink::WebPointerProperties::Button::kBack && + outermost->GetController().CanGoBack()) { + outermost->GetController().GoBack(); + return true; + } else if (event.button == blink::WebPointerProperties::Button::kForward && + outermost->GetController().CanGoForward()) { + outermost->GetController().GoForward(); + return true; + } + } + return false; +} + +bool WebContentsImpl::HandleKeyboardEvent( + const input::NativeWebKeyboardEvent& event) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::HandleKeyboardEvent"); + if (browser_plugin_embedder_ && + browser_plugin_embedder_->HandleKeyboardEvent(event)) { + return true; + } + return delegate_ && delegate_->HandleKeyboardEvent(this, event); +} + +bool WebContentsImpl::HandleWheelEvent(const blink::WebMouseWheelEvent& event) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::HandleWheelEvent"); +#if !BUILDFLAG(IS_MAC) + // On platforms other than Mac, control+mousewheel may change zoom. On Mac, + // this isn't done for two reasons: + // -the OS already has a gesture to do this through pinch-zoom + // -if a user starts an inertial scroll, let's go, and presses control + // (i.e. control+tab) then the OS's buffered scroll events will come in + // with control key set which isn't what the user wants + if (delegate_ && event.wheel_ticks_y && + event.event_action == blink::WebMouseWheelEvent::EventAction::kPageZoom) { + // Count only integer cumulative scrolls as zoom events; this handles + // smooth scroll and regular scroll device behavior. + zoom_scroll_remainder_ += event.wheel_ticks_y; + int whole_zoom_scroll_remainder_ = std::lround(zoom_scroll_remainder_); + zoom_scroll_remainder_ -= whole_zoom_scroll_remainder_; + if (whole_zoom_scroll_remainder_ != 0) { + delegate_->ContentsZoomChange(whole_zoom_scroll_remainder_ > 0); + } + return true; + } +#endif + return false; +} + +bool WebContentsImpl::PreHandleGestureEvent( + const blink::WebGestureEvent& event) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::PreHandleGestureEvent"); + return delegate_ && delegate_->PreHandleGestureEvent(this, event); +} + +input::RenderWidgetHostInputEventRouter* +WebContentsImpl::GetInputEventRouter() { + if (!IsBeingDestroyed()) { + if (GetOuterWebContents()) { + return GetOuterWebContents()->GetInputEventRouter(); + } + + if (!rwh_input_event_router_.get()) { + rwh_input_event_router_ = + std::make_unique( + GetHostFrameSinkManager(), this); + } + } + return rwh_input_event_router_.get(); +} + +void WebContentsImpl::GetRenderWidgetHostAtPointAsynchronously( + RenderWidgetHostViewBase* root_view, + const gfx::PointF& point, + base::OnceCallback, + std::optional)> callback) { + GetInputEventRouter()->GetRenderWidgetHostAtPointAsynchronously( + root_view, point, base::BindOnce(&RunCallback, std::move(callback))); +} + +std::vector +WebContentsImpl::GetRenderWidgetHostViewsForTests() { + auto input_hosts = + GetInputEventRouter()->GetRenderWidgetHostViewInputsForTests(); + std::vector hosts; + for (auto host : input_hosts) { + hosts.push_back(static_cast(host)); + } + return hosts; +} + +RenderWidgetHostImpl* WebContentsImpl::GetFocusedRenderWidgetHost( + RenderWidgetHostImpl* receiving_widget) { + // Events for widgets other than the main frame (e.g., popup menus) should be + // forwarded directly to the widget they arrived on. + if (receiving_widget != GetPrimaryMainFrame()->GetRenderWidgetHost()) { + return receiving_widget; + } + + // If the focused WebContents is a guest WebContents, then get the focused + // frame in the embedder WebContents instead. + FrameTreeNode* focused_frame = GetFocusedFrameTree()->GetFocusedFrame(); + + if (!focused_frame) { + return receiving_widget; + } + + // The view may be null if a subframe's renderer process has crashed while + // the subframe has focus. Drop the event in that case. Do not give + // it to the main frame, so that the user doesn't unexpectedly type into the + // wrong frame if a focused subframe renderer crashes while they type. + RenderWidgetHostView* view = focused_frame->current_frame_host()->GetView(); + if (!view) { + return nullptr; + } + + return RenderWidgetHostImpl::From(view->GetRenderWidgetHost()); +} + +RenderWidgetHostImpl* WebContentsImpl::GetRenderWidgetHostWithPageFocus() { + FrameTree* focused_frame_tree = GetFocusedFrameTree(); + return focused_frame_tree->root() + ->current_frame_host() + ->GetRenderWidgetHost(); +} + +bool WebContentsImpl::CanEnterFullscreenMode( + RenderFrameHostImpl* requesting_frame) { + // It's possible that this WebContents was spawned while blocking UI was on + // the screen, or that it was downstream from a WebContents when UI was + // blocked. Therefore, disqualify it from fullscreen if it or any upstream + // WebContents has an active blocker. + return base::ranges::all_of(GetAllOpeningWebContents(this), + [](auto* opener) { + return opener->fullscreen_blocker_count_ == 0; + }) && + delegate_->CanEnterFullscreenModeForTab(requesting_frame); +} + +void WebContentsImpl::EnterFullscreenMode( + RenderFrameHostImpl* requesting_frame, + const blink::mojom::FullscreenOptions& options) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterFullscreenMode"); + DCHECK(CanEnterFullscreenMode(requesting_frame)); + DCHECK(requesting_frame->IsActive()); + DCHECK(ContainsOrIsFocusedWebContents()); + if (base::FeatureList::IsEnabled( + features::kAutomaticFullscreenContentSetting)) { + // Ensure the window is made active to take input focus. The user may have + // activated another window between making a gesture and the site handling + // that gesture to request fullscreen. The experimental automatic fullscreen + // feature also enables allowlisted sites to request fullscreen without any + // gesture, even if the window was inactive. Note: requests from inactive + // tabs of multi-tab windows should be rejected before reaching this code. + Activate(); + } + + // When WebView is the `delegate_` we can end up with VisualProperties changes + // synchronously. Notify the view ahead so it can handle the transition. + if (auto* view = GetRenderWidgetHostView()) { + static_cast(view)->EnterFullscreenMode(options); + } + + if (delegate_) { + delegate_->EnterFullscreenModeForTab(requesting_frame, options); + + if (keyboard_lock_widget_) { + delegate_->RequestKeyboardLock(this, esc_key_locked_); + } + } + + observers_.NotifyObservers( + &WebContentsObserver::DidToggleFullscreenModeForTab, IsFullscreen(), + false); + FullscreenContentsSet(GetBrowserContext())->insert(this); +} + +void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ExitFullscreenMode", + "will_cause_resize", will_cause_resize); + // When WebView is the `delegate_` we can end up with VisualProperties changes + // synchronously. Notify the view ahead so it can handle the transition. + if (auto* view = GetRenderWidgetHostView()) { + static_cast(view)->ExitFullscreenMode(); + } + + GetFullscreenUserData(GetBrowserContext()) + ->last_exits() + ->insert_or_assign(GetPrimaryMainFrame()->GetLastCommittedOrigin(), + base::TimeTicks::Now()); + + if (delegate_) { + // This may spin the message loop and destroy this object crbug.com/1506535 + base::WeakPtr weak_ptr = weak_factory_.GetWeakPtr(); + delegate_->ExitFullscreenModeForTab(this); + if (!weak_ptr) { + return; + } + + if (keyboard_lock_widget_) { + delegate_->CancelKeyboardLockRequest(this); + } + } + + // The fullscreen state is communicated to the renderer through a resize + // message. If the change in fullscreen state doesn't cause a view resize + // then we must ensure web contents exit the fullscreen state by explicitly + // sending a resize message. This is required for the situation of the browser + // moving the view into a "browser fullscreen" state and then the contents + // entering "tab fullscreen". Exiting the contents "tab fullscreen" then won't + // have the side effect of the view resizing, hence the explicit call here is + // required. + if (!will_cause_resize) { + if (RenderWidgetHostView* rwhv = GetRenderWidgetHostView()) { + if (RenderWidgetHost* render_widget_host = rwhv->GetRenderWidgetHost()) { + render_widget_host->SynchronizeVisualProperties(); + } + } + } + + current_fullscreen_frame_id_ = GlobalRenderFrameHostId(); + + observers_.NotifyObservers( + &WebContentsObserver::DidToggleFullscreenModeForTab, IsFullscreen(), + will_cause_resize); + + if (safe_area_insets_host_) { + safe_area_insets_host_->DidExitFullscreen(); + } + + FullscreenContentsSet(GetBrowserContext())->erase(this); +} + +void WebContentsImpl::FullscreenStateChanged( + RenderFrameHostImpl* rfh, + bool is_fullscreen, + blink::mojom::FullscreenOptionsPtr options) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::FullscreenStateChanged", + "render_frame_host", rfh, "is_fullscreen", + is_fullscreen); + + GetView()->FullscreenStateChanged(is_fullscreen); + + if (is_fullscreen) { + if (options.is_null()) { + ReceivedBadMessage(rfh->GetProcess(), + bad_message::WCI_INVALID_FULLSCREEN_OPTIONS); + return; + } + + if (delegate_) { + delegate_->FullscreenStateChangedForTab(rfh, *options); + } + + if (!base::Contains(fullscreen_frames_, rfh)) { + fullscreen_frames_.insert(rfh); + FullscreenFrameSetUpdated(); + } + return; + } + + // If |rfh| is no longer in fullscreen, remove it and any descendants. + // See https://fullscreen.spec.whatwg.org. + size_t size_before_deletion = fullscreen_frames_.size(); + std::erase_if(fullscreen_frames_, [&](RenderFrameHostImpl* current) { + while (current) { + if (current == rfh) { + return true; + } + // We only look for direct parents. fencedframes will not enter + // fullscreen. + current = current->GetParent(); + } + return false; + }); + + if (size_before_deletion != fullscreen_frames_.size()) { + FullscreenFrameSetUpdated(); + } +} + +bool WebContentsImpl::CanUseWindowingControls( + RenderFrameHostImpl* requesting_frame) { + return GetDelegate() && + GetDelegate()->CanUseWindowingControls(requesting_frame); +} + +void WebContentsImpl::Maximize() { + if (!GetDelegate()) { + return; + } + GetDelegate()->MaximizeFromWebAPI(); +} + +void WebContentsImpl::Minimize() { + if (!GetDelegate()) { + return; + } + GetDelegate()->MinimizeFromWebAPI(); +} + +void WebContentsImpl::Restore() { + if (!GetDelegate()) { + return; + } + GetDelegate()->RestoreFromWebAPI(); +} + +// TODO(laurila, crbug.com/1466855): Map into new `ui::DisplayState` enum +// instead of `ui::WindowShowState`. +ui::WindowShowState WebContentsImpl::GetWindowShowState() { + return GetDelegate() ? GetDelegate()->GetWindowShowState() + : ui::SHOW_STATE_DEFAULT; +} + +blink::mojom::DevicePostureProvider* +WebContentsImpl::GetDevicePostureProvider() { + return DevicePostureProviderImpl::GetOrCreate(this); +} + +bool WebContentsImpl::GetResizable() { + return GetDelegate() && GetDelegate()->GetCanResize(); +} + +void WebContentsImpl::FullscreenFrameSetUpdated() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::FullscreenFrameSetUpdated"); + if (fullscreen_frames_.empty()) { + current_fullscreen_frame_id_ = GlobalRenderFrameHostId(); + return; + } + + // Find the current fullscreen frame and call the observers. + // If frame A is fullscreen, then frame B goes into inner fullscreen, then B + // exits fullscreen - that will result in A being fullscreen. + RenderFrameHostImpl* new_fullscreen_frame = *std::max_element( + fullscreen_frames_.begin(), fullscreen_frames_.end(), FrameCompareDepth); + + // If we have already notified observers about this frame then we should not + // fire the observers again. + if (new_fullscreen_frame->GetGlobalId() == current_fullscreen_frame_id_) { + return; + } + current_fullscreen_frame_id_ = new_fullscreen_frame->GetGlobalId(); + + observers_.NotifyObservers(&WebContentsObserver::DidAcquireFullscreen, + new_fullscreen_frame); + if (safe_area_insets_host_) { + safe_area_insets_host_->DidAcquireFullscreen(new_fullscreen_frame); + } +} + +PageVisibilityState WebContentsImpl::CalculatePageVisibilityState( + Visibility visibility) const { + // Only hide the page if there are no entities capturing screenshots + // or video (e.g. mirroring or WebXR). If there are, apply the correct state + // of kHidden or kHiddenButPainting. + bool web_contents_visible_in_vr = false; +#if BUILDFLAG(ENABLE_VR) + web_contents_visible_in_vr = + XRRuntimeManagerImpl::GetImmersiveSessionWebContents() == this; +#endif + + // If there are entities in Picture-in-Picture mode, don't activate the + // "disable rendering" optimization, since it still needs to drive the video, + // and possibly other elements on the page like canvas, to keep the picture in + // picture window up to date. + if (visibility == Visibility::VISIBLE || visible_capturer_count_ > 0 || + web_contents_visible_in_vr) { + return PageVisibilityState::kVisible; + } else if (hidden_capturer_count_ > 0 || has_picture_in_picture_video_ || + has_picture_in_picture_document_) { + return PageVisibilityState::kHiddenButPainting; + } + return PageVisibilityState::kHidden; +} + +PageVisibilityState WebContentsImpl::GetPageVisibilityState() const { + return CalculatePageVisibilityState(visibility_); +} + +void WebContentsImpl::UpdateVisibilityAndNotifyPageAndView( + Visibility new_visibility, + bool is_activity) { + DCHECK(!IsBeingDestroyed()); + + PageVisibilityState page_visibility = + CalculatePageVisibilityState(new_visibility); + + // A crashed frame might be covered by a sad tab. See docs on SadTabHelper + // exactly when it is or isn't. Either way, don't make it visible. + bool view_is_visible = + !IsCrashed() && page_visibility != PageVisibilityState::kHidden; + + // Prerendering relies on overriding FrameTree::Delegate::IsHidden, + // while for other frame trees FrameTree::Delegate::IsHidden + // resolves to WebContents' visibility, so we avoid Prerender RennderViewHosts + // here. + ForEachRenderViewHostTypes view_mask = + static_cast( + ForEachRenderViewHostTypes::kBackForwardCacheViews | + ForEachRenderViewHostTypes::kActiveViews); + + RenderViewHostIterationCallback update_frame_tree_visibility = + base::BindRepeating( + [](PageVisibilityState page_visibility, + RenderViewHostImpl* render_view_host) { + render_view_host->SetFrameTreeVisibility(page_visibility); + }, + page_visibility); + if (page_visibility != PageVisibilityState::kHidden) { + // We cannot show a page or capture video unless there is a valid renderer + // associated with this web contents. The navigation controller for this + // page must be set to active (allowing navigation to complete, a renderer + // and its associated views to be created, etc.) if any of these conditions + // holds. + // + // Previously, it was possible for browser-side code to try to capture video + // from a restored tab (for a variety of reasons, including the browser + // creating preview thumbnails) and the tab would never actually load. By + // keying this behavior off of |page_visibility| instead of just + // |new_visibility| we avoid this case. See crbug.com/1020782 for more + // context. + GetController().SetActive(true); + + // This shows the Page before showing the individual RenderWidgets, as + // RenderWidgets will work to produce compositor frames and handle input + // as soon as they are shown. But the Page and other classes do not expect + // to be producing frames when the Page is hidden. So we make sure the Page + // is shown first. + ForEachRenderViewHost(view_mask, update_frame_tree_visibility); + } + + // |GetRenderWidgetHostView()| can be null if the user middle clicks a link to + // open a tab in the background, then closes the tab before selecting it. + // This is because closing the tab calls WebContentsImpl::Destroy(), which + // removes the |GetRenderViewHost()|; then when we actually destroy the + // window, OnWindowPosChanged() notices and calls WasHidden() (which + // calls us). + if (auto* view = GetRenderWidgetHostView()) { + if (view_is_visible) { + static_cast(view)->ShowWithVisibility( + page_visibility); + } else if (new_visibility == Visibility::HIDDEN) { + view->Hide(); + } else { + view->WasOccluded(); + } + } + + SetVisibilityForChildViews(view_is_visible); + + // Make sure to call SetVisibilityAndNotifyObservers(VISIBLE) before notifying + // the CrossProcessFrameConnector. + if (new_visibility == Visibility::VISIBLE) { + if (is_activity) { + last_active_time_ = base::TimeTicks::Now(); + } + SetVisibilityAndNotifyObservers(new_visibility); + } + + if (page_visibility == PageVisibilityState::kHidden) { + // Similar to when showing the page, we only hide the page after + // hiding the individual RenderWidgets. + ForEachRenderViewHost(view_mask, update_frame_tree_visibility); + } else { + for (FrameTreeNode* node : + FrameTree::SubtreeAndInnerTreeNodes(GetPrimaryMainFrame())) { + RenderFrameProxyHost* proxy_to_parent_or_outer_delegate = + node->render_manager()->GetProxyToParentOrOuterDelegate(); + if (!proxy_to_parent_or_outer_delegate) { + continue; + } + + // DelegateWasShown keeps track of crash metrics. This is safe to + // call for GuestViews, and inner frame trees. + proxy_to_parent_or_outer_delegate->cross_process_frame_connector() + ->DelegateWasShown(); + } + } + + if (new_visibility != Visibility::VISIBLE) { + SetVisibilityAndNotifyObservers(new_visibility); + } + + if (base::FeatureList::IsEnabled(kUpdateInnerWebContentsVisibility)) { + // Inner WebContents are skipped in ForEachRenderViewHost() above, which + // causes inner WebContents to not be notified of visibility changes. + // + // Note: An inner WebContents that is hidden within the embedder could + // spuriously be set to visible (e.g. if its parent is display:none), but + // this is ignored here for now. + for (WebContents* inner : GetInnerWebContents()) { + static_cast(inner) + ->UpdateVisibilityAndNotifyPageAndView(new_visibility, is_activity); + } + } +} + +#if BUILDFLAG(IS_ANDROID) +void WebContentsImpl::UpdateUserGestureCarryoverInfo() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::UpdateUserGestureCarryoverInfo"); + if (delegate_) { + delegate_->UpdateUserGestureCarryoverInfo(this); + } +} +#endif + +bool WebContentsImpl::IsFullscreen() { + return delegate_ && delegate_->IsFullscreenForTabOrPending(this); +} + +bool WebContentsImpl::ShouldShowStaleContentOnEviction() { + return GetDelegate() && GetDelegate()->ShouldShowStaleContentOnEviction(this); +} + +blink::mojom::DisplayMode WebContentsImpl::GetDisplayMode() const { + return delegate_ ? delegate_->GetDisplayMode(this) + : blink::mojom::DisplayMode::kBrowser; +} + +void WebContentsImpl::RequestToLockPointer( + RenderWidgetHostImpl* render_widget_host, + bool user_gesture, + bool last_unlocked_by_target, + bool privileged) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RequestPointerLock", + "render_widget_host", render_widget_host, "privileged", + privileged); + if (render_widget_host->frame_tree()->is_fenced_frame()) { + // The renderer should have checked and disallowed the request for fenced + // frames in PointerLockController and dispatched pointerlockerror. Ignore + // the request and mark it as bad if it didn't happen for some reason. + ReceivedBadMessage(render_widget_host->GetProcess(), + bad_message::WCI_REQUEST_LOCK_MOUSE_FENCED_FRAME); + return; + } + for (WebContentsImpl* current = this; current; + current = current->GetOuterWebContents()) { + if (current->pointer_lock_widget_) { + render_widget_host->GotResponseToPointerLockRequest( + blink::mojom::PointerLockResult::kAlreadyLocked); + return; + } + } + + if (privileged) { + DCHECK(!GetOuterWebContents()); + pointer_lock_widget_ = render_widget_host; + render_widget_host->GotResponseToPointerLockRequest( + blink::mojom::PointerLockResult::kSuccess); + return; + } + + bool widget_in_frame_tree = false; + for (FrameTreeNode* node : primary_frame_tree_.Nodes()) { + if (node->current_frame_host()->GetRenderWidgetHost() == + render_widget_host) { + widget_in_frame_tree = true; + break; + } + } + + if (widget_in_frame_tree && delegate_) { + for (WebContentsImpl* current = this; current; + current = current->GetOuterWebContents()) { + current->pointer_lock_widget_ = render_widget_host; + } + observers_.NotifyObservers(&WebContentsObserver::PointerLockRequested); + delegate_->RequestPointerLock(this, user_gesture, last_unlocked_by_target); + } else { + render_widget_host->GotResponseToPointerLockRequest( + blink::mojom::PointerLockResult::kWrongDocument); + } +} + +void WebContentsImpl::LostPointerLock( + RenderWidgetHostImpl* render_widget_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::LostPointerLock", + "render_widget_host", render_widget_host); + CHECK(pointer_lock_widget_); + + if (WebContentsImpl::FromRenderWidgetHostImpl(pointer_lock_widget_) != this) { + return pointer_lock_widget_->delegate()->LostPointerLock( + render_widget_host); + } + + pointer_lock_widget_->SendPointerLockLost(); + for (WebContentsImpl* current = this; current; + current = current->GetOuterWebContents()) { + current->pointer_lock_widget_ = nullptr; + } + + if (delegate_) { + delegate_->LostPointerLock(); + } +} + +bool WebContentsImpl::HasPointerLock(RenderWidgetHostImpl* render_widget_host) { + // To verify if the mouse is locked, the mouse_lock_widget_ needs to be + // assigned to the widget that requested the mouse lock, and the top-level + // platform RenderWidgetHostView needs to hold the mouse lock from the OS. + auto* widget_host = GetTopLevelRenderWidgetHostView(); + return pointer_lock_widget_ == render_widget_host && widget_host && + widget_host->IsPointerLocked(); +} + +RenderWidgetHostImpl* WebContentsImpl::GetPointerLockWidget() { + auto* widget_host = GetTopLevelRenderWidgetHostView(); + if (widget_host && widget_host->IsPointerLocked()) { + return pointer_lock_widget_; + } + + return nullptr; +} + +bool WebContentsImpl::RequestKeyboardLock( + RenderWidgetHostImpl* render_widget_host, + bool esc_key_locked) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RequestKeyboardLock", + "render_widget_host", render_widget_host, + "esc_key_locked", esc_key_locked); + DCHECK(render_widget_host); + if (WebContentsImpl::FromRenderWidgetHostImpl(render_widget_host) != this) { + NOTREACHED_IN_MIGRATION(); + return false; + } + + // KeyboardLock is only supported when called by the top-level browsing + // context and is not supported in embedded content scenarios. + if (GetOuterWebContents()) { + render_widget_host->GotResponseToKeyboardLockRequest(false); + return false; + } + + esc_key_locked_ = esc_key_locked; + keyboard_lock_widget_ = render_widget_host; + + if (delegate_) { + observers_.NotifyObservers(&WebContentsObserver::KeyboardLockRequested); + delegate_->RequestKeyboardLock(this, esc_key_locked_); + } + return true; +} + +void WebContentsImpl::CancelKeyboardLock( + RenderWidgetHostImpl* render_widget_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::CancelKeyboardLockRequest", + "render_widget_host", render_widget_host); + if (!keyboard_lock_widget_ || render_widget_host != keyboard_lock_widget_) { + return; + } + + RenderWidgetHostImpl* old_keyboard_lock_widget = keyboard_lock_widget_; + keyboard_lock_widget_ = nullptr; + + if (delegate_) { + delegate_->CancelKeyboardLockRequest(this); + } + + old_keyboard_lock_widget->CancelKeyboardLock(); +} + +RenderWidgetHostImpl* WebContentsImpl::GetKeyboardLockWidget() { + return keyboard_lock_widget_; +} + +bool WebContentsImpl::OnRenderFrameProxyVisibilityChanged( + RenderFrameProxyHost* render_frame_proxy_host, + blink::mojom::FrameVisibility visibility) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::OnRenderFrameProxyVisibilityChanged", + "visibility", static_cast(visibility)); + + // Check that we are responsible for the RenderFrameProxyHost by checking that + // its FrameTreeNode matches our `primary_frame_tree_` root. Otherwise this is + // not a visibility change that affects all frames in an inner WebContents. + if (render_frame_proxy_host->frame_tree_node() != + primary_frame_tree_.root()) { + return false; + } + + DCHECK(GetOuterWebContents()); + + switch (visibility) { + case blink::mojom::FrameVisibility::kRenderedInViewport: + WasShown(); + break; + case blink::mojom::FrameVisibility::kNotRendered: + WasHidden(); + break; + case blink::mojom::FrameVisibility::kRenderedOutOfViewport: + WasOccluded(); + break; + } + return true; +} + +FrameTree* WebContentsImpl::CreateNewWindow( + RenderFrameHostImpl* opener, + const mojom::CreateNewWindowParams& params, + bool is_new_browsing_instance, + bool has_user_gesture, + SessionStorageNamespace* session_storage_namespace) { + TRACE_EVENT2("browser,content,navigation", "WebContentsImpl::CreateNewWindow", + "opener", opener, "params", params); + DCHECK(opener); + + if (active_file_chooser_) { + // Do not allow opening a new window or tab while a file select is active + // file chooser to avoid user confusion over which tab triggered the file + // chooser. + opener->AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kWarning, + "window.open blocked due to active file chooser."); + return nullptr; + } + + int render_process_id = opener->GetProcess()->GetID(); + SiteInstanceImpl* source_site_instance = opener->GetSiteInstance(); + const auto& partition_config = + source_site_instance->GetStoragePartitionConfig(); + + { + StoragePartition* partition = + GetBrowserContext()->GetStoragePartition(source_site_instance); + DOMStorageContextWrapper* dom_storage_context = + static_cast( + partition->GetDOMStorageContext()); + SessionStorageNamespaceImpl* session_storage_namespace_impl = + static_cast(session_storage_namespace); + CHECK(session_storage_namespace_impl->IsFromContext(dom_storage_context)); + } + + if (delegate_ && delegate_->IsWebContentsCreationOverridden( + source_site_instance, params.window_container_type, + opener->GetLastCommittedURL(), params.frame_name, + params.target_url)) { + auto* web_contents_impl = + static_cast(delegate_->CreateCustomWebContents( + opener, source_site_instance, is_new_browsing_instance, + opener->GetLastCommittedURL(), params.frame_name, params.target_url, + partition_config, session_storage_namespace)); + if (!web_contents_impl) { + return nullptr; + } + web_contents_impl->is_popup_ = + params.disposition == WindowOpenDisposition::NEW_POPUP; + return &web_contents_impl->GetPrimaryFrameTree(); + } + + bool renderer_started_hidden = + params.disposition == WindowOpenDisposition::NEW_BACKGROUND_TAB; + + bool is_guest = IsGuest(); + + // We usually create the new window in the same BrowsingInstance (group of + // script-related windows), by passing in the current SiteInstance. However, + // if the opener is being suppressed, we need to ensure that the new + // SiteInstance is created in a new BrowsingInstance. + scoped_refptr site_instance; + if (params.opener_suppressed) { + if (is_guest) { + // For guests, noopener windows can be created in a new BrowsingInstance + // as long as they preserve the guest's StoragePartition. + site_instance = + SiteInstance::CreateForGuest(GetBrowserContext(), partition_config); + } else { + site_instance = SiteInstance::Create(GetBrowserContext()); + } + } else { + site_instance = source_site_instance; + } + + // Create the new web contents. This will automatically create the new + // WebContentsView. In the future, we may want to create the view separately. + CreateParams create_params(GetBrowserContext(), site_instance.get()); + create_params.main_frame_name = params.frame_name; + create_params.opener_render_process_id = render_process_id; + create_params.opener_render_frame_id = opener->GetRoutingID(); + create_params.opener_suppressed = params.opener_suppressed; + create_params.initially_hidden = renderer_started_hidden; + create_params.initial_popup_url = params.target_url; + + // Even though all codepaths leading here are in response to a renderer + // trying to open a new window, if the new window ends up in a different + // browsing instance, then the RenderViewHost, RenderWidgetHost, + // RenderFrameHost constellation is effectively browser initiated + // the opener's process will not given the routing IDs for the new + // objects. + create_params.renderer_initiated_creation = !is_new_browsing_instance; + + if (params.pip_options) { + create_params.picture_in_picture_options = *(params.pip_options); + } + + // Check whether there is an available prerendered page for this navigation if + // this is not for guest. If it exists, take WebContents pre-created for + // hosting the prerendered page instead of creating new WebContents. + // TODO(crbug.com/40234240): Instead of filtering out the guest case here, + // check it and drop prerender requests before starting prerendering. + std::unique_ptr new_contents; + if (base::FeatureList::IsEnabled(blink::features::kPrerender2InNewTab) && + !is_guest) { + new_contents = + GetPrerenderHostRegistry()->TakePreCreatedWebContentsForNewTabIfExists( + params, create_params); + if (new_contents) { + // The SiteInstance of the pre-created WebContents should be in a + // different BrowsingInstance from the source SiteInstance, while they + // should be in the same StoragePartition. + SiteInstanceImpl* new_site_instance = new_contents->GetSiteInstance(); + DCHECK(!new_site_instance->IsRelatedSiteInstance(source_site_instance)); + DCHECK_EQ(new_site_instance->GetStoragePartitionConfig(), + source_site_instance->GetStoragePartitionConfig()); + } + } + + if (!new_contents) { + if (!is_guest) { + create_params.context = view_->GetNativeView(); + new_contents = WebContentsImpl::Create(create_params); + } else { + new_contents = + GetBrowserPluginGuest()->CreateNewGuestWindow(create_params); + } + new_contents->GetController().SetSessionStorageNamespace( + partition_config, session_storage_namespace); + } + + auto* new_contents_impl = new_contents.get(); + new_contents_impl->is_popup_ = + params.disposition == WindowOpenDisposition::NEW_POPUP; + + // If the new frame has a name, make sure any SiteInstances that can find + // this named frame have proxies for it. Must be called after + // SetSessionStorageNamespace, since this calls CreateRenderView, which uses + // GetSessionStorageNamespace. + if (!params.frame_name.empty()) { + new_contents_impl->GetRenderManager()->CreateProxiesForNewNamedFrame( + new_contents_impl->GetPrimaryMainFrame()->browsing_context_state()); + } + + // Save the window for later if we're not suppressing the opener (since it + // will be shown immediately). + if (!params.opener_suppressed) { + if (!is_guest) { + WebContentsView* new_view = new_contents_impl->view_.get(); + + // TODO(brettw): It seems bogus that we have to call this function on the + // newly created object and give it one of its own member variables. + RenderWidgetHostView* widget_view = new_view->CreateViewForWidget( + new_contents_impl->GetRenderViewHost()->GetWidget()); + view_->SetOverscrollControllerEnabled(CanOverscrollContent()); + if (!renderer_started_hidden) { + // RenderWidgets for frames always initialize as hidden. If the renderer + // created this window as visible, then we show it here. + widget_view->Show(); + } + } + // Save the created window associated with the route so we can show it + // later. + // + // TODO(ajwong): This should be keyed off the RenderFrame routing id or the + // FrameTreeNode id instead of the routing id of the Widget for the main + // frame. https://crbug.com/545684 + int32_t main_frame_routing_id = new_contents_impl->GetPrimaryMainFrame() + ->GetRenderWidgetHost() + ->GetRoutingID(); + GlobalRoutingID id(render_process_id, main_frame_routing_id); + pending_contents_[id] = + CreatedWindow(std::move(new_contents), params.target_url); + AddWebContentsDestructionObserver(new_contents_impl); + } + + if (delegate_) { + delegate_->WebContentsCreated(this, render_process_id, + opener->GetRoutingID(), params.frame_name, + params.target_url, new_contents_impl); + } + + observers_.NotifyObservers(&WebContentsObserver::DidOpenRequestedURL, + new_contents_impl, opener, params.target_url, + params.referrer.To(), params.disposition, + ui::PAGE_TRANSITION_LINK, + false, // started_from_context_menu + true); // renderer_initiated + + if (params.opener_suppressed) { + // When the opener is suppressed, the original renderer cannot access the + // new window. As a result, we need to show and navigate the window here. + bool was_blocked = false; + + if (delegate_) { + base::WeakPtr weak_new_contents = + new_contents_impl->weak_factory_.GetWeakPtr(); + + delegate_->AddNewContents( + this, std::move(new_contents), params.target_url, params.disposition, + *params.features, has_user_gesture, &was_blocked); + // The delegate may delete |new_contents_impl| during AddNewContents(). + if (!weak_new_contents) { + return nullptr; + } + } + + if (!was_blocked) { + std::unique_ptr load_params = + std::make_unique( + params.target_url); + load_params->initiator_origin = opener->GetLastCommittedOrigin(); + load_params->initiator_process_id = opener->GetProcess()->GetID(); + load_params->initiator_frame_token = opener->GetFrameToken(); + // Avoiding setting |load_params->source_site_instance| when + // |opener_suppressed| is true, because in that case we do not want to use + // the old SiteInstance and/or BrowsingInstance. See also the test here: + // NewPopupCOOP_SameOriginPolicyAndCrossOriginIframeSetsNoopener. + load_params->referrer = params.referrer.To(); + load_params->transition_type = ui::PAGE_TRANSITION_LINK; + load_params->is_renderer_initiated = true; + load_params->was_opener_suppressed = true; + load_params->has_user_gesture = has_user_gesture; + load_params->is_form_submission = params.is_form_submission; + if (params.form_submission_post_data) { + load_params->load_type = NavigationController::LOAD_TYPE_HTTP_POST; + load_params->post_data = params.form_submission_post_data; + load_params->post_content_type = + params.form_submission_post_content_type; + } + load_params->impression = params.impression; + load_params->override_user_agent = + new_contents_impl->should_override_user_agent_in_new_tabs_ + ? NavigationController::UA_OVERRIDE_TRUE + : NavigationController::UA_OVERRIDE_FALSE; + load_params->download_policy = params.download_policy; + load_params->initiator_activation_and_ad_status = + params.initiator_activation_and_ad_status; + + if (delegate_ && !is_guest && + !delegate_->ShouldResumeRequestsForCreatedWindow()) { + // We are in asynchronous add new contents path, delay navigation. + DCHECK(!new_contents_impl->delayed_open_url_params_); + new_contents_impl->delayed_load_url_params_ = std::move(load_params); + } else { + new_contents_impl->GetController().LoadURLWithParams( + *load_params.get()); + if (!is_guest) { + new_contents_impl->Focus(); + } + } + } + } + return &new_contents_impl->GetPrimaryFrameTree(); +} + +RenderWidgetHostImpl* WebContentsImpl::CreateNewPopupWidget( + base::SafeRef site_instance_group, + int32_t route_id, + mojo::PendingAssociatedReceiver + blink_popup_widget_host, + mojo::PendingAssociatedReceiver blink_widget_host, + mojo::PendingAssociatedRemote blink_widget) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::CreateNewPopupWidget", + "route_id", route_id); + + if (visibility_ != Visibility::VISIBLE) { + // Don't create popups for hidden tabs. http://crbug.com/1521345 + return nullptr; + } + + RenderWidgetHostImpl* widget_host = RenderWidgetHostFactory::CreateSelfOwned( + &primary_frame_tree_, this, site_instance_group, route_id, IsHidden()); + + widget_host->BindWidgetInterfaces(std::move(blink_widget_host), + std::move(blink_widget)); + widget_host->BindPopupWidgetInterface(std::move(blink_popup_widget_host)); + RenderWidgetHostViewBase* widget_view = + static_cast( + view_->CreateViewForChildWidget(widget_host)); + if (!widget_view) { + return nullptr; + } + widget_view->SetWidgetType(WidgetType::kPopup); + + // Save the created widget associated with the route so we can show it later. + pending_widgets_.insert( + {GlobalRoutingID(site_instance_group->process()->GetID(), route_id), + widget_host}); + AddRenderWidgetHostDestructionObserver(widget_host); + + return widget_host; +} + +int64_t WebContentsImpl::AdjustWindowRect(gfx::Rect* bounds, + RenderFrameHostImpl* opener) { + // Auto-resize can override other mechanisms for enforcing min/max window size + // for some modals and popups to fit the size of their contents. Borderless + // apps shouldn't have overlap with auto-resize mode windows. + if (!(GetRenderWidgetHostView() && + static_cast(GetRenderWidgetHostView()) + ->IsAutoResizeEnabled())) { + // For borderless apps the minimum size is + // `blink::kMinimumBorderlessWindowSize` instead of the default + // `blink::kMinimumWindowSize`. + int minimum_size = + GetDisplayMode() == blink::mojom::DisplayMode::kBorderless && + IsWindowManagementGranted(opener) + ? blink::kMinimumBorderlessWindowSize + : blink::kMinimumWindowSize; + AdjustWindowRectForMinimum(bounds, minimum_size); + } + + int64_t display_id = display::kInvalidDisplayId; + if (*bounds != gfx::Rect()) { + display_id = AdjustWindowRectForDisplay(bounds, opener); + } + return display_id; +} + +void WebContentsImpl::ShowCreatedWindow( + RenderFrameHostImpl* opener, + int main_frame_widget_route_id, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& window_features, + bool user_gesture) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::ShowCreatedWindow", + "opener", opener, "main_frame_widget_route_id", + main_frame_widget_route_id); + // This method is the renderer requesting an existing top level window to + // show a new top level window that the renderer created. Each top level + // window is associated with a WebContents. In this case it was created + // earlier but showing it was deferred until the renderer requested for it + // to be shown. We find that previously created WebContents here. + // TODO(danakj): Why do we defer this show step until the renderer asks for it + // when it will always do so. What needs to happen in the renderer before we + // reach here? + std::optional owned_created = GetCreatedWindow( + opener->GetProcess()->GetID(), main_frame_widget_route_id); + + // The browser may have rejected the request to make a new window, or the + // renderer could be requesting to show a previously shown window (occurs when + // mojom::CreateNewWindowStatus::kReuse is used). Ignore the request then. + if (!owned_created || !owned_created->contents) { + return; + } + + if (base::FeatureList::IsEnabled(features::kWindowOpenFileSelectFix) && + active_file_chooser_) { + // Do not allow opening a new window or tab while a file select is active + // file chooser to avoid user confusion over which tab triggered the file + // chooser. + opener->AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kWarning, + "window.open blocked due to active file chooser."); + return; + } + + WebContentsImpl* created = owned_created->contents.get(); + + // This uses the delegate for the WebContents where the window was created + // from, to control how to show the newly created window. + WebContentsDelegate* delegate = GetDelegate(); + + // Individual members of |window_features.bounds| may be 0 to indicate that + // the window.open() feature string did not specify a value. This code does + // not distinguish between an unspecified value and 0. + // Assume that if any single value is non-zero, all values should be used. + // TODO(crbug.com/40092782): Utilize window_features.has_x and others. + blink::mojom::WindowFeatures adjusted_features = window_features; + int64_t display_id = AdjustWindowRect(&adjusted_features.bounds, opener); + + // Drop fullscreen when opening a WebContents to prohibit deceptive behavior. + // Only drop fullscreen on the specific destination display, if it is known. + // This supports sites using cross-screen window management capabilities to + // retain fullscreen and open a window on another screen. + ForSecurityDropFullscreen(display_id).RunAndReset(); + + // The delegate can be null in tests, so we must check for it :(. + if (delegate) { + // Mark the web contents as pending resume, then immediately do + // the resume if the delegate wants it. + created->is_resume_pending_ = true; + if (delegate->ShouldResumeRequestsForCreatedWindow()) { + created->ResumeLoadingCreatedWebContents(); + } + + delegate->AddNewContents(this, std::move(owned_created->contents), + std::move(owned_created->target_url), disposition, + adjusted_features, user_gesture, nullptr); + } +} + +void WebContentsImpl::ShowCreatedWidget(int process_id, + int widget_route_id, + const gfx::Rect& initial_rect, + const gfx::Rect& initial_anchor_rect) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::ShowCreatedWidget", + "process_id", process_id, "widget_route_id", + widget_route_id); + RenderWidgetHostViewBase* widget_host_view = + static_cast( + GetCreatedWidget(process_id, widget_route_id)); + if (!widget_host_view) { + return; + } + + // GetOutermostWebContents() returns |this| if there are no outer WebContents. + auto* outer_web_contents = GetOuterWebContents(); + auto* outermost_web_contents = GetOutermostWebContents(); + RenderWidgetHostView* view = + outermost_web_contents->GetRenderWidgetHostView(); + // It's not entirely obvious why we need the transform only in the case where + // the outer webcontents is not the same as the outermost webcontents. It may + // be due to the fact that oopifs that are children of the mainframe get + // correct values for their screenrects, but deeper cross-process frames do + // not. Hopefully this can be resolved with https://crbug.com/928825. + // Handling these cases separately is needed for http://crbug.com/1015298. + bool needs_transform = this != outermost_web_contents && + outermost_web_contents != outer_web_contents; + + gfx::Rect transformed_rect(initial_rect); + gfx::Rect transformed_anchor_rect(initial_anchor_rect); + RenderWidgetHostView* this_view = GetRenderWidgetHostView(); + if (needs_transform) { + // We need to transform the coordinates of initial_rect. + gfx::Point origin = + this_view->TransformPointToRootCoordSpace(initial_rect.origin()); + gfx::Point bottom_right = + this_view->TransformPointToRootCoordSpace(initial_rect.bottom_right()); + transformed_rect = + gfx::Rect(origin.x(), origin.y(), bottom_right.x() - origin.x(), + bottom_right.y() - origin.y()); + + origin = + this_view->TransformPointToRootCoordSpace(initial_anchor_rect.origin()); + bottom_right = this_view->TransformPointToRootCoordSpace( + initial_anchor_rect.bottom_right()); + transformed_anchor_rect = + gfx::Rect(origin.x(), origin.y(), bottom_right.x() - origin.x(), + bottom_right.y() - origin.y()); + } + + RenderWidgetHostImpl* render_widget_host_impl = widget_host_view->host(); + auto permission_exclusion_area_bounds = + PermissionControllerImpl::FromBrowserContext(GetBrowserContext()) + ->GetExclusionAreaBoundsInScreen(outermost_web_contents); + if (permission_exclusion_area_bounds && + permission_exclusion_area_bounds->Intersects(transformed_rect)) { + render_widget_host_impl->ShutdownAndDestroyWidget(true); + return; + } + + widget_host_view->InitAsPopup(view, transformed_rect, + transformed_anchor_rect); + + // Renderer-owned popup widgets wait for the renderer to request for them + // to be shown. We signal that this condition is satisfied by calling Init(). + render_widget_host_impl->Init(); +} + +std::optional WebContentsImpl::GetCreatedWindow( + int process_id, + int main_frame_widget_route_id) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::GetCreatedWindow", + "process_id", process_id, "main_frame_widget_route_id", + main_frame_widget_route_id); + + auto key = GlobalRoutingID(process_id, main_frame_widget_route_id); + auto iter = pending_contents_.find(key); + + // Certain systems can block the creation of new windows. If we didn't succeed + // in creating one, just return NULL. + if (iter == pending_contents_.end()) { + return std::nullopt; + } + + CreatedWindow result = std::move(iter->second); + WebContentsImpl* new_contents = result.contents.get(); + pending_contents_.erase(key); + RemoveWebContentsDestructionObserver(new_contents); + + // Don't initialize the guest WebContents immediately. + if (new_contents->IsGuest()) { + return result; + } + + if (!new_contents->GetPrimaryMainFrame() + ->GetProcess() + ->IsInitializedAndNotDead() || + !new_contents->GetPrimaryMainFrame()->GetView()) { + return std::nullopt; + } + + return result; +} + +RenderWidgetHostView* WebContentsImpl::GetCreatedWidget(int process_id, + int route_id) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::GetCreatedWidget", + "process_id", process_id, "route_id", route_id); + + auto iter = pending_widgets_.find(GlobalRoutingID(process_id, route_id)); + if (iter == pending_widgets_.end()) { + DCHECK(false); + return nullptr; + } + + RenderWidgetHost* widget_host = iter->second; + pending_widgets_.erase(GlobalRoutingID(process_id, route_id)); + RemoveRenderWidgetHostDestructionObserver(widget_host); + + if (!widget_host->GetProcess()->IsInitializedAndNotDead()) { + // The view has gone away or the renderer crashed. Nothing to do. + return nullptr; + } + + return widget_host->GetView(); +} + +void WebContentsImpl::CreateMediaPlayerHostForRenderFrameHost( + RenderFrameHostImpl* frame_host, + mojo::PendingAssociatedReceiver receiver) { + media_web_contents_observer()->BindMediaPlayerHost(frame_host->GetGlobalId(), + std::move(receiver)); +} + +void WebContentsImpl::RequestMediaAccessPermission( + const MediaStreamRequest& request, + MediaResponseCallback callback) { + OPTIONAL_TRACE_EVENT2("content", + "WebContentsImpl::RequestMediaAccessPermission", + "render_process_id", request.render_process_id, + "render_frame_id", request.render_frame_id); + + if (delegate_) { + delegate_->RequestMediaAccessPermission(this, request, std::move(callback)); + } else { + std::move(callback).Run( + blink::mojom::StreamDevicesSet(), + blink::mojom::MediaStreamRequestResult::FAILED_DUE_TO_SHUTDOWN, + std::unique_ptr()); + } +} + +bool WebContentsImpl::CheckMediaAccessPermission( + RenderFrameHostImpl* render_frame_host, + const url::Origin& security_origin, + blink::mojom::MediaStreamType type) { + OPTIONAL_TRACE_EVENT2("content", + "WebContentsImpl::CheckMediaAccessPermission", + "render_frame_host", render_frame_host, + "security_origin", security_origin); + + DCHECK(type == blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE || + type == blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE); + return delegate_ && delegate_->CheckMediaAccessPermission( + render_frame_host, security_origin, type); +} + +void WebContentsImpl::SetCaptureHandleConfig( + blink::mojom::CaptureHandleConfigPtr config) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + + if (capture_handle_config_ == *config) { + return; // Avoid unnecessary notifications. + } + + capture_handle_config_ = std::move(*config); + + // Propagates the capture-handle-config inside of the browser process. + // Only render processes which are eligible based on |permittedOrigins| + // will get this. + observers_.NotifyObservers(&WebContentsObserver::OnCaptureHandleConfigUpdate, + capture_handle_config_); +} + +bool WebContentsImpl::IsJavaScriptDialogShowing() const { + return is_showing_javascript_dialog_; +} + +bool WebContentsImpl::ShouldIgnoreUnresponsiveRenderer() { + // Suppress unresponsive renderers if the command line asks for it. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableHangMonitor)) { + return true; + } + + if (IsBeingDestroyed()) { + return true; + } + + if (suppress_unresponsive_renderer_count_ > 0) { + return true; + } + + // Ignore unresponsive renderers if the debugger is attached to them since the + // unresponsiveness might be a result of the renderer sitting on a breakpoint. + // +#if BUILDFLAG(IS_WIN) + // Check if a windows debugger is attached to the renderer process. + base::ProcessHandle process_handle = + GetPrimaryMainFrame()->GetProcess()->GetProcess().Handle(); + BOOL debugger_present = FALSE; + if (CheckRemoteDebuggerPresent(process_handle, &debugger_present) && + debugger_present) { + return true; + } +#endif // BUILDFLAG(IS_WIN) + + // TODO(pfeldman): Fix this to only return true if the renderer is *actually* + // sitting on a breakpoint. https://crbug.com/684202 + return DevToolsAgentHost::IsDebuggerAttached(this); +} + +ui::AXMode WebContentsImpl::GetAccessibilityMode() { + return accessibility_mode_; +} + +void WebContentsImpl::AXTreeIDForMainFrameHasChanged() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::AXTreeIDForMainFrameHasChanged"); + + RenderWidgetHostViewBase* rwhv = + static_cast(GetRenderWidgetHostView()); + if (rwhv) { + rwhv->SetMainFrameAXTreeID(GetPrimaryMainFrame()->GetAXTreeID()); + } + + observers_.NotifyObservers( + &WebContentsObserver::AXTreeIDForMainFrameHasChanged); +} + +void WebContentsImpl::ProcessAccessibilityUpdatesAndEvents( + ui::AXUpdatesAndEvents& details) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::AccessibilityEventReceived"); + + // First, supply the data to consumers that won't change it. + observers_.NotifyObservers(&WebContentsObserver::AccessibilityEventReceived, + details); + + // Next, supply the data to consumers that may change it or who need to avoid + // extra copying. Note that this also includes those who will pass to mojo + // pipes not taking const. + // TODO(accessibility): add support for this. WebContentsDelegate isn't the + // right abstraction since it contains many other side effects. +} + +void WebContentsImpl::AccessibilityLocationChangesReceived( + const std::vector& details) { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::AccessibilityLocationChangesReceived"); + observers_.NotifyObservers( + &WebContentsObserver::AccessibilityLocationChangesReceived, details); +} + +ui::AXNode* WebContentsImpl::GetAccessibilityRootNode() { + BrowserAccessibilityManager* manager = GetRootBrowserAccessibilityManager(); + if (!manager || !manager->ax_tree()) { + return nullptr; + } + return manager->ax_tree()->root(); +} + +std::string WebContentsImpl::DumpAccessibilityTree( + bool internal, + std::vector property_filters) { + ui::AXApiType::Type api_type = + internal ? ui::AXApiType::Type(ui::AXApiType::kBlink) + : AXInspectFactory::DefaultPlatformFormatterType(); + return DumpAccessibilityTree(api_type, property_filters); +} + +std::string WebContentsImpl::DumpAccessibilityTree( + ui::AXApiType::Type api_type, + std::vector property_filters) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DumpAccessibilityTree"); + auto* ax_mgr = GetOrCreateRootBrowserAccessibilityManager(); + // Since for Web Content we get the AXTree updates through the renderer at a + // point after the manager is created, there are cases where at this point in + // the lifecycle the AXTree associated with `ax_mgr` does not have a valid + // tree ID. As such, if this is the case we return an empty string early. If + // we don't have this check, there will be a scenario where we then try to get + // the manager using the ID (which at this point is invalid) which leads to a + // crash. See https://crbug.com/1405036. + if (!ax_mgr || !ax_mgr->HasValidTreeID()) { + return "-"; + } + + // Developer mode: crash immediately on any accessibility fatal error. + // This only runs during integration tests, or if a developer is + // using an inspection tool, e.g. chrome://accessibility. + ui::AXTreeManager::AlwaysFailFast(); + DCHECK(base::Contains(AXInspectFactory::SupportedApis(), api_type)); + std::unique_ptr formatter = + AXInspectFactory::CreateFormatter(api_type); + + formatter->SetPropertyFilters(property_filters); + return formatter->Format(ax_mgr->GetBrowserAccessibilityRoot()); +} + +void WebContentsImpl::RecordAccessibilityEvents( + bool start_recording, + std::optional callback) { + RecordAccessibilityEvents(AXInspectFactory::DefaultPlatformRecorderType(), + start_recording, callback); +} +void WebContentsImpl::RecordAccessibilityEvents( + ui::AXApiType::Type api_type, + bool start_recording, + std::optional callback) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::RecordAccessibilityEvents"); + + // Only pass a callback to RecordAccessibilityEvents when starting to record. + DCHECK_EQ(start_recording, callback.has_value()); + if (start_recording) { + // TODO(grt): Do we need to do the same for all inner WebContentses?. + recording_mode_ = + BrowserAccessibilityState::GetInstance() + ->CreateScopedModeForWebContents(this, ui::kAXModeBasic); + auto* ax_mgr = GetOrCreateRootBrowserAccessibilityManager(); + CHECK(ax_mgr); + base::ProcessId pid = base::Process::Current().Pid(); + gfx::AcceleratedWidget widget = + ax_mgr->GetBrowserAccessibilityRoot() + ->GetTargetForNativeAccessibilityEvent(); + + DCHECK(base::Contains(AXInspectFactory::SupportedApis(), api_type)); + event_recorder_ = content::AXInspectFactory::CreateRecorder( + api_type, ax_mgr, pid, ui::AXTreeSelector(widget)); + event_recorder_->ListenToEvents(*callback); + } else { + if (event_recorder_) { + event_recorder_->WaitForDoneRecording(); + event_recorder_.reset(nullptr); + } + recording_mode_.reset(); + } +} + +void WebContentsImpl::UnrecoverableAccessibilityError() { + SetAccessibilityMode(ui::AXMode::kNone); + unrecoverable_accessibility_error_ = true; +} + +device::mojom::GeolocationContext* WebContentsImpl::GetGeolocationContext() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GetGeolocationContext"); + if (delegate_) { + auto* installed_webapp_context = + delegate_->GetInstalledWebappGeolocationContext(); + if (installed_webapp_context) { + return installed_webapp_context; + } + } + + if (!geolocation_context_) { + GetDeviceService().BindGeolocationContext( + geolocation_context_.BindNewPipeAndPassReceiver()); + } + return geolocation_context_.get(); +} + +device::mojom::WakeLockContext* WebContentsImpl::GetWakeLockContext() { + if (!enable_wake_locks_) { + return nullptr; + } + if (!wake_lock_context_host_) { + wake_lock_context_host_ = std::make_unique(this); + } + return wake_lock_context_host_->GetWakeLockContext(); +} + +#if BUILDFLAG(IS_ANDROID) +void WebContentsImpl::GetNFC( + RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) { + if (!nfc_host_) { + nfc_host_ = std::make_unique(this); + } + nfc_host_->GetNFC(render_frame_host, std::move(receiver)); +} +#endif + +void WebContentsImpl::SendScreenRects() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SendScreenRects"); + + DCHECK(!IsBeingDestroyed()); + + GetPrimaryMainFrame()->ForEachRenderFrameHost( + [](RenderFrameHostImpl* render_frame_host) { + if (render_frame_host->is_local_root()) { + render_frame_host->GetRenderWidgetHost()->SendScreenRects(); + } + }); +} + +void WebContentsImpl::SendActiveState(bool active) { + DCHECK(!IsBeingDestroyed()); + + // Replicate the active state to all LocalRoots. + GetPrimaryMainFrame()->ForEachRenderFrameHost( + [active](RenderFrameHostImpl* render_frame_host) { + if (render_frame_host->is_local_root()) { + render_frame_host->GetRenderWidgetHost()->SetActive(active); + } + }); +} + +TextInputManager* WebContentsImpl::GetTextInputManager() { + if (suppress_ime_events_for_testing_) { + return nullptr; + } + + if (GetOuterWebContents()) { + return GetOuterWebContents()->GetTextInputManager(); + } + + if (!text_input_manager_ && !browser_plugin_guest_) { + text_input_manager_ = std::make_unique(); + } + + return text_input_manager_.get(); +} + +bool WebContentsImpl::IsWidgetForPrimaryMainFrame( + RenderWidgetHostImpl* render_widget_host) { + return render_widget_host == GetPrimaryMainFrame()->GetRenderWidgetHost(); +} + +BrowserAccessibilityManager* +WebContentsImpl::GetRootBrowserAccessibilityManager() { + RenderFrameHostImpl* rfh = + static_cast(GetPrimaryMainFrame()); + return rfh ? rfh->browser_accessibility_manager() : nullptr; +} + +BrowserAccessibilityManager* +WebContentsImpl::GetOrCreateRootBrowserAccessibilityManager() { + RenderFrameHostImpl* rfh = + static_cast(GetPrimaryMainFrame()); + return rfh ? rfh->GetOrCreateBrowserAccessibilityManager() : nullptr; +} + +void WebContentsImpl::ExecuteEditCommand( + const std::string& command, + const std::optional& value) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ExecuteEditCommand"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + input_handler->ExecuteEditCommand(command, value); +} + +void WebContentsImpl::MoveRangeSelectionExtent(const gfx::Point& extent) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MoveRangeSelectionExtent"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + input_handler->MoveRangeSelectionExtent(extent); +} + +void WebContentsImpl::SelectRange(const gfx::Point& base, + const gfx::Point& extent) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SelectRange"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + input_handler->SelectRange(base, extent); +} + +void WebContentsImpl::SelectAroundCaret( + blink::mojom::SelectionGranularity granularity, + bool should_show_handle, + bool should_show_context_menu) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SelectAroundCaret"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->SelectAroundCaret(granularity, should_show_handle, + should_show_context_menu, base::DoNothing()); +} + +void WebContentsImpl::MoveCaret(const gfx::Point& extent) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::MoveCaret"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + input_handler->MoveCaret(extent); +} + +void WebContentsImpl::AdjustSelectionByCharacterOffset( + int start_adjust, + int end_adjust, + bool show_selection_menu) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::AdjustSelectionByCharacterOffset"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + using blink::mojom::SelectionMenuBehavior; + input_handler->AdjustSelectionByCharacterOffset( + start_adjust, end_adjust, + show_selection_menu ? SelectionMenuBehavior::kShow + : SelectionMenuBehavior::kHide); +} + +void WebContentsImpl::ResizeDueToAutoResize( + RenderWidgetHostImpl* render_widget_host, + const gfx::Size& new_size) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ResizeDueToAutoResize", + "render_widget_host", render_widget_host); + if (render_widget_host != GetRenderViewHost()->GetWidget()) { + return; + } + + if (delegate_) { + delegate_->ResizeDueToAutoResize(this, new_size); + } +} + +WebContents* WebContentsImpl::OpenURL( + const OpenURLParams& params, + base::OnceCallback + navigation_handle_callback) { + TRACE_EVENT1("content", "WebContentsImpl::OpenURL", "url", params.url); +#if DCHECK_IS_ON() + DCHECK(params.Valid()); +#endif + + if (!delegate_) { + // Embedder can delay setting a delegate on new WebContents with + // WebContentsDelegate::ShouldResumeRequestsForCreatedWindow. In the mean + // time, navigations, including the initial one, that goes through OpenURL + // should be delayed until embedder is ready to resume loading. + delayed_open_url_params_ = std::make_unique(params); + delayed_navigation_handle_callback_ = std::move(navigation_handle_callback); + + // If there was a navigation deferred when creating the window through + // CreateNewWindow, drop it in favor of this navigation. + delayed_load_url_params_.reset(); + + return nullptr; + } + + RenderFrameHost* source_render_frame_host = RenderFrameHost::FromID( + params.source_render_process_id, params.source_render_frame_id); + + // Prevent frames that are not active (e.g. a prerendering page) from opening + // new windows, tabs, popups, etc. + if (params.disposition != WindowOpenDisposition::CURRENT_TAB && + source_render_frame_host && !source_render_frame_host->IsActive()) { + return nullptr; + } + + if (params.frame_tree_node_id != FrameTreeNode::kFrameTreeNodeInvalidId) { + if (auto* frame_tree_node = + FrameTreeNode::GloballyFindByID(params.frame_tree_node_id)) { + // If a frame tree node ID is specified and it exists, ensure it is for a + // node within this WebContents. Note: this WebContents could be hosting + // multiple frame trees (e.g. prerendering) so it's not enough to check + // against this->primary_frame_tree_. Check against page_delegate(), which + // is always a WebContentsImpl, while delegate() may be implemented by + // something else such as for prerendered frame trees. + FrameTree& frame_tree = frame_tree_node->frame_tree(); + CHECK_EQ(frame_tree.page_delegate(), this); + + // Prerendering and fenced frame navigations are hidden from embedders. + // If the navigation is targeting a frame in a prerendering or fenced + // frame tree, we shouldn't run that navigation through the embedder + // delegate. Embedder implementations of + // `WebContentsDelegate::OpenURLFromTab` assume that the primary + // frame tree Navigation controller should be used for navigating. + // Instead, we just navigate directly on the relevant frame + // tree. + if (frame_tree.is_prerendering() || + frame_tree_node->IsInFencedFrameTree()) { + DCHECK_EQ(params.disposition, WindowOpenDisposition::CURRENT_TAB); + frame_tree.controller().LoadURLWithParams( + NavigationController::LoadURLParams(params)); + return this; + } + } else { + // If the node doesn't exist it was probably removed from its frame tree. + // In that case, abort since continuing would navigate the root frame. + return nullptr; + } + } + + WebContents* new_contents = delegate_->OpenURLFromTab( + this, params, std::move(navigation_handle_callback)); + + if (source_render_frame_host && params.source_site_instance) { + CHECK_EQ(source_render_frame_host->GetSiteInstance(), + params.source_site_instance.get()); + } + + if (new_contents && source_render_frame_host && new_contents != this) { + observers_.NotifyObservers( + &WebContentsObserver::DidOpenRequestedURL, new_contents, + source_render_frame_host, params.url, params.referrer, + params.disposition, params.transition, params.started_from_context_menu, + params.is_renderer_initiated); + } + + return new_contents; +} + +void WebContentsImpl::SetHistoryOffsetAndLengthForView( + RenderViewHost* render_view_host, + int history_offset, + int history_length) { + OPTIONAL_TRACE_EVENT2( + "content", "WebContentsImpl::SetHistoryOffsetAndLengthForView", + "history_offset", history_offset, "history_length", history_length); + if (auto& broadcast = static_cast(render_view_host) + ->GetAssociatedPageBroadcast()) { + broadcast->SetHistoryOffsetAndLength(history_offset, history_length); + } +} + +void WebContentsImpl::ReloadFocusedFrame() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ReloadFocusedFrame"); + RenderFrameHost* focused_frame = GetFocusedFrame(); + if (!focused_frame) { + return; + } + + focused_frame->Reload(); +} + +void WebContentsImpl::Undo() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Undo"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->Undo(); + RecordAction(base::UserMetricsAction("Undo")); +} + +void WebContentsImpl::Redo() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Redo"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->Redo(); + RecordAction(base::UserMetricsAction("Redo")); +} + +void WebContentsImpl::Cut() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Cut"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->Cut(); + RecordAction(base::UserMetricsAction("Cut")); +} + +void WebContentsImpl::Copy() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Copy"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->Copy(); + RecordAction(base::UserMetricsAction("Copy")); +} + +void WebContentsImpl::CopyToFindPboard() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::CopyToFindPboard"); +#if BUILDFLAG(IS_MAC) + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + // Windows/Linux don't have the concept of a find pasteboard. + input_handler->CopyToFindPboard(); + RecordAction(base::UserMetricsAction("CopyToFindPboard")); +#endif +} + +void WebContentsImpl::CenterSelection() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::CenterSelection"); +#if BUILDFLAG(IS_MAC) + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->CenterSelection(); +#endif +} + +void WebContentsImpl::Paste() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Paste"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->Paste(); + observers_.NotifyObservers(&WebContentsObserver::OnPaste); + RecordAction(base::UserMetricsAction("Paste")); +} + +void WebContentsImpl::PasteAndMatchStyle() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::PasteAndMatchStyle"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->PasteAndMatchStyle(); + observers_.NotifyObservers(&WebContentsObserver::OnPaste); + RecordAction(base::UserMetricsAction("PasteAndMatchStyle")); +} + +void WebContentsImpl::Delete() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Delete"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->Delete(); + RecordAction(base::UserMetricsAction("DeleteSelection")); +} + +void WebContentsImpl::SelectAll() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SelectAll"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->SelectAll(); + RecordAction(base::UserMetricsAction("SelectAll")); +} + +void WebContentsImpl::CollapseSelection() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::CollapseSelection"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->CollapseSelection(); +} + +void WebContentsImpl::ScrollToTopOfDocument() { + ExecuteEditCommand("ScrollToBeginningOfDocument", std::nullopt); +} + +void WebContentsImpl::ScrollToBottomOfDocument() { + ExecuteEditCommand("ScrollToEndOfDocument", std::nullopt); +} + +void WebContentsImpl::Replace(const std::u16string& word) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Replace"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->Replace(word); +} + +void WebContentsImpl::ReplaceMisspelling(const std::u16string& word) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ReplaceMisspelling"); + auto* input_handler = GetFocusedFrameWidgetInputHandler(); + if (!input_handler) { + return; + } + + last_interaction_time_ = ui::EventTimeForNow(); + input_handler->ReplaceMisspelling(word); +} + +void WebContentsImpl::NotifyContextMenuClosed(const GURL& link_followed) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::NotifyContextMenuClosed"); + RenderFrameHost* focused_frame = GetFocusedFrame(); + if (!focused_frame) { + return; + } + + if (context_menu_client_) { + context_menu_client_->ContextMenuClosed(link_followed); + } + + context_menu_client_.reset(); +} + +void WebContentsImpl::ExecuteCustomContextMenuCommand( + int action, + const GURL& link_followed) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::ExecuteCustomContextMenuCommand", + "action", action); + RenderFrameHost* focused_frame = GetFocusedFrame(); + if (!focused_frame) { + return; + } + + if (context_menu_client_) { + context_menu_client_->CustomContextMenuAction(action); + } +} + +gfx::NativeView WebContentsImpl::GetNativeView() { + return view_->GetNativeView(); +} + +gfx::NativeView WebContentsImpl::GetContentNativeView() { + return view_->GetContentNativeView(); +} + +gfx::NativeWindow WebContentsImpl::GetTopLevelNativeWindow() { + return view_->GetTopLevelNativeWindow(); +} + +gfx::Rect WebContentsImpl::GetViewBounds() { + return view_->GetViewBounds(); +} + +gfx::Rect WebContentsImpl::GetContainerBounds() { + return view_->GetContainerBounds(); +} + +DropData* WebContentsImpl::GetDropData() { + return view_->GetDropData(); +} + +void WebContentsImpl::Focus() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Focus"); + view_->Focus(); +} + +void WebContentsImpl::SetInitialFocus() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetInitialFocus"); + view_->SetInitialFocus(); +} + +void WebContentsImpl::StoreFocus() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::StoreFocus"); + view_->StoreFocus(); +} + +void WebContentsImpl::RestoreFocus() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::RestoreFocus"); + view_->RestoreFocus(); +} + +void WebContentsImpl::FocusThroughTabTraversal(bool reverse) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::FocusThroughTabTraversal", + "reverse", reverse); + view_->FocusThroughTabTraversal(reverse); +} + +bool WebContentsImpl::IsSavable() { + // WebKit creates Document object when MIME type is application/xhtml+xml, + // so we also support this MIME type. + std::string mime_type = GetContentsMimeType(); + return mime_type == "text/html" || mime_type == "text/xml" || + mime_type == "application/xhtml+xml" || mime_type == "text/plain" || + mime_type == "text/css" || + blink::IsSupportedJavascriptMimeType(mime_type); +} + +void WebContentsImpl::OnSavePage() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnSavePage"); + // If we can not save the page, try to download it. + if (!IsSavable()) { + SaveFrame(GetLastCommittedURL(), Referrer(), GetPrimaryMainFrame()); + return; + } + + Stop(); + + // Create the save package and possibly prompt the user for the name to save + // the page as. The user prompt is an asynchronous operation that runs on + // another thread. + save_package_ = new SavePackage(GetPrimaryPage()); + save_package_->GetSaveInfo(); +} + +// Used in automated testing to bypass prompting the user for file names. +// Instead, the names and paths are hard coded rather than running them through +// file name sanitation and extension / mime checking. +bool WebContentsImpl::SavePage(const base::FilePath& main_file, + const base::FilePath& dir_path, + SavePageType save_type) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SavePage", "main_file", + main_file, "dir_path", dir_path); + // Stop the page from navigating. + Stop(); + + save_package_ = + new SavePackage(GetPrimaryPage(), save_type, main_file, dir_path); + return save_package_->Init(SavePackageDownloadCreatedCallback()); +} + +void WebContentsImpl::SaveFrame(const GURL& url, + const Referrer& referrer, + RenderFrameHost* rfh) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SaveFrame"); + SaveFrameWithHeaders(url, referrer, std::string(), std::u16string(), rfh, + /*is_subresource=*/false); +} + +void WebContentsImpl::SaveFrameWithHeaders( + const GURL& url, + const Referrer& referrer, + const std::string& headers, + const std::u16string& suggested_filename, + RenderFrameHost* rfh, + bool is_subresource) { + DCHECK(rfh); + auto& rfhi = *static_cast(rfh); + + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SaveFrameWithHeaders", + "url", url, "headers", headers); + // Check and see if the guest can handle this. + if (delegate_) { + WebContents* guest_web_contents = nullptr; + if (browser_plugin_embedder_) { + BrowserPluginGuest* guest = browser_plugin_embedder_->GetFullPageGuest(); + if (guest) { + guest_web_contents = guest->GetWebContents(); + } + } else if (browser_plugin_guest_) { + guest_web_contents = this; + } + + if (guest_web_contents && delegate_->GuestSaveFrame(guest_web_contents)) { + return; + } + } + + if (!GetLastCommittedURL().is_valid()) { + return; + } + if (delegate_ && delegate_->SaveFrame(url, referrer, rfh)) { + return; + } + + int64_t post_id = -1; + if (rfhi.is_main_frame() && !is_subresource) { + NavigationEntry* entry = + rfhi.frame_tree()->controller().GetLastCommittedEntry(); + if (entry) { + post_id = entry->GetPostID(); + } + } + net::NetworkTrafficAnnotationTag traffic_annotation = + net::DefineNetworkTrafficAnnotation("download_web_contents_frame", R"( + semantics { + sender: "Save Page Action" + description: + "Saves the given frame's URL to the local file system." + trigger: + "The user has triggered a save operation on the frame through a " + "context menu or other mechanism." + data: "None." + destination: WEBSITE + } + policy { + cookies_allowed: YES + cookies_store: "user" + setting: + "This feature cannot be disabled by settings, but it's is only " + "triggered by user request." + policy_exception_justification: "Not implemented." + })"); + auto params = std::make_unique( + url, rfh->GetProcess()->GetID(), rfh->GetRoutingID(), traffic_annotation); + params->set_referrer(referrer.url); + params->set_referrer_policy( + Referrer::ReferrerPolicyForUrlRequest(referrer.policy)); + params->set_post_id(post_id); + if (post_id >= 0) { + params->set_method("POST"); + } + params->set_prompt(true); + + if (!headers.empty()) { + for (download::DownloadUrlParameters::RequestHeadersNameValuePair + key_value : ParseDownloadHeaders(headers)) { + params->add_request_header(key_value.first, key_value.second); + } + } + params->set_prefer_cache(true); + params->set_suggested_name(suggested_filename); + params->set_download_source(download::DownloadSource::WEB_CONTENTS_API); + params->set_isolation_info(rfhi.ComputeIsolationInfoForNavigation(url)); + + GetBrowserContext()->GetDownloadManager()->DownloadUrl(std::move(params)); +} + +void WebContentsImpl::GenerateMHTML( + const MHTMLGenerationParams& params, + base::OnceCallback callback) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GenerateMHTML"); + base::OnceCallback wrapper_callback = + base::BindOnce( + [](base::OnceCallback size_callback, + const MHTMLGenerationResult& result) { + std::move(size_callback).Run(result.file_size); + }, + std::move(callback)); + MHTMLGenerationManager::GetInstance()->SaveMHTML(this, params, + std::move(wrapper_callback)); +} + +void WebContentsImpl::GenerateMHTMLWithResult( + const MHTMLGenerationParams& params, + MHTMLGenerationResult::GenerateMHTMLCallback callback) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GenerateMHTMLWithResult"); + MHTMLGenerationManager::GetInstance()->SaveMHTML(this, params, + std::move(callback)); +} + +const std::string& WebContentsImpl::GetContentsMimeType() { + return GetPrimaryPage().GetContentsMimeType(); +} + +blink::RendererPreferences* WebContentsImpl::GetMutableRendererPrefs() { + return &renderer_preferences_; +} + +void WebContentsImpl::DragSourceEndedAt(float client_x, + float client_y, + float screen_x, + float screen_y, + ui::mojom::DragOperation operation, + RenderWidgetHost* source_rwh) { + OPTIONAL_TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("content.verbose"), + "WebContentsImpl::DragSourceEndedAt"); + if (source_rwh) { + source_rwh->DragSourceEndedAt(gfx::PointF(client_x, client_y), + gfx::PointF(screen_x, screen_y), operation, + base::DoNothing()); + } +} + +void WebContentsImpl::LoadStateChanged(network::mojom::LoadInfoPtr load_info) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::LoadStateChanged", "host", + load_info->host, "load_state", load_info->load_state); + + // If the new load state isn't progressed as far as the current loading state + // or both are sending an upload and the upload is smaller, return early + // discarding the new load state. + if (load_info_timestamp_ + kUpdateLoadStatesInterval > load_info->timestamp && + (load_state_.state > load_info->load_state || + (load_state_.state == load_info->load_state && + load_state_.state == net::LOAD_STATE_SENDING_REQUEST && + upload_size_ > load_info->upload_size))) { + return; + } + + load_info_timestamp_ = load_info->timestamp; + std::u16string host16 = url_formatter::IDNToUnicode(load_info->host); + // Drop no-op updates. + if (load_state_.state == load_info->load_state && + load_state_.param == load_info->state_param && + upload_position_ == load_info->upload_position && + upload_size_ == load_info->upload_size && load_state_host_ == host16) { + return; + } + load_state_ = net::LoadStateWithParam( + static_cast(load_info->load_state), + load_info->state_param); + load_state_host_ = host16; +} + +void WebContentsImpl::SetVisibilityAndNotifyObservers(Visibility visibility) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::SetVisibilityAndNotifyObservers", + "visibility", static_cast(visibility)); + const Visibility previous_visibility = visibility_; + visibility_ = visibility; + + // Notify observers if the visibility changed or if WasShown() is being called + // for the first time. + if (visibility != previous_visibility || + (visibility == Visibility::VISIBLE && !did_first_set_visible_)) { + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.OnVisibilityChanged"); + observers_.NotifyObservers(&WebContentsObserver::OnVisibilityChanged, + visibility); + } +} + +void WebContentsImpl::NotifyWebContentsFocused( + RenderWidgetHost* render_widget_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::NotifyWebContentsFocused", + "render_widget_host", render_widget_host); + observers_.NotifyObservers(&WebContentsObserver::OnWebContentsFocused, + render_widget_host); +} + +void WebContentsImpl::NotifyWebContentsLostFocus( + RenderWidgetHost* render_widget_host) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::NotifyWebContentsLostFocus", + "render_widget_host", render_widget_host); + observers_.NotifyObservers(&WebContentsObserver::OnWebContentsLostFocus, + render_widget_host); +} + +void WebContentsImpl::SystemDragEnded(RenderWidgetHost* source_rwh) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SystemDragEnded", + "render_widget_host", source_rwh); + if (source_rwh) { + source_rwh->DragSourceSystemDragEnded(); + } +} + +void WebContentsImpl::SetClosedByUserGesture(bool value) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetClosedByUserGesture", + "value", value); + closed_by_user_gesture_ = value; +} + +bool WebContentsImpl::GetClosedByUserGesture() { + return closed_by_user_gesture_; +} + +int WebContentsImpl::GetMinimumZoomPercent() { + return minimum_zoom_percent_; +} + +int WebContentsImpl::GetMaximumZoomPercent() { + return maximum_zoom_percent_; +} + +void WebContentsImpl::SetPageScale(float scale_factor) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetPageScale", + "scale_factor", scale_factor); + GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetScaleFactor( + scale_factor); +} + +gfx::Size WebContentsImpl::GetPreferredSize() { + return IsBeingCaptured() ? preferred_size_for_capture_ : preferred_size_; +} + +bool WebContentsImpl::GotResponseToPointerLockRequest( + blink::mojom::PointerLockResult result) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::GotResponseToPointerLockRequest"); + if (pointer_lock_widget_) { + auto* web_contents = + WebContentsImpl::FromRenderWidgetHostImpl(pointer_lock_widget_); + if (web_contents != this) { + return web_contents->GotResponseToPointerLockRequest(result); + } + + if (pointer_lock_widget_->GotResponseToPointerLockRequest(result)) { + return true; + } + } + + for (WebContentsImpl* current = this; current; + current = current->GetOuterWebContents()) { + current->pointer_lock_widget_ = nullptr; + } + + return false; +} + +void WebContentsImpl::GotPointerLockPermissionResponse(bool allowed) { + GotResponseToPointerLockRequest( + allowed ? blink::mojom::PointerLockResult::kSuccess + : blink::mojom::PointerLockResult::kPermissionDenied); +} + +void WebContentsImpl::DropPointerLockForTesting() { + if (pointer_lock_widget_) { + pointer_lock_widget_->RejectPointerLockOrUnlockIfNecessary( + blink::mojom::PointerLockResult::kUnknownError); + for (WebContentsImpl* current = this; current; + current = current->GetOuterWebContents()) { + current->pointer_lock_widget_ = nullptr; + } + } +} + +bool WebContentsImpl::GotResponseToKeyboardLockRequest(bool allowed) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::GotResponseToKeyboardLockRequest", + "allowed", allowed); + if (!keyboard_lock_widget_) { + return false; + } + if (WebContentsImpl::FromRenderWidgetHostImpl(keyboard_lock_widget_) != + this) { + NOTREACHED_IN_MIGRATION(); + return false; + } + // KeyboardLock is only supported when called by the top-level browsing + // context and is not supported in embedded content scenarios. + if (GetOuterWebContents()) { + keyboard_lock_widget_->GotResponseToKeyboardLockRequest(false); + return false; + } + keyboard_lock_widget_->GotResponseToKeyboardLockRequest(allowed); + return true; +} + +bool WebContentsImpl::HasOpener() { + return GetOpener() != nullptr; +} + +RenderFrameHostImpl* WebContentsImpl::GetOpener() { + FrameTreeNode* opener_ftn = primary_frame_tree_.root()->opener(); + return opener_ftn ? opener_ftn->current_frame_host() : nullptr; +} + +bool WebContentsImpl::HasLiveOriginalOpenerChain() { + return GetFirstWebContentsInLiveOriginalOpenerChain() != nullptr; +} + +WebContents* WebContentsImpl::GetFirstWebContentsInLiveOriginalOpenerChain() { + FrameTreeNode* opener_ftn = + primary_frame_tree_.root() + ->first_live_main_frame_in_original_opener_chain(); + return opener_ftn ? WebContents::FromRenderFrameHost( + opener_ftn->current_frame_host()) + : nullptr; +} + +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) +void WebContentsImpl::DidChooseColorInColorChooser(SkColor color) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::DidChooseColorInColorChooser", + "color", color); + if (color_chooser_holder_) { + color_chooser_holder_->DidChooseColorInColorChooser(color); + } +} + +void WebContentsImpl::DidEndColorChooser() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DidEndColorChooser"); + color_chooser_holder_.reset(); +} +#endif + +int WebContentsImpl::DownloadImage( + const GURL& url, + bool is_favicon, + const gfx::Size& preferred_size, + uint32_t max_bitmap_size, + bool bypass_cache, + WebContents::ImageDownloadCallback callback) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DownloadImage", "url", + url); + return DownloadImageInFrame(GlobalRenderFrameHostId(), url, is_favicon, + preferred_size, max_bitmap_size, bypass_cache, + std::move(callback)); +} + +int WebContentsImpl::DownloadImageInFrame( + const GlobalRenderFrameHostId& initiator_frame_routing_id, + const GURL& url, + bool is_favicon, + const gfx::Size& preferred_size, + uint32_t max_bitmap_size, + bool bypass_cache, + WebContents::ImageDownloadCallback callback) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DownloadImageInFrame"); + DCHECK_CURRENTLY_ON(BrowserThread::UI); + static int next_image_download_id = 0; + const int download_id = ++next_image_download_id; + + RenderFrameHostImpl* initiator_frame = + initiator_frame_routing_id.child_id + ? RenderFrameHostImpl::FromID(initiator_frame_routing_id) + : GetPrimaryMainFrame(); + if (!initiator_frame->IsRenderFrameLive()) { + // If the renderer process is dead (i.e. crash, or memory pressure on + // Android), the downloader service will be invalid. Pre-Mojo, this would + // hang the callback indefinitely since the IPC would be dropped. Now, + // respond with a 400 HTTP error code to indicate that something went wrong. + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, + base::BindOnce( + &WebContentsImpl::OnDidDownloadImage, weak_factory_.GetWeakPtr(), + initiator_frame->GetWeakPtr(), std::move(callback), download_id, + url, 400, std::vector(), std::vector())); + return download_id; + } + + initiator_frame->GetMojoImageDownloader()->DownloadImage( + url, is_favicon, preferred_size, max_bitmap_size, bypass_cache, + base::BindOnce(&WebContentsImpl::OnDidDownloadImage, + weak_factory_.GetWeakPtr(), initiator_frame->GetWeakPtr(), + std::move(callback), download_id, url)); + return download_id; +} + +void WebContentsImpl::Find(int request_id, + const std::u16string& search_text, + blink::mojom::FindOptionsPtr options, + bool skip_delay) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Find"); + // Cowardly refuse to search for no text. + if (search_text.empty()) { + NOTREACHED_IN_MIGRATION(); + return; + } + + GetOrCreateFindRequestManager()->Find(request_id, search_text, + std::move(options), skip_delay); +} + +void WebContentsImpl::StopFinding(StopFindAction action) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::StopFinding"); + if (FindRequestManager* manager = GetFindRequestManager()) { + manager->StopFinding(action); + } +} + +bool WebContentsImpl::WasEverAudible() { + return was_ever_audible_; +} + +void WebContentsImpl::ExitFullscreen(bool will_cause_resize) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ExitFullscreen"); + // Clean up related state and initiate the fullscreen exit. + GetRenderViewHost()->GetWidget()->RejectPointerLockOrUnlockIfNecessary( + blink::mojom::PointerLockResult::kUserRejected); + ExitFullscreenMode(will_cause_resize); +} + +base::ScopedClosureRunner WebContentsImpl::ForSecurityDropFullscreen( + int64_t display_id) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ForSecurityDropFullscreen", + "display_id", display_id); + // Make WebContentses "related" to this instance exit HTML element fullscreen, + // ignoring browser fullscreen and fullscreen-within-tab modes. This needs to + // be done with two passes, because it is simple to walk _up_ the chain of + // openers and outer contents, but it not simple to walk _down_ the chain. + auto is_fullscreen = [](WebContentsImpl* tab, int64_t display_id) { + if (!tab || !tab->GetDelegate()) { + return false; + } + const FullscreenState state = tab->GetDelegate()->GetFullscreenState(tab); + return state.target_mode == FullscreenMode::kContent && + (display_id == display::kInvalidDisplayId || + state.target_display_id == display::kInvalidDisplayId || + state.target_display_id == display_id); + }; + + // First, determine if any fullscreen WebContents has this WebContents as an + // upstream contents. Drop that WebContents out of fullscreen if it does. This + // is theoretically quadratic-ish (fullscreen contentses x each one's opener + // length) but neither of those is expected to ever be a large number. + auto fullscreen_set_copy = *FullscreenContentsSet(GetBrowserContext()); + for (WebContentsImpl* fullscreen_contents : fullscreen_set_copy) { + if (is_fullscreen(fullscreen_contents, display_id)) { + auto opener_contentses = GetAllOpeningWebContents(fullscreen_contents); + if (opener_contentses.count(this)) { + fullscreen_contents->ExitFullscreen(true); + } + } + } + + // Second, walk upstream from this WebContents, and drop the fullscreen of + // all WebContentses that are in fullscreen. Block all the WebContentses in + // the chain from entering fullscreen while the returned closure runner is + // alive. It's OK that this set doesn't contain downstream WebContentses, as + // any request to enter fullscreen will have the upstream of the WebContents + // checked. (See CanEnterFullscreenMode().) + + std::vector> blocked_contentses; + + for (auto* opener : GetAllOpeningWebContents(this)) { + if (is_fullscreen(opener, display_id)) { + opener->ExitFullscreen(true); + } + + // ...block the WebContents from entering fullscreen until further notice. + ++opener->fullscreen_blocker_count_; + blocked_contentses.push_back(opener->weak_factory_.GetWeakPtr()); + } + + return base::ScopedClosureRunner(base::BindOnce( + [](std::vector> blocked_contentses) { + for (base::WeakPtr& web_contents : + blocked_contentses) { + if (web_contents) { + DCHECK_GT(web_contents->fullscreen_blocker_count_, 0); + --web_contents->fullscreen_blocker_count_; + } + } + }, + std::move(blocked_contentses))); +} + +void WebContentsImpl::ResumeLoadingCreatedWebContents() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::ResumeLoadingCreatedWebContents"); + if (delayed_load_url_params_.get()) { + DCHECK(!delayed_open_url_params_); + base::WeakPtr navigation = + GetController().LoadURLWithParams(*delayed_load_url_params_.get()); + if (delayed_navigation_handle_callback_ && navigation) { + std::move(delayed_navigation_handle_callback_).Run(*navigation); + } + delayed_navigation_handle_callback_.Reset(); + delayed_load_url_params_.reset(nullptr); + return; + } + + CHECK(!delayed_navigation_handle_callback_); + + if (delayed_open_url_params_.get()) { + OpenURL(*delayed_open_url_params_.get(), + std::move(delayed_navigation_handle_callback_)); + delayed_open_url_params_.reset(nullptr); + return; + } + + // Renderer-created main frames wait for the renderer to request for them to + // perform navigations and to be shown. We signal that this condition is + // satisfied by calling Init(). + if (is_resume_pending_) { + is_resume_pending_ = false; + GetPrimaryMainFrame()->Init(); + } +} + +bool WebContentsImpl::FocusLocationBarByDefault() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::FocusLocationBarByDefault"); + if (should_focus_location_bar_by_default_) { + return true; + } + + return delegate_ && delegate_->ShouldFocusLocationBarByDefault(this); +} + +void WebContentsImpl::DidStartNavigation(NavigationHandle* navigation_handle) { + TRACE_EVENT1("navigation", "WebContentsImpl::DidStartNavigation", + "navigation_handle", navigation_handle); + base::ElapsedTimer duration; + observers_.NotifyObservers(&WebContentsObserver::DidStartNavigation, + navigation_handle); + base::TimeDelta elapsed = duration.Elapsed(); + base::UmaHistogramTimes("WebContentsObserver.DidStartNavigation", elapsed); + base::UmaHistogramTimes( + base::StrCat( + {"WebContentsObserver.DidStartNavigation.", + navigation_handle->IsInMainFrame() ? "MainFrame" : "Subframe"}), + elapsed); + if (navigation_handle->IsInPrimaryMainFrame()) { + // When the browser is started with about:blank as the startup URL, focus + // the location bar (which will also select its contents) so people can + // simply begin typing to navigate elsewhere. + // + // We need to be careful not to trigger this for anything other than the + // startup navigation. In particular, if we allow an attacker to open a + // popup to about:blank, then navigate, focusing the Omnibox will cause the + // end of the new URL to be scrolled into view instead of the start, + // allowing the attacker to spoof other URLs. The conditions checked here + // are all aimed at ensuring no such attacker-controlled navigation can + // trigger this. + should_focus_location_bar_by_default_ = + GetController().IsInitialNavigation() && + !navigation_handle->IsRendererInitiated() && + navigation_handle->GetURL() == url::kAboutBlankURL; + } +} + +void WebContentsImpl::DidRedirectNavigation( + NavigationHandle* navigation_handle) { + TRACE_EVENT1("navigation", "WebContentsImpl::DidRedirectNavigation", + "navigation_handle", navigation_handle); + { + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidRedirectNavigation"); + observers_.NotifyObservers(&WebContentsObserver::DidRedirectNavigation, + navigation_handle); + } + // Notify accessibility if this is a reload. This has to called on the + // BrowserAccessibilityManager associated with the old RFHI. + if (navigation_handle->GetReloadType() != ReloadType::NONE) { + NavigationRequest* request = NavigationRequest::From(navigation_handle); + BrowserAccessibilityManager* manager = + request->frame_tree_node() + ->current_frame_host() + ->browser_accessibility_manager(); + if (manager) { + manager->UserIsReloading(); + } + } +} + +void WebContentsImpl::ReadyToCommitNavigation( + NavigationHandle* navigation_handle) { + TRACE_EVENT1("navigation", "WebContentsImpl::ReadyToCommitNavigation", + "navigation_handle", navigation_handle); + + // Cross-document navigation of the top-level frame resets the capture + // handle config. Using IsInPrimaryMainFrame is valid here since the browser + // caches this state for the active main frame only. + if (!navigation_handle->IsSameDocument() && + navigation_handle->IsInPrimaryMainFrame()) { + SetCaptureHandleConfig(blink::mojom::CaptureHandleConfig::New()); + } + + observers_.NotifyObservers(&WebContentsObserver::ReadyToCommitNavigation, + navigation_handle); + + // If any domains are blocked from accessing 3D APIs because they may + // have caused the GPU to reset recently, unblock them here if the user + // initiated this navigation. This implies that the user was involved in + // the decision to navigate, so there's no concern about + // denial-of-service issues. Want to do this as early as + // possible to avoid race conditions with pages attempting to access + // WebGL early on. + // + // TODO(crbug.com/41257523): currently navigations initiated by the browser + // (reload button, reload menu option, pressing return in the Omnibox) + // return false from HasUserGesture(). If or when that is addressed, + // remove the check for IsRendererInitiated() below. + // + // TODO(crbug.com/40571460): HasUserGesture comes from the renderer + // process and isn't validated. Until it is, don't trust it. + if (!navigation_handle->IsRendererInitiated()) { + GpuDataManagerImpl::GetInstance()->UnblockDomainFrom3DAPIs( + navigation_handle->GetURL()); + } + + if (navigation_handle->IsSameDocument()) { + return; + } + + // SSLInfo is not needed on subframe navigations since the main-frame + // certificate is the only one that can be inspected (using the info + // bubble) without refreshing the page with DevTools open. + // We don't call DidStartResourceResponse on net errors, since that results on + // existing cert exceptions being revoked, which leads to weird behavior with + // committed interstitials or while offline. We only need the error check for + // the main frame case. + if (navigation_handle->IsInMainFrame() && + navigation_handle->GetNetErrorCode() == net::OK) { + static_cast(navigation_handle) + ->frame_tree_node() + ->frame_tree() + .controller() + .ssl_manager() + ->DidStartResourceResponse( + url::SchemeHostPort(navigation_handle->GetURL()), + navigation_handle->GetSSLInfo().has_value() + ? net::IsCertStatusError( + navigation_handle->GetSSLInfo()->cert_status) + : false); + } +} + +void WebContentsImpl::DidFinishNavigation(NavigationHandle* navigation_handle) { + TRACE_EVENT1("navigation", "WebContentsImpl::DidFinishNavigation", + "navigation_handle", navigation_handle); + + { + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidFinishNavigation"); + observers_.NotifyObservers(&WebContentsObserver::DidFinishNavigation, + navigation_handle); + } + if (safe_area_insets_host_) { + safe_area_insets_host_->DidFinishNavigation(navigation_handle); + } + + if (navigation_handle->HasCommitted()) { + // TODO(domfarolino, dmazzoni): Do this using WebContentsObserver. See + // https://crbug.com/981271. + BrowserAccessibilityManager* manager = + static_cast( + navigation_handle->GetRenderFrameHost()) + ->browser_accessibility_manager(); + if (manager) { + if (navigation_handle->IsErrorPage()) { + manager->NavigationFailed(); + } else { + manager->NavigationSucceeded(); + } + } + + // TODO(crbug.com/40774464) : Move this tracking to PageImpl. + if (navigation_handle->IsInPrimaryMainFrame() && + !navigation_handle->IsSameDocument()) { + was_ever_audible_ = false; + } + + if (!navigation_handle->IsSameDocument()) { + last_screen_orientation_change_time_ = base::TimeTicks(); + } + } + + // If we didn't end up on about:blank after setting this in DidStartNavigation + // then don't focus the location bar. + if (should_focus_location_bar_by_default_ && + navigation_handle->GetURL() != url::kAboutBlankURL) { + should_focus_location_bar_by_default_ = false; + } + + if (navigation_handle->IsInPrimaryMainFrame() && + first_primary_navigation_completed_) { + RecordMaxFrameCountUMA(max_loaded_frame_count_); + } + + // If navigation has successfully finished in the main frame, set + // |first_primary_navigation_completed_| to true so that we will record + // |max_loaded_frame_count_| above when future main frame navigations finish. + if (navigation_handle->IsInPrimaryMainFrame() && + !navigation_handle->IsErrorPage()) { + first_primary_navigation_completed_ = true; + + // Navigation has completed in main frame. Reset |max_loaded_frame_count_|. + // |max_loaded_frame_count_| is not necessarily 1 if the navigation was + // served from BackForwardCache. + max_loaded_frame_count_ = GetFrameTreeSize(&primary_frame_tree_); + } + + if (web_preferences_) { + // Update the WebPreferences for this WebContents that depends on changes + // that might occur during navigation. This will only update the preferences + // that needs to be updated (and won't cause an update/overwrite preferences + // that needs to stay the same after navigations). + bool value_changed_due_to_override = + GetContentClient()->browser()->OverrideWebPreferencesAfterNavigation( + this, web_preferences_.get()); + // We need to update the WebPreferences value on the renderer if the value + // is changed due to the override above, or if the navigation is served from + // the back-forward cache, because the WebPreferences value stored in the + // renderer might be stale (because we don't send WebPreferences updates to + // bfcached renderers). Same for prerendering. + // TODO(rakina): Maybe handle the back-forward cache case in + // ReadyToCommitNavigation instead? + // TODO(crbug.com/40758687): Maybe sync RendererPreferences as well? + if (value_changed_due_to_override || + NavigationRequest::From(navigation_handle)->IsPageActivation()) { + SetWebPreferences(*web_preferences_.get()); + } + } + + if (navigation_handle->HasCommitted() && + navigation_handle->IsPrerenderedPageActivation()) { + // We defer favicon and manifest URL updates while prerendering. Upon + // activation, we must inform interested parties about our candidate favicon + // URLs and the manifest URL. + DCHECK(navigation_handle->IsInPrimaryMainFrame()); + auto* rfhi = static_cast( + navigation_handle->GetRenderFrameHost()); + UpdateFaviconURL(rfhi, rfhi->FaviconURLs()); + OnManifestUrlChanged(rfhi->GetPage()); + + // The page might have set its title while prerendering, and if it was, we + // skipped notifying observers then, and we need to notify them now after + // the page is activated. + DCHECK(navigation_handle->IsInPrimaryMainFrame()); + NavigationEntryImpl* entry = GetController().GetLastCommittedEntry(); + DCHECK(entry); + if (!entry->GetTitle().empty()) { + NotifyTitleUpdateForEntry(entry); + } + } +} + +void WebContentsImpl::DidCancelNavigationBeforeStart( + NavigationHandle* navigation_handle) { +#if BUILDFLAG(IS_ANDROID) + if (auto* animation_manager = + static_cast( + GetBackForwardTransitionAnimationManager())) { + animation_manager->OnNavigationCancelledBeforeStart(navigation_handle); + } +#endif +} + +void WebContentsImpl::DidFailLoadWithError( + RenderFrameHostImpl* render_frame_host, + const GURL& url, + int error_code) { + TRACE_EVENT2("content,navigation", "WebContentsImpl::DidFailLoadWithError", + "render_frame_host", render_frame_host, "url", url); + observers_.NotifyObservers(&WebContentsObserver::DidFailLoad, + render_frame_host, url, error_code); +} + +void WebContentsImpl::DraggableRegionsChanged( + const std::vector& regions) { + if (!GetDelegate()) { + return; + } + GetDelegate()->DraggableRegionsChanged(regions, this); +} + +void WebContentsImpl::NotifyChangedNavigationState( + InvalidateTypes changed_flags) { + NotifyNavigationStateChanged(changed_flags); +} + +bool WebContentsImpl::ShouldAllowRendererInitiatedCrossProcessNavigation( + bool is_outermost_main_frame_navigation) { + OPTIONAL_TRACE_EVENT1( + "content", + "WebContentsImpl::ShouldAllowRendererInitiatedCrossProcessNavigation", + "is_outermost_main_frame_navigation", is_outermost_main_frame_navigation); + if (!delegate_) { + return true; + } + return delegate_->ShouldAllowRendererInitiatedCrossProcessNavigation( + is_outermost_main_frame_navigation); +} + +bool WebContentsImpl::ShouldPreserveAbortedURLs() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::ShouldPreserveAbortedURLs"); + if (!delegate_) { + return false; + } + return delegate_->ShouldPreserveAbortedURLs(this); +} + +void WebContentsImpl::NotifyNavigationStateChangedFromController( + InvalidateTypes changed_flags) { + NotifyNavigationStateChanged(changed_flags); +} + +input::TouchEmulator* WebContentsImpl::GetTouchEmulator( + bool create_if_necessary) { + CHECK(rwh_input_event_router_); + + if (!touch_emulator_ && create_if_necessary) { + touch_emulator_ = std::make_unique( + rwh_input_event_router_.get(), + rwh_input_event_router_->last_device_scale_factor()); + } + + return touch_emulator_.get(); +} + +void WebContentsImpl::DidNavigateMainFramePreCommit( + NavigationHandle* navigation_handle, + bool navigation_is_within_page) { + auto* request = static_cast(navigation_handle); + FrameTreeNode* frame_tree_node = request->frame_tree_node(); + + // The `frame_tree_node` is always a main frame. + DCHECK(frame_tree_node->IsMainFrame()); + TRACE_EVENT1("content,navigation", + "WebContentsImpl::DidNavigateMainFramePreCommit", + "navigation_is_within_page", navigation_is_within_page); + const bool is_primary_mainframe = + frame_tree_node->GetFrameType() == FrameType::kPrimaryMainFrame; + // If running for a non-primary main frame, early out. + if (!is_primary_mainframe) { + return; + } + +#if BUILDFLAG(IS_ANDROID) + auto* animation_manager = + static_cast( + GetBackForwardTransitionAnimationManager()); + if (animation_manager) { + animation_manager->OnDidNavigatePrimaryMainFramePreCommit( + request, frame_tree_node->render_manager()->current_frame_host(), + request->GetRenderFrameHost()); + } +#endif + + // Ensure fullscreen mode is exited before committing the navigation to a + // different page. The next page will not start out assuming it is in + // fullscreen mode. + if (navigation_is_within_page) { + // No page change? Then, the renderer and browser can remain in fullscreen. + return; + } + + if (IsFullscreen()) { + ExitFullscreen(false); + } + + if (base::FeatureList::IsEnabled( + features::kInvalidateLocalSurfaceIdPreCommit)) { + auto* rwhvb = static_cast( + frame_tree_node->current_frame_host()->GetView()); + if (rwhvb) { + rwhvb->OnOldViewDidNavigatePreCommit(); + } + } + + // Clean up keyboard lock state when navigating. + CancelKeyboardLock(keyboard_lock_widget_); +} + +void WebContentsImpl::DidNavigateMainFramePostCommit( + RenderFrameHostImpl* render_frame_host, + const LoadCommittedDetails& details) { + // The render_frame_host is always a main frame. + DCHECK(render_frame_host->is_main_frame()); + OPTIONAL_TRACE_EVENT1("content,navigation", + "WebContentsImpl::DidNavigateMainFramePostCommit", + "render_frame_host", render_frame_host); + const bool is_primary_main_frame = render_frame_host->IsInPrimaryMainFrame(); + + auto* rwhvb = static_cast( + render_frame_host->GetMainFrame()->GetView()); + + if (details.is_navigation_to_different_page()) { + if (is_primary_main_frame) { + // Clear the status bubble. This is a workaround for a bug where WebKit + // doesn't let us know that the cursor left an element during a + // transition (this is also why the mouse cursor remains as a hand after + // clicking on a link); see bugs 1184641 and 980803. We don't want to + // clear the bubble when a user navigates to a named anchor in the same + // page. + ClearTargetURL(); + + // If the feature flag is enabled, we only call the PostCommit on the new + // View, for a primary main frame navigation. The PreCommit counterpart is + // called in `WCImpl:DidNavigateMainFramePreCommit`. + if (rwhvb && base::FeatureList::IsEnabled( + features::kInvalidateLocalSurfaceIdPreCommit)) { + rwhvb->OnNewViewDidNavigatePostCommit(); + } + } + + // If the feature flag is disabled, we restore to the "original" behavior ( + // the behavior prior to https://crrev.com/c/4702023): + // When the new view is just made visible, we: + // - Reset the LocalSurfaceId on the new View (PreCommit), and + // - Cancel the ongoing gestures on the new View (PostCommit), and + // - We call the two APIs on all main frames, including non-primary ones. + if (rwhvb && !base::FeatureList::IsEnabled( + features::kInvalidateLocalSurfaceIdPreCommit)) { + rwhvb->OnOldViewDidNavigatePreCommit(); + rwhvb->OnNewViewDidNavigatePostCommit(); + } + } + + PageImpl& page = render_frame_host->GetPage(); + if (page.IsPrimary()) { + // The following events will not fire again if the this is a back-forward + // cache restore or prerendering activation. Fire them ourselves if needed. + if (details.is_navigation_to_different_page() && + page.did_first_visually_non_empty_paint()) { + OnFirstVisuallyNonEmptyPaint(page); + } + OnThemeColorChanged(page); + OnBackgroundColorChanged(page); + DidInferColorScheme(page); + AXTreeIDForMainFrameHasChanged(); + } +} + +void WebContentsImpl::DidNavigateAnyFramePostCommit( + RenderFrameHostImpl* render_frame_host, + const LoadCommittedDetails& details) { + OPTIONAL_TRACE_EVENT1("content,navigation", + "WebContentsImpl::DidNavigateAnyFramePostCommit", + "render_frame_host", render_frame_host); + + // This function can be called by prerendered frames or other inactive frames, + // we want to guard the dialog cancellations below. + const bool is_active = render_frame_host->IsActive(); + + // If we navigate off the active non-fenced frame page, close all JavaScript + // dialogs. We do not cancel the dialogs for fenced frames because it can be + // used as a communication channel. Please see also: + // RenderFrameHostManager::UnloadOldFrame in + // content/browser/renderer_host/render_frame_host_manager.cc + // + // TODO(crbug.com/40215909): Note that fenced frames cannot open modal dialogs + // so this only affects dialogs outside the fenced frame tree. If this is ever + // changed then the navigation should be deferred till the dialog from within + // the fenced frame is open. + if (is_active && !render_frame_host->IsNestedWithinFencedFrame() && + !details.is_same_document) { + CancelActiveAndPendingDialogs(); + } + + // If this is a user-initiated navigation, start allowing JavaScript dialogs + // again. + // + // TODO(crbug.com/40249773): Consider using the actual value of + // "whether a navigation started with user activation or not" instead of + // has_user_gesture, which might get filtered out when navigating from + // proxies. If so, we can remove tracking of + // `last_committed_common_params_has_user_gesture` entirely. + if (render_frame_host->last_committed_common_params_has_user_gesture() && + dialog_manager_) { + DCHECK(is_active); + dialog_manager_->CancelDialogs(this, /*reset_state=*/true); + } +} + +void WebContentsImpl::DidUpdateNavigationHandleTiming( + NavigationHandle* navigation_handle) { + SCOPED_UMA_HISTOGRAM_TIMER( + "WebContentsObserver.DidUpdateNavigationHandleTiming"); + observers_.NotifyObservers( + &WebContentsObserver::DidUpdateNavigationHandleTiming, navigation_handle); +} + +bool WebContentsImpl::CanOverscrollContent() const { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::CanOverscrollContent"); + // Disable overscroll when touch emulation is on. See crbug.com/369938. + if (force_disable_overscroll_content_) { + return false; + } + return delegate_ && delegate_->CanOverscrollContent(); +} + +void WebContentsImpl::OnThemeColorChanged(PageImpl& page) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnThemeColorChanged", + "page", page); + if (!page.IsPrimary()) { + return; + } + + if (page.did_first_visually_non_empty_paint() && + last_sent_theme_color_ != page.theme_color()) { + observers_.NotifyObservers(&WebContentsObserver::DidChangeThemeColor); + last_sent_theme_color_ = page.theme_color(); + } +} + +void WebContentsImpl::OnBackgroundColorChanged(PageImpl& page) { + if (!page.IsPrimary()) { + return; + } + + if (page.did_first_visually_non_empty_paint() && + last_sent_background_color_ != page.background_color()) { + observers_.NotifyObservers(&WebContentsObserver::OnBackgroundColorChanged); + last_sent_background_color_ = page.background_color(); + return; + } + + if (page.background_color().has_value()) { + if (auto* view = GetRenderWidgetHostView()) { + static_cast(view)->SetContentBackgroundColor( + page.background_color().value()); + } + } +} + +void WebContentsImpl::DidInferColorScheme(PageImpl& page) { + // If the page is primary, notify embedders that the current inferred color + // scheme for this WebContents has changed. + if (page.IsPrimary()) { + observers_.NotifyObservers(&WebContentsObserver::InferredColorSchemeUpdated, + page.inferred_color_scheme()); + if (page.inferred_color_scheme().has_value()) { + bool dark = page.inferred_color_scheme().value() == + blink::mojom::PreferredColorScheme::kDark; + base::UmaHistogramBoolean("Power.DarkMode.InferredDarkPageColorScheme", + dark); + if (web_preferences_ && web_preferences_->preferred_color_scheme == + blink::mojom::PreferredColorScheme::kDark) { + base::UmaHistogramBoolean( + "Power.DarkMode.DarkColorScheme.InferredDarkPageColorScheme", dark); + } + } + } +} + +void WebContentsImpl::OnVirtualKeyboardModeChanged(PageImpl& page) { + if (!page.IsPrimary()) { + return; + } + + observers_.NotifyObservers(&WebContentsObserver::VirtualKeyboardModeChanged, + page.virtual_keyboard_mode()); +} + +void WebContentsImpl::DidLoadResourceFromMemoryCache( + RenderFrameHostImpl* source, + const GURL& url, + const std::string& http_method, + const std::string& mime_type, + network::mojom::RequestDestination request_destination, + bool include_credentials) { + OPTIONAL_TRACE_EVENT2("content", + "WebContentsImpl::DidLoadResourceFromMemoryCache", + "render_frame_host", source, "url", url); + observers_.NotifyObservers( + &WebContentsObserver::DidLoadResourceFromMemoryCache, source, url, + mime_type, request_destination); + + if (!url.is_valid() || !url.SchemeIsHTTPOrHTTPS()) { + return; + } + + StoragePartition* partition = source->GetProcess()->GetStoragePartition(); + + // This method should only be called for resource loads (not navigations), so + // CHECK that here using `request_destination`. Note that + // `network::mojom::RequestDestination::kObject` and + // `network::mojom::RequestDestination::kEmbed` can correspond to navigations + // (see `blink::IsRequestDestinationFrame()`) but can also correspond to + // resource loads, so exclude those from the CHECK. + CHECK(request_destination != network::mojom::RequestDestination::kDocument); + CHECK(!network::IsRequestDestinationEmbeddedFrame(request_destination)); + + partition->GetNetworkContext()->NotifyExternalCacheHit( + url, http_method, source->GetNetworkIsolationKey(), + /*include_credentials=*/include_credentials); +} + +void WebContentsImpl::PrimaryMainDocumentElementAvailable() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::PrimaryMainDocumentElementAvailable"); + SCOPED_UMA_HISTOGRAM_TIMER( + "WebContentsObserver.PrimaryMainDocumentElementAvailable"); + observers_.NotifyObservers( + &WebContentsObserver::PrimaryMainDocumentElementAvailable); +} + +void WebContentsImpl::PassiveInsecureContentFound(const GURL& resource_url) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::PassiveInsecureContentFound", + "resource_url", resource_url); + if (delegate_) { + delegate_->PassiveInsecureContentFound(resource_url); + } +} + +bool WebContentsImpl::ShouldAllowRunningInsecureContent( + bool allowed_per_prefs, + const url::Origin& origin, + const GURL& resource_url) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::ShouldAllowRunningInsecureContent"); + if (delegate_) { + return delegate_->ShouldAllowRunningInsecureContent(this, allowed_per_prefs, + origin, resource_url); + } + + return allowed_per_prefs; +} + +void WebContentsImpl::ViewSource(RenderFrameHostImpl* frame) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ViewSource", + "render_frame_host", frame); + DCHECK_EQ(this, WebContents::FromRenderFrameHost(frame)); + + // Don't do anything if there is no |delegate_| that could accept and show the + // new WebContents containing the view-source. + if (!delegate_) { + return; + } + + // Use the last committed entry, since the pending entry hasn't loaded yet and + // won't be copied into the cloned tab. + NavigationEntryImpl* last_committed_entry = + frame->frame_tree()->controller().GetLastCommittedEntry(); + if (!last_committed_entry) { + return; + } + + FrameNavigationEntry* frame_entry = + last_committed_entry->GetFrameEntry(frame->frame_tree_node()); + if (!frame_entry) { + return; + } + + // Any new WebContents opened while this WebContents is in fullscreen can be + // used to confuse the user, so drop fullscreen. + base::ScopedClosureRunner fullscreen_block = + ForSecurityDropFullscreen(/*display_id=*/display::kInvalidDisplayId); + // The new view source contents will be independent of this contents, so + // release the fullscreen block. + fullscreen_block.RunAndReset(); + + // We intentionally don't share the SiteInstance with the original frame so + // that view source has a consistent process model and always ends up in a new + // process (https://crbug.com/699493). + scoped_refptr site_instance_for_view_source; + // Referrer and initiator are not important, because view-source should not + // hit the network, but should be served from the cache instead. + Referrer referrer_for_view_source; + std::optional initiator_for_view_source = std::nullopt; + std::optional initiator_base_url_for_view_source = std::nullopt; + // Do not restore title, derive it from the url. + std::u16string title_for_view_source; + auto navigation_entry = std::make_unique( + site_instance_for_view_source, frame_entry->url(), + referrer_for_view_source, initiator_for_view_source, + initiator_base_url_for_view_source, title_for_view_source, + ui::PAGE_TRANSITION_LINK, + /* is_renderer_initiated = */ false, + /* blob_url_loader_factory = */ nullptr, /* is_initial_entry = */ false); + const GURL url(content::kViewSourceScheme + std::string(":") + + frame_entry->url().spec()); + navigation_entry->SetVirtualURL(url); + + // View source opens the URL in a new tab as a top-level navigation. A + // top-level navigation may have a different IsolationInfo than the source + // iframe, so preserve the IsolationInfo from the origin frame, to use the + // same network shard and increase chances of a cache hit. + navigation_entry->set_isolation_info( + frame->ComputeIsolationInfoForNavigation(navigation_entry->GetURL())); + + // Do not restore scroller position. + // TODO(creis, lukasza, arthursonzogni): Do not reuse the original PageState, + // but start from a new one and only copy the needed data. + const blink::PageState& new_page_state = + frame_entry->page_state().RemoveScrollOffset(); + + scoped_refptr new_frame_entry = + navigation_entry->root_node()->frame_entry; + new_frame_entry->set_method(frame_entry->method()); + new_frame_entry->SetPageState(new_page_state); + + // Create a new WebContents, which is used to display the source code. + std::unique_ptr view_source_contents = + Create(CreateParams(GetBrowserContext())); + + // Restore the previously created NavigationEntry. + std::vector> navigation_entries; + navigation_entries.push_back(std::move(navigation_entry)); + view_source_contents->GetController().Restore(0, RestoreType::kRestored, + &navigation_entries); + + // Add |view_source_contents| as a new tab. + constexpr bool kUserGesture = true; + bool ignored_was_blocked; + delegate_->AddNewContents(this, std::move(view_source_contents), url, + WindowOpenDisposition::NEW_FOREGROUND_TAB, + blink::mojom::WindowFeatures(), kUserGesture, + &ignored_was_blocked); + // Note that the |delegate_| could have deleted |view_source_contents| during + // AddNewContents method call. +} + +void WebContentsImpl::ResourceLoadComplete( + RenderFrameHostImpl* render_frame_host, + const GlobalRequestID& request_id, + blink::mojom::ResourceLoadInfoPtr resource_load_info) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::ResourceLoadComplete", + "render_frame_host", render_frame_host, "request_id", + request_id); + const blink::mojom::ResourceLoadInfo& resource_load_info_ref = + *resource_load_info; + observers_.NotifyObservers(&WebContentsObserver::ResourceLoadComplete, + render_frame_host, request_id, + resource_load_info_ref); +} + +const blink::web_pref::WebPreferences& +WebContentsImpl::GetOrCreateWebPreferences() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::GetOrCreateWebPreferences"); + // Compute WebPreferences based on the current state if it's null. + if (!web_preferences_) { + OnWebPreferencesChanged(); + } + return *web_preferences_.get(); +} + +void WebContentsImpl::SetWebPreferences( + const blink::web_pref::WebPreferences& prefs) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetWebPreferences"); + web_preferences_ = std::make_unique(prefs); + // Get all the RenderViewHosts (except the ones for currently back-forward + // cached pages), and make them send the current WebPreferences + // to the renderer. WebPreferences updates for back-forward cached pages will + // be sent when we restore those pages from the back-forward cache. + primary_frame_tree_.ForEachRenderViewHost( + [](RenderViewHostImpl* rvh) { rvh->SendWebPreferencesToRenderer(); }); +} + +void WebContentsImpl::RecomputeWebPreferencesSlow() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::RecomputeWebPreferencesSlow"); + // OnWebPreferencesChanged is a no-op when this is true. + if (updating_web_preferences_) { + return; + } + // Resets |web_preferences_| so that we won't have any cached value for slow + // attributes (which won't get recomputed if we have pre-existing values for + // them). + web_preferences_.reset(); + OnWebPreferencesChanged(); +} + +std::optional WebContentsImpl::GetBaseBackgroundColor() { + return page_base_background_color_; +} + +blink::ColorProviderColorMaps WebContentsImpl::GetColorProviderColorMaps() + const { + const auto* color_mode_source = GetColorProviderSource(); + + // Unlike preferred color scheme, ForcedColors should always use the + // default color provider source, which reflects the NativeTheme web instance. + // This is because the Page colors feature only modifies the Forced colors + // mode for web without affecting the UI. + const auto* forced_colors_source = DefaultColorProviderSource::GetInstance(); + ui::ColorProviderKey::ForcedColors forced_colors = + forced_colors_source->GetForcedColors(); + if (forced_colors == ui::ColorProviderKey::ForcedColors::kNone) { + forced_colors = ui::ColorProviderKey::ForcedColors::kActive; + } + + return blink::ColorProviderColorMaps{ + color_mode_source->GetRendererColorMap( + ui::ColorProviderKey::ColorMode::kLight, + ui::ColorProviderKey::ForcedColors::kNone), + color_mode_source->GetRendererColorMap( + ui::ColorProviderKey::ColorMode::kDark, + ui::ColorProviderKey::ForcedColors::kNone), + forced_colors_source->GetRendererColorMap( + forced_colors_source->GetColorMode(), forced_colors)}; +} + +void WebContentsImpl::PrintCrossProcessSubframe( + const gfx::Rect& rect, + int document_cookie, + RenderFrameHostImpl* subframe_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::PrintCrossProcessSubframe", + "subframe", subframe_host); + auto* outer_contents = GetOuterWebContents(); + if (outer_contents) { + // When an extension or app page is printed, the content should be + // composited with outer content, so the outer contents should handle the + // print request. + outer_contents->PrintCrossProcessSubframe(rect, document_cookie, + subframe_host); + return; + } + + // If there is no delegate such as in tests or during deletion, do nothing. + if (!delegate_) { + return; + } + + delegate_->PrintCrossProcessSubframe(this, rect, document_cookie, + subframe_host); +} + +void WebContentsImpl::CapturePaintPreviewOfCrossProcessSubframe( + const gfx::Rect& rect, + const base::UnguessableToken& guid, + RenderFrameHostImpl* render_frame_host) { + OPTIONAL_TRACE_EVENT1( + "content", "WebContentsImpl::CapturePaintPreviewOfCrossProcessSubframe", + "render_frame_host", render_frame_host); + if (!delegate_) { + return; + } + delegate_->CapturePaintPreviewOfSubframe(this, rect, guid, render_frame_host); +} + +#if BUILDFLAG(IS_ANDROID) +base::android::ScopedJavaLocalRef +WebContentsImpl::GetJavaRenderFrameHostDelegate() { + return GetJavaWebContents(); +} +#endif + +void WebContentsImpl::DOMContentLoaded(RenderFrameHostImpl* render_frame_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DOMContentLoaded", + "render_frame_host", render_frame_host); + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DOMContentLoaded"); + observers_.NotifyObservers(&WebContentsObserver::DOMContentLoaded, + render_frame_host); +} + +void WebContentsImpl::OnDidFinishLoad(RenderFrameHostImpl* render_frame_host, + const GURL& url) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnDidFinishLoad", + "render_frame_host", render_frame_host, "url", url); + GURL validated_url(url); + render_frame_host->GetProcess()->FilterURL(false, &validated_url); + + { + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidFinishLoad"); + observers_.NotifyObservers(&WebContentsObserver::DidFinishLoad, + render_frame_host, validated_url); + } + size_t tree_size = GetFrameTreeSize(&primary_frame_tree_); + if (max_loaded_frame_count_ < tree_size) { + max_loaded_frame_count_ = tree_size; + } + + if (!render_frame_host->GetParentOrOuterDocument()) { + UMA_HISTOGRAM_COUNTS_1000("Navigation.MainFrame.FrameCount", tree_size); + } +} + +bool WebContentsImpl::IsAllowedToGoToEntryAtOffset(int32_t offset) { + // TODO(crbug.com/40165695): This should probably be renamed to + // WebContentsDelegate::IsAllowedToGoToEntryAtOffset or + // ShouldGoToEntryAtOffset + return !delegate_ || delegate_->OnGoToEntryOffset(offset); +} + +void WebContentsImpl::OnPageScaleFactorChanged(PageImpl& source) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPageScaleFactorChanged", + "source", source); + + if (source.IsPrimary()) { + observers_.NotifyObservers(&WebContentsObserver::OnPageScaleFactorChanged, + source.GetPageScaleFactor()); + } +} + +void WebContentsImpl::EnumerateDirectory( + base::WeakPtr file_chooser, + RenderFrameHost* render_frame_host, + scoped_refptr listener, + const base::FilePath& directory_path) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::EnumerateDirectory", + "render_frame_host", render_frame_host, + "directory_path", directory_path); + absl::Cleanup cancel_chooser = [&listener] { + listener->FileSelectionCanceled(); + }; + if (visibility_ == Visibility::HIDDEN) { + // Do not allow background tab to open file chooser. + return; + } + if (active_file_chooser_) { + // Only allow one active file chooser at one time. + return; + } + + // Any explicit focusing of another window while this WebContents is in + // fullscreen can be used to confuse the user, so drop fullscreen. + base::ScopedClosureRunner fullscreen_block = + ForSecurityDropFullscreen(/*display_id=*/display::kInvalidDisplayId); + listener->SetFullscreenBlock(std::move(fullscreen_block)); + + if (delegate_) { + active_file_chooser_ = std::move(file_chooser); + delegate_->EnumerateDirectory(this, std::move(listener), directory_path); + std::move(cancel_chooser).Cancel(); + } +} + +void WebContentsImpl::RegisterProtocolHandler(RenderFrameHostImpl* source, + const std::string& protocol, + const GURL& url, + bool user_gesture) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RegisterProtocolHandler", + "render_frame_host", source, "protocol", protocol); + // TODO(nick): Do we need to apply FilterURL to |url|? + if (!delegate_) { + return; + } + + blink::ProtocolHandlerSecurityLevel security_level = + delegate_->GetProtocolHandlerSecurityLevel(source); + + // Run the protocol handler arguments normalization process defined in the + // spec. + // https://html.spec.whatwg.org/multipage/system-state.html#normalize-protocol-handler-parameters + if (!AreValidRegisterProtocolHandlerArguments( + protocol, url, source->GetLastCommittedOrigin(), security_level)) { + ReceivedBadMessage(source->GetProcess(), + bad_message::REGISTER_PROTOCOL_HANDLER_INVALID_URL); + return; + } + + delegate_->RegisterProtocolHandler(source, protocol, url, user_gesture); +} + +void WebContentsImpl::UnregisterProtocolHandler(RenderFrameHostImpl* source, + const std::string& protocol, + const GURL& url, + bool user_gesture) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::UnregisterProtocolHandler", + "render_frame_host", source, "protocol", protocol); + // TODO(nick): Do we need to apply FilterURL to |url|? + if (!delegate_) { + return; + } + + blink::ProtocolHandlerSecurityLevel security_level = + delegate_->GetProtocolHandlerSecurityLevel(source); + + if (!AreValidRegisterProtocolHandlerArguments( + protocol, url, source->GetLastCommittedOrigin(), security_level)) { + ReceivedBadMessage(source->GetProcess(), + bad_message::REGISTER_PROTOCOL_HANDLER_INVALID_URL); + return; + } + + delegate_->UnregisterProtocolHandler(source, protocol, url, user_gesture); +} + +void WebContentsImpl::DomOperationResponse(RenderFrameHost* render_frame_host, + const std::string& json_string) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::DomOperationResponse", + "render_frame_host", render_frame_host, "json_string", + json_string); + + observers_.NotifyObservers(&WebContentsObserver::DomOperationResponse, + render_frame_host, json_string); +} + +void WebContentsImpl::SavableResourceLinksResponse( + RenderFrameHostImpl* source, + const std::vector& resources_list, + blink::mojom::ReferrerPtr referrer, + const std::vector& subframes) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::SavableResourceLinksResponse", + "render_frame_host", source); + if (save_package_) { + save_package_->SavableResourceLinksResponse(source, resources_list, + std::move(referrer), subframes); + } +} + +void WebContentsImpl::SavableResourceLinksError(RenderFrameHostImpl* source) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SavableResourceLinksError", + "render_frame_host", source); + if (save_package_) { + save_package_->SavableResourceLinksError(source); + } +} + +void WebContentsImpl::OnServiceWorkerAccessed( + RenderFrameHost* render_frame_host, + const GURL& scope, + AllowServiceWorkerResult allowed) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnServiceWorkerAccessed", + "render_frame_host", render_frame_host, "scope", scope); + // Use a variable to select between overloads. + void (WebContentsObserver::*func)(RenderFrameHost*, const GURL&, + AllowServiceWorkerResult) = + &WebContentsObserver::OnServiceWorkerAccessed; + observers_.NotifyObservers(func, render_frame_host, scope, allowed); +} + +void WebContentsImpl::OnServiceWorkerAccessed( + NavigationHandle* navigation, + const GURL& scope, + AllowServiceWorkerResult allowed) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnServiceWorkerAccessed", + "navigation_handle", navigation, "scope", scope); + // Use a variable to select between overloads. + void (WebContentsObserver::*func)(NavigationHandle*, const GURL&, + AllowServiceWorkerResult) = + &WebContentsObserver::OnServiceWorkerAccessed; + observers_.NotifyObservers(func, navigation, scope, allowed); +} + +void WebContentsImpl::OnColorChooserFactoryReceiver( + mojo::PendingReceiver receiver) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::OnColorChooserFactoryReceiver"); + color_chooser_factory_receivers_.Add(this, std::move(receiver)); +} + +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) +void WebContentsImpl::OpenColorChooser( + mojo::PendingReceiver chooser_receiver, + mojo::PendingRemote client, + SkColor color, + std::vector suggestions) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OpenColorChooser"); + // Create `color_chooser_holder_` before calling OpenColorChooser since + // OpenColorChooser may callback with results. + color_chooser_holder_.reset(); + color_chooser_holder_ = std::make_unique( + std::move(chooser_receiver), std::move(client)); + + auto new_color_chooser = + delegate_ ? delegate_->OpenColorChooser(this, color, suggestions) + : nullptr; + if (color_chooser_holder_ && new_color_chooser) { + color_chooser_holder_->SetChooser(std::move(new_color_chooser)); + } else if (new_color_chooser) { + // OpenColorChooser synchronously called back to DidEndColorChooser. + DCHECK(!color_chooser_holder_); + new_color_chooser->End(); + } else if (color_chooser_holder_) { + DCHECK(!new_color_chooser); + color_chooser_holder_.reset(); + } +} +#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) + +#if BUILDFLAG(ENABLE_PPAPI) +void WebContentsImpl::OnPepperInstanceCreated(RenderFrameHostImpl* source, + int32_t pp_instance) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperInstanceCreated", + "render_frame_host", source); + observers_.NotifyObservers(&WebContentsObserver::PepperInstanceCreated); + pepper_playback_observer_->PepperInstanceCreated(source, pp_instance); +} + +void WebContentsImpl::OnPepperInstanceDeleted(RenderFrameHostImpl* source, + int32_t pp_instance) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperInstanceDeleted", + "render_frame_host", source); + observers_.NotifyObservers(&WebContentsObserver::PepperInstanceDeleted); + pepper_playback_observer_->PepperInstanceDeleted(source, pp_instance); +} + +void WebContentsImpl::OnPepperPluginHung(RenderFrameHostImpl* source, + int plugin_child_id, + const base::FilePath& path, + bool is_hung) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperPluginHung", + "render_frame_host", source); + observers_.NotifyObservers(&WebContentsObserver::PluginHungStatusChanged, + plugin_child_id, path, is_hung); +} + +void WebContentsImpl::OnPepperStartsPlayback(RenderFrameHostImpl* source, + int32_t pp_instance) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperStartsPlayback", + "render_frame_host", source); + pepper_playback_observer_->PepperStartsPlayback(source, pp_instance); +} + +void WebContentsImpl::OnPepperStopsPlayback(RenderFrameHostImpl* source, + int32_t pp_instance) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperStopsPlayback", + "render_frame_host", source); + pepper_playback_observer_->PepperStopsPlayback(source, pp_instance); +} + +void WebContentsImpl::OnPepperPluginCrashed(RenderFrameHostImpl* source, + const base::FilePath& plugin_path, + base::ProcessId plugin_pid) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnPepperPluginCrashed", + "render_frame_host", source); + // TODO(nick): Eliminate the |plugin_pid| parameter, which can't be trusted, + // and is only used by WebTestControlHost. + observers_.NotifyObservers(&WebContentsObserver::PluginCrashed, plugin_path, + plugin_pid); +} + +#endif // BUILDFLAG(ENABLE_PPAPI) + +void WebContentsImpl::UpdateFaviconURL( + RenderFrameHostImpl* source, + const std::vector& candidates) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::UpdateFaviconURL", + "render_frame_host", source); + // We get updated favicon URLs after the page stops loading. If a cross-site + // navigation occurs while a page is still loading, the initial page + // may stop loading and send us updated favicon URLs after the navigation + // for the new page has committed. + if (!source->IsInPrimaryMainFrame()) { + return; + } + + observers_.NotifyObservers(&WebContentsObserver::DidUpdateFaviconURL, source, + candidates); +} + +void WebContentsImpl::SetIsOverlayContent(bool is_overlay_content) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetIsOverlayContent", + "is_overlay_content", is_overlay_content); + is_overlay_content_ = is_overlay_content; +} + +void WebContentsImpl::OnFirstVisuallyNonEmptyPaint(PageImpl& page) { + OPTIONAL_TRACE_EVENT1( + "content", "WebContentsImpl::OnFirstVisuallyNonEmptyPaint", "page", page); + if (!page.IsPrimary()) { + return; + } + + { + SCOPED_UMA_HISTOGRAM_TIMER( + "WebContentsObserver.DidFirstVisuallyNonEmptyPaint"); + observers_.NotifyObservers( + &WebContentsObserver::DidFirstVisuallyNonEmptyPaint); + } + if (page.theme_color() != last_sent_theme_color_) { + // Theme color should have updated by now if there was one. + observers_.NotifyObservers(&WebContentsObserver::DidChangeThemeColor); + last_sent_theme_color_ = GetPrimaryPage().theme_color(); + } + + if (page.background_color() != last_sent_background_color_) { + // Background color should have updated by now if there was one. + observers_.NotifyObservers(&WebContentsObserver::OnBackgroundColorChanged); + last_sent_background_color_ = page.background_color(); + } +} + +bool WebContentsImpl::IsGuest() { + return !!browser_plugin_guest_; +} + +void WebContentsImpl::NotifyBeforeFormRepostWarningShow() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::NotifyBeforeFormRepostWarningShow"); + observers_.NotifyObservers(&WebContentsObserver::BeforeFormRepostWarningShow); +} + +void WebContentsImpl::ActivateAndShowRepostFormWarningDialog() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::ActivateAndShowRepostFormWarningDialog"); + Activate(); + if (delegate_) { + delegate_->ShowRepostFormWarningDialog(this); + } +} + +bool WebContentsImpl::HasAccessedInitialDocument() { + return GetPrimaryFrameTree().has_accessed_initial_main_document(); +} + +void WebContentsImpl::UpdateTitleForEntry(NavigationEntry* entry, + const std::u16string& title) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::UpdateTitleForEntry", + "title", title); + NavigationEntryImpl* entry_impl = + NavigationEntryImpl::FromNavigationEntry(entry); + bool title_changed = UpdateTitleForEntryImpl(entry_impl, title); + if (title_changed) { + NotifyTitleUpdateForEntry(entry_impl); + } +} + +bool WebContentsImpl::UpdateTitleForEntryImpl(NavigationEntryImpl* entry, + const std::u16string& title) { + DCHECK(entry); + std::u16string final_title; + base::TrimWhitespace(title, base::TRIM_ALL, &final_title); + + if (final_title == entry->GetTitle()) { + return false; // Nothing changed, don't bother. + } + + entry->SetTitle(std::move(final_title)); + return true; +} + +void WebContentsImpl::NotifyTitleUpdateForEntry(NavigationEntryImpl* entry) { + // |entry| must belong to the primary frame tree's NavigationController. + DCHECK(GetController().GetEntryWithUniqueIDIncludingPending( + entry->GetUniqueID())); + std::u16string final_title = entry->GetTitleForDisplay(); + bool did_web_contents_title_change = entry == GetNavigationEntryForTitle(); + if (did_web_contents_title_change) { + view_->SetPageTitle(final_title); + } + + { + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.TitleWasSet"); + observers_.NotifyObservers(&WebContentsObserver::TitleWasSet, entry); + } + + if (did_web_contents_title_change) { + NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE); + } +} + +NavigationEntry* WebContentsImpl::GetNavigationEntryForTitle() { + // We use the title for the last committed entry rather than a pending + // navigation entry. For example, when the user types in a URL, we want to + // keep the old page's title until the new load has committed and we get a new + // title. + NavigationEntry* entry = GetController().GetLastCommittedEntry(); + + // We make an exception for initial navigations. We only want to use the title + // from the visible entry if: + // 1. The pending entry has been explicitly assigned a title to display. + // 2. The user is doing a history navigation in a new tab (e.g., Ctrl+Back), + // which case there is a pending entry index other than -1. + // + // Otherwise, we want to stick with the last committed entry's title during + // new navigations, which have pending entries at index -1 with no title. + if (GetController().IsInitialNavigation() && + ((GetController().GetVisibleEntry() && + !GetController().GetVisibleEntry()->GetTitle().empty()) || + GetController().GetPendingEntryIndex() != -1)) { + entry = GetController().GetVisibleEntry(); + } + + return entry; +} + +void WebContentsImpl::SendChangeLoadProgress() { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SendChangeLoadProgress", + "load_progress", GetLoadProgress()); + loading_last_progress_update_ = base::TimeTicks::Now(); + + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.LoadProgressChanged"); + observers_.NotifyObservers(&WebContentsObserver::LoadProgressChanged, + GetLoadProgress()); +} + +void WebContentsImpl::ResetLoadProgressState() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ResetLoadProgressState"); + GetPrimaryPage().set_load_progress(0.0); + loading_weak_factory_.InvalidateWeakPtrs(); + loading_last_progress_update_ = base::TimeTicks(); +} + +// Notifies the RenderWidgetHost instance about the fact that the page is +// loading, or done loading. +void WebContentsImpl::LoadingStateChanged(LoadingState new_state) { + if (IsBeingDestroyed()) { + return; + } + + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::LoadingStateChanged", + "loading_state", new_state); + + if (new_state == LoadingState::NONE) { + load_state_ = + net::LoadStateWithParam(net::LOAD_STATE_IDLE, std::u16string()); + load_state_host_.clear(); + upload_size_ = 0; + upload_position_ = 0; + } + + if (delegate_) { + delegate_->LoadingStateChanged( + this, new_state == LoadingState::LOADING_UI_REQUESTED); + } + NotifyNavigationStateChanged(INVALIDATE_TYPE_LOAD); +} + +void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_view, + RenderViewHost* new_view) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::NotifyViewSwapped", + "old_view", old_view, "new_view", new_view); + DCHECK_NE(old_view, new_view); + // After sending out a swap notification, we need to send a disconnect + // notification so that clients that pick up a pointer to |this| can NULL the + // pointer. See Bug 1230284. + notify_disconnection_ = true; + observers_.NotifyObservers(&WebContentsObserver::RenderViewHostChanged, + old_view, new_view); + view_->RenderViewHostChanged(old_view, new_view); + + // If this is an inner WebContents that has swapped views, we need to reattach + // it to its outer WebContents. + if (node_.outer_web_contents()) { + ReattachToOuterWebContentsFrame(); + } + + // Ensure that the associated embedder gets cleared after a RenderViewHost + // gets swapped, so we don't reuse the same embedder next time a + // RenderViewHost is attached to this WebContents. + RemoveBrowserPluginEmbedder(); +} + +void WebContentsImpl::NotifyFrameSwapped(RenderFrameHostImpl* old_frame, + RenderFrameHostImpl* new_frame) { + TRACE_EVENT2("content", "WebContentsImpl::NotifyFrameSwapped", "old_frame", + old_frame, "new_frame", new_frame); +#if BUILDFLAG(IS_ANDROID) + // Copy importance from |old_frame| if |new_frame| is a main frame. + if (old_frame && !new_frame->GetParent()) { + RenderWidgetHostImpl* old_widget = old_frame->GetRenderWidgetHost(); + RenderWidgetHostImpl* new_widget = new_frame->GetRenderWidgetHost(); + new_widget->SetImportance(old_widget->importance()); + } +#endif + observers_.NotifyObservers(&WebContentsObserver::RenderFrameHostChanged, + old_frame, new_frame); +} + +void WebContentsImpl::NotifyNavigationEntryCommitted( + const LoadCommittedDetails& load_details) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::NotifyNavigationEntryCommitted"); + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.NavigationEntryCommitted"); + observers_.NotifyObservers(&WebContentsObserver::NavigationEntryCommitted, + load_details); +} + +void WebContentsImpl::NotifyNavigationEntryChanged( + const EntryChangedDetails& change_details) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::NotifyNavigationEntryChanged"); + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.NavigationEntryChanged"); + observers_.NotifyObservers(&WebContentsObserver::NavigationEntryChanged, + change_details); +} + +void WebContentsImpl::NotifyNavigationListPruned( + const PrunedDetails& pruned_details) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::NotifyNavigationListPruned"); + observers_.NotifyObservers(&WebContentsObserver::NavigationListPruned, + pruned_details); +} + +void WebContentsImpl::NotifyNavigationEntriesDeleted() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::NotifyNavigationEntriesDeleted"); + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.NavigationEntryDeleted"); + observers_.NotifyObservers(&WebContentsObserver::NavigationEntriesDeleted); +} + +void WebContentsImpl::OnDidBlockNavigation( + const GURL& blocked_url, + const GURL& initiator_url, + blink::mojom::NavigationBlockedReason reason) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnDidBlockNavigation", + "details", [&](perfetto::TracedValue context) { + // TODO(crbug.com/40751990): Replace this with passing + // more parameters to TRACE_EVENT directly when + // available. + auto dict = std::move(context).WriteDictionary(); + dict.Add("blocked_url", blocked_url); + dict.Add("initiator_url", initiator_url); + dict.Add("reason", reason); + }); + if (delegate_) { + delegate_->OnDidBlockNavigation(this, blocked_url, initiator_url, reason); + } +} + +void WebContentsImpl::RenderFrameCreated( + RenderFrameHostImpl* render_frame_host) { + TRACE_EVENT1("content", "WebContentsImpl::RenderFrameCreated", + "render_frame_host", render_frame_host); + + if (render_frame_host->IsInPrimaryMainFrame()) { + NotifyPrimaryMainFrameProcessIsAlive(); + } + + { + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.RenderFrameCreated"); + observers_.NotifyObservers(&WebContentsObserver::RenderFrameCreated, + render_frame_host); + } + render_frame_host->UpdateAccessibilityMode(); + + if (safe_area_insets_host_) { + safe_area_insets_host_->RenderFrameCreated(render_frame_host); + } +} + +void WebContentsImpl::RenderFrameDeleted( + RenderFrameHostImpl* render_frame_host) { + TRACE_EVENT1("content", "WebContentsImpl::RenderFrameDeleted", + "render_frame_host", render_frame_host); + { + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.RenderFrameDeleted"); + observers_.NotifyObservers(&WebContentsObserver::RenderFrameDeleted, + render_frame_host); + } +#if BUILDFLAG(ENABLE_PPAPI) + pepper_playback_observer_->RenderFrameDeleted(render_frame_host); +#endif + + if (safe_area_insets_host_) { + safe_area_insets_host_->RenderFrameDeleted(render_frame_host); + } + + // Remove any fullscreen state that the frame has stored. + FullscreenStateChanged(render_frame_host, false /* is_fullscreen */, + blink::mojom::FullscreenOptionsPtr()); +} + +void WebContentsImpl::ShowContextMenu( + RenderFrameHost& render_frame_host, + mojo::PendingAssociatedRemote + context_menu_client, + const ContextMenuParams& params) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ShowContextMenu", + "render_frame_host", render_frame_host); + // If a renderer fires off a second command to show a context menu before the + // first context menu is closed, just ignore it. https://crbug.com/707534 + if (showing_context_menu_) { + return; + } + + if (context_menu_client) { + context_menu_client_.reset(); + context_menu_client_.Bind(std::move(context_menu_client)); + } + + ContextMenuParams context_menu_params(params); + // Allow WebContentsDelegates to handle the context menu operation first. + if (delegate_ && + delegate_->HandleContextMenu(render_frame_host, context_menu_params)) { + return; + } + + render_view_host_delegate_view_->ShowContextMenu(render_frame_host, + context_menu_params); +} + +namespace { +// Normalizes the line endings: \r\n -> \n, lone \r -> \n. +std::u16string NormalizeLineBreaks(const std::u16string& source) { + static const base::NoDestructor kReturnNewline(u"\r\n"); + static const base::NoDestructor kReturn(u"\r"); + static const base::NoDestructor kNewline(u"\n"); + + std::vector pieces; + + for (const auto& rn_line : base::SplitStringPieceUsingSubstr( + source, *kReturnNewline, base::KEEP_WHITESPACE, + base::SPLIT_WANT_ALL)) { + auto r_lines = base::SplitStringPieceUsingSubstr( + rn_line, *kReturn, base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); + std::move(std::begin(r_lines), std::end(r_lines), + std::back_inserter(pieces)); + } + + return base::JoinString(pieces, *kNewline); +} +} // namespace + +void WebContentsImpl::RunJavaScriptDialog( + RenderFrameHostImpl* render_frame_host, + const std::u16string& message, + const std::u16string& default_prompt, + JavaScriptDialogType dialog_type, + bool disable_third_party_subframe_suppresion, + JavaScriptDialogCallback response_callback) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RunJavaScriptDialog", + "render_frame_host", render_frame_host); + DCHECK(render_frame_host->GetPage().IsPrimary()); + + // Ensure that if showing a dialog is the first thing that a page does, that + // the contents of the previous page aren't shown behind it. This is required + // because showing a dialog freezes the renderer, so no frames will be coming + // from it. https://crbug.com/823353 + auto* render_widget_host_impl = render_frame_host->GetRenderWidgetHost(); + if (render_widget_host_impl) { + render_widget_host_impl->ForceFirstFrameAfterNavigationTimeout(); + } + + // Running a dialog causes an exit to webpage-initiated fullscreen. + // http://crbug.com/728276 + base::ScopedClosureRunner fullscreen_block = + ForSecurityDropFullscreen(/*display_id=*/display::kInvalidDisplayId); + + auto callback = base::BindOnce( + &WebContentsImpl::OnDialogClosed, weak_factory_.GetWeakPtr(), + render_frame_host->GetProcess()->GetID(), + render_frame_host->GetRoutingID(), std::move(response_callback), + std::move(fullscreen_block)); + + std::vector page_handlers = + protocol::PageHandler::EnabledForWebContents(this); + + if (delegate_) { + dialog_manager_ = delegate_->GetJavaScriptDialogManager(this); + } + + // While a JS message dialog is showing, defer commits in this WebContents. + javascript_dialog_dismiss_notifier_ = + std::make_unique(); + + // Suppress JavaScript dialogs when requested. + bool should_suppress = delegate_ && delegate_->ShouldSuppressDialogs(this); + bool has_non_devtools_handlers = delegate_ && dialog_manager_; + bool has_handlers = page_handlers.size() || has_non_devtools_handlers; + bool suppress_this_message = should_suppress || !has_handlers; + + if (!disable_third_party_subframe_suppresion && + GetContentClient()->browser()->SuppressDifferentOriginSubframeJSDialogs( + GetBrowserContext())) { + // We can't check for opaque origin cases, default to allowing them to + // trigger dialogs. + // TODO(carlosil): The main use case for opaque use cases are tests, + // investigate if there are uses in the wild, otherwise adapt tests that + // require dialogs so they commit an origin first, and remove this + // conditional. + if (!render_frame_host->GetLastCommittedOrigin().opaque()) { + bool is_different_origin_subframe = + render_frame_host->GetLastCommittedOrigin() != + render_frame_host->GetOutermostMainFrame()->GetLastCommittedOrigin(); + suppress_this_message |= is_different_origin_subframe; + if (is_different_origin_subframe) { + GetPrimaryMainFrame()->AddMessageToConsole( + blink::mojom::ConsoleMessageLevel::kWarning, + base::StringPrintf( + "A different origin subframe tried to create a JavaScript " + "dialog. This is no longer allowed and was blocked. See " + "https://www.chromestatus.com/feature/5148698084376576 for " + "more details.")); + } + } + } + + if (suppress_this_message) { + std::move(callback).Run(true, false, std::u16string()); + return; + } + + scoped_refptr wrapper = + new CloseDialogCallbackWrapper(std::move(callback)); + + is_showing_javascript_dialog_ = true; + + std::u16string normalized_message = NormalizeLineBreaks(message); + + for (auto* handler : page_handlers) { + handler->DidRunJavaScriptDialog( + render_frame_host->GetLastCommittedURL(), normalized_message, + default_prompt, dialog_type, has_non_devtools_handlers, + base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false)); + } + + if (dialog_manager_) { + dialog_manager_->RunJavaScriptDialog( + this, render_frame_host, dialog_type, normalized_message, + default_prompt, + base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false), + &suppress_this_message); + } + + if (suppress_this_message) { + // If we are suppressing messages, just reply as if the user immediately + // pressed "Cancel", passing true to |dialog_was_suppressed|. + wrapper->Run(true, false, std::u16string()); + } +} + +void WebContentsImpl::NotifyOnJavaScriptDialogDismiss( + base::OnceClosure callback) { + DCHECK(javascript_dialog_dismiss_notifier_); + javascript_dialog_dismiss_notifier_->NotifyOnDismiss(std::move(callback)); +} + +void WebContentsImpl::RunBeforeUnloadConfirm( + RenderFrameHostImpl* render_frame_host, + bool is_reload, + JavaScriptDialogCallback response_callback) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RunBeforeUnloadConfirm", + "render_frame_host", render_frame_host, "is_reload", + is_reload); + DCHECK(render_frame_host->GetPage().IsPrimary()); + + // Ensure that if showing a dialog is the first thing that a page does, that + // the contents of the previous page aren't shown behind it. This is required + // because showing a dialog freezes the renderer, so no frames will be coming + // from it. https://crbug.com/823353 + auto* render_widget_host_impl = render_frame_host->GetRenderWidgetHost(); + if (render_widget_host_impl) { + render_widget_host_impl->ForceFirstFrameAfterNavigationTimeout(); + } + + // Running a dialog causes an exit to webpage-initiated fullscreen. + // http://crbug.com/728276 + base::ScopedClosureRunner fullscreen_block = + ForSecurityDropFullscreen(/*display_id=*/display::kInvalidDisplayId); + + auto callback = base::BindOnce( + &WebContentsImpl::OnDialogClosed, weak_factory_.GetWeakPtr(), + render_frame_host->GetProcess()->GetID(), + render_frame_host->GetRoutingID(), std::move(response_callback), + std::move(fullscreen_block)); + + std::vector page_handlers = + protocol::PageHandler::EnabledForWebContents(this); + + if (delegate_) { + dialog_manager_ = delegate_->GetJavaScriptDialogManager(this); + } + + // While a JS beforeunload dialog is showing, defer commits in this + // WebContents. + javascript_dialog_dismiss_notifier_ = + std::make_unique(); + + bool should_suppress = delegate_ && delegate_->ShouldSuppressDialogs(this); + bool has_non_devtools_handlers = delegate_ && dialog_manager_; + bool has_handlers = page_handlers.size() || has_non_devtools_handlers; + if (should_suppress || !has_handlers) { + std::move(callback).Run(false, true, std::u16string()); + return; + } + + is_showing_before_unload_dialog_ = true; + + scoped_refptr wrapper = + new CloseDialogCallbackWrapper(std::move(callback)); + + GURL frame_url = render_frame_host->GetLastCommittedURL(); + for (auto* handler : page_handlers) { + handler->DidRunBeforeUnloadConfirm( + frame_url, has_non_devtools_handlers, + base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false)); + } + + if (dialog_manager_) { + dialog_manager_->RunBeforeUnloadDialog( + this, render_frame_host, is_reload, + base::BindOnce(&CloseDialogCallbackWrapper::Run, wrapper, false)); + } +} + +void WebContentsImpl::RunFileChooser( + base::WeakPtr file_chooser, + RenderFrameHost* render_frame_host, + scoped_refptr listener, + const blink::mojom::FileChooserParams& params) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RunFileChooser", + "render_frame_host", render_frame_host); + + absl::Cleanup cancel_chooser = [&listener] { + listener->FileSelectionCanceled(); + }; + if (visibility_ == Visibility::HIDDEN) { + // Do not allow background tab to open file chooser. + return; + } + if (active_file_chooser_) { + // Only allow one active file chooser at one time. + return; + } + + // Any explicit focusing of another window while this WebContents is in + // fullscreen can be used to confuse the user, so drop fullscreen. + base::ScopedClosureRunner fullscreen_block = + ForSecurityDropFullscreen(/*display_id=*/display::kInvalidDisplayId); + listener->SetFullscreenBlock(std::move(fullscreen_block)); + + if (delegate_) { + active_file_chooser_ = std::move(file_chooser); + delegate_->RunFileChooser(render_frame_host, std::move(listener), params); + std::move(cancel_chooser).Cancel(); + } +} + +double WebContentsImpl::GetPendingPageZoomLevel() { +#if BUILDFLAG(IS_ANDROID) + // On Android, use the default page zoom level when the AccessibilityPageZoom + // feature is disabled. + if (!base::FeatureList::IsEnabled(features::kAccessibilityPageZoom)) { + return 0.0; + } +#endif + NavigationEntry* pending_entry = GetController().GetPendingEntry(); + if (!pending_entry) { + return HostZoomMap::GetZoomLevel(this); + } + + GURL url = pending_entry->GetURL(); +#if BUILDFLAG(IS_ANDROID) + return HostZoomMap::GetForWebContents(this) + ->GetZoomLevelForHostAndSchemeAndroid(url.scheme(), + net::GetHostOrSpecFromURL(url)); +#else + return HostZoomMap::GetForWebContents(this)->GetZoomLevelForHostAndScheme( + url.scheme(), net::GetHostOrSpecFromURL(url)); +#endif +} + +bool WebContentsImpl::IsPictureInPictureAllowedForFullscreenVideo() const { + return media_web_contents_observer_ + ->IsPictureInPictureAllowedForFullscreenVideo(); +} + +bool WebContentsImpl::IsFocusedElementEditable() { + RenderFrameHostImpl* frame = GetFocusedFrame(); + return frame && frame->has_focused_editable_element(); +} + +bool WebContentsImpl::IsShowingContextMenu() { + return showing_context_menu_; +} + +void WebContentsImpl::SetShowingContextMenu(bool showing) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::SetShowingContextMenu", + "showing", showing); + + DCHECK_NE(showing_context_menu_, showing); + showing_context_menu_ = showing; + + if (auto* view = GetRenderWidgetHostView()) { + // Notify the main frame's RWHV to run the platform-specific code, if any. + static_cast(view)->SetShowingContextMenu( + showing); + } +} + +void WebContentsImpl::ClearFocusedElement() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ClearFocusedElement"); + if (auto* frame = GetFocusedFrame()) { + frame->ClearFocusedElement(); + } +} + +bool WebContentsImpl::IsNeverComposited() { + if (!delegate_) { + return false; + } + return delegate_->IsNeverComposited(this); +} + +RenderViewHostDelegateView* WebContentsImpl::GetDelegateView() { + return render_view_host_delegate_view_; +} + +const blink::RendererPreferences& WebContentsImpl::GetRendererPrefs() const { + return renderer_preferences_; +} + +RenderFrameHostImpl* WebContentsImpl::GetOuterWebContentsFrame() { + if (GetOuterDelegateFrameTreeNodeId() == + FrameTreeNode::kFrameTreeNodeInvalidId) { + return nullptr; + } + + FrameTreeNode* outer_node = + FrameTreeNode::GloballyFindByID(GetOuterDelegateFrameTreeNodeId()); + // The outer node should be in the outer WebContents. + DCHECK_EQ(&outer_node->frame_tree(), + &GetOuterWebContents()->GetPrimaryFrameTree()); + return outer_node->parent(); +} + +WebContentsImpl* WebContentsImpl::GetOuterWebContents() { + return node_.outer_web_contents(); +} + +std::vector WebContentsImpl::GetInnerWebContents() { + std::vector all_inner_contents; + const auto& inner_contents = node_.GetInnerWebContents(); + all_inner_contents.insert(all_inner_contents.end(), inner_contents.begin(), + inner_contents.end()); + return all_inner_contents; +} + +WebContentsImpl* WebContentsImpl::GetResponsibleWebContents() { + return FromRenderFrameHostImpl( + GetPrimaryMainFrame()->GetOutermostMainFrameOrEmbedder()); +} + +WebContentsImpl* WebContentsImpl::GetFocusedWebContents() { + return WebContentsImpl::FromFrameTreeNode(GetFocusedFrameTree()->root()); +} + +FrameTree* WebContentsImpl::GetFocusedFrameTree() { + return GetOutermostWebContents()->node_.focused_frame_tree(); +} + +void WebContentsImpl::SetFocusToLocationBar() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetFocusToLocationBar"); + if (delegate_) { + delegate_->SetFocusToLocationBar(); + } +} + +bool WebContentsImpl::ContainsOrIsFocusedWebContents() { + for (WebContentsImpl* focused_contents = GetFocusedWebContents(); + focused_contents; + focused_contents = focused_contents->GetOuterWebContents()) { + if (focused_contents == this) { + return true; + } + } + + return false; +} + +void WebContentsImpl::RemoveBrowserPluginEmbedder() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::RemoveBrowserPluginEmbedder"); + browser_plugin_embedder_.reset(); +} + +WebContentsImpl* WebContentsImpl::GetOutermostWebContents() { + WebContentsImpl* root = this; + while (root->GetOuterWebContents()) { + root = root->GetOuterWebContents(); + } + return root; +} + +void WebContentsImpl::InnerWebContentsCreated(WebContents* inner_web_contents) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::InnerWebContentsCreated"); + observers_.NotifyObservers(&WebContentsObserver::InnerWebContentsCreated, + inner_web_contents); +} + +void WebContentsImpl::InnerWebContentsAttached( + WebContents* inner_web_contents) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::InnerWebContentsDetached"); + if (inner_web_contents->IsCurrentlyAudible()) { + OnAudioStateChanged(); + } +} + +void WebContentsImpl::InnerWebContentsDetached( + WebContents* inner_web_contents) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::InnerWebContentsCreated"); + if (!IsBeingDestroyed()) { + OnAudioStateChanged(); + } +} + +void WebContentsImpl::RenderViewReady(RenderViewHost* rvh) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderViewReady", + "render_view_host", rvh); + if (rvh != GetRenderViewHost()) { + // Don't notify the world, since this came from a renderer in the + // background. + return; + } + + RenderWidgetHostViewBase* rwhv = + static_cast(GetRenderWidgetHostView()); + if (rwhv) { + rwhv->SetMainFrameAXTreeID(GetPrimaryMainFrame()->GetAXTreeID()); + } + + notify_disconnection_ = true; + + { + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.RenderViewReady"); + observers_.NotifyObservers(&WebContentsObserver::RenderViewReady); + } + view_->RenderViewReady(); +} + +void WebContentsImpl::RenderViewTerminated(RenderViewHost* rvh, + base::TerminationStatus status, + int error_code) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::RenderViewTerminated", + "render_view_host", rvh, "status", + static_cast(status)); + + // It is possible to get here while the WebContentsImpl is being destroyed, + // in particular when the destruction of the main frame's RenderFrameHost and + // RenderViewHost triggers cleanup of the main frame's process, which in turn + // dispatches RenderProcessExited observers, one of which calls in here. In + // this state, we cannot check GetRenderViewHost() below, since + // current_frame_host() for the root FrameTreeNode has already been cleared. + // Since the WebContents is going away, none of the work here is needed, so + // just return early. + if (IsBeingDestroyed()) { + return; + } + + if (rvh != GetRenderViewHost()) { + // The pending page's RenderViewHost is gone. + return; + } + + auto* rvh_impl = static_cast(rvh); + DCHECK(rvh_impl->GetMainRenderFrameHost()->IsInPrimaryMainFrame()) + << "GetRenderViewHost() must belong to the primary frame tree"; + + // Ensure fullscreen mode is exited in the |delegate_| since a crashed + // renderer may not have made a clean exit. + if (IsFullscreen()) { + ExitFullscreenMode(false); + } + + // Ensure any video or document in Picture-in-Picture is exited in the + // |delegate_| since a crashed renderer may not have made a clean exit. + if (HasPictureInPictureVideo() || HasPictureInPictureDocument()) { + ExitPictureInPicture(); + } + + // Cancel any visible dialogs so they are not left dangling over the sad tab. + CancelActiveAndPendingDialogs(); + + audio_stream_monitor_.RenderProcessGone(rvh_impl->GetProcess()->GetID()); + + // Reset the loading progress. TODO(avi): What does it mean to have a + // "renderer crash" when there is more than one renderer process serving a + // webpage? Once this function is called at a more granular frame level, we + // probably will need to more granularly reset the state here. + ResetLoadProgressState(); + + SetPrimaryMainFrameProcessStatus(status, error_code); + + TRACE_EVENT0( + "content", + "Dispatching WebContentsObserver::PrimaryMainFrameRenderProcessGone"); + // Some observers might destroy WebContents in + // PrimaryMainFrameRenderProcessGone. + base::WeakPtr weak_ptr = weak_factory_.GetWeakPtr(); + for (auto& observer : observers_.observer_list()) { + observer.PrimaryMainFrameRenderProcessGone(status); + if (!weak_ptr) { + return; + } + } + + // |this| might have been deleted. Do not add code here. +} + +void WebContentsImpl::RenderViewDeleted(RenderViewHost* rvh) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderViewDeleted", + "render_view_host", rvh); + observers_.NotifyObservers(&WebContentsObserver::RenderViewDeleted, rvh); +} + +void WebContentsImpl::ClearTargetURL() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ClearTargetURL"); + frame_that_set_last_target_url_ = nullptr; + if (delegate_) { + delegate_->UpdateTargetURL(this, GURL()); + } +} + +void WebContentsImpl::Close() { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::Close", + "render_frame_host", GetPrimaryMainFrame()); +#if BUILDFLAG(IS_MAC) + // The UI may be in an event-tracking loop, such as between the + // mouse-down and mouse-up in text selection or a button click. + // Defer the close until after tracking is complete, so that we + // don't free objects out from under the UI. + // TODO(shess): This could get more fine-grained. For instance, + // closing a tab in another window while selecting text in the + // current window's Omnibox should be just fine. + if (view_->CloseTabAfterEventTrackingIfNeeded()) { + return; + } +#endif + + if (delegate_) { + delegate_->CloseContents(this); + } +} + +void WebContentsImpl::SetWindowRect(const gfx::Rect& new_bounds) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetWindowRect"); + if (!delegate_) { + return; + } + + // Members of |new_bounds| may be 0 to indicate uninitialized values for newly + // opened windows, even if the |GetContainerBounds()| inner rect is correct. + // TODO(crbug.com/40092782): Plumb values as specified; fallback on outer + // rect. + auto bounds = new_bounds; + if (bounds.IsEmpty()) { + bounds.set_size(GetContainerBounds().size()); + } + + // Only requests from the main frame, not subframes, should reach this code. + int64_t display_id = AdjustWindowRect(&bounds, GetPrimaryMainFrame()); + + // Drop fullscreen when placing a WebContents to prohibit deceptive behavior. + // Only drop fullscreen on the specific destination display, which is known. + // This supports sites using cross-screen window management capabilities to + // retain fullscreen and place a window on another screen. + ForSecurityDropFullscreen(display_id).RunAndReset(); + + delegate_->SetContentsBounds(this, bounds); +} + +void WebContentsImpl::UpdateWindowPreferredSize(const gfx::Size& pref_size) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::UpdatePreferredSize"); + const gfx::Size old_size = GetPreferredSize(); + preferred_size_ = pref_size; + OnPreferredSizeChanged(old_size); +} + +std::vector +WebContentsImpl::GetActiveTopLevelDocumentsInGroup( + RenderFrameHostImpl* render_frame_host, + GroupType group_type) { + std::vector out; + for (WebContentsImpl* web_contents : GetAllWebContents()) { + RenderFrameHostImpl* other_render_frame_host = + web_contents->GetPrimaryMainFrame(); + + // Filters out inactive documents. + if (other_render_frame_host->lifecycle_state() != + RenderFrameHostImpl::LifecycleStateImpl::kActive) { + continue; + } + + // If we're looking for frames in the same browsing context group, filter + // frames in different browsing context groups. + if (group_type == GroupType::kBrowsingContextGroup && + !render_frame_host->GetSiteInstance()->IsRelatedSiteInstance( + other_render_frame_host->GetSiteInstance())) { + continue; + } + + // If we're looking for frames in the same CoopRelatedGroup, filter frames + // in different CoopRelatedGroups. + if (group_type == GroupType::kCoopRelatedGroup && + !render_frame_host->GetSiteInstance()->IsCoopRelatedSiteInstance( + other_render_frame_host->GetSiteInstance())) { + continue; + } + + out.push_back(other_render_frame_host); + } + return out; +} + +std::vector +WebContentsImpl::GetActiveTopLevelDocumentsInBrowsingContextGroup( + RenderFrameHostImpl* render_frame_host) { + return GetActiveTopLevelDocumentsInGroup(render_frame_host, + GroupType::kBrowsingContextGroup); +} + +std::vector +WebContentsImpl::GetActiveTopLevelDocumentsInCoopRelatedGroup( + RenderFrameHostImpl* render_frame_host) { + return GetActiveTopLevelDocumentsInGroup(render_frame_host, + GroupType::kCoopRelatedGroup); +} + +PrerenderHostRegistry* WebContentsImpl::GetPrerenderHostRegistry() { + DCHECK(prerender_host_registry_); + return prerender_host_registry_.get(); +} + +void WebContentsImpl::DidStartLoading(FrameTreeNode* frame_tree_node) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DidStartLoading", + "frame_tree_node", frame_tree_node); + + TRACE_EVENT_NESTABLE_ASYNC_BEGIN2( + "browser,navigation", "WebContentsImpl Loading", this, "URL", "NULL", + "Primary Main FrameTreeNode id", + GetPrimaryFrameTree().root()->frame_tree_node_id()); + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidStartLoading"); + observers_.NotifyObservers(&WebContentsObserver::DidStartLoading); + + // Reset the focus state from DidStartNavigation to false if a new load starts + // afterward, in case loading logic triggers a FocusLocationBarByDefault call. + should_focus_location_bar_by_default_ = false; + + // Notify accessibility that the user is navigating away from the + // current document. + // TODO(domfarolino, dmazzoni): Do this using WebContentsObserver. See + // https://crbug.com/981271. + BrowserAccessibilityManager* manager = + frame_tree_node->current_frame_host()->browser_accessibility_manager(); + if (manager) { + manager->UserIsNavigatingAway(); + } +} + +void WebContentsImpl::DidStopLoading() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DidStopLoading"); + if (IsBeingDestroyed()) { + return; + } + + // Use the last committed entry rather than the active one, in case a + // pending entry has been created. + // An entry may not exist for a stop when loading an initial blank page or + // if an iframe injected by script into a blank page finishes loading. + NavigationEntry* entry = GetController().GetLastCommittedEntry(); + std::string url = + (entry ? entry->GetVirtualURL().possibly_invalid_spec() : "NULL"); + + TRACE_EVENT_NESTABLE_ASYNC_END1("browser,navigation", + "WebContentsImpl Loading", this, "URL", url); + SCOPED_UMA_HISTOGRAM_TIMER("WebContentsObserver.DidStopLoading"); + observers_.NotifyObservers(&WebContentsObserver::DidStopLoading); + + GetPrimaryMainFrame()->ForEachRenderFrameHost( + [](RenderFrameHostImpl* render_frame_host) { + BrowserAccessibilityManager* manager = + render_frame_host->browser_accessibility_manager(); + if (manager) { + manager->DidStopLoading(); + } + }); +} + +void WebContentsImpl::DidChangeLoadProgressForPrimaryMainFrame() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DidChangeLoadProgress"); + if (IsBeingDestroyed()) { + return; + } + double load_progress = GetLoadProgress(); + + // The delegate is notified immediately for the first and last updates. Also, + // since the message loop may be pretty busy when a page is loaded, it might + // not execute a posted task in a timely manner so the progress report is sent + // immediately if enough time has passed. + base::TimeDelta min_delay = minimum_delay_between_loading_updates_ms_; + bool delay_elapsed = + loading_last_progress_update_.is_null() || + base::TimeTicks::Now() - loading_last_progress_update_ > min_delay; + + if (load_progress == 0.0 || load_progress == 1.0 || delay_elapsed) { + // If there is a pending task to send progress, it is now obsolete. + loading_weak_factory_.InvalidateWeakPtrs(); + + // Notify the load progress change. + SendChangeLoadProgress(); + + // Clean-up the states if needed. + if (load_progress == 1.0) { + ResetLoadProgressState(); + } + return; + } + + if (loading_weak_factory_.HasWeakPtrs()) { + return; + } + + if (min_delay == base::Milliseconds(0)) { + SendChangeLoadProgress(); + } else { + base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&WebContentsImpl::SendChangeLoadProgress, + loading_weak_factory_.GetWeakPtr()), + min_delay); + } +} + +bool WebContentsImpl::IsHidden() { + return GetPageVisibilityState() == PageVisibilityState::kHidden; +} + +std::vector> +WebContentsImpl::CreateThrottlesForNavigation( + NavigationHandle* navigation_handle) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::CreateThrottlesForNavigation", + "navigation", navigation_handle); + auto throttles = GetContentClient()->browser()->CreateThrottlesForNavigation( + navigation_handle); + + return throttles; +} + +std::vector> +WebContentsImpl::CreateDeferringConditionsForNavigationCommit( + NavigationHandle& navigation_handle, + CommitDeferringCondition::NavigationType type) { + OPTIONAL_TRACE_EVENT2( + "content", "WebContentsImpl::CreateDeferringConditionsForNavigation", + "navigation", navigation_handle, "NavigationType", type); + std::vector> conditions = + GetContentClient() + ->browser() + ->CreateCommitDeferringConditionsForNavigation(&navigation_handle, + type); + + if (auto condition = JavaScriptDialogCommitDeferringCondition::MaybeCreate( + static_cast(navigation_handle))) { + conditions.push_back(std::move(condition)); + } + return conditions; +} + +std::unique_ptr WebContentsImpl::GetNavigationUIData( + NavigationHandle* navigation_handle) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::GetNavigationUIData"); + return GetContentClient()->browser()->GetNavigationUIData(navigation_handle); +} + +void WebContentsImpl::RegisterExistingOriginAsHavingDefaultIsolation( + const url::Origin& origin, + NavigationRequest* navigation_request_to_exclude) { + OPTIONAL_TRACE_EVENT2( + "content", + "WebContentsImpl::RegisterExistingOriginAsHavingDefaultIsolation", + "origin", origin, "navigation_request_to_exclude", + navigation_request_to_exclude); + // Note: This function can be made static if we ever need call it without + // a WebContentsImpl instance, in which case we can use a wrapper to + // implement the override from NavigatorDelegate. + for (WebContentsImpl* web_contents : GetAllWebContents()) { + // We only need to search entries in the same BrowserContext as us. + if (web_contents->GetBrowserContext() != GetBrowserContext()) { + continue; + } + + // Walk the frame trees to notify each one's NavigationController about the + // opting-in or opting-out `origin`, and also pick up any frames without + // FrameNavigationEntries. + // * Some frames won't have FrameNavigationEntries (Issues 524208, 608402). + // * Some pending navigations won't have NavigationEntries. + web_contents->ForEachFrameTree(base::BindRepeating( + [](const url::Origin& origin, + NavigationRequest* navigation_request_to_exclude, + FrameTree& frame_tree) { + frame_tree.RegisterExistingOriginAsHavingDefaultIsolation( + origin, navigation_request_to_exclude); + }, + origin, navigation_request_to_exclude)); + } +} + +bool WebContentsImpl::MaybeCopyContentAreaAsBitmap( + base::OnceCallback callback) { + if (!GetDelegate()) { + return false; + } + return GetDelegate()->MaybeCopyContentAreaAsBitmap(std::move(callback)); +} + +void WebContentsImpl::DidChangeName(RenderFrameHostImpl* render_frame_host, + const std::string& name) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::DidChangeName", + "render_frame_host", render_frame_host, "name", name); + observers_.NotifyObservers(&WebContentsObserver::FrameNameChanged, + render_frame_host, name); +} + +void WebContentsImpl::DidReceiveUserActivation( + RenderFrameHostImpl* render_frame_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DidReceiveUserActivation", + "render_frame_host", render_frame_host); + observers_.NotifyObservers(&WebContentsObserver::FrameReceivedUserActivation, + render_frame_host); +} + +void WebContentsImpl::WebAuthnAssertionRequestSucceeded( + RenderFrameHostImpl* render_frame_host) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::WebAuthnAssertionRequestSucceeded", + "render_frame_host", render_frame_host); + observers_.NotifyObservers( + &WebContentsObserver::WebAuthnAssertionRequestSucceeded, + render_frame_host); +} + +void WebContentsImpl::BindDisplayCutoutHost( + RenderFrameHostImpl* render_frame_host, + mojo::PendingAssociatedReceiver receiver) { + if (safe_area_insets_host_) { + safe_area_insets_host_->BindReceiver(std::move(receiver), + render_frame_host); + } +} + +void WebContentsImpl::DidChangeDisplayState( + RenderFrameHostImpl* render_frame_host, + bool is_display_none) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::DidChangeDisplayState", + "render_frame_host", render_frame_host, + "is_display_none", is_display_none); + observers_.NotifyObservers(&WebContentsObserver::FrameDisplayStateChanged, + render_frame_host, is_display_none); +} + +void WebContentsImpl::FrameSizeChanged(RenderFrameHostImpl* render_frame_host, + const gfx::Size& frame_size) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::FrameSizeChanged", + "render_frame_host", render_frame_host); + observers_.NotifyObservers(&WebContentsObserver::FrameSizeChanged, + render_frame_host, frame_size); +} + +void WebContentsImpl::DocumentOnLoadCompleted( + RenderFrameHostImpl* render_frame_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DocumentOnLoadCompleted", + "render_frame_host", render_frame_host); + DCHECK(render_frame_host->IsInPrimaryMainFrame()); + ShowInsecureLocalhostWarningIfNeeded(render_frame_host->GetPage()); + + observers_.NotifyObservers( + &WebContentsObserver::DocumentOnLoadCompletedInPrimaryMainFrame); +} + +void WebContentsImpl::UpdateTitle(RenderFrameHostImpl* render_frame_host, + const std::u16string& title, + base::i18n::TextDirection title_direction) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::UpdateTitle", + "render_frame_host", render_frame_host, "title", title); + // Try to find the navigation entry, which might not be the current one. + // For example, it might be from a pending deletion RFH, or it might be from a + // non-primary frame tree. + NavigationEntryImpl* entry = + render_frame_host->frame_tree()->controller().GetEntryWithUniqueID( + render_frame_host->nav_entry_id()); + + if (!entry) { + // We can handle title updates with no matching NavigationEntry, but only if + // the update is for the initial NavigationEntry. In that case the initial + // empty document RFH wouldn't have a `nav_entry_id` set because it hasn't + // committed any navigation. Note that if the title update came from the + // initial empty document but the WebContents is doing a session restore, + // we will ignore the title update (because GetLastCommittedEntry() would + // return the non-initial restored entry), which avoids accidental + // overwriting of the restored entry's title. + if (render_frame_host->GetParent() || !render_frame_host->frame_tree() + ->controller() + .GetLastCommittedEntry() + ->IsInitialEntry()) { + return; + } + entry = + render_frame_host->frame_tree()->controller().GetLastCommittedEntry(); + } + + // TODO(evan): make use of title_direction. + // http://code.google.com/p/chromium/issues/detail?id=27094 + bool title_changed = UpdateTitleForEntryImpl(entry, title); + if (title_changed && render_frame_host == GetPrimaryMainFrame()) { + NotifyTitleUpdateForEntry(entry); + } +} + +void WebContentsImpl::UpdateAppTitle(RenderFrameHostImpl* render_frame_host, + const std::u16string& app_title) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::UpdateTitle", + "render_frame_host", render_frame_host, "app_title", + app_title); + // Same logic as UpdateTitle() above. + NavigationEntryImpl* entry = + render_frame_host->frame_tree()->controller().GetEntryWithUniqueID( + render_frame_host->nav_entry_id()); + if (!entry) { + if (render_frame_host->GetParent() || !render_frame_host->frame_tree() + ->controller() + .GetLastCommittedEntry() + ->IsInitialEntry()) { + return; + } + entry = + render_frame_host->frame_tree()->controller().GetLastCommittedEntry(); + } + std::u16string final_app_title; + base::TrimWhitespace(app_title, base::TRIM_ALL, &final_app_title); + + if (final_app_title == entry->GetAppTitle()) { + return; + } + + entry->SetAppTitle(final_app_title); + NotifyNavigationStateChanged(INVALIDATE_TYPE_TITLE); +} + +void WebContentsImpl::UpdateTargetURL(RenderFrameHostImpl* render_frame_host, + const GURL& url) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::UpdateTargetURL", + "render_frame_host", render_frame_host, "url", url); + // In case of racey updates from multiple RenderViewHosts, the last URL should + // be shown - see also some discussion in https://crbug.com/807776. + if (!url.is_valid() && render_frame_host != frame_that_set_last_target_url_) { + return; + } + frame_that_set_last_target_url_ = + url.is_valid() ? render_frame_host : nullptr; + + if (delegate_) { + delegate_->UpdateTargetURL(this, url); + } +} + +bool WebContentsImpl::ShouldRouteMessageEvent( + RenderFrameHostImpl* target_rfh) const { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ShouldRouteMessageEvent", + "render_frame_host", target_rfh); + // Allow the message if this WebContents is dedicated to a browser plugin + // guest. + // Note: This check means that an embedder could theoretically receive a + // postMessage from anyone (not just its own guests). However, this is + // probably not a risk for apps since other pages won't have references + // to App windows. + return GetBrowserPluginGuest() || GetBrowserPluginEmbedder(); +} + +void WebContentsImpl::EnsureOpenerProxiesExist( + RenderFrameHostImpl* source_rfh) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::EnsureOpenerProxiesExist", + "render_frame_host", source_rfh); + WebContentsImpl* source_web_contents = static_cast( + WebContents::FromRenderFrameHost(source_rfh)); + + if (source_web_contents) { + // If this message is going to outer WebContents from inner WebContents, + // then we should not create a RenderView. AttachToOuterWebContentsFrame() + // already created a RenderFrameProxyHost for that purpose. + if (GetBrowserPluginEmbedder() && + source_web_contents->browser_plugin_guest_) { + return; + } + + if (this != source_web_contents && GetBrowserPluginGuest()) { + // We create a RenderFrameProxyHost for the embedder in the guest's render + // process but we intentionally do not expose the embedder's opener chain + // to it. + source_web_contents->GetRenderManager()->CreateRenderFrameProxy( + GetSiteInstance()->group(), + source_web_contents->GetPrimaryMainFrame()->browsing_context_state()); + } else { + source_rfh->frame_tree_node()->render_manager()->CreateOpenerProxies( + GetSiteInstance()->group(), nullptr, + source_rfh->browsing_context_state()); + } + } +} + +void WebContentsImpl::SetAsFocusedWebContentsIfNecessary() { + SetFocusedFrameTree(&GetPrimaryFrameTree()); +} + +void WebContentsImpl::SetFocusedFrameTree(FrameTree* frame_tree_to_focus) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetFocusedFrameTree"); + DCHECK(frame_tree_to_focus); + + // Only change focus if we are not currently focused. + FrameTree* old_focused_frame_tree = GetFocusedFrameTree(); + if (old_focused_frame_tree == frame_tree_to_focus) { + return; + } + + GetOutermostWebContents()->node_.SetFocusedFrameTree(frame_tree_to_focus); + + // Send a page level blur to the `old_focused_frame_tree` so that it displays + // inactive UI and focus `frame_tree_to_focus` to activate it. + if (old_focused_frame_tree) { + old_focused_frame_tree->root() + ->current_frame_host() + ->GetRenderWidgetHost() + ->SetPageFocus(false); + } + + // Make sure the outer frame trees knows our frame is focused. Otherwise, the + // outer renderer could have the element before or after the frame element + // focused which would return early without actually advancing focus. + RenderFrameHostImpl::UpdateAXFocusDeferScope focus_defer_scope( + *frame_tree_to_focus->root() + ->current_frame_host() + ->GetOutermostMainFrameOrEmbedder()); + if (frame_tree_to_focus->GetFocusedFrame() && + frame_tree_to_focus->GetFocusedFrame() + ->current_frame_host() + ->inner_tree_main_frame_tree_node_id() != + FrameTreeNode::kFrameTreeNodeInvalidId) { + // If an inner frame tree, in `frame_tree_to_focus`, had focus, the + // placeholder RenderFrameHost needs to be unset as the focused frame in + // `frame_tree_to_focus`. + frame_tree_to_focus->SetFocusedFrame(frame_tree_to_focus->root(), nullptr); + } + frame_tree_to_focus->FocusOuterFrameTrees(); + + frame_tree_to_focus->root() + ->current_frame_host() + ->GetRenderWidgetHost() + ->SetPageFocus(true); +} + +void WebContentsImpl::SetFocusedFrame(FrameTreeNode* node, + SiteInstanceGroup* source) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetFocusedFrame", + "frame_tree_node", node, "source_site_instance_group", + source); + + if (GetFocusedFrameTree()->GetFocusedFrame()) { + RenderFrameHostImpl* focused_rfh = + GetFocusedFrameTree()->GetFocusedFrame()->current_frame_host(); + // This is only enforced for focus changes that cross a fenced frame + // boundary. + if (!node->current_frame_host()->VerifyFencedFrameFocusChange( + focused_rfh)) { + return; + } + } + + // Focus will not be in a consistent state until the focused frame tree is + // also updated (if necessary). + RenderFrameHostImpl::UpdateAXFocusDeferScope focus_defer_scope( + *node->current_frame_host()->GetOutermostMainFrameOrEmbedder()); + + node->frame_tree().SetFocusedFrame(node, source); + + auto* inner_contents = node_.GetInnerWebContentsInFrame(node); + + // We currently do not need to descend into inner frame trees that + // are not an inner WebContents for focus. If `inner_contents` is null, + // then the only supported inner frame tree type would be fenced frames. + // An embedding frame focusing a fenced frame is not allowed since that would + // be an information leak. If a renderer attempts to do that, that should be + // blocked by `RenderFrameProxyHost::DidFocusFrame()`. + DCHECK(inner_contents || + node->current_frame_host()->inner_tree_main_frame_tree_node_id() == + FrameTreeNode::kFrameTreeNodeInvalidId); + + if (inner_contents) { + // An inner WebContents is not created from Fenced Frames so we + // shouldn't end up in this branch. + DCHECK(!node->IsInFencedFrameTree()); + + // |this| is an outer WebContents and |node| represents an inner + // WebContents. Transfer the focus to the inner contents if |this| is + // focused. + if (GetFocusedWebContents() == this) { + inner_contents->SetAsFocusedWebContentsIfNecessary(); + } + } else if (node_.OuterContentsFrameTreeNode() && + node_.OuterContentsFrameTreeNode() + ->current_frame_host() + ->GetSiteInstance() + ->group() == source) { + // A GuestView embedding a fenced frame will have an + // OuterContentsFrameTreeNode. However, it will not have the same site + // instance because a FencedFrame creates a new BrowsingInstance. + DCHECK(!node->IsInFencedFrameTree()); + + // |this| is an inner WebContents, |node| is its main FrameTreeNode and + // the outer WebContents FrameTreeNode is at |source|'s SiteInstance. + // Transfer the focus to the inner WebContents if the outer WebContents is + // focused. This branch is used when an inner WebContents is focused through + // its RenderFrameProxyHost (via FrameFocused mojo call, used to + // implement the window.focus() API). + if (GetFocusedWebContents() == GetOuterWebContents()) { + SetFocusedFrameTree(&node->frame_tree()); + } + } else if (!GetOuterWebContents() || GetFocusedWebContents() == this) { + // This is an outermost WebContents or we are currently focused so allow + // the requested node's frame tree to be focused. The + // (GetFocusedWebContents() == this) is needed when there are multiple + // frame trees within an inner WebContents (ie. a GuestView with fenced + // frames). + SetFocusedFrameTree(&node->frame_tree()); + } + + CloseListenerManager::DidChangeFocusedFrame(this); +} + +FrameTree* WebContentsImpl::GetOwnedPictureInPictureFrameTree() { +#if !BUILDFLAG(IS_ANDROID) + if (has_picture_in_picture_document_) { + WebContents* picture_in_picture_web_contents = + PictureInPictureWindowController:: + GetOrCreateDocumentPictureInPictureController(this) + ->GetChildWebContents(); + if (picture_in_picture_web_contents) { + return &(static_cast(picture_in_picture_web_contents) + ->GetPrimaryFrameTree()); + } + } +#endif // !BUILDFLAG(IS_ANDROID) + + return nullptr; +} + +FrameTree* WebContentsImpl::GetPictureInPictureOpenerFrameTree() { +#if !BUILDFLAG(IS_ANDROID) + if (picture_in_picture_opener_) { + return &(static_cast(picture_in_picture_opener_.get()) + ->GetPrimaryFrameTree()); + } +#endif // !BUILDFLAG(IS_ANDROID) + + return nullptr; +} + +void WebContentsImpl::DidCallFocus() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DidCallFocus"); + // Any explicit focusing of another window while this WebContents is in + // fullscreen can be used to confuse the user, so drop fullscreen. + base::ScopedClosureRunner fullscreen_block = + ForSecurityDropFullscreen(/*display_id=*/display::kInvalidDisplayId); + // The other contents is independent of this contents, so release the + // fullscreen block. + fullscreen_block.RunAndReset(); +} + +void WebContentsImpl::OnAdvanceFocus(RenderFrameHostImpl* source_rfh) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnAdvanceFocus", + "render_frame_host", source_rfh); + // When a RenderFrame needs to advance focus to a `blink::RemoteFrame` (by + // hitting TAB), the `blink::RemoteFrame` sends an IPC to + // RenderFrameProxyHost. When this RenderFrameProxyHost represents an inner + // WebContents, the outer WebContents needs to focus the inner WebContents. + if (GetOuterWebContents() && + GetOuterWebContents() == WebContents::FromRenderFrameHost(source_rfh) && + GetFocusedWebContents() == GetOuterWebContents()) { + SetAsFocusedWebContentsIfNecessary(); + } +} + +void WebContentsImpl::OnFocusedElementChangedInFrame( + RenderFrameHostImpl* frame, + const gfx::Rect& bounds_in_root_view, + blink::mojom::FocusType focus_type) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::OnFocusedElementChangedInFrame", + "render_frame_host", frame); + RenderWidgetHostViewBase* root_view = + static_cast(GetRenderWidgetHostView()); + if (!root_view || !frame->GetView()) { + return; + } + // Convert to screen coordinates from window coordinates by adding the + // window's origin. + gfx::Point origin = bounds_in_root_view.origin(); + origin += root_view->GetViewBounds().OffsetFromOrigin(); + gfx::Rect bounds_in_screen(origin, bounds_in_root_view.size()); + + root_view->FocusedNodeChanged(frame->has_focused_editable_element(), + bounds_in_screen); + + FocusedNodeDetails details = {frame->has_focused_editable_element(), + bounds_in_screen, focus_type}; + BrowserAccessibilityStateImpl::GetInstance()->OnFocusChangedInPage(details); + observers_.NotifyObservers(&WebContentsObserver::OnFocusChangedInPage, + &details); +} + +bool WebContentsImpl::DidAddMessageToConsole( + RenderFrameHostImpl* source_frame, + blink::mojom::ConsoleMessageLevel log_level, + const std::u16string& message, + int32_t line_no, + const std::u16string& source_id, + const std::optional& untrusted_stack_trace) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DidAddMessageToConsole", + "message", message); + + observers_.NotifyObservers(&WebContentsObserver::OnDidAddMessageToConsole, + source_frame, log_level, message, line_no, + source_id, untrusted_stack_trace); + + if (!delegate_) { + return false; + } + return delegate_->DidAddMessageToConsole(this, log_level, message, line_no, + source_id); +} + +void WebContentsImpl::DidReceiveInputEvent( + RenderWidgetHostImpl* render_widget_host, + const blink::WebInputEvent& event) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::DidReceiveInputEvent", + "render_widget_host", render_widget_host); + + if (event.GetType() == blink::WebInputEvent::Type::kMouseDown && + static_cast(event).button == + blink::WebPointerProperties::Button::kBack) { + BackNavigationLikely(content_preloading_predictor::kMouseBackButton, + WindowOpenDisposition::CURRENT_TAB); + } + + if (!IsUserInteractionInputType(event.GetType())) { + return; + } + + // Ignore unless the widget is currently in the frame tree. + if (!HasMatchingWidgetHost(&primary_frame_tree_, render_widget_host)) { + return; + } + + if (event.GetType() != blink::WebInputEvent::Type::kGestureScrollBegin) { + last_interaction_time_ = ui::EventTimeForNow(); + } + + observers_.NotifyObservers(&WebContentsObserver::DidGetUserInteraction, + event); +} + +bool WebContentsImpl::ShouldIgnoreWebInputEvents( + const blink::WebInputEvent& event) { + if (ignore_input_events_count_ > 0) { + return true; + } + for (const auto& callback : web_input_event_audit_callbacks_) { + if (!callback.second.Run(event)) { + return true; + } + } + WebContentsImpl* web_contents = GetOuterWebContents(); + if (!web_contents) { + return false; + } + return web_contents->ShouldIgnoreWebInputEvents(event); +} + +bool WebContentsImpl::ShouldIgnoreInputEvents() { + if (ignore_input_events_count_ > 0 || + !web_input_event_audit_callbacks_.empty()) { + return true; + } + WebContentsImpl* web_contents = GetOuterWebContents(); + if (!web_contents) { + return false; + } + return web_contents->ShouldIgnoreInputEvents(); +} + +void WebContentsImpl::FocusOwningWebContents( + RenderWidgetHostImpl* render_widget_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::FocusOwningWebContents", + "render_widget_host", render_widget_host); + RenderWidgetHostImpl* main_frame_widget_host = + GetPrimaryMainFrame()->GetRenderWidgetHost(); + RenderWidgetHostImpl* focused_widget = + GetFocusedRenderWidgetHost(main_frame_widget_host); + + if (focused_widget != render_widget_host && + (!focused_widget || + focused_widget->delegate() != render_widget_host->delegate())) { +#if BUILDFLAG(IS_ANDROID) + if (&GetPrimaryFrameTree() != GetFocusedFrameTree()) { + UMA_HISTOGRAM_BOOLEAN("Android.FocusChanged.FocusOwningWebContents", + true); + } +#endif + SetAsFocusedWebContentsIfNecessary(); + } else { +#if BUILDFLAG(IS_ANDROID) + UMA_HISTOGRAM_BOOLEAN("Android.FocusChanged.FocusOwningWebContents", false); +#endif + } +} + +void WebContentsImpl::OnIgnoredUIEvent() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnIgnoredUIEvent"); + // Notify observers. + observers_.NotifyObservers(&WebContentsObserver::DidGetIgnoredUIEvent); +} + +void WebContentsImpl::RendererUnresponsive( + RenderWidgetHostImpl* render_widget_host, + base::RepeatingClosure hang_monitor_restarter) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RendererUnresponsive", + "render_widget_host", render_widget_host); + if (ShouldIgnoreUnresponsiveRenderer()) { + return; + } + + // Do not report hangs (to task manager, to hang renderer dialog, etc.) for + // invisible tabs (like extension background page, background tabs). See + // https://crbug.com/881812 for rationale and for choosing the visibility + // (rather than process priority) as the signal here. + if (GetVisibility() != Visibility::VISIBLE) { + return; + } + + if (!render_widget_host->renderer_initialized()) { + return; + } + + if (base::FeatureList::IsEnabled(features::kCrashReporting) && + base::FeatureList::IsEnabled( + blink::features::kDocumentPolicyIncludeJSCallStacksInCrashReports) && + this->GetLastCommittedURL().SchemeIsHTTPOrHTTPS()) { + RenderProcessHost* rph = render_widget_host->GetProcess(); + if (rph) { + RenderProcessHostImpl* process_host = + static_cast(rph); + process_host->InterruptJavaScriptIsolateAndCollectCallStack(); + } + } + + observers_.NotifyObservers(&WebContentsObserver::OnRendererUnresponsive, + render_widget_host->GetProcess()); + if (delegate_) { + delegate_->RendererUnresponsive(this, render_widget_host, + std::move(hang_monitor_restarter)); + } +} + +void WebContentsImpl::RendererResponsive( + RenderWidgetHostImpl* render_widget_host) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::RenderResponsive", + "render_widget_host", render_widget_host); + observers_.NotifyObservers(&WebContentsObserver::OnRendererResponsive, + render_widget_host->GetProcess()); + + if (delegate_) { + delegate_->RendererResponsive(this, render_widget_host); + } +} + +void WebContentsImpl::BeforeUnloadFiredFromRenderManager( + bool proceed, + bool* proceed_to_fire_unload) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::BeforeUnloadFiredFromRenderManager"); + observers_.NotifyObservers(&WebContentsObserver::BeforeUnloadFired, proceed); + if (delegate_) { + delegate_->BeforeUnloadFired(this, proceed, proceed_to_fire_unload); + } + // Note: |this| might be deleted at this point. +} + +void WebContentsImpl::CancelModalDialogsForRenderManager() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::CancelModalDialogsForRenderManager"); + // We need to cancel modal dialogs when doing a process swap, since the load + // deferrer would prevent us from swapping out. We also clear the state + // because this is a cross-process navigation, which means that it's a new + // site that should not have to pay for the sins of its predecessor. + // + // Note that we don't bother telling |browser_plugin_embedder_| because the + // cross-process navigation will either destroy the browser plugins or not + // require their dialogs to close. + if (dialog_manager_) { + dialog_manager_->CancelDialogs(this, /*reset_state=*/true); + } +} + +void WebContentsImpl::NotifySwappedFromRenderManager( + RenderFrameHostImpl* old_frame, + RenderFrameHostImpl* new_frame) { + TRACE_EVENT2("content", "WebContentsImpl::NotifySwappedFromRenderManager", + "old_render_frame_host", old_frame, "new_render_frame_host", + new_frame); + DCHECK_NE(new_frame->lifecycle_state(), + RenderFrameHostImpl::LifecycleStateImpl::kSpeculative); + + // Only fire RenderViewHostChanged if it is related to our FrameTree, as + // observers can not deal with events coming from non-primary FrameTree. + // TODO(crbug.com/40165060): Update observers to deal with the events, + // and fire events for all frame trees. + if (new_frame->IsInPrimaryMainFrame()) { + // The |new_frame| and its various compadres are already swapped into place + // for the WebContentsImpl when this method is called. + DCHECK_EQ( + primary_frame_tree_.root()->render_manager()->GetRenderWidgetHostView(), + new_frame->GetView()); + + RenderViewHost* old_rvh = + old_frame ? old_frame->GetRenderViewHost() : nullptr; + RenderViewHost* new_rvh = new_frame->GetRenderViewHost(); + // |old_rvh| and |new_rvh| might be equal when navigating from a crashed + // RenderFrameHost to a new same-site one. With RenderDocument, this will + // happen for every same-site navigation. + if (old_rvh != new_rvh) { + NotifyViewSwapped(old_rvh, new_rvh); + } + + auto* rwhv = static_cast(new_frame->GetView()); + if (rwhv) { + rwhv->SetMainFrameAXTreeID(new_frame->GetAXTreeID()); + + // The RenderWidgetHostView for the speculative RenderFrameHost is not + // resized with the current RenderFrameHost while a navigation is + // pending. So when we swap in the main frame, we need to update the + // RenderWidgetHostView's size. + // + // Historically, this was done to fix b/1079768 for interstitials. + rwhv->SetSize(GetSizeForMainFrame()); + } + + NotifyPrimaryMainFrameProcessIsAlive(); + } + + NotifyFrameSwapped(old_frame, new_frame); +} + +void WebContentsImpl::NotifySwappedFromRenderManagerWithoutFallbackContent( + RenderFrameHostImpl* new_frame) { + auto* rwhv = static_cast(new_frame->GetView()); + if (rwhv) { + rwhv->ClearFallbackSurfaceForCommitPending(); + } +} + +void WebContentsImpl::NotifyMainFrameSwappedFromRenderManager( + RenderFrameHostImpl* old_frame, + RenderFrameHostImpl* new_frame) { + // Only fire RenderViewHostChanged if it is + // related to our FrameTree, as observers cannot deal with events coming + // from non-primary FrameTree. + // TODO(crbug.com/40165060): Update observers to deal with the events, + // and fire events for all frame trees. + if (!new_frame->IsInPrimaryMainFrame()) { + return; + } + NotifyViewSwapped(old_frame ? old_frame->GetRenderViewHost() : nullptr, + new_frame->GetRenderViewHost()); +} + +void WebContentsImpl::CreateRenderWidgetHostViewForRenderManager( + RenderViewHost* render_view_host) { + OPTIONAL_TRACE_EVENT1( + "content", "WebContentsImpl::CreateRenderWidgetHostViewForRenderManager", + "render_view_host", render_view_host); + bool is_inner_frame_tree = static_cast(render_view_host) + ->frame_tree() + ->is_fenced_frame(); + if (is_inner_frame_tree) { + WebContentsViewChildFrame::CreateRenderWidgetHostViewForInnerFrameTree( + this, render_view_host->GetWidget()); + } else { + RenderWidgetHostViewBase* rwh_view = + view_->CreateViewForWidget(render_view_host->GetWidget()); + view_->SetOverscrollControllerEnabled(CanOverscrollContent()); + rwh_view->SetSize(GetSizeForMainFrame()); + } +} + +void WebContentsImpl::ReattachOuterDelegateIfNeeded() { + if (node_.outer_web_contents()) { + ReattachToOuterWebContentsFrame(); + } +} + +bool WebContentsImpl::CreateRenderViewForRenderManager( + RenderViewHost* render_view_host, + const std::optional& opener_frame_token, + RenderFrameProxyHost* proxy_host) { + TRACE_EVENT1("browser,navigation", + "WebContentsImpl::CreateRenderViewForRenderManager", + "render_view_host", render_view_host); + auto* rvh_impl = static_cast(render_view_host); + // Observers should not destroy the WebContents here or we will crash as the + // stack unwinds. See crbug.com/1181043. + base::AutoReset scope(&prevent_destruction_, true); + + if (!proxy_host) { + CreateRenderWidgetHostViewForRenderManager(render_view_host); + } + + const auto proxy_routing_id = + proxy_host ? proxy_host->GetRoutingID() : MSG_ROUTING_NONE; + // TODO(crbug.com/40166243): Given MPArch, should we pass + // opened_by_another_window_ for non primary FrameTrees? + if (!rvh_impl->CreateRenderView(opener_frame_token, proxy_routing_id, + opened_by_another_window_)) { + return false; + } + + // Set the TextAutosizer state from the main frame's renderer on the new view, + // but only if it's not for the main frame. Main frame renderers should create + // this state themselves from up-to-date values, so we shouldn't override it + // with the cached values. + if (!rvh_impl->GetMainRenderFrameHost() && proxy_host) { + proxy_host->GetAssociatedRemoteMainFrame()->UpdateTextAutosizerPageInfo( + proxy_host->frame_tree_node() + ->current_frame_host() + ->GetPage() + .text_autosizer_page_info() + .Clone()); + } + + // If `render_view_host` is for an inner WebContents, ensure that its + // RenderWidgetHostView is properly reattached to the outer WebContents. Note + // that this should only be done when `render_view_host` is already the + // current RenderViewHost in this WebContents. If it isn't, the reattachment + // will happen later when `render_view_host` becomes current as part of + // committing the speculative RenderFrameHost it's associated with. + if (!proxy_host && render_view_host == GetRenderViewHost()) { + ReattachOuterDelegateIfNeeded(); + } + + SetHistoryOffsetAndLengthForView( + render_view_host, + rvh_impl->frame_tree()->controller().GetLastCommittedEntryIndex(), + rvh_impl->frame_tree()->controller().GetEntryCount()); + +#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_ANDROID) + // Force a ViewMsg_Resize to be sent, needed to make plugins show up on + // linux. See crbug.com/83941. + RenderWidgetHostView* rwh_view = render_view_host->GetWidget()->GetView(); + if (rwh_view) { + if (RenderWidgetHost* render_widget_host = + rwh_view->GetRenderWidgetHost()) { + render_widget_host->SynchronizeVisualProperties(); + } + } +#endif + + return true; +} + +#if BUILDFLAG(IS_ANDROID) + +base::android::ScopedJavaLocalRef +WebContentsImpl::GetJavaWebContents() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + return GetWebContentsAndroid()->GetJavaObject(); +} + +base::android::ScopedJavaLocalRef +WebContentsImpl::GetJavaCreatorLocation() { + return base::android::ScopedJavaLocalRef(java_creator_location_); +} + +WebContentsAndroid* WebContentsImpl::GetWebContentsAndroid() { + if (!web_contents_android_) { + web_contents_android_ = std::make_unique(this); + } + return web_contents_android_.get(); +} + +void WebContentsImpl::ClearWebContentsAndroid() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + web_contents_android_.reset(); +} + +void WebContentsImpl::ActivateNearestFindResult(float x, float y) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::ActivateNearestFindResult"); + GetOrCreateFindRequestManager()->ActivateNearestFindResult(x, y); +} + +void WebContentsImpl::RequestFindMatchRects(int current_version) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::RequestFindMatchRects"); + GetOrCreateFindRequestManager()->RequestFindMatchRects(current_version); +} + +service_manager::InterfaceProvider* WebContentsImpl::GetJavaInterfaces() { + if (!java_interfaces_) { + mojo::PendingRemote provider; + BindInterfaceRegistryForWebContents( + provider.InitWithNewPipeAndPassReceiver(), this); + java_interfaces_ = std::make_unique( + base::SingleThreadTaskRunner::GetCurrentDefault()); + java_interfaces_->Bind(std::move(provider)); + } + return java_interfaces_.get(); +} + +#endif + +bool WebContentsImpl::CompletedFirstVisuallyNonEmptyPaint() { + return GetPrimaryPage().did_first_visually_non_empty_paint(); +} + +void WebContentsImpl::OnDidDownloadImage( + base::WeakPtr rfh, + ImageDownloadCallback callback, + int id, + const GURL& image_url, + int32_t http_status_code, + const std::vector& images, + const std::vector& original_image_sizes) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnDidDownloadImage", + "image_url", image_url); + + // Guard against buggy or compromised renderers that could violate the API + // contract that |images| and |original_image_sizes| must have the same + // length. + if (images.size() != original_image_sizes.size()) { + if (rfh) { + ReceivedBadMessage(rfh->GetProcess(), + bad_message::WCI_INVALID_DOWNLOAD_IMAGE_RESULT); + } + // Respond with a 400 to indicate that something went wrong. + std::move(callback).Run(id, 400, image_url, std::vector(), + std::vector()); + return; + } + + std::move(callback).Run(id, http_status_code, image_url, images, + original_image_sizes); +} + +void WebContentsImpl::OnDialogClosed(int render_process_id, + int render_frame_id, + JavaScriptDialogCallback response_callback, + base::ScopedClosureRunner fullscreen_block, + bool dialog_was_suppressed, + bool success, + const std::u16string& user_input) { + RenderFrameHostImpl* rfh = + RenderFrameHostImpl::FromID(render_process_id, render_frame_id); + // The user confirms and closes a dialog even after the page has navigated + // away and got into BackForwardCache. + DCHECK(!rfh || rfh->GetPage().IsPrimary() || rfh->IsInBackForwardCache()); + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnDialogClosed", + "render_frame_host", rfh); + last_dialog_suppressed_ = dialog_was_suppressed; + fullscreen_block.RunAndReset(); + + javascript_dialog_dismiss_notifier_.reset(); + + if (is_showing_before_unload_dialog_ && !success) { + // It is possible for the current RenderFrameHost to have changed in the + // meantime. Do not reset the navigation state in that case. + if (rfh && rfh == rfh->frame_tree_node()->current_frame_host()) { + rfh->frame_tree_node()->BeforeUnloadCanceled(); + rfh->frame_tree()->controller().DiscardNonCommittedEntries(); + } + + // Update the URL display either way, to avoid showing a stale URL. + NotifyNavigationStateChanged(INVALIDATE_TYPE_URL); + + observers_.NotifyObservers( + &WebContentsObserver::BeforeUnloadDialogCancelled); + } + + std::move(response_callback).Run(success, user_input); + + std::vector page_handlers = + protocol::PageHandler::EnabledForWebContents(this); + for (auto* handler : page_handlers) { + handler->DidCloseJavaScriptDialog(success, user_input); + } + + is_showing_javascript_dialog_ = false; + is_showing_before_unload_dialog_ = false; +} + +RenderFrameHostManager* WebContentsImpl::GetRenderManager() { + return primary_frame_tree_.root()->render_manager(); +} + +BrowserPluginGuest* WebContentsImpl::GetBrowserPluginGuest() const { + return browser_plugin_guest_.get(); +} + +void WebContentsImpl::SetBrowserPluginGuest( + std::unique_ptr guest) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetBrowserPluginGuest"); + DCHECK(!browser_plugin_guest_); + DCHECK(guest); + browser_plugin_guest_ = std::move(guest); +} + +base::UnguessableToken WebContentsImpl::GetAudioGroupId() { + return GetAudioStreamFactory()->group_id(); +} + +const std::vector& +WebContentsImpl::GetFaviconURLs() { + return GetPrimaryMainFrame()->FaviconURLs(); +} + +// The Mac implementation of the next two methods is in +// web_contents_impl_mac.mm +#if !BUILDFLAG(IS_MAC) + +void WebContentsImpl::Resize(const gfx::Rect& new_bounds) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::Resize"); +#if defined(USE_AURA) + aura::Window* window = GetNativeView(); + window->SetBounds(gfx::Rect(window->bounds().origin(), new_bounds.size())); +#elif BUILDFLAG(IS_ANDROID) + content::RenderWidgetHostView* view = GetRenderWidgetHostView(); + if (view) { + view->SetBounds(new_bounds); + } +#endif +} + +gfx::Size WebContentsImpl::GetSize() { +#if defined(USE_AURA) + aura::Window* window = GetNativeView(); + return window->bounds().size(); +#elif BUILDFLAG(IS_ANDROID) + ui::ViewAndroid* view_android = GetNativeView(); + return view_android->bounds().size(); +#elif BUILDFLAG(IS_IOS) + // TODO(crbug.com/40254930): Implement me. + NOTREACHED_IN_MIGRATION(); + return gfx::Size(); +#endif +} + +#endif // !BUILDFLAG(IS_MAC) + +gfx::Rect WebContentsImpl::GetWindowsControlsOverlayRect() const { + return window_controls_overlay_rect_; +} + +void WebContentsImpl::UpdateWindowControlsOverlay( + const gfx::Rect& bounding_rect) { + if (window_controls_overlay_rect_ == bounding_rect) { + return; + } + + window_controls_overlay_rect_ = bounding_rect; + + // Updates to the |window_controls_overlay_rect_| are sent via + // the VisualProperties message. + if (RenderWidgetHost* render_widget_host = + GetPrimaryMainFrame()->GetRenderWidgetHost()) { + render_widget_host->SynchronizeVisualProperties(); + } + + view_->UpdateWindowControlsOverlay(bounding_rect); +} + +BrowserPluginEmbedder* WebContentsImpl::GetBrowserPluginEmbedder() const { + return browser_plugin_embedder_.get(); +} + +void WebContentsImpl::CreateBrowserPluginEmbedderIfNecessary() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::CreateBrowserPluginEmbedderIfNecessary"); + if (browser_plugin_embedder_) { + return; + } + browser_plugin_embedder_.reset(BrowserPluginEmbedder::Create(this)); +} + +gfx::Size WebContentsImpl::GetSizeForMainFrame() { + if (delegate_) { + // The delegate has a chance to specify a size independent of the UI. + gfx::Size delegate_size = delegate_->GetSizeForNewRenderView(this); + if (!delegate_size.IsEmpty()) { + return delegate_size; + } + } + + // Device emulation, when enabled, can specify a size independent of the UI. + if (!device_emulation_size_.IsEmpty()) { + return device_emulation_size_; + } + + return GetContainerBounds().size(); +} + +void WebContentsImpl::OnFrameTreeNodeDestroyed(FrameTreeNode* node) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnFrameTreeNodeDestroyed", + "node", node); + // If we are the focused frame tree and are destroying the root node + // reassign the focused frame tree node. + if (!node->parent() && GetFocusedFrameTree() == &node->frame_tree() && + &node->frame_tree() != &primary_frame_tree_) { + FrameTreeNode* frame_in_embedder = + node->render_manager()->GetOuterDelegateNode(); + SetFocusedFrameTree(frame_in_embedder ? &frame_in_embedder->frame_tree() + : &primary_frame_tree_); + } + + observers_.NotifyObservers(&WebContentsObserver::FrameDeleted, + node->frame_tree_node_id()); +} + +void WebContentsImpl::OnPreferredSizeChanged(const gfx::Size& old_size) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnPreferredSizeChanged"); + if (!delegate_) { + return; + } + const gfx::Size new_size = GetPreferredSize(); + if (new_size != old_size) { + delegate_->UpdatePreferredSize(this, new_size); + } +} + +FindRequestManager* WebContentsImpl::GetFindRequestManager() { + for (auto* contents = this; contents; + contents = contents->GetOuterWebContents()) { + if (contents->find_request_manager_) { + return contents->find_request_manager_.get(); + } + } + + return nullptr; +} + +FindRequestManager* WebContentsImpl::GetOrCreateFindRequestManager() { + if (FindRequestManager* manager = GetFindRequestManager()) { + return manager; + } + + DCHECK(!browser_plugin_guest_ || GetOuterWebContents()); + + // No existing FindRequestManager found, so one must be created. + find_request_manager_ = std::make_unique(this); + + // Concurrent find sessions must not overlap, so destroy any existing + // FindRequestManagers in any inner WebContentses. + for (WebContents* contents : GetWebContentsAndAllInner()) { + auto* web_contents_impl = static_cast(contents); + if (web_contents_impl == this) { + continue; + } + if (web_contents_impl->find_request_manager_) { + web_contents_impl->find_request_manager_->StopFinding( + STOP_FIND_ACTION_CLEAR_SELECTION); + web_contents_impl->find_request_manager_.release(); + } + } + + return find_request_manager_.get(); +} + +void WebContentsImpl::NotifyFindReply(int request_id, + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::NotifyFindReply"); + if (delegate_ && !IsBeingDestroyed() && + !GetPrimaryMainFrame()->GetProcess()->FastShutdownStarted()) { + delegate_->FindReply(this, request_id, number_of_matches, selection_rect, + active_match_ordinal, final_update); + } +} + +void WebContentsImpl::IncrementBluetoothConnectedDeviceCount() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::IncrementBluetoothConnectedDeviceCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + // Notify for UI updates if the state changes. + bluetooth_connected_device_count_++; + if (bluetooth_connected_device_count_ == 1) { + OnIsConnectedToBluetoothDeviceChanged(true); + } +} + +void WebContentsImpl::DecrementBluetoothConnectedDeviceCount() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::DecrementBluetoothConnectedDeviceCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + // Notify for UI updates if the state changes. + DCHECK_NE(bluetooth_connected_device_count_, 0u); + bluetooth_connected_device_count_--; + if (bluetooth_connected_device_count_ == 0) { + OnIsConnectedToBluetoothDeviceChanged(false); + } +} + +void WebContentsImpl::OnIsConnectedToBluetoothDeviceChanged( + bool is_connected_to_bluetooth_device) { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::OnIsConnectedToBluetoothDeviceChanged"); + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + observers_.NotifyObservers( + &WebContentsObserver::OnIsConnectedToBluetoothDeviceChanged, + is_connected_to_bluetooth_device); +} + +void WebContentsImpl::IncrementBluetoothScanningSessionsCount() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::IncrementBluetoothScanningSessionsCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + // Notify for UI updates if the state changes. + bluetooth_scanning_sessions_count_++; + if (bluetooth_scanning_sessions_count_ == 1) { + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + } +} + +void WebContentsImpl::DecrementBluetoothScanningSessionsCount() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::DecrementBluetoothScanningSessionsCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + DCHECK_NE(0u, bluetooth_scanning_sessions_count_); + bluetooth_scanning_sessions_count_--; + if (bluetooth_scanning_sessions_count_ == 0) { + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + } +} + +void WebContentsImpl::IncrementSerialActiveFrameCount() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::IncrementSerialActiveFrameCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + // Notify for UI updates if the state changes. + serial_active_frame_count_++; + if (serial_active_frame_count_ == 1) { + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + } +} + +void WebContentsImpl::DecrementSerialActiveFrameCount() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::DecrementSerialActiveFrameCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + // Notify for UI updates if the state changes. + DCHECK_NE(0u, serial_active_frame_count_); + serial_active_frame_count_--; + if (serial_active_frame_count_ == 0) { + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + } +} + +void WebContentsImpl::IncrementHidActiveFrameCount() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::IncrementHidActiveFrameCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + // Notify for UI updates if the active frame count transitions from zero to + // non-zero. + hid_active_frame_count_++; + if (hid_active_frame_count_ == 1) { + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + } +} + +void WebContentsImpl::DecrementHidActiveFrameCount() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::DecrementHidActiveFrameCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + // Notify for UI updates if the active frame count transitions from non-zero + // to zero. + DCHECK_NE(0u, hid_active_frame_count_); + hid_active_frame_count_--; + if (hid_active_frame_count_ == 0) { + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + } +} + +void WebContentsImpl::OnIsConnectedToUsbDeviceChanged( + bool is_connected_to_usb_device) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::OnIsConnectedToUsbDeviceChanged"); + NotifyNavigationStateChanged(INVALIDATE_TYPE_TAB); + observers_.NotifyObservers( + &WebContentsObserver::OnIsConnectedToUsbDeviceChanged, + is_connected_to_usb_device); +} + +void WebContentsImpl::IncrementUsbActiveFrameCount() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::IncrementUsbActiveFrameCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + // Notify for UI updates if the active frame count transitions from zero to + // non-zero. + usb_active_frame_count_++; + if (usb_active_frame_count_ == 1) { + OnIsConnectedToUsbDeviceChanged(true); + } +} + +void WebContentsImpl::DecrementUsbActiveFrameCount() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::DecrementUsbActiveFrameCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + // Notify for UI updates if the active frame count transitions from non-zero + // to zero. + DCHECK_NE(0u, usb_active_frame_count_); + usb_active_frame_count_--; + if (usb_active_frame_count_ == 0) { + OnIsConnectedToUsbDeviceChanged(false); + } +} + +void WebContentsImpl::IncrementFileSystemAccessHandleCount() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::IncrementFileSystemAccessHandleCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + // Notify for UI updates if the state changes. Need both TYPE_TAB and TYPE_URL + // to update both the tab-level usage indicator and the usage indicator in the + // omnibox. + file_system_access_handle_count_++; + if (file_system_access_handle_count_ == 1) { + NotifyNavigationStateChanged(static_cast( + INVALIDATE_TYPE_TAB | INVALIDATE_TYPE_URL)); + } +} + +void WebContentsImpl::DecrementFileSystemAccessHandleCount() { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::DecrementFileSystemAccessHandleCount"); + // Trying to invalidate the tab state while being destroyed could result in a + // use after free. + if (IsBeingDestroyed()) { + return; + } + + // Notify for UI updates if the state changes. Need both TYPE_TAB and TYPE_URL + // to update both the tab-level usage indicator and the usage indicator in the + // omnibox. + DCHECK_NE(0u, file_system_access_handle_count_); + file_system_access_handle_count_--; + if (file_system_access_handle_count_ == 0) { + NotifyNavigationStateChanged(static_cast( + INVALIDATE_TYPE_TAB | INVALIDATE_TYPE_URL)); + } +} + +void WebContentsImpl::SetHasPersistentVideo(bool has_persistent_video) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::SetHasPersistentVideo", + "has_persistent_video", has_persistent_video, + "had_persistent_value", has_persistent_video_); + if (has_persistent_video_ == has_persistent_video) { + return; + } + + has_persistent_video_ = has_persistent_video; + NotifyPreferencesChanged(); + media_web_contents_observer()->RequestPersistentVideo(has_persistent_video); + + // This is Picture-in-Picture on Android S+. + if (auto* view = GetRenderWidgetHostView()) { + static_cast(view)->SetHasPersistentVideo( + has_persistent_video); + } +} + +void WebContentsImpl::SetSpatialNavigationDisabled(bool disabled) { + OPTIONAL_TRACE_EVENT2( + "content", "WebContentsImpl::SetSpatialNavigationDisabled", "disabled", + disabled, "was_disabled", is_spatial_navigation_disabled_); + if (is_spatial_navigation_disabled_ == disabled) { + return; + } + + is_spatial_navigation_disabled_ = disabled; + NotifyPreferencesChanged(); +} + +void WebContentsImpl::SetStylusHandwritingEnabled(bool enabled) { + if (stylus_handwriting_enabled_ == enabled) { + return; + } + stylus_handwriting_enabled_ = enabled; + NotifyPreferencesChanged(); +} + +PictureInPictureResult WebContentsImpl::EnterPictureInPicture() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::EnterPictureInPicture"); + return delegate_ ? delegate_->EnterPictureInPicture(this) + : PictureInPictureResult::kNotSupported; +} + +void WebContentsImpl::ExitPictureInPicture() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ExitPictureInPicture"); + if (delegate_) { + delegate_->ExitPictureInPicture(); + } +} + +void WebContentsImpl::OnXrHasRenderTarget( + const viz::FrameSinkId& frame_sink_id) { + xr_render_target_ = frame_sink_id; + observers_.NotifyObservers(&WebContentsObserver::CaptureTargetChanged); +} + +WebContentsImpl::CaptureTarget WebContentsImpl::GetCaptureTarget() { + // We don't provide a view for the Android AR capturer. This is not a problem + // because it is currently only used by the MouseCursorOverlayController, + // which isn't used on Android anyway. + if (xr_render_target_.is_valid()) { + return CaptureTarget{.sink_id = xr_render_target_}; + } + + RenderWidgetHostView* host_view = GetRenderWidgetHostView(); + if (!host_view) { + return {}; + } + + RenderWidgetHostViewBase* base_view = + static_cast(host_view); + return CaptureTarget{.sink_id = base_view->GetFrameSinkId(), + .view = host_view->GetNativeView()}; +} + +#if BUILDFLAG(IS_ANDROID) +void WebContentsImpl::NotifyFindMatchRectsReply( + int version, + const std::vector& rects, + const gfx::RectF& active_rect) { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::NotifyFindMatchRectsReply"); + if (delegate_) { + delegate_->FindMatchRectsReply(this, version, rects, active_rect); + } +} +#endif + +void WebContentsImpl::SetForceDisableOverscrollContent(bool force_disable) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::SetForceDisableOverscrollContent", + "force_disable", force_disable); + force_disable_overscroll_content_ = force_disable; + if (view_) { + view_->SetOverscrollControllerEnabled(CanOverscrollContent()); + } +} + +bool WebContentsImpl::SetDeviceEmulationSize(const gfx::Size& new_size) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetDeviceEmulationSize"); + device_emulation_size_ = new_size; + RenderWidgetHostView* rwhv = GetPrimaryMainFrame()->GetView(); + + const gfx::Size current_size = rwhv->GetViewBounds().size(); + if (view_size_before_emulation_.IsEmpty()) { + view_size_before_emulation_ = current_size; + } + + if (current_size != new_size) { + rwhv->SetSize(new_size); + } + + return current_size != new_size; +} + +void WebContentsImpl::ClearDeviceEmulationSize() { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::ClearDeviceEmulationSize"); + RenderWidgetHostView* rwhv = GetPrimaryMainFrame()->GetView(); + // WebContentsView could get resized during emulation, which also resizes + // RWHV. If it happens, assume user would like to keep using the size after + // emulation. + // TODO(jzfeng): Prohibit resizing RWHV through any other means (at least when + // WebContentsView size changes). + if (!view_size_before_emulation_.IsEmpty() && rwhv && + rwhv->GetViewBounds().size() == device_emulation_size_) { + rwhv->SetSize(view_size_before_emulation_); + } + device_emulation_size_ = gfx::Size(); + view_size_before_emulation_ = gfx::Size(); +} + +ForwardingAudioStreamFactory* WebContentsImpl::GetAudioStreamFactory() { + if (!audio_stream_factory_) { + std::unique_ptr broker_factory; + if (delegate_) { + broker_factory = delegate_->CreateAudioStreamBrokerFactory(this); + } + if (!broker_factory) { + broker_factory = AudioStreamBrokerFactory::CreateImpl(); + } + audio_stream_factory_.emplace( + this, + // BrowserMainLoop::GetInstance() may be null in unit tests. + BrowserMainLoop::GetInstance() + ? static_cast( + BrowserMainLoop::GetInstance()->user_input_monitor()) + : nullptr, + std::move(broker_factory)); + } + + return &*audio_stream_factory_; +} + +void WebContentsImpl::MediaStartedPlaying( + const WebContentsObserver::MediaPlayerInfo& media_info, + const MediaPlayerId& id) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MediaStartedPlaying"); + if (media_info.has_video) { + currently_playing_video_count_++; + } + + observers_.NotifyObservers(&WebContentsObserver::MediaStartedPlaying, + media_info, id); +} + +void WebContentsImpl::MediaStoppedPlaying( + const WebContentsObserver::MediaPlayerInfo& media_info, + const MediaPlayerId& id, + WebContentsObserver::MediaStoppedReason reason) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MediaStoppedPlaying"); + if (media_info.has_video) { + currently_playing_video_count_--; + } + + observers_.NotifyObservers(&WebContentsObserver::MediaStoppedPlaying, + media_info, id, reason); +} + +void WebContentsImpl::MediaResized(const gfx::Size& size, + const MediaPlayerId& id) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MediaResized"); + cached_video_sizes_[id] = size; + + observers_.NotifyObservers(&WebContentsObserver::MediaResized, size, id); +} + +void WebContentsImpl::MediaEffectivelyFullscreenChanged(bool is_fullscreen) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::MediaEffectivelyFullscreenChanged", + "is_fullscreen", is_fullscreen); + observers_.NotifyObservers( + &WebContentsObserver::MediaEffectivelyFullscreenChanged, is_fullscreen); +} + +void WebContentsImpl::MediaDestroyed(const MediaPlayerId& id) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::MediaDestroyed"); + observers_.NotifyObservers(&WebContentsObserver::MediaDestroyed, id); +} + +void WebContentsImpl::MediaSessionCreated(MediaSession* media_session) { + observers_.NotifyObservers(&WebContentsObserver::MediaSessionCreated, + media_session); +} + +int WebContentsImpl::GetCurrentlyPlayingVideoCount() { + return currently_playing_video_count_; +} + +std::optional WebContentsImpl::GetFullscreenVideoSize() { + std::optional id = + media_web_contents_observer_->GetFullscreenVideoMediaPlayerId(); + if (id && base::Contains(cached_video_sizes_, id.value())) { + return std::optional(cached_video_sizes_[id.value()]); + } + return std::nullopt; +} + +void WebContentsImpl::AudioContextPlaybackStarted(RenderFrameHostImpl* host, + int context_id) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::AudioContextPlaybackStarted", + "render_frame_host", host); + WebContentsObserver::AudioContextId audio_context_id(host, context_id); + observers_.NotifyObservers(&WebContentsObserver::AudioContextPlaybackStarted, + audio_context_id); +} + +void WebContentsImpl::AudioContextPlaybackStopped(RenderFrameHostImpl* host, + int context_id) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::AudioContextPlaybackStopped", + "render_frame_host", host); + WebContentsObserver::AudioContextId audio_context_id(host, context_id); + observers_.NotifyObservers(&WebContentsObserver::AudioContextPlaybackStopped, + audio_context_id); +} + +void WebContentsImpl::OnFrameAudioStateChanged(RenderFrameHostImpl* host, + bool is_audible) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnFrameAudioStateChanged", + "render_frame_host", host, "is_audible", is_audible); + observers_.NotifyObservers(&WebContentsObserver::OnFrameAudioStateChanged, + host, is_audible); +} + +void WebContentsImpl::OnFrameVisibilityChanged( + RenderFrameHostImpl* host, + blink::mojom::FrameVisibility visibility) { + OPTIONAL_TRACE_EVENT2("content", "WebContentsImpl::OnFrameVisibilityChanged", + "render_frame_host", host, "visibility", visibility); + observers_.NotifyObservers(&WebContentsObserver::OnFrameVisibilityChanged, + host, visibility); +} + +void WebContentsImpl::OnFrameIsCapturingMediaStreamChanged( + RenderFrameHostImpl* host, + bool is_capturing_media_stream) { + observers_.NotifyObservers( + &WebContentsObserver::OnFrameIsCapturingMediaStreamChanged, host, + is_capturing_media_stream); +} + +// Cf. `GetProspectiveOuterDocument` which applies to the same situation, but is +// for ascending. +std::vector WebContentsImpl::GetUnattachedOwnedNodes( + RenderFrameHostImpl* owner) { + std::vector unattached_owned_nodes; + BrowserPluginGuestManager* guest_manager = + GetBrowserContext()->GetGuestManager(); + if (owner == GetPrimaryMainFrame() && guest_manager) { + guest_manager->ForEachUnattachedGuest( + this, [&](WebContents* guest_contents) { + unattached_owned_nodes.push_back( + static_cast(guest_contents) + ->primary_frame_tree_.root()); + }); + } + return unattached_owned_nodes; +} + +void WebContentsImpl::IsClipboardPasteAllowedByPolicy( + const ClipboardEndpoint& source, + const ClipboardEndpoint& destination, + const ClipboardMetadata& metadata, + ClipboardPasteData clipboard_paste_data, + IsClipboardPasteAllowedCallback callback) { + ++suppress_unresponsive_renderer_count_; + GetContentClient()->browser()->IsClipboardPasteAllowedByPolicy( + source, destination, metadata, std::move(clipboard_paste_data), + base::BindOnce(&WebContentsImpl::IsClipboardPasteAllowedWrapperCallback, + weak_factory_.GetWeakPtr(), std::move(callback))); +} + +void WebContentsImpl::OnTextCopiedToClipboard( + RenderFrameHostImpl* render_frame_host, + const std::u16string& copied_text) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::OnTextCopiedToClipboard", + "render_frame_host", render_frame_host); + observers_.NotifyObservers(&WebContentsObserver::OnTextCopiedToClipboard, + render_frame_host, copied_text); +} + +void WebContentsImpl::IsClipboardPasteAllowedWrapperCallback( + IsClipboardPasteAllowedCallback callback, + std::optional clipboard_paste_data) { + std::move(callback).Run(std::move(clipboard_paste_data)); + --suppress_unresponsive_renderer_count_; +} + +void WebContentsImpl::BindScreenOrientation( + RenderFrameHost* rfh, + mojo::PendingAssociatedReceiver + receiver) { + screen_orientation_provider_->BindScreenOrientation(rfh, std::move(receiver)); +} + +bool WebContentsImpl::IsTransientActivationRequiredForHtmlFullscreen() { + // Allow fullscreen if the screen orientation changed in the last 1 second. + static constexpr base::TimeDelta kMaxInterval = base::Seconds(1); + const base::TimeDelta delta = + ui::EventTimeForNow() - last_screen_orientation_change_time_; + if (delta <= kMaxInterval) { + return false; + } + + RenderFrameHostImpl* host = GetPrimaryMainFrame(); + if (base::FeatureList::IsEnabled( + blink::features::kWindowPlacementFullscreenOnScreensChange) && + IsWindowManagementGranted(host) && + transient_allow_fullscreen_.IsActive()) { + return false; + } + + // Require transient activation shortly after a same-origin WebContents exit. + auto* last_exits = GetFullscreenUserData(GetBrowserContext())->last_exits(); + auto last_exit = last_exits->find(host->GetLastCommittedOrigin()); + constexpr base::TimeDelta kCooldown = base::Seconds(5); + if (last_exit != last_exits->end() && + base::TimeTicks::Now() < last_exit->second + kCooldown) { + return true; + } + + // Waive transient activation requirements if Automatic Fullscreen is granted. + if (IsAutomaticFullscreenGranted(host)) { + return false; + } + + return GetContentClient() + ->browser() + ->IsTransientActivationRequiredForHtmlFullscreen(host); +} + +bool WebContentsImpl::IsBackForwardCacheSupported() { + if (!GetDelegate()) { + return false; + } + return GetDelegate()->IsBackForwardCacheSupported(*this); +} + +FrameTree* WebContentsImpl::LoadingTree() { + return &GetPrimaryFrameTree(); +} + +void WebContentsImpl::DidChangeScreenOrientation() { + last_screen_orientation_change_time_ = ui::EventTimeForNow(); +} + +void WebContentsImpl::UpdateWebContentsVisibility(Visibility visibility) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::UpdateWebContentsVisibility", + "visibility", visibility); + // Occlusion is disabled when + // |switches::kDisableBackgroundingOccludedWindowsForTesting| is specified on + // the command line (to avoid flakiness in browser tests). + const bool occlusion_is_disabled = + base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableBackgroundingOccludedWindowsForTesting); + if (occlusion_is_disabled && visibility == Visibility::OCCLUDED) { + visibility = Visibility::VISIBLE; + } + + if (!did_first_set_visible_) { + if (visibility == Visibility::VISIBLE) { + // A WebContents created with CreateParams::initially_hidden = false + // starts with GetVisibility() == Visibility::VISIBLE even though it is + // not really visible. Call WasShown() when it becomes visible for real as + // the page load mechanism and some WebContentsObserver rely on that. + WasShown(); + did_first_set_visible_ = true; + } + + // Trust the initial visibility of the WebContents and do not switch it to + // HIDDEN or OCCLUDED before it becomes VISIBLE for real. Doing so would + // result in destroying resources that would immediately be recreated (e.g. + // UpdateWebContents(HIDDEN) can be called when a WebContents is added to a + // hidden window that is about to be shown). + + return; + } + + if (visibility == visibility_) { + return; + } + + UpdateVisibilityAndNotifyPageAndView(visibility); +} + +void WebContentsImpl::UpdateOverridingUserAgent() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::UpdateOverridingUserAgent"); + NotifyPreferencesChanged(); +} + +void WebContentsImpl::SetJavaScriptDialogManagerForTesting( + JavaScriptDialogManager* dialog_manager) { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::SetJavaScriptDialogManagerForTesting"); + dialog_manager_ = dialog_manager; +} + +void WebContentsImpl::ShowInsecureLocalhostWarningIfNeeded(PageImpl& page) { + OPTIONAL_TRACE_EVENT0( + "content", "WebContentsImpl::ShowInsecureLocalhostWarningIfNeeded"); + + bool allow_localhost = base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAllowInsecureLocalhost); + if (!allow_localhost) { + return; + } + + RenderFrameHostImpl& frame = page.GetMainDocument(); + NavigationEntry* entry = + frame.frame_tree()->controller().GetLastCommittedEntry(); + if (!entry || !net::IsLocalhost(entry->GetURL())) { + return; + } + + SSLStatus ssl_status = entry->GetSSL(); + if (!net::IsCertStatusError(ssl_status.cert_status)) { + return; + } + + frame.AddMessageToConsole(blink::mojom::ConsoleMessageLevel::kWarning, + "This site does not have a valid SSL " + "certificate! Without SSL, your site's and " + "visitors' data is vulnerable to theft and " + "tampering. Get a valid SSL certificate before " + " releasing your website to the public."); +} + +bool WebContentsImpl::IsShowingContextMenuOnPage() const { + return showing_context_menu_; +} + +download::DownloadUrlParameters::RequestHeadersType +WebContentsImpl::ParseDownloadHeaders(const std::string& headers) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::ParseDownloadHeaders", + "headers", headers); + download::DownloadUrlParameters::RequestHeadersType request_headers; + for (std::string_view key_value : base::SplitStringPiece( + headers, "\r\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) { + std::vector pair = base::SplitString( + key_value, ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + if (2ul == pair.size()) { + request_headers.push_back(make_pair(pair[0], pair[1])); + } + } + return request_headers; +} + +void WebContentsImpl::SetOpenerForNewContents(FrameTreeNode* opener, + bool opener_suppressed) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::SetOpenerForNewContents"); + if (opener) { + FrameTreeNode* new_root = GetPrimaryFrameTree().root(); + + // For the "original opener", track the opener's main frame instead, because + // if the opener is a subframe, the opener tracking could be easily bypassed + // by spawning from a subframe and deleting the subframe. + // https://crbug.com/705316 + new_root->SetOriginalOpener(opener->frame_tree().root()); + new_root->SetOpenerDevtoolsFrameToken( + opener->current_frame_host()->devtools_frame_token()); + opened_by_another_window_ = true; + + if (!opener_suppressed) { + new_root->SetOpener(opener); + } + } +} + +void WebContentsImpl::MediaMutedStatusChanged(const MediaPlayerId& id, + bool muted) { + OPTIONAL_TRACE_EVENT1("content", "WebContentsImpl::MediaMutedStatusChanged", + "muted", muted); + observers_.NotifyObservers(&WebContentsObserver::MediaMutedStatusChanged, id, + muted); +} + +void WebContentsImpl::SetVisibilityForChildViews(bool visible) { + OPTIONAL_TRACE_EVENT1("content", + "WebContentsImpl::SetVisibilityForChildViews", + "visible", visible); + GetPrimaryMainFrame()->SetVisibilityForChildViews(visible); +} + +void WebContentsImpl::OnNativeThemeUpdated(ui::NativeTheme* observed_theme) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::OnNativeThemeUpdated"); + DCHECK(native_theme_observation_.IsObservingSource(observed_theme)); + + bool using_dark_colors = observed_theme->ShouldUseDarkColors(); + bool in_forced_colors = observed_theme->InForcedColorsMode(); + ui::NativeTheme::PreferredColorScheme preferred_color_scheme = + observed_theme->GetPreferredColorScheme(); + ui::NativeTheme::PreferredContrast preferred_contrast = + observed_theme->GetPreferredContrast(); + bool prefers_reduced_transparency = + observed_theme->GetPrefersReducedTransparency(); + bool inverted_colors = observed_theme->GetInvertedColors(); + base::TimeDelta caret_blink_interval = + observed_theme->GetCaretBlinkInterval(); + bool preferences_changed = false; + + if (using_dark_colors_ != using_dark_colors) { + using_dark_colors_ = using_dark_colors; + preferences_changed = true; + } + if (in_forced_colors_ != in_forced_colors) { + in_forced_colors_ = in_forced_colors; + preferences_changed = true; + } + if (preferred_color_scheme_ != preferred_color_scheme) { + preferred_color_scheme_ = preferred_color_scheme; + preferences_changed = true; + } + if (preferred_contrast_ != preferred_contrast) { + preferred_contrast_ = preferred_contrast; + preferences_changed = true; + } + if (prefers_reduced_transparency_ != prefers_reduced_transparency) { + prefers_reduced_transparency_ = prefers_reduced_transparency; + preferences_changed = true; + } + if (inverted_colors_ != inverted_colors) { + inverted_colors_ = inverted_colors; + preferences_changed = true; + } + + if (preferences_changed) { + NotifyPreferencesChanged(); + } + + // Only caret blink interval from NativeTheme impacts + // blink::RendererPreferences, which are not synced in + // NotifyPreferencesChanged(). Sync these if the interval has changed. + if (renderer_preferences_.caret_blink_interval != caret_blink_interval) { + renderer_preferences_.caret_blink_interval = caret_blink_interval; + SyncRendererPrefs(); + } +} + +void WebContentsImpl::OnCaptionStyleUpdated() { + NotifyPreferencesChanged(); +} + +void WebContentsImpl::OnColorProviderChanged() { + // OnColorProviderChanged() might have been triggered as the result of the + // observed source being reset. If this is the case fallback to the default + // source. + if (!GetColorProviderSource()) { + SetColorProviderSource(DefaultColorProviderSource::GetInstance()); + return; + } + + blink::ColorProviderColorMaps color_map = GetColorProviderColorMaps(); + ExecutePageBroadcastMethodForAllPages(base::BindRepeating( + [](const blink::ColorProviderColorMaps& color_map, + RenderViewHostImpl* rvh) { + if (auto& broadcast = rvh->GetAssociatedPageBroadcast()) { + broadcast->UpdateColorProviders(color_map); + } + }, + color_map)); + + observers_.NotifyObservers(&WebContentsObserver::OnColorProviderChanged); + + // Web preferences may change in response to events such as + // OnNativeThemeUpdated(). However web preferences may also depend on + // ColorProvider state and the associated ColorProvider may change + // independently of the native theme. Ensure we propagate web preferences here + // to cover this case. + // OnColorProviderChanged() can be emitted during the WebContentsImpl's + // constructor in response to setting the ColorProviderSource. In this case + // Init() will not yet have been called and the current frame host will not be + // defined, so we must guard against this here. + // TODO(tluk): There may be a more appropriate way to identify this condition. + if (GetRenderManager()->current_frame_host()) { + NotifyPreferencesChanged(); + } +} + +const ui::ColorProvider& WebContentsImpl::GetColorProvider() const { + auto* source = GetColorProviderSource(); + DCHECK(source); + auto* color_provider = source->GetColorProvider(); + DCHECK(color_provider); + return *color_provider; +} + +blink::mojom::FrameWidgetInputHandler* +WebContentsImpl::GetFocusedFrameWidgetInputHandler() { + auto* focused_render_widget_host = + GetFocusedRenderWidgetHost(GetPrimaryMainFrame()->GetRenderWidgetHost()); + if (!focused_render_widget_host) { + return nullptr; + } + return focused_render_widget_host->GetFrameWidgetInputHandler(); +} + +ukm::SourceId WebContentsImpl::GetCurrentPageUkmSourceId() { + return GetPrimaryMainFrame()->GetPageUkmSourceId(); +} + +void WebContentsImpl::ForEachRenderViewHost( + ForEachRenderViewHostTypes view_mask, + RenderViewHostIterationCallback on_render_view_host) { + std::set render_view_hosts; + + if ((view_mask & (ForEachRenderViewHostTypes::kPrerenderViews | + ForEachRenderViewHostTypes::kActiveViews)) != 0) { + ForEachFrameTree(base::BindRepeating( + [](ForEachRenderViewHostTypes view_mask, + std::set& render_view_hosts, + FrameTree& frame_tree) { + // Check the view masks. + if (frame_tree.is_prerendering()) { + // We are in a prerendering page. + if ((view_mask & ForEachRenderViewHostTypes::kPrerenderViews) == + 0) { + return; + } + } else { + // We are in an active page. + if ((view_mask & ForEachRenderViewHostTypes::kActiveViews) == 0) { + return; + } + } + frame_tree.ForEachRenderViewHost( + [&render_view_hosts](RenderViewHostImpl* rvh) { + render_view_hosts.insert(rvh); + }); + }, + view_mask, std::ref(render_view_hosts))); + } + + if ((view_mask & ForEachRenderViewHostTypes::kBackForwardCacheViews) != 0) { + // Add RenderViewHostImpls in BackForwardCache. + const auto& entries = GetController().GetBackForwardCache().GetEntries(); + for (const auto& entry : entries) { + for (const auto& render_view : entry->render_view_hosts()) { + render_view_hosts.insert(&*render_view); + } + } + } + + for (auto* render_view_host : render_view_hosts) { + on_render_view_host.Run(render_view_host); + } +} + +void WebContentsImpl::NotifyPageBecamePrimary(PageImpl& page) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::PrimaryPageChanged"); + + DCHECK_EQ(&page, &GetPrimaryPage()); + + // Clear |save_package_| since the primary page changed. + if (save_package_) { + save_package_->ClearPage(); + save_package_.reset(); + } + observers_.NotifyObservers(&WebContentsObserver::PrimaryPageChanged, page); +} + +bool WebContentsImpl::IsPageInPreviewMode() const { + return IsInPreviewMode(); +} + +void WebContentsImpl::CancelPreviewByMojoBinderPolicy( + const std::string& interface_name) { + if (delegate_) { + delegate_->CancelPreview( + PreviewCancelReason::BlockedByMojoBinderPolicy(interface_name)); + } +} + +void WebContentsImpl::OnCanResizeFromWebAPIChanged() { + delegate_->OnCanResizeFromWebAPIChanged(); +} + +int WebContentsImpl::GetOuterDelegateFrameTreeNodeId() { + return node_.outer_contents_frame_tree_node_id(); +} + +// Cf. `GetUnattachedOwnedNodes` which applies to the same situation, but is for +// descending. +RenderFrameHostImpl* WebContentsImpl::GetProspectiveOuterDocument() { + // If the outer WebContents is already known, then there was no need to call + // this method. + DCHECK(!GetOuterWebContents()); + + RenderFrameHostImpl* unattached_guest_owner = + browser_plugin_guest_ + ? browser_plugin_guest_->GetProspectiveOuterDocument() + : nullptr; + if (unattached_guest_owner) { + return unattached_guest_owner; + } + + return nullptr; +} + +void WebContentsImpl::RenderFrameHostStateChanged( + RenderFrameHost* render_frame_host, + LifecycleState old_state, + LifecycleState new_state) { + DCHECK_NE(old_state, new_state); + OPTIONAL_TRACE_EVENT2("content", + "WebContentsImpl::RenderFrameHostStateChanged", + "render_frame_host", render_frame_host, "states", + [&](perfetto::TracedValue context) { + // TODO(crbug.com/40751990): Replace this with passing + // more parameters to TRACE_EVENT directly when + // available. + auto dict = std::move(context).WriteDictionary(); + dict.Add("old", old_state); + dict.Add("new", new_state); + }); + +#if BUILDFLAG(IS_ANDROID) + if (old_state == LifecycleState::kActive && !render_frame_host->GetParent()) { + // TODO(sreejakshetty): Remove this reset when ColorChooserHolder becomes + // per-frame. + // Close the color chooser popup when RenderFrameHost changes state from + // kActive. + color_chooser_holder_.reset(); + } +#endif // BUILDFLAG(IS_ANDROID) + + observers_.NotifyObservers(&WebContentsObserver::RenderFrameHostStateChanged, + render_frame_host, old_state, new_state); +} + +void WebContentsImpl::DecrementCapturerCount(bool stay_hidden, + bool stay_awake, + bool is_activity) { + OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DecrementCapturerCount"); + if (stay_hidden) { + --hidden_capturer_count_; + } else { + --visible_capturer_count_; + } + if (stay_awake) { + --stay_awake_capturer_count_; + } + DCHECK_GE(hidden_capturer_count_, 0); + DCHECK_GE(visible_capturer_count_, 0); + DCHECK_GE(stay_awake_capturer_count_, 0); + + if (IsBeingDestroyed()) { + return; + } + + view_->OnCapturerCountChanged(); + + const bool is_being_captured = IsBeingCaptured(); + if (!is_being_captured) { + const gfx::Size old_size = preferred_size_for_capture_; + preferred_size_for_capture_ = gfx::Size(); + OnPreferredSizeChanged(old_size); + } + + if (capture_wake_lock_ && + (!is_being_captured || !stay_awake_capturer_count_)) { + capture_wake_lock_->CancelWakeLock(); + } + + UpdateVisibilityAndNotifyPageAndView(GetVisibility(), is_activity); +} + +void WebContentsImpl::NotifyPrimaryMainFrameProcessIsAlive() { + // The WebContents tracks the process state for the primary main frame's + // renderer. + // Consider renderer as terminated when exited with any termination status. + bool was_renderer_terminated = primary_main_frame_process_status_ != + base::TERMINATION_STATUS_STILL_RUNNING; + SetPrimaryMainFrameProcessStatus(base::TERMINATION_STATUS_STILL_RUNNING, 0); + // Restore the focus to the tab (otherwise the focus will be on the top + // window). + if (was_renderer_terminated && !FocusLocationBarByDefault()) { + if (!delegate_ || delegate_->ShouldFocusPageAfterCrash(this)) { + view_->Focus(); + } + } +} + +void WebContentsImpl::UpdateBrowserControlsState( + cc::BrowserControlsState constraints, + cc::BrowserControlsState current, + bool animate, + const std::optional& offset_tags_info) { + // Browser controls should be synchronised with the scroll state. Therefore, + // they are controlled from the renderer by the main RenderFrame(Host). + GetPrimaryPage().UpdateBrowserControlsState(constraints, current, animate, + offset_tags_info); +} + +void WebContentsImpl::SetV8CompileHints(base::ReadOnlySharedMemoryRegion data) { + GetPrimaryMainFrame()->GetAssociatedLocalMainFrame()->SetV8CompileHints( + std::move(data)); +} + +void WebContentsImpl::SetTabSwitchStartTime(base::TimeTicks start_time, + bool destination_is_loaded) { + GetVisibleTimeRequestTrigger().UpdateRequest( + start_time, destination_is_loaded, + /*show_reason_tab_switching=*/true, + /*show_reason_bfcache_restore=*/false); +} + +bool WebContentsImpl::IsInPreviewMode() const { + return is_in_preview_mode_; +} + +void WebContentsImpl::WillActivatePreviewPage() { + CHECK(is_in_preview_mode_); + is_in_preview_mode_ = false; +} + +void WebContentsImpl::ActivatePreviewPage() { + TRACE_EVENT0("content", "WebContentsImpl::ActivatePreviewPage"); + + // WillActivatePreviewPage() should be called to reset it beforehand. + CHECK(!is_in_preview_mode_); + + PageImpl& preview_page = GetPrimaryPage(); + preview_page.SetActivationStartTime(base::TimeTicks::Now()); + + // TODO(b:299240273): Gather all relevant RVHs. + StoredPage::RenderViewHostImplSafeRefSet render_view_hosts; + render_view_hosts.insert(GetRenderViewHost()->GetSafeRef()); + + preview_page.Activate( + PageImpl::ActivationType::kPreview, render_view_hosts, std::nullopt, + base::BindOnce(&WebContentsImpl::DidActivatePreviewedPage, + weak_factory_.GetWeakPtr())); +} + +VisibleTimeRequestTrigger& WebContentsImpl::GetVisibleTimeRequestTrigger() { + return visible_time_request_trigger_; +} + +gfx::mojom::DelegatedInkPointRenderer* WebContentsImpl::GetDelegatedInkRenderer( + ui::Compositor* compositor) { + if (!delegated_ink_point_renderer_.is_bound()) { + // The remote can't be bound if the compositor is null, so bail if + // that is the case so we don't crash by trying to use an unbound + // remote. + if (!compositor) { + return nullptr; + } + + TRACE_EVENT_INSTANT0("delegated_ink_trails", + "Binding mojo interface for delegated ink points.", + TRACE_EVENT_SCOPE_THREAD); + compositor->SetDelegatedInkPointRenderer( + delegated_ink_point_renderer_.BindNewPipeAndPassReceiver()); + delegated_ink_point_renderer_.reset_on_disconnect(); + } + return delegated_ink_point_renderer_.get(); +} + +void WebContentsImpl::StartPrefetch( + const GURL& prefetch_url, + bool use_prefetch_proxy, + const blink::mojom::Referrer& referrer, + const std::optional& referring_origin, + base::WeakPtr attempt) { + if (!base::FeatureList::IsEnabled( + features::kPrefetchBrowserInitiatedTriggers)) { + return; + } + + PrefetchService* prefetch_service = + BrowserContextImpl::From(GetBrowserContext())->GetPrefetchService(); + if (!prefetch_service) { + return; + } + + PrefetchType prefetch_type(PreloadingTriggerType::kEmbedder, + use_prefetch_proxy); + + auto container = std::make_unique( + *this, prefetch_url, prefetch_type, referrer, referring_origin, + /*no_vary_search_expected=*/std::nullopt, std::move(attempt)); + + // TODO(crbug.com/40946257): Update this list when prefetch container is + // eliminated from `PrefetchService`. + prefetch_containers_.push_back(container->GetWeakPtr()); + prefetch_service->AddPrefetchContainer(std::move(container)); +} + +std::unique_ptr WebContentsImpl::StartPrerendering( + const GURL& prerendering_url, + PreloadingTriggerType trigger_type, + const std::string& embedder_histogram_suffix, + ui::PageTransition page_transition, + bool should_warm_up_compositor, + PreloadingHoldbackStatus holdback_status_override, + PreloadingAttempt* preloading_attempt, + base::RepeatingCallback url_match_predicate, + base::RepeatingCallback + prerender_navigation_handle_callback) { + PrerenderAttributes attributes( + prerendering_url, trigger_type, embedder_histogram_suffix, + /*target_hint=*/std::nullopt, content::Referrer(), + /*eagerness=*/std::nullopt, + /*no_vary_search_expected=*/std::nullopt, + /*initiator_origin=*/std::nullopt, + content::ChildProcessHost::kInvalidUniqueID, GetWeakPtr(), + /*initiator_frame_token=*/std::nullopt, + /*initiator_frame_tree_node_id=*/RenderFrameHost::kNoFrameTreeNodeId, + ukm::kInvalidSourceId, page_transition, should_warm_up_compositor, + std::move(url_match_predicate), + std::move(prerender_navigation_handle_callback)); + attributes.holdback_status_override = holdback_status_override; + + int frame_tree_node_id = GetPrerenderHostRegistry()->CreateAndStartHost( + attributes, preloading_attempt); + + if (frame_tree_node_id != FrameTreeNode::kFrameTreeNodeInvalidId) { + return std::make_unique( + GetPrerenderHostRegistry()->GetWeakPtr(), frame_tree_node_id, + prerendering_url); + } + return nullptr; +} + +void WebContentsImpl::CancelAllPrerendering() { + GetPrerenderHostRegistry()->CancelAllHosts( + PrerenderFinalStatus::kAllPrerenderingCanceled); +} + +void WebContentsImpl::BackNavigationLikely(PreloadingPredictor predictor, + WindowOpenDisposition disposition) { + CHECK(!IsBeingDestroyed()); + + // See the comment of `last_back_navigation_hint_time_` for why this cooldown + // exists. The choice of 5 seconds is arbitrary. + constexpr base::TimeDelta kCooldown = base::Seconds(5); + base::TimeTicks now = ui::EventTimeForNow(); + if (now - last_back_navigation_hint_time_ < kCooldown) { + return; + } + last_back_navigation_hint_time_ = now; + + if (disposition != WindowOpenDisposition::CURRENT_TAB) { + RecordPrerenderBackNavigationEligibility( + predictor, PrerenderBackNavigationEligibility::kTargetingOtherWindow, + nullptr); + return; + } + + GetPrerenderHostRegistry()->BackNavigationLikely(predictor); +} + +void WebContentsImpl::SetOwnerLocationForDebug( + std::optional owner_location) { + ownership_location_ = owner_location; +} + +void WebContentsImpl::AboutToBeDiscarded(WebContents* new_contents) { + observers_.NotifyObservers(&WebContentsObserver::AboutToBeDiscarded, + new_contents); +} + +base::ScopedClosureRunner WebContentsImpl::CreateDisallowCustomCursorScope( + int max_dimension_dips) { + auto* render_widget_host_base = GetPrimaryMainFrame() + ->GetRenderWidgetHost() + ->GetRenderWidgetHostViewBase(); + + // It's possible for |render_widget_host_base| to be null if the renderer + // crashed. To avoid race conditions, null-check here. See crbug.com/1421552 + // as well. + if (!render_widget_host_base) { + return base::ScopedClosureRunner(); + } + + auto* cursor_manager = render_widget_host_base->GetCursorManager(); + return cursor_manager->CreateDisallowCustomCursorScope(max_dimension_dips); +} + +bool WebContentsImpl::CancelPrerendering(FrameTreeNode* frame_tree_node, + PrerenderFinalStatus final_status) { + if (!frame_tree_node) { + return false; + } + + DCHECK_EQ(this, FromFrameTreeNode(frame_tree_node)); + + // A prerendered page is identified by its root FrameTreeNode id, so if the + // given `frame_tree_node` is in any way embedded, we need to iterate up to + // the prerender root. + if (frame_tree_node->GetParentOrOuterDocumentOrEmbedder()) { + return frame_tree_node->GetParentOrOuterDocumentOrEmbedder() + ->CancelPrerendering(PrerenderCancellationReason(final_status)); + } + return GetPrerenderHostRegistry()->CancelHost( + frame_tree_node->frame_tree_node_id(), final_status); +} + +ui::mojom::VirtualKeyboardMode WebContentsImpl::GetVirtualKeyboardMode() const { + return primary_frame_tree_.root() + ->current_frame_host() + ->GetPage() + .virtual_keyboard_mode(); +} + +// static +std::pair WebContentsImpl::GetAvailablePointerAndHoverTypes() { + // On Windows we have to temporarily allow blocking calls since + // ui::GetAvailablePointerAndHoverTypes needs to call some in order to + // figure out tablet device details in base::win::IsDeviceUsedAsATablet, + // see https://crbug.com/1262162. +#if BUILDFLAG(IS_WIN) + base::ScopedAllowBlocking scoped_allow_blocking; +#endif + return ui::GetAvailablePointerAndHoverTypes(); +} + +void WebContentsImpl::SetOverscrollNavigationEnabled(bool enabled) { + GetView()->SetOverscrollControllerEnabled(enabled); +} + +network::mojom::AttributionSupport WebContentsImpl::GetAttributionSupport() { + ContentBrowserClient::AttributionReportingOsRegistrars reportTypes = + AttributionOsLevelManager::GetAttributionReportingOsRegistrars(this); + + return AttributionManager::GetAttributionSupport( + reportTypes.source_registrar == + AttributionReportingOsRegistrar::kDisabled && + reportTypes.trigger_registrar == + AttributionReportingOsRegistrar::kDisabled); +} + +void WebContentsImpl::UpdateAttributionSupportRenderer() { + OPTIONAL_TRACE_EVENT0("content", + "WebContentsImpl::UpdateAttributionSupportRenderer"); + + network::mojom::AttributionSupport support = GetAttributionSupport(); + ExecutePageBroadcastMethodForAllPages(base::BindRepeating( + [](network::mojom::AttributionSupport support, RenderViewHostImpl* rvh) { + if (auto& broadcast = rvh->GetAssociatedPageBroadcast()) { + broadcast->SetPageAttributionSupport(support); + } + }, + support)); +} + +BackForwardTransitionAnimationManager* +WebContentsImpl::GetBackForwardTransitionAnimationManager() { + return GetView()->GetBackForwardTransitionAnimationManager(); +} + +#if BUILDFLAG(IS_ANDROID) +void WebContentsImpl::SetLongPressLinkSelectText(bool enabled) { + if (long_press_link_select_text_ == enabled) { + return; + } + long_press_link_select_text_ = enabled; + NotifyPreferencesChanged(); +} +#endif + +net::handles::NetworkHandle WebContentsImpl::GetTargetNetwork() { + return target_network_; +} + +// static +void WebContentsImpl::UpdateAttributionSupportAllRenderers() { + for (WebContentsImpl* web_contents : GetAllWebContents()) { + web_contents->UpdateAttributionSupportRenderer(); + } +} + +void WebContentsImpl::GetMediaCaptureRawDeviceIdsOpened( + blink::mojom::MediaStreamType type, + base::OnceCallback)> callback) { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + CHECK(type == blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE || + type == blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE); + + MediaStreamManager* media_stream_manager = + BrowserMainLoop::GetInstance()->media_stream_manager(); + if (!media_stream_manager) { + std::move(callback).Run({}); + return; + } + + media_stream_manager->GetRawDeviceIdsOpenedForFrame( + GetPrimaryMainFrame(), type, + base::BindPostTaskToCurrentDefault(std::move(callback))); +} + +} // namespace content diff --git a/tools/under-control/src/content/child/runtime_features.cc b/tools/under-control/src/content/child/runtime_features.cc new file mode 100755 index 000000000..ec9a79e21 --- /dev/null +++ b/tools/under-control/src/content/child/runtime_features.cc @@ -0,0 +1,791 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/child/runtime_features.h" + +#include +#include + +#include "base/base_switches.h" +#include "base/command_line.h" +#include "base/feature_list.h" +#include "base/memory/raw_ref.h" +#include "base/metrics/field_trial.h" +#include "base/metrics/field_trial_params.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "cc/base/features.h" +#include "components/attribution_reporting/features.h" +#include "content/common/content_navigation_policy.h" +#include "content/common/content_switches_internal.h" +#include "content/common/features.h" +#include "content/public/common/content_features.h" +#include "content/public/common/content_switches.h" +#include "device/base/features.h" +#include "device/fido/features.h" +#include "device/gamepad/public/cpp/gamepad_features.h" +#include "device/vr/buildflags/buildflags.h" +#include "gpu/config/gpu_finch_features.h" +#include "gpu/config/gpu_switches.h" +#include "media/base/media_switches.h" +#include "services/device/public/cpp/device_features.h" +#include "services/network/public/cpp/features.h" +#include "services/webnn/public/mojom/features.mojom-features.h" +#include "third_party/blink/public/common/buildflags.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/features_generated.h" +#include "third_party/blink/public/common/loader/referrer_utils.h" +#include "third_party/blink/public/common/switches.h" +#include "third_party/blink/public/platform/web_runtime_features.h" +#include "ui/accessibility/accessibility_features.h" +#include "ui/base/ui_base_features.h" +#include "ui/events/blink/blink_features.h" +#include "ui/gfx/switches.h" +#include "ui/gl/gl_switches.h" +#include "ui/native_theme/native_theme_features.h" + +#if BUILDFLAG(IS_ANDROID) +#include "base/android/build_info.h" +#endif + +#if BUILDFLAG(ENABLE_VR) +#include "device/vr/public/cpp/features.h" +#endif + +using blink::WebRuntimeFeatures; + +namespace { + +// Sets blink runtime features for specific platforms. +// This should be a last resort vs runtime_enabled_features.json5. +void SetRuntimeFeatureDefaultsForPlatform( + const base::CommandLine& command_line) { + // Please consider setting up feature defaults for different platforms + // in runtime_enabled_features.json5 instead of here + // TODO(rodneyding): Move the more common cases here + // to baseFeature/switch functions below and move more complex + // ones to special case functions. +#if defined(USE_AURA) + WebRuntimeFeatures::EnableCompositedSelectionUpdate(true); +#endif + +#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS_LACROS) + const bool enable_canvas_2d_image_chromium = + command_line.HasSwitch( + blink::switches::kEnableGpuMemoryBufferCompositorResources) && + !command_line.HasSwitch(switches::kDisable2dCanvasImageChromium) && + !command_line.HasSwitch(switches::kDisableGpu) && + base::FeatureList::IsEnabled(features::kCanvas2DImageChromium); +#else + constexpr bool enable_canvas_2d_image_chromium = false; +#endif + WebRuntimeFeatures::EnableCanvas2dImageChromium( + enable_canvas_2d_image_chromium); + +#if BUILDFLAG(IS_APPLE) + const bool enable_web_gl_image_chromium = + command_line.HasSwitch( + blink::switches::kEnableGpuMemoryBufferCompositorResources) && + !command_line.HasSwitch(switches::kDisableWebGLImageChromium) && + !command_line.HasSwitch(switches::kDisableGpu); +#else + const bool enable_web_gl_image_chromium = + command_line.HasSwitch(switches::kEnableWebGLImageChromium); +#endif + WebRuntimeFeatures::EnableWebGLImageChromium(enable_web_gl_image_chromium); + +#if BUILDFLAG(IS_ANDROID) + if (command_line.HasSwitch(switches::kDisableMediaSessionAPI)) { + WebRuntimeFeatures::EnableMediaSession(false); + } +#endif + +#if BUILDFLAG(IS_ANDROID) + if (base::android::BuildInfo::GetInstance()->sdk_int() >= + base::android::SDK_VERSION_P) { + // Display Cutout is limited to Android P+. + WebRuntimeFeatures::EnableDisplayCutoutAPI(true); + } +#endif + +#if BUILDFLAG(IS_ANDROID) + WebRuntimeFeatures::EnableMediaControlsExpandGesture( + base::FeatureList::IsEnabled(media::kMediaControlsExpandGesture)); +#endif +} + +enum RuntimeFeatureEnableOptions { + // - If the base::Feature default is overridden by field trial or command + // line, set Blink feature to the state of the base::Feature; + // - Otherwise if the base::Feature is enabled, enable the Blink feature. + // - Otherwise no change. + kDefault, + // Enables the Blink feature when the base::Feature is overridden by field + // trial or command line. Otherwise no change. Its difference from kDefault is + // that the Blink feature isn't affected by the default state of the + // base::Feature. This is useful for Blink origin trial features especially + // those implemented in both Chromium and Blink. As origin trial only controls + // the Blink features, for now we require the base::Feature to be enabled by + // default, but we don't want the default enabled status affect the Blink + // feature. See also https://crbug.com/1048656#c10. + // This can also be used for features that are enabled by default in Chromium + // but not in Blink on all platforms and we want to use the Blink status. + // However, we would prefer consistent Chromium and Blink status to this. + kSetOnlyIfOverridden, +}; + +template +// Helper class that describes the desired actions for the runtime feature +// depending on a check for chromium base::Feature. +struct RuntimeFeatureToChromiumFeatureMap { + // This can be either an enabler function defined in web_runtime_features.cc + // or the string name of the feature in runtime_enabled_features.json5. + T feature_enabler; + // The chromium base::Feature to check. + const raw_ref chromium_feature; + const RuntimeFeatureEnableOptions option = kDefault; +}; + +template +void SetRuntimeFeatureFromChromiumFeature(const base::Feature& chromium_feature, + RuntimeFeatureEnableOptions option, + const Enabler& enabler) { + using FeatureList = base::FeatureList; + const bool feature_enabled = FeatureList::IsEnabled(chromium_feature); + const bool is_overridden = + FeatureList::GetStateIfOverridden(chromium_feature).has_value(); + switch (option) { + case kSetOnlyIfOverridden: + if (is_overridden) { + enabler(feature_enabled); + } + break; + case kDefault: + if (feature_enabled || is_overridden) { + enabler(feature_enabled); + } + break; + default: + NOTREACHED_IN_MIGRATION(); + } +} + +// Sets blink runtime features that are either directly +// controlled by Chromium base::Feature or are overridden +// by base::Feature states. +void SetRuntimeFeaturesFromChromiumFeatures() { + using wf = WebRuntimeFeatures; + // To add a runtime feature control, add a new + // RuntimeFeatureToChromiumFeatureMap entry here if there is a custom + // enabler function defined. Otherwise add the entry with string name + // in the next list. + const RuntimeFeatureToChromiumFeatureMap + blinkFeatureToBaseFeatureMapping[] = { + {wf::EnableAccessibilityAriaVirtualContent, + raw_ref(features::kEnableAccessibilityAriaVirtualContent)}, +#if BUILDFLAG(IS_ANDROID) + {wf::EnableAccessibilityPageZoom, + raw_ref(features::kAccessibilityPageZoom)}, +#endif + {wf::EnableAccessibilityUseAXPositionForDocumentMarkers, + raw_ref(features::kUseAXPositionForDocumentMarkers)}, + {wf::EnableAOMAriaRelationshipProperties, + raw_ref(features::kEnableAriaElementReflection)}, + {wf::EnableBackgroundFetch, raw_ref(features::kBackgroundFetch)}, + {wf::EnableBoundaryEventDispatchTracksNodeRemoval, + raw_ref(blink::features::kBoundaryEventDispatchTracksNodeRemoval)}, + {wf::EnableBrowserVerifiedUserActivationKeyboard, + raw_ref(features::kBrowserVerifiedUserActivationKeyboard)}, + {wf::EnableBrowserVerifiedUserActivationMouse, + raw_ref(features::kBrowserVerifiedUserActivationMouse)}, + {wf::EnableCompositeBGColorAnimation, + raw_ref(features::kCompositeBGColorAnimation)}, + {wf::EnableCooperativeScheduling, + raw_ref(features::kCooperativeScheduling)}, + {wf::EnableDigitalGoods, raw_ref(features::kDigitalGoodsApi), + kSetOnlyIfOverridden}, + {wf::EnableDocumentPolicyNegotiation, + raw_ref(features::kDocumentPolicyNegotiation)}, + {wf::EnableEyeDropperAPI, raw_ref(features::kEyeDropper), + kSetOnlyIfOverridden}, + {wf::EnableFedCm, raw_ref(features::kFedCm), kSetOnlyIfOverridden}, + {wf::EnableFedCmButtonMode, raw_ref(features::kFedCmButtonMode), + kSetOnlyIfOverridden}, + {wf::EnableFedCmAuthz, raw_ref(features::kFedCmAuthz), kDefault}, + {wf::EnableFedCmIdPRegistration, + raw_ref(features::kFedCmIdPRegistration), kDefault}, + {wf::EnableFedCmIdpSigninStatus, + raw_ref(features::kFedCmIdpSigninStatusEnabled), + kSetOnlyIfOverridden}, + {wf::EnableGamepadMultitouch, + raw_ref(features::kEnableGamepadMultitouch)}, + {wf::EnableSharedStorageAPI, + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {wf::EnableSharedStorageAPI, + raw_ref(features::kPrivacySandboxAdsAPIsM1Override)}, + {wf::EnableSharedStorageAPIM118, + raw_ref(blink::features::kSharedStorageAPIM118), kDefault}, + {wf::EnableSharedStorageAPIM125, + raw_ref(blink::features::kSharedStorageAPIM125), kDefault}, + {wf::EnableFedCmMultipleIdentityProviders, + raw_ref(features::kFedCmMultipleIdentityProviders), + kSetOnlyIfOverridden}, + {wf::EnableFedCmSelectiveDisclosure, + raw_ref(features::kFedCmSelectiveDisclosure), kDefault}, + {wf::EnableFencedFrames, + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {wf::EnableFencedFrames, + raw_ref(features::kPrivacySandboxAdsAPIsM1Override)}, + {wf::EnableForcedColors, raw_ref(features::kForcedColors)}, + {wf::EnableFractionalScrollOffsets, + raw_ref(features::kFractionalScrollOffsets)}, + {wf::EnableSensorExtraClasses, + raw_ref(features::kGenericSensorExtraClasses)}, +#if BUILDFLAG(IS_ANDROID) + {wf::EnableGetDisplayMedia, + raw_ref(features::kUserMediaScreenCapturing)}, +#endif + {wf::EnableInstalledApp, raw_ref(features::kInstalledApp)}, + {wf::EnableLazyInitializeMediaControls, + raw_ref(features::kLazyInitializeMediaControls)}, +#if BUILDFLAG(IS_CHROMEOS) + {wf::EnableLockedMode, raw_ref(blink::features::kLockedMode)}, +#endif + {wf::EnableMediaCastOverlayButton, + raw_ref(media::kMediaCastOverlayButton)}, + {wf::EnableMediaEngagementBypassAutoplayPolicies, + raw_ref(media::kMediaEngagementBypassAutoplayPolicies)}, + {wf::EnableNotificationContentImage, + raw_ref(features::kNotificationContentImage), kSetOnlyIfOverridden}, + {wf::EnablePaymentApp, raw_ref(features::kServiceWorkerPaymentApps)}, + {wf::EnablePaymentRequest, raw_ref(features::kWebPayments)}, + {wf::EnablePercentBasedScrolling, + raw_ref(features::kWindowsScrollingPersonality)}, + {wf::EnablePeriodicBackgroundSync, + raw_ref(features::kPeriodicBackgroundSync)}, + {wf::EnablePushMessagingSubscriptionChange, + raw_ref(features::kPushSubscriptionChangeEvent)}, + {wf::EnableRestrictGamepadAccess, + raw_ref(features::kRestrictGamepadAccess)}, + {wf::EnableSecurePaymentConfirmation, + raw_ref(features::kSecurePaymentConfirmation)}, + {wf::EnableSecurePaymentConfirmationDebug, + raw_ref(features::kSecurePaymentConfirmationDebug)}, + {wf::EnableSendBeaconThrowForBlobWithNonSimpleType, + raw_ref(features::kSendBeaconThrowForBlobWithNonSimpleType)}, + {wf::EnableSharedArrayBuffer, raw_ref(features::kSharedArrayBuffer)}, + {wf::EnableSharedArrayBufferOnDesktop, + raw_ref(features::kSharedArrayBufferOnDesktop)}, +#if BUILDFLAG(IS_ANDROID) + {wf::EnableSmartZoom, raw_ref(features::kSmartZoom)}, +#endif + {wf::EnableTouchDragAndContextMenu, + raw_ref(features::kTouchDragAndContextMenu)}, + {wf::EnableUserActivationSameOriginVisibility, + raw_ref(features::kUserActivationSameOriginVisibility)}, + {wf::EnableWebBluetooth, raw_ref(features::kWebBluetooth), + kSetOnlyIfOverridden}, + {wf::EnableWebBluetoothGetDevices, + raw_ref(features::kWebBluetoothNewPermissionsBackend), + kSetOnlyIfOverridden}, + {wf::EnableWebBluetoothWatchAdvertisements, + raw_ref(features::kWebBluetoothNewPermissionsBackend), + kSetOnlyIfOverridden}, +#if BUILDFLAG(IS_ANDROID) + {wf::EnableWebNFC, raw_ref(features::kWebNfc), kSetOnlyIfOverridden}, +#endif + {wf::EnableWebIdentityDigitalCredentials, + raw_ref(features::kWebIdentityDigitalCredentials), + kSetOnlyIfOverridden}, + {wf::EnableWebOTP, raw_ref(features::kWebOTP), kSetOnlyIfOverridden}, + {wf::EnableWebOTPAssertionFeaturePolicy, + raw_ref(features::kWebOTPAssertionFeaturePolicy), + kSetOnlyIfOverridden}, + {wf::EnableWebUSB, raw_ref(features::kWebUsb)}, + {wf::EnableWebXR, raw_ref(features::kWebXr)}, +#if BUILDFLAG(ENABLE_VR) + {wf::EnableWebXRFrontFacing, + raw_ref(device::features::kWebXrIncubations)}, + {wf::EnableWebXRFrameRate, + raw_ref(device::features::kWebXrIncubations)}, + {wf::EnableWebXRHandInput, + raw_ref(device::features::kWebXrHandInput)}, + {wf::EnableWebXRImageTracking, + raw_ref(device::features::kWebXrIncubations)}, + {wf::EnableWebXRLayers, raw_ref(device::features::kWebXrLayers)}, + {wf::EnableWebXRPlaneDetection, + raw_ref(device::features::kWebXrIncubations)}, + {wf::EnableWebXRPoseMotionData, + raw_ref(device::features::kWebXrIncubations)}, + {wf::EnableWebXRSpecParity, + raw_ref(device::features::kWebXrIncubations)}, +#endif + {wf::EnableRemoveMobileViewportDoubleTap, + raw_ref(features::kRemoveMobileViewportDoubleTap)}, + {wf::EnableServiceWorkerStaticRouter, + raw_ref(features::kServiceWorkerStaticRouter)}, + {wf::EnablePermissions, raw_ref(features::kWebPermissionsApi), + kSetOnlyIfOverridden}, + }; + for (const auto& mapping : blinkFeatureToBaseFeatureMapping) { + SetRuntimeFeatureFromChromiumFeature( + *mapping.chromium_feature, mapping.option, mapping.feature_enabler); + } + + // TODO(crbug.com/40571563): Cleanup the inconsistency between custom WRF + // enabler function and using feature string name with + // EnableFeatureFromString. + const RuntimeFeatureToChromiumFeatureMap + runtimeFeatureNameToChromiumFeatureMapping[] = { + {"AllowContentInitiatedDataUrlNavigations", + raw_ref(features::kAllowContentInitiatedDataUrlNavigations)}, + {"AllowURNsInIframes", raw_ref(blink::features::kAllowURNsInIframes)}, + {"AllowURNsInIframes", + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"AllowURNsInIframes", + raw_ref(features::kPrivacySandboxAdsAPIsM1Override)}, + {"AttributionReporting", + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"AttributionReporting", + raw_ref(features::kPrivacySandboxAdsAPIsM1Override)}, + {"AttributionReportingCrossAppWeb", + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"AndroidDownloadableFontsMatching", + raw_ref(features::kAndroidDownloadableFontsMatching)}, +#if BUILDFLAG(IS_ANDROID) + {"CCTNewRFMPushBehavior", + raw_ref(blink::features::kCCTNewRFMPushBehavior)}, +#endif + {"CompressionDictionaryTransport", + raw_ref(network::features::kCompressionDictionaryTransport)}, + {"CompressionDictionaryTransportBackend", + raw_ref(network::features::kCompressionDictionaryTransportBackend)}, + {"CookieDeprecationFacilitatedTesting", + raw_ref(features::kCookieDeprecationFacilitatedTesting)}, + {"Database", raw_ref(blink::features::kWebSQLAccess), + kSetOnlyIfOverridden}, + {"DocumentPolicyIncludeJSCallStacksInCrashReports", + raw_ref(blink::features:: + kDocumentPolicyIncludeJSCallStacksInCrashReports), + kSetOnlyIfOverridden}, + {"FencedFramesLocalUnpartitionedDataAccess", + raw_ref(blink::features::kFencedFramesLocalUnpartitionedDataAccess)}, + {"Fledge", raw_ref(blink::features::kFledge)}, + {"Fledge", raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"Fledge", raw_ref(features::kPrivacySandboxAdsAPIsM1Override), + kSetOnlyIfOverridden}, + {"FontationsFontBackend", + raw_ref(blink::features::kFontationsFontBackend)}, + {"FontSrcLocalMatching", raw_ref(features::kFontSrcLocalMatching)}, + {"LegacyWindowsDWriteFontFallback", + raw_ref(features::kLegacyWindowsDWriteFontFallback)}, + {"MachineLearningNeuralNetwork", + raw_ref(webnn::mojom::features::kWebMachineLearningNeuralNetwork)}, + {"OriginIsolationHeader", raw_ref(features::kOriginIsolationHeader)}, + {"ReduceAcceptLanguage", + raw_ref(network::features::kReduceAcceptLanguage)}, + {"SerialPortConnected", raw_ref(features::kSerialPortConnected)}, + {"TopicsAPI", raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"TopicsAPI", raw_ref(features::kPrivacySandboxAdsAPIsM1Override)}, + {"TopicsDocumentAPI", + raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"TopicsDocumentAPI", + raw_ref(features::kPrivacySandboxAdsAPIsM1Override)}, + {"TouchTextEditingRedesign", + raw_ref(features::kTouchTextEditingRedesign)}, + {"TrustedTypesFromLiteral", + raw_ref(features::kTrustedTypesFromLiteral)}, + {"WebSerialBluetooth", + raw_ref(features::kEnableBluetoothSerialPortProfileInSerialApi)}, + {"MediaStreamTrackTransfer", + raw_ref(features::kMediaStreamTrackTransfer)}, + {"PrivateNetworkAccessPermissionPrompt", + raw_ref(network::features::kPrivateNetworkAccessPermissionPrompt), + kSetOnlyIfOverridden}}; + for (const auto& mapping : runtimeFeatureNameToChromiumFeatureMapping) { + SetRuntimeFeatureFromChromiumFeature( + *mapping.chromium_feature, mapping.option, [&mapping](bool enabled) { + wf::EnableFeatureFromString(mapping.feature_enabler, enabled); + }); + } + + WebRuntimeFeatures::UpdateStatusFromBaseFeatures(); +} + +// Helper class that describes the desired enable/disable action +// for a runtime feature when a command line switch exists. +struct SwitchToFeatureMap { + // The enabler function defined in web_runtime_features.cc. + void (*feature_enabler)(bool); + // The switch to check for on command line. + const char* switch_name; + // This is the desired state for the runtime feature if the + // switch exists on command line. + bool target_enabled_state; +}; + +// Sets blink runtime features controlled by command line switches. +void SetRuntimeFeaturesFromCommandLine(const base::CommandLine& command_line) { + // To add a new switch-controlled runtime feature, add a new + // SwitchToFeatureMap entry to the initializer list below. + // Note: command line switches are now discouraged, please consider + // using base::Feature instead. + // https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/configuration.md#switches + using wrf = WebRuntimeFeatures; + const SwitchToFeatureMap switchToFeatureMapping[] = { + // Stable Features + {wrf::EnablePresentation, switches::kDisablePresentationAPI, false}, + {wrf::EnableRemotePlayback, switches::kDisableRemotePlaybackAPI, false}, + {wrf::EnableTimerThrottlingForBackgroundTabs, + switches::kDisableBackgroundTimerThrottling, false}, + // End of Stable Features + {wrf::EnableAutomationControlled, switches::kEnableAutomation, true}, + {wrf::EnableAutomationControlled, switches::kHeadless, true}, + {wrf::EnableAutomationControlled, switches::kRemoteDebuggingPipe, true}, + {wrf::EnableDatabase, switches::kDisableDatabases, false}, + {wrf::EnableFileSystem, switches::kDisableFileSystem, false}, + {wrf::EnableNetInfoDownlinkMax, + switches::kEnableNetworkInformationDownlinkMax, true}, + {wrf::EnableNotifications, switches::kDisableNotifications, false}, + {wrf::EnablePreciseMemoryInfo, switches::kEnablePreciseMemoryInfo, true}, + // Chrome's Push Messaging implementation relies on Web Notifications. + {wrf::EnablePushMessaging, switches::kDisableNotifications, false}, + {wrf::EnableScriptedSpeechRecognition, switches::kDisableSpeechAPI, + false}, + {wrf::EnableScriptedSpeechSynthesis, switches::kDisableSpeechAPI, false}, + {wrf::EnableScriptedSpeechSynthesis, switches::kDisableSpeechSynthesisAPI, + false}, + {wrf::EnableSharedWorker, switches::kDisableSharedWorkers, false}, + {wrf::EnableMutationEvents, blink::switches::kMutationEventsEnabled, + true}, + {wrf::EnableKeyboardFocusableScrollers, + blink::switches::kKeyboardFocusableScrollersEnabled, true}, + {wrf::EnableKeyboardFocusableScrollers, + blink::switches::kKeyboardFocusableScrollersOptOut, false}, + {wrf::EnableStandardizedBrowserZoom, + blink::switches::kDisableStandardizedBrowserZoom, false}, + {wrf::EnableCSSCustomStateDeprecatedSyntax, + blink::switches::kCSSCustomStateDeprecatedSyntaxEnabled, true}, + {wrf::EnableTextFragmentIdentifiers, + switches::kDisableScrollToTextFragment, false}, + {wrf::EnableWebAuthenticationRemoteDesktopSupport, + switches::kWebAuthRemoteDesktopSupport, true}, + {wrf::EnableWebGLDeveloperExtensions, + switches::kEnableWebGLDeveloperExtensions, true}, + {wrf::EnableWebGLDraftExtensions, switches::kEnableWebGLDraftExtensions, + true}, + {wrf::EnableWebGPUDeveloperFeatures, + switches::kEnableWebGPUDeveloperFeatures, true}, + {wrf::EnableWebGPUExperimentalFeatures, switches::kEnableUnsafeWebGPU, + true}, + }; + + for (const auto& mapping : switchToFeatureMapping) { + if (command_line.HasSwitch(mapping.switch_name)) { + mapping.feature_enabler(mapping.target_enabled_state); + } + } + + // Set EnableAutomationControlled if the caller passes + // --remote-debugging-port=0 on the command line. This means + // the caller has requested an ephemeral port which is how ChromeDriver + // launches the browser by default. + // If the caller provides a specific port number, this is + // more likely for attaching a debugger, so we should leave + // EnableAutomationControlled unset to ensure the browser behaves as it does + // when not under automation control. + if (command_line.HasSwitch(switches::kRemoteDebuggingPort)) { + std::string port_str = + command_line.GetSwitchValueASCII(::switches::kRemoteDebuggingPort); + int port; + if (base::StringToInt(port_str, &port) && port == 0) { + WebRuntimeFeatures::EnableAutomationControlled(true); + } + } + + // Enable or disable BeforeunloadEventCancelByPreventDefault for Enterprise + // Policy. This overrides any existing settings via base::Feature. + if (command_line.HasSwitch( + blink::switches::kBeforeunloadEventCancelByPreventDefaultPolicy)) { + const std::string value = command_line.GetSwitchValueASCII( + blink::switches::kBeforeunloadEventCancelByPreventDefaultPolicy); + if (value == + blink::switches:: + kBeforeunloadEventCancelByPreventDefaultPolicy_ForceEnable) { + WebRuntimeFeatures::EnableBeforeunloadEventCancelByPreventDefault(true); + } + if (value == + blink::switches:: + kBeforeunloadEventCancelByPreventDefaultPolicy_ForceDisable) { + WebRuntimeFeatures::EnableBeforeunloadEventCancelByPreventDefault(false); + } + } +} + +// Sets blink runtime features that depend on a combination +// of args rather than a single check of base::Feature or switch. +// This can be a combination of both or custom checking logic +// not covered by other functions. In short, this should be used +// as a last resort. +void SetCustomizedRuntimeFeaturesFromCombinedArgs( + const base::CommandLine& command_line) { + // CAUTION: Only add custom enabling logic here if it cannot + // be covered by the other functions. + + // These checks are custom wrappers around base::FeatureList::IsEnabled + // They're moved here to distinguish them from actual base checks + WebRuntimeFeatures::EnableOverlayScrollbars(ui::IsOverlayScrollbarEnabled()); + WebRuntimeFeatures::EnableFluentScrollbars(ui::IsFluentScrollbarEnabled()); + WebRuntimeFeatures::EnableFluentOverlayScrollbars( + ui::IsFluentOverlayScrollbarEnabled()); + + // TODO(rodneyding): This is a rare case for a stable feature + // Need to investigate more to determine whether to refactor it. + if (command_line.HasSwitch(switches::kDisableV8IdleTasks)) { + WebRuntimeFeatures::EnableV8IdleTasks(false); + } else { + WebRuntimeFeatures::EnableV8IdleTasks(true); + } + + WebRuntimeFeatures::EnableBackForwardCache( + content::IsBackForwardCacheEnabled()); + + if (base::FeatureList::IsEnabled(network::features::kPrivateStateTokens)) { + WebRuntimeFeatures::EnablePrivateStateTokens(true); + WebRuntimeFeatures::EnablePrivateStateTokensAlwaysAllowIssuance(true); + } else if (base::FeatureList::IsEnabled(network::features::kFledgePst)) { + // See https://bit.ly/configuring-trust-tokens. + using network::features::TrustTokenOriginTrialSpec; + switch ( + network::features::kTrustTokenOperationsRequiringOriginTrial.Get()) { + case TrustTokenOriginTrialSpec::kOriginTrialNotRequired: + // Setting PrivateStateTokens=true enables the Trust Tokens interface; + // PrivateStateTokensAlwaysAllowIssuance disables a runtime check + // during issuance that the origin trial is active (see + // blink/.../trust_token_issuance_authorization.h). + WebRuntimeFeatures::EnablePrivateStateTokens(true); + WebRuntimeFeatures::EnablePrivateStateTokensAlwaysAllowIssuance(true); + break; + case TrustTokenOriginTrialSpec::kAllOperationsRequireOriginTrial: + // The origin trial itself will be responsible for enabling the + // PrivateStateTokens RuntimeEnabledFeature. + WebRuntimeFeatures::EnablePrivateStateTokens(false); + WebRuntimeFeatures::EnablePrivateStateTokensAlwaysAllowIssuance(false); + break; + case TrustTokenOriginTrialSpec::kOnlyIssuanceRequiresOriginTrial: + // At issuance, a runtime check will be responsible for checking that + // the origin trial is present. + WebRuntimeFeatures::EnablePrivateStateTokens(true); + WebRuntimeFeatures::EnablePrivateStateTokensAlwaysAllowIssuance(false); + break; + } + } +} + +// Ensures that the various ways of enabling/disabling features do not produce +// an invalid configuration. +void ResolveInvalidConfigurations() { + // Fenced frames cannot be enabled without the support of the + // browser process. + if ((base::FeatureList::IsEnabled(features::kPrivacySandboxAdsAPIsOverride) || + base::FeatureList::IsEnabled( + features::kPrivacySandboxAdsAPIsM1Override)) && + !base::FeatureList::IsEnabled(blink::features::kFencedFrames)) { + LOG_IF(WARNING, WebRuntimeFeatures::IsFencedFramesEnabled()) + << "Fenced frames cannot be enabled in this configuration. Use --" + << switches::kEnableFeatures << "=" + << blink::features::kFencedFrames.name << " instead."; + WebRuntimeFeatures::EnableFencedFrames(false); + } + + if (!base::FeatureList::IsEnabled(blink::features::kFencedFrames) && + base::FeatureList::IsEnabled( + blink::features::kFencedFramesLocalUnpartitionedDataAccess)) { + LOG_IF( + WARNING, + WebRuntimeFeatures::IsFencedFramesLocalUnpartitionedDataAccessEnabled()) + << "Fenced frames must be enabled in order to enable local " + "unpartitioned " + << "data access. Use --" << switches::kEnableFeatures << "=" + << blink::features::kFencedFrames.name << " in addition."; + WebRuntimeFeatures::EnableFeatureFromString( + "FencedFramesLocalUnpartitionedDataAccess", false); + } + + // Topics API cannot be enabled without the support of the browser process. + // The Document API should be additionally gated by the + // `kBrowsingTopicsDocumentAPI` feature. + if (!base::FeatureList::IsEnabled(blink::features::kBrowsingTopics)) { + LOG_IF(WARNING, WebRuntimeFeatures::IsTopicsAPIEnabled()) + << "Topics cannot be enabled in this configuration. Use --" + << switches::kEnableFeatures << "=" + << blink::features::kBrowsingTopics.name << " in addition."; + WebRuntimeFeatures::EnableTopicsAPI(false); + WebRuntimeFeatures::EnableTopicsDocumentAPI(false); + } else { + if (!base::FeatureList::IsEnabled( + blink::features::kBrowsingTopicsDocumentAPI)) { + LOG_IF(WARNING, WebRuntimeFeatures::IsTopicsDocumentAPIEnabled()) + << "Topics Document API cannot be enabled in this configuration. Use " + "--" + << switches::kEnableFeatures << "=" + << blink::features::kBrowsingTopicsDocumentAPI.name + << " in addition."; + WebRuntimeFeatures::EnableTopicsDocumentAPI(false); + } + } + + if (!base::FeatureList::IsEnabled(blink::features::kSharedStorageAPI)) { + LOG_IF(WARNING, WebRuntimeFeatures::IsSharedStorageAPIEnabled()) + << "SharedStorage cannot be enabled in this " + "configuration. Use --" + << switches::kEnableFeatures << "=" + << blink::features::kSharedStorageAPI.name << " in addition."; + WebRuntimeFeatures::EnableSharedStorageAPI(false); + } + + if (!base::FeatureList::IsEnabled(blink::features::kSharedStorageAPIM118) || + !base::FeatureList::IsEnabled(blink::features::kSharedStorageAPI)) { + LOG_IF(WARNING, WebRuntimeFeatures::IsSharedStorageAPIM118Enabled()) + << "SharedStorage for M118+ cannot be enabled in this " + "configuration. Use --" + << switches::kEnableFeatures << "=" + << blink::features::kSharedStorageAPI.name << "," + << blink::features::kSharedStorageAPIM118.name << " in addition."; + WebRuntimeFeatures::EnableSharedStorageAPIM118(false); + } + + if (!base::FeatureList::IsEnabled(blink::features::kSharedStorageAPIM125) || + !base::FeatureList::IsEnabled(blink::features::kSharedStorageAPI)) { + LOG_IF(WARNING, WebRuntimeFeatures::IsSharedStorageAPIM125Enabled()) + << "SharedStorage for M125+ cannot be enabled in this " + "configuration. Use --" + << switches::kEnableFeatures << "=" + << blink::features::kSharedStorageAPI.name << "," + << blink::features::kSharedStorageAPIM125.name << " in addition."; + WebRuntimeFeatures::EnableSharedStorageAPIM125(false); + } + + if (!base::FeatureList::IsEnabled( + attribution_reporting::features::kConversionMeasurement)) { + LOG_IF(WARNING, WebRuntimeFeatures::IsAttributionReportingEnabled()) + << "AttributionReporting cannot be enabled in this " + "configuration. Use --" + << switches::kEnableFeatures << "=" + << attribution_reporting::features::kConversionMeasurement.name + << " in addition."; + WebRuntimeFeatures::EnableAttributionReporting(false); + } + + if (!base::FeatureList::IsEnabled( + attribution_reporting::features::kConversionMeasurement) || + !base::FeatureList::IsEnabled( + network::features::kAttributionReportingCrossAppWeb)) { + LOG_IF(WARNING, + WebRuntimeFeatures::IsAttributionReportingCrossAppWebEnabled()) + << "AttributionReportingCrossAppWeb cannot be enabled in this " + "configuration. Use --" + << switches::kEnableFeatures << "=" + << attribution_reporting::features::kConversionMeasurement.name << "," + << network::features::kAttributionReportingCrossAppWeb.name + << " in addition."; + WebRuntimeFeatures::EnableAttributionReportingCrossAppWeb(false); + } + + if (!base::FeatureList::IsEnabled(blink::features::kInterestGroupStorage)) { + LOG_IF(WARNING, WebRuntimeFeatures::IsAdInterestGroupAPIEnabled()) + << "AdInterestGroupAPI cannot be enabled in this " + "configuration. Use --" + << switches::kEnableFeatures << "=" + << blink::features::kInterestGroupStorage.name << " in addition."; + WebRuntimeFeatures::EnableAdInterestGroupAPI(false); + WebRuntimeFeatures::EnableFledge(false); + } + + if (base::FeatureList::IsEnabled( + features::kCookieDeprecationFacilitatedTesting)) { + WebRuntimeFeatures::EnableFledgeMultiBid(false); + WebRuntimeFeatures::EnableFledgeRealTimeReporting(false); + + if (!base::FeatureList::IsEnabled( + blink::features:: + kAlwaysAllowFledgeDeprecatedRenderURLReplacements)) { + WebRuntimeFeatures::EnableFledgeDeprecatedRenderURLReplacements(false); + } + } + + // PermissionElement cannot be enabled without the support of the + // browser process. + if (!base::FeatureList::IsEnabled(blink::features::kPermissionElement)) { + LOG_IF(WARNING, WebRuntimeFeatures::IsPermissionElementEnabled()) + << "PermissionElement cannot be enabled in this configuration. Use --" + << switches::kEnableFeatures << "=" + << blink::features::kPermissionElement.name << " instead."; + WebRuntimeFeatures::EnablePermissionElement(false); + } +} + +} // namespace + +namespace content { + +void SetRuntimeFeaturesDefaultsAndUpdateFromArgs( + const base::CommandLine& command_line) { + // Sets experimental features. + bool enable_experimental_web_platform_features = + command_line.HasSwitch(switches::kEnableExperimentalWebPlatformFeatures); + bool enable_blink_test_features = + command_line.HasSwitch(switches::kEnableBlinkTestFeatures); + + if (enable_blink_test_features) { + enable_experimental_web_platform_features = true; + WebRuntimeFeatures::EnableTestOnlyFeatures(true); + } + + if (enable_experimental_web_platform_features) { + WebRuntimeFeatures::EnableExperimentalFeatures(true); + } + + SetRuntimeFeatureDefaultsForPlatform(command_line); + + // Sets origin trial features. + if (command_line.HasSwitch( + switches::kDisableOriginTrialControlledBlinkFeatures)) { + WebRuntimeFeatures::EnableOriginTrialControlledFeatures(false); + } + + // TODO(rodneyding): add doc explaining ways to add new runtime features + // controls in the following functions. + + SetRuntimeFeaturesFromChromiumFeatures(); + + SetRuntimeFeaturesFromCommandLine(command_line); + + SetCustomizedRuntimeFeaturesFromCombinedArgs(command_line); + + // Enable explicitly enabled features, and then disable explicitly disabled + // ones. + for (const std::string& feature : + FeaturesFromSwitch(command_line, switches::kEnableBlinkFeatures)) { + WebRuntimeFeatures::EnableFeatureFromString(feature, true); + } + for (const std::string& feature : + FeaturesFromSwitch(command_line, switches::kDisableBlinkFeatures)) { + WebRuntimeFeatures::EnableFeatureFromString(feature, false); + } + + ResolveInvalidConfigurations(); +} + +} // namespace content diff --git a/tools/under-control/src/content/public/browser/content_browser_client.cc b/tools/under-control/src/content/public/browser/content_browser_client.cc new file mode 100755 index 000000000..dc4110d88 --- /dev/null +++ b/tools/under-control/src/content/public/browser/content_browser_client.cc @@ -0,0 +1,1769 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/public/browser/content_browser_client.h" + +#include +#include +#include + +#include "base/check.h" +#include "base/feature_list.h" +#include "base/files/file_path.h" +#include "base/functional/callback_helpers.h" +#include "base/no_destructor.h" +#include "base/notreached.h" +#include "base/task/sequenced_task_runner.h" +#include "base/task/thread_pool/thread_pool_instance.h" +#include "base/values.h" +#include "build/build_config.h" +#include "build/buildflag.h" +#include "build/chromeos_buildflags.h" +#include "content/browser/ai/echo_ai_manager_impl.h" +#include "content/public/browser/anchor_element_preconnect_delegate.h" +#include "content/public/browser/authenticator_request_client_delegate.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_main_parts.h" +#include "content/public/browser/client_certificate_delegate.h" +#include "content/public/browser/devtools_manager_delegate.h" +#include "content/public/browser/digital_identity_provider.h" +#include "content/public/browser/dips_delegate.h" +#include "content/public/browser/identity_request_dialog_controller.h" +#include "content/public/browser/legacy_tech_cookie_issue_details.h" +#include "content/public/browser/login_delegate.h" +#include "content/public/browser/navigation_throttle.h" +#include "content/public/browser/navigation_ui_data.h" +#include "content/public/browser/network_service_instance.h" +#include "content/public/browser/overlay_window.h" +#include "content/public/browser/page_navigator.h" +#include "content/public/browser/prefetch_service_delegate.h" +#include "content/public/browser/prerender_web_contents_delegate.h" +#include "content/public/browser/private_network_device_delegate.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/browser/responsiveness_calculator_delegate.h" +#include "content/public/browser/sms_fetcher.h" +#include "content/public/browser/speculation_host_delegate.h" +#include "content/public/browser/tracing_delegate.h" +#include "content/public/browser/url_loader_request_interceptor.h" +#include "content/public/browser/vpn_service_proxy.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_view_delegate.h" +#include "content/public/common/alternative_error_page_override_info.mojom.h" +#include "content/public/common/content_features.h" +#include "content/public/common/url_utils.h" +#include "media/audio/audio_manager.h" +#include "media/capture/content/screen_enumerator.h" +#include "media/mojo/mojom/media_service.mojom.h" +#include "mojo/public/cpp/bindings/message.h" +#include "net/base/isolation_info.h" +#include "net/cookies/site_for_cookies.h" +#include "net/ssl/client_cert_identity.h" +#include "net/ssl/client_cert_store.h" +#include "sandbox/policy/features.h" +#include "sandbox/policy/mojom/sandbox.mojom.h" +#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h" +#include "services/device/public/cpp/geolocation/location_provider.h" +#include "services/metrics/public/cpp/ukm_source_id.h" +#include "services/network/public/cpp/features.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/network/public/mojom/network_service.mojom.h" +#include "services/network/public/mojom/web_transport.mojom.h" +#include "storage/browser/quota/quota_manager.h" +#include "third_party/blink/public/common/features.h" +#include "third_party/blink/public/common/loader/url_loader_throttle.h" +#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h" +#include "third_party/blink/public/common/user_agent/user_agent_metadata.h" +#include "third_party/blink/public/mojom/browsing_topics/browsing_topics.mojom.h" +#include "third_party/blink/public/mojom/file_system_access/file_system_access_cloud_identifier.mojom.h" +#include "third_party/blink/public/mojom/file_system_access/file_system_access_error.mojom.h" +#include "third_party/blink/public/mojom/origin_trials/origin_trials_settings.mojom.h" +#include "third_party/blink/public/mojom/payments/payment_credential.mojom.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/shell_dialogs/select_file_policy.h" +#include "url/gurl.h" +#include "url/origin.h" + +#if BUILDFLAG(IS_ANDROID) +#include "content/public/browser/tts_environment_android.h" +#else +#include "services/video_effects/public/mojom/video_effects_processor.mojom-forward.h" +#include "third_party/blink/public/mojom/installedapp/related_application.mojom.h" +#endif + +using AttributionReportType = + content::ContentBrowserClient::AttributionReportingOsRegistrar; + +namespace content { + +std::unique_ptr ContentBrowserClient::CreateBrowserMainParts( + bool /* is_integration_test */) { + return nullptr; +} + +void ContentBrowserClient::PostAfterStartupTask( + const base::Location& from_here, + const scoped_refptr& task_runner, + base::OnceClosure task) { + task_runner->PostTask(from_here, std::move(task)); +} + +bool ContentBrowserClient::IsBrowserStartupComplete() { + return true; +} + +void ContentBrowserClient::SetBrowserStartupIsCompleteForTesting() {} + +std::unique_ptr +ContentBrowserClient::GetWebContentsViewDelegate(WebContents* web_contents) { + return nullptr; +} + +bool ContentBrowserClient::IsShuttingDown() { + return false; +} + +void ContentBrowserClient::ThreadPoolWillTerminate() {} + +bool ContentBrowserClient::AllowGpuLaunchRetryOnIOThread() { + return true; +} + +bool ContentBrowserClient::CanShutdownGpuProcessNowOnIOThread() { + return false; +} + +GURL ContentBrowserClient::GetEffectiveURL(BrowserContext* browser_context, + const GURL& url) { + DCHECK(browser_context); + return url; +} + +bool ContentBrowserClient::ShouldCompareEffectiveURLsForSiteInstanceSelection( + BrowserContext* browser_context, + content::SiteInstance* candidate_site_instance, + bool is_outermost_main_frame, + const GURL& candidate_url, + const GURL& destination_url) { + DCHECK(browser_context); + return true; +} + +bool ContentBrowserClient::IsExplicitNavigation(ui::PageTransition transition) { + return transition & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR; +} + +bool ContentBrowserClient::ShouldUseProcessPerSite( + BrowserContext* browser_context, + const GURL& site_url) { + DCHECK(browser_context); + return false; +} + +bool ContentBrowserClient::ShouldAllowProcessPerSiteForMultipleMainFrames( + BrowserContext* context) { + return true; +} + +std::optional +ContentBrowserClient::ShouldUseSpareRenderProcessHost( + BrowserContext* browser_context, + const GURL& site_url) { + return std::nullopt; +} + +bool ContentBrowserClient::DoesSiteRequireDedicatedProcess( + BrowserContext* browser_context, + const GURL& effective_site_url) { + DCHECK(browser_context); + return false; +} + +bool ContentBrowserClient::ShouldAllowCrossProcessSandboxedFrameForPrecursor( + BrowserContext* browser_context, + const GURL& precursor, + const GURL& url) { + DCHECK(browser_context); + return true; +} + +bool ContentBrowserClient::ShouldLockProcessToSite( + BrowserContext* browser_context, + const GURL& effective_url) { + DCHECK(browser_context); + return true; +} + +bool ContentBrowserClient::ShouldEnforceNewCanCommitUrlChecks() { + return true; +} + +bool ContentBrowserClient::DoesWebUIUrlRequireProcessLock(const GURL& url) { + return true; +} + +bool ContentBrowserClient::ShouldTreatURLSchemeAsFirstPartyWhenTopLevel( + std::string_view scheme, + bool is_embedded_origin_secure) { + return false; +} + +bool ContentBrowserClient::ShouldIgnoreSameSiteCookieRestrictionsWhenTopLevel( + std::string_view scheme, + bool is_embedded_origin_secure) { + return false; +} + +std::string ContentBrowserClient::GetSiteDisplayNameForCdmProcess( + BrowserContext* browser_context, + const GURL& site_url) { + return site_url.spec(); +} + +void ContentBrowserClient::OverrideURLLoaderFactoryParams( + BrowserContext* browser_context, + const url::Origin& origin, + bool is_for_isolated_world, + network::mojom::URLLoaderFactoryParams* factory_params) {} + +void ContentBrowserClient::GetAdditionalViewSourceSchemes( + std::vector* additional_schemes) { + GetAdditionalWebUISchemes(additional_schemes); +} + +network::mojom::IPAddressSpace +ContentBrowserClient::DetermineAddressSpaceFromURL(const GURL& url) { + return network::mojom::IPAddressSpace::kUnknown; +} + +bool ContentBrowserClient::LogWebUIUrl(const GURL& web_ui_url) { + return false; +} + +bool ContentBrowserClient::IsWebUIAllowedToMakeNetworkRequests( + const url::Origin& origin) { + return false; +} + +bool ContentBrowserClient::IsHandledURL(const GURL& url) { + return false; +} + +bool ContentBrowserClient::HasCustomSchemeHandler( + content::BrowserContext* browser_context, + const std::string& scheme) { + return false; +} + +bool ContentBrowserClient::CanCommitURL(RenderProcessHost* process_host, + const GURL& site_url) { + return true; +} + +bool ContentBrowserClient::ShouldStayInParentProcessForNTP( + const GURL& url, + const GURL& parent_site_url) { + return false; +} + +bool ContentBrowserClient::IsSuitableHost(RenderProcessHost* process_host, + const GURL& site_url) { + return true; +} + +bool ContentBrowserClient::MayReuseHost(RenderProcessHost* process_host) { + return true; +} + +size_t ContentBrowserClient::GetProcessCountToIgnoreForLimit() { + return 0; +} + +std::optional +ContentBrowserClient::GetPermissionsPolicyForIsolatedWebApp( + WebContents* web_contents, + const url::Origin& app_origin) { + return blink::ParsedPermissionsPolicy(); +} + +bool ContentBrowserClient::ShouldTryToUseExistingProcessHost( + BrowserContext* browser_context, + const GURL& url) { + DCHECK(browser_context); + return false; +} + +bool ContentBrowserClient::ShouldEmbeddedFramesTryToReuseExistingProcess( + RenderFrameHost* outermost_main_frame) { + return true; +} + +bool ContentBrowserClient::ShouldAllowNoLongerUsedProcessToExit() { + return true; +} + +bool ContentBrowserClient::ShouldSwapBrowsingInstancesForNavigation( + SiteInstance* site_instance, + const GURL& current_effective_url, + const GURL& destination_effective_url) { + return false; +} + +bool ContentBrowserClient::ShouldIsolateErrorPage(bool in_main_frame) { + return in_main_frame; +} + +std::unique_ptr ContentBrowserClient::CreateAudioManager( + media::AudioLogFactory* audio_log_factory) { + return nullptr; +} + +std::unique_ptr +ContentBrowserClient::CreateScreenEnumerator() const { + return nullptr; +} + +bool ContentBrowserClient::OverridesAudioManager() { + return false; +} + +bool ContentBrowserClient::EnforceSystemAudioEchoCancellation() { + return false; +} + +std::vector +ContentBrowserClient::GetOriginsRequiringDedicatedProcess() { + return std::vector(); +} + +bool ContentBrowserClient::ShouldEnableStrictSiteIsolation() { +#if BUILDFLAG(IS_ANDROID) + return false; +#else + return true; +#endif +} + +bool ContentBrowserClient::ShouldDisableSiteIsolation( + SiteIsolationMode site_isolation_mode) { + return false; +} + +std::vector +ContentBrowserClient::GetAdditionalSiteIsolationModes() { + return std::vector(); +} + +bool ContentBrowserClient::ShouldUrlUseApplicationIsolationLevel( + BrowserContext* browser_context, + const GURL& url) { + return false; +} + +bool ContentBrowserClient::IsIsolatedContextAllowedForUrl( + BrowserContext* browser_context, + const GURL& lock_url) { + return false; +} + +void ContentBrowserClient::CheckGetAllScreensMediaAllowed( + content::RenderFrameHost* render_frame_host, + base::OnceCallback callback) { + std::move(callback).Run(false); +} + +size_t ContentBrowserClient::GetMaxRendererProcessCountOverride() { + return 0u; +} + +bool ContentBrowserClient::IsFileAccessAllowed( + const base::FilePath& path, + const base::FilePath& absolute_path, + const base::FilePath& profile_path) { + return true; +} + +bool ContentBrowserClient::ForceSniffingFileUrlsForHtml() { + return false; +} + +std::string ContentBrowserClient::GetApplicationClientGUIDForQuarantineCheck() { + return std::string(); +} + +download::QuarantineConnectionCallback +ContentBrowserClient::GetQuarantineConnectionCallback() { + return base::NullCallback(); +} + +std::string ContentBrowserClient::GetApplicationLocale() { + return "en-US"; +} + +std::string ContentBrowserClient::GetAcceptLangs(BrowserContext* context) { + DCHECK(context); + return std::string(); +} + +gfx::ImageSkia ContentBrowserClient::GetDefaultFavicon() { + return gfx::ImageSkia(); +} + +base::FilePath ContentBrowserClient::GetLoggingFileName( + const base::CommandLine& command_line) { + return base::FilePath(); +} + +AllowServiceWorkerResult ContentBrowserClient::AllowServiceWorker( + const GURL& scope, + const net::SiteForCookies& site_for_cookies, + const std::optional& top_frame_origin, + const GURL& script_url, + BrowserContext* context) { + return AllowServiceWorkerResult::Yes(); +} + +bool ContentBrowserClient::MayDeleteServiceWorkerRegistration( + const GURL& scope, + BrowserContext* browser_context) { + return true; +} + +bool ContentBrowserClient::ShouldTryToUpdateServiceWorkerRegistration( + const GURL& scope, + BrowserContext* browser_context) { + return true; +} + +void ContentBrowserClient::UpdateEnabledBlinkRuntimeFeaturesInIsolatedWorker( + BrowserContext* context, + const GURL& script_url, + std::vector& out_forced_enabled_runtime_features) {} + +bool ContentBrowserClient::AllowSharedWorker( + const GURL& worker_url, + const net::SiteForCookies& site_for_cookies, + const std::optional& top_frame_origin, + const std::string& name, + const blink::StorageKey& storage_key, + const blink::mojom::SharedWorkerSameSiteCookies same_site_cookies, + BrowserContext* context, + int render_process_id, + int render_frame_id) { + DCHECK(context); + return true; +} + +bool ContentBrowserClient::DoesSchemeAllowCrossOriginSharedWorker( + const std::string& scheme) { + return false; +} + +bool ContentBrowserClient::AllowSignedExchange(BrowserContext* context) { + return true; +} + +bool ContentBrowserClient::AllowCompressionDictionaryTransport( + BrowserContext* context) { + return true; +} + +bool ContentBrowserClient::OverrideWebPreferencesAfterNavigation( + WebContents* web_contents, + blink::web_pref::WebPreferences* prefs) { + return false; +} + +bool ContentBrowserClient::IsDataSaverEnabled(BrowserContext* context) { + DCHECK(context); + return false; +} + +void ContentBrowserClient::UpdateRendererPreferencesForWorker( + BrowserContext* browser_context, + blink::RendererPreferences* out_prefs) { + // |browser_context| may be null (e.g. during shutdown of a service worker). +} + +void ContentBrowserClient::RequestFilesAccess( + const std::vector& files, + const GURL& destination_url, + base::OnceCallback + continuation_callback) { + std::move(continuation_callback) + .Run(file_access::ScopedFileAccess::Allowed()); +} + +void ContentBrowserClient::AllowWorkerFileSystem( + const GURL& url, + BrowserContext* browser_context, + const std::vector& render_frames, + base::OnceCallback callback) { + std::move(callback).Run(true); +} + +bool ContentBrowserClient::AllowWorkerIndexedDB( + const GURL& url, + BrowserContext* browser_context, + const std::vector& render_frames) { + return true; +} + +bool ContentBrowserClient::AllowWorkerCacheStorage( + const GURL& url, + BrowserContext* browser_context, + const std::vector& render_frames) { + return true; +} + +bool ContentBrowserClient::AllowWorkerWebLocks( + const GURL& url, + BrowserContext* browser_context, + const std::vector& render_frames) { + return true; +} + +ContentBrowserClient::AllowWebBluetoothResult +ContentBrowserClient::AllowWebBluetooth( + content::BrowserContext* browser_context, + const url::Origin& requesting_origin, + const url::Origin& embedding_origin) { + DCHECK(browser_context); + return AllowWebBluetoothResult::ALLOW; +} + +std::string ContentBrowserClient::GetWebBluetoothBlocklist() { + return std::string(); +} + +bool ContentBrowserClient::IsInterestGroupAPIAllowed( + content::RenderFrameHost* render_frame_host, + InterestGroupApiOperation operation, + const url::Origin& top_frame_origin, + const url::Origin& api_origin) { + return false; +} + +bool ContentBrowserClient::IsPrivacySandboxReportingDestinationAttested( + content::BrowserContext* browser_context, + const url::Origin& destination_origin, + content::PrivacySandboxInvokingAPI invoking_api, + bool post_impression_reporting) { + return false; +} + +void ContentBrowserClient::OnAuctionComplete( + RenderFrameHost* render_frame_host, + InterestGroupManager::InterestGroupDataKey data_key) {} + +network::mojom::AttributionSupport ContentBrowserClient::GetAttributionSupport( + AttributionReportingOsApiState state, + bool client_os_disabled) { + switch (state) { + case AttributionReportingOsApiState::kDisabled: + return network::mojom::AttributionSupport::kWeb; + case AttributionReportingOsApiState::kEnabled: + return client_os_disabled ? network::mojom::AttributionSupport::kWeb + : network::mojom::AttributionSupport::kWebAndOs; + } +} + +bool ContentBrowserClient::IsAttributionReportingOperationAllowed( + content::BrowserContext* browser_context, + AttributionReportingOperation operation, + content::RenderFrameHost* rfh, + const url::Origin* source_origin, + const url::Origin* destination_origin, + const url::Origin* reporting_origin, + bool* can_bypass) { + return true; +} + +ContentBrowserClient::AttributionReportingOsRegistrars +ContentBrowserClient::GetAttributionReportingOsRegistrars( + WebContents* web_contents) { + return {AttributionReportType::kWeb, AttributionReportType::kWeb}; +} + +bool ContentBrowserClient::IsAttributionReportingAllowedForContext( + content::BrowserContext* browser_context, + content::RenderFrameHost* rfh, + const url::Origin& context_origin, + const url::Origin& reporting_origin) { + return true; +} + +bool ContentBrowserClient::IsSharedStorageAllowed( + content::BrowserContext* browser_context, + content::RenderFrameHost* rfh, + const url::Origin& top_frame_origin, + const url::Origin& accessing_origin, + std::string* out_debug_message, + bool* out_block_is_site_setting_specific) { + return false; +} + +bool ContentBrowserClient::IsSharedStorageSelectURLAllowed( + content::BrowserContext* browser_context, + const url::Origin& top_frame_origin, + const url::Origin& accessing_origin, + std::string* out_debug_message, + bool* out_block_is_site_setting_specific) { + return false; +} + +bool ContentBrowserClient::IsPrivateAggregationAllowed( + content::BrowserContext* browser_context, + const url::Origin& top_frame_origin, + const url::Origin& reporting_origin, + bool* out_block_is_site_setting_specific) { + return true; +} + +bool ContentBrowserClient::IsPrivateAggregationDebugModeAllowed( + content::BrowserContext* browser_context, + const url::Origin& top_frame_origin, + const url::Origin& reporting_origin) { + return true; +} + +bool ContentBrowserClient::IsCookieDeprecationLabelAllowed( + content::BrowserContext* browser_context) { + return false; +} + +bool ContentBrowserClient::IsCookieDeprecationLabelAllowedForContext( + content::BrowserContext* browser_context, + const url::Origin& top_frame_origin, + const url::Origin& context_origin) { + return false; +} + +bool ContentBrowserClient::IsFullCookieAccessAllowed( + content::BrowserContext* browser_context, + content::WebContents* web_contents, + const GURL& url, + const blink::StorageKey& storage_key) { + return true; +} + +bool ContentBrowserClient::CanSendSCTAuditingReport( + BrowserContext* browser_context) { + return false; +} + +GeneratedCodeCacheSettings ContentBrowserClient::GetGeneratedCodeCacheSettings( + BrowserContext* context) { + // By default, code cache is disabled, embedders should override. + return GeneratedCodeCacheSettings(false, 0, base::FilePath()); +} + +std::string ContentBrowserClient::GetWebUIHostnameForCodeCacheMetrics( + const GURL& webui_url) const { + return std::string(); +} + +void ContentBrowserClient::AllowCertificateError( + WebContents* web_contents, + int cert_error, + const net::SSLInfo& ssl_info, + const GURL& request_url, + bool is_primary_main_frame_request, + bool strict_enforcement, + base::OnceCallback callback) { + std::move(callback).Run(CERTIFICATE_REQUEST_RESULT_TYPE_DENY); +} + +bool ContentBrowserClient::ShouldDenyRequestOnCertificateError( + const GURL main_frame_url) { + // Generally we shouldn't deny all certificate errors, but individual + // subclasses may override this for special cases. + return false; +} + +base::OnceClosure ContentBrowserClient::SelectClientCertificate( + BrowserContext* browser_context, + int process_id, + WebContents* web_contents, + net::SSLCertRequestInfo* cert_request_info, + net::ClientCertIdentityList client_certs, + std::unique_ptr delegate) { + return base::OnceClosure(); +} + +std::unique_ptr +ContentBrowserClient::OverrideSystemLocationProvider() { + return nullptr; +} + +scoped_refptr +ContentBrowserClient::GetSystemSharedURLLoaderFactory() { + return nullptr; +} + +network::mojom::NetworkContext* +ContentBrowserClient::GetSystemNetworkContext() { + return nullptr; +} + +std::string ContentBrowserClient::GetGeolocationApiKey() { + return std::string(); +} + +device::GeolocationSystemPermissionManager* +ContentBrowserClient::GetGeolocationSystemPermissionManager() { + return nullptr; +} + +#if BUILDFLAG(IS_ANDROID) +bool ContentBrowserClient::ShouldUseGmsCoreGeolocationProvider() { + return false; +} +#endif + +StoragePartitionConfig ContentBrowserClient::GetStoragePartitionConfigForSite( + BrowserContext* browser_context, + const GURL& site) { + DCHECK(browser_context); + + return StoragePartitionConfig::CreateDefault(browser_context); +} + +MediaObserver* ContentBrowserClient::GetMediaObserver() { + return nullptr; +} + +FeatureObserverClient* ContentBrowserClient::GetFeatureObserverClient() { + return nullptr; +} + +bool ContentBrowserClient::CanCreateWindow( + RenderFrameHost* opener, + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const url::Origin& source_origin, + content::mojom::WindowContainerType container_type, + const GURL& target_url, + const Referrer& referrer, + const std::string& frame_name, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + bool* no_javascript_access) { + *no_javascript_access = false; + return true; +} + +SpeechRecognitionManagerDelegate* +ContentBrowserClient::CreateSpeechRecognitionManagerDelegate() { + return nullptr; +} + +#if BUILDFLAG(IS_CHROMEOS_ASH) +TtsControllerDelegate* ContentBrowserClient::GetTtsControllerDelegate() { + return nullptr; +} +#endif + +TtsPlatform* ContentBrowserClient::GetTtsPlatform() { + return nullptr; +} + +#if !BUILDFLAG(IS_ANDROID) +DirectSocketsDelegate* ContentBrowserClient::GetDirectSocketsDelegate() { + return nullptr; +} +#endif + +base::FilePath ContentBrowserClient::GetDefaultDownloadDirectory() { + return base::FilePath(); +} + +std::string ContentBrowserClient::GetDefaultDownloadName() { + return std::string(); +} + +base::FilePath ContentBrowserClient::GetShaderDiskCacheDirectory() { + return base::FilePath(); +} + +base::FilePath ContentBrowserClient::GetGrShaderDiskCacheDirectory() { + return base::FilePath(); +} + +base::FilePath ContentBrowserClient::GetGraphiteDawnDiskCacheDirectory() { + return base::FilePath(); +} + +base::FilePath ContentBrowserClient::GetNetLogDefaultDirectory() { + return base::FilePath(); +} + +base::FilePath ContentBrowserClient::GetFirstPartySetsDirectory() { + return base::FilePath(); +} + +std::optional ContentBrowserClient::GetLocalTracesDirectory() { + return std::nullopt; +} + +BrowserPpapiHost* ContentBrowserClient::GetExternalBrowserPpapiHost( + int plugin_process_id) { + return nullptr; +} + +bool ContentBrowserClient::AllowPepperSocketAPI( + BrowserContext* browser_context, + const GURL& url, + bool private_api, + const SocketPermissionRequest* params) { + DCHECK(browser_context); + return false; +} + +bool ContentBrowserClient::IsPepperVpnProviderAPIAllowed( + BrowserContext* browser_context, + const GURL& url) { + DCHECK(browser_context); + return false; +} + +std::unique_ptr ContentBrowserClient::GetVpnServiceProxy( + BrowserContext* browser_context) { + DCHECK(browser_context); + return nullptr; +} + +std::unique_ptr +ContentBrowserClient::CreateSelectFilePolicy(WebContents* web_contents) { + return nullptr; +} + +std::unique_ptr +ContentBrowserClient::CreateDevToolsManagerDelegate() { + return nullptr; +} + +void ContentBrowserClient::UpdateDevToolsBackgroundServiceExpiration( + BrowserContext* browser_context, + int service, + base::Time expiration_time) {} + +base::flat_map +ContentBrowserClient::GetDevToolsBackgroundServiceExpirations( + BrowserContext* browser_context) { + return {}; +} + +std::unique_ptr ContentBrowserClient::CreateTracingDelegate() { + return nullptr; +} + +bool ContentBrowserClient::IsSystemWideTracingEnabled() { + return false; +} + +bool ContentBrowserClient::IsPluginAllowedToCallRequestOSFileHandle( + BrowserContext* browser_context, + const GURL& url) { + DCHECK(browser_context); + return false; +} + +bool ContentBrowserClient::IsPluginAllowedToUseDevChannelAPIs( + BrowserContext* browser_context, + const GURL& url) { + // |browser_context| may be null (e.g. when called from + // PpapiPluginProcessHost::PpapiPluginProcessHost). + + return false; +} + +mojo::Remote +ContentBrowserClient::RunSecondaryMediaService() { + return mojo::Remote(); +} + +void ContentBrowserClient::RegisterAssociatedInterfaceBindersForRenderFrameHost( + RenderFrameHost& render_frame_host, + blink::AssociatedInterfaceRegistry& associated_registry) {} + +ControllerPresentationServiceDelegate* +ContentBrowserClient::GetControllerPresentationServiceDelegate( + WebContents* web_contents) { + return nullptr; +} + +ReceiverPresentationServiceDelegate* +ContentBrowserClient::GetReceiverPresentationServiceDelegate( + WebContents* web_contents) { + return nullptr; +} + +void ContentBrowserClient::AddPresentationObserver( + PresentationObserver* observer, + WebContents* web_contents) {} + +void ContentBrowserClient::RemovePresentationObserver( + PresentationObserver* observer, + WebContents* web_contents) {} + +bool ContentBrowserClient::AddPrivacySandboxAttestationsObserver( + PrivacySandboxAttestationsObserver* observer) { + return true; +} + +void ContentBrowserClient::RemovePrivacySandboxAttestationsObserver( + PrivacySandboxAttestationsObserver* observer) {} + +void ContentBrowserClient::OpenURL( + content::SiteInstance* site_instance, + const content::OpenURLParams& params, + base::OnceCallback callback) { + DCHECK(site_instance); + std::move(callback).Run(nullptr); +} + +std::vector> +content::ContentBrowserClient::CreateThrottlesForNavigation( + NavigationHandle* navigation_handle) { + return std::vector>(); +} + +std::vector> +ContentBrowserClient::CreateCommitDeferringConditionsForNavigation( + NavigationHandle* navigation_handle, + content::CommitDeferringCondition::NavigationType navigation_type) { + DCHECK(navigation_handle); + return std::vector>(); +} + +std::unique_ptr ContentBrowserClient::GetNavigationUIData( + NavigationHandle* navigation_handle) { + return nullptr; +} + +#if BUILDFLAG(IS_WIN) + +bool ContentBrowserClient::PreSpawnChild(sandbox::TargetConfig* config, + sandbox::mojom::Sandbox sandbox_type, + ChildSpawnFlags flags) { + return true; +} + +bool ContentBrowserClient::IsUtilityCetCompatible( + const std::string& utility_sub_type) { + return true; +} + +std::wstring ContentBrowserClient::GetAppContainerSidForSandboxType( + sandbox::mojom::Sandbox sandbox_type, + AppContainerFlags flags) { + // Embedders should override this method and return different SIDs for each + // sandbox type. Note: All content level tests will run child processes in the + // same AppContainer. + return std::wstring( + L"S-1-15-2-3251537155-1984446955-2931258699-841473695-1938553385-" + L"924012148-129201922"); +} + +bool ContentBrowserClient::IsAppContainerDisabled( + sandbox::mojom::Sandbox sandbox_type) { + return false; +} + +std::wstring ContentBrowserClient::GetLPACCapabilityNameForNetworkService() { + // Embedders should override this method and return different LPAC capability + // name. This will be used to secure the user data files required for the + // network service. + return std::wstring(L"lpacContentNetworkService"); +} + +bool ContentBrowserClient::IsRendererCodeIntegrityEnabled() { + return false; +} + +bool ContentBrowserClient::IsPdfFontProxyEnabled() { + return false; +} + +bool ContentBrowserClient::ShouldEnableAudioProcessHighPriority() { + // TODO(crbug.com/40242320): Delete this method when the + // kAudioProcessHighPriorityEnabled enterprise policy is deprecated. + return false; +} + +bool ContentBrowserClient::ShouldUseSkiaFontManager(const GURL& site_url) { + return false; +} + +#endif // BUILDFLAG(IS_WIN) + +std::vector> +ContentBrowserClient::CreateURLLoaderThrottles( + const network::ResourceRequest& request, + BrowserContext* browser_context, + const base::RepeatingCallback& wc_getter, + NavigationUIData* navigation_ui_data, + int frame_tree_node_id, + std::optional navigation_id) { + return std::vector>(); +} + +std::vector> +ContentBrowserClient::CreateURLLoaderThrottlesForKeepAlive( + const network::ResourceRequest& request, + BrowserContext* browser_context, + const base::RepeatingCallback& wc_getter, + int frame_tree_node_id) { + return std::vector>(); +} + +mojo::PendingRemote +ContentBrowserClient::CreateNonNetworkNavigationURLLoaderFactory( + const std::string& scheme, + int frame_tree_node_id) { + return {}; +} + +void ContentBrowserClient:: + RegisterNonNetworkWorkerMainResourceURLLoaderFactories( + BrowserContext* browser_context, + NonNetworkURLLoaderFactoryMap* factories) {} + +void ContentBrowserClient:: + RegisterNonNetworkServiceWorkerUpdateURLLoaderFactories( + BrowserContext* browser_context, + NonNetworkURLLoaderFactoryMap* factories) {} + +void ContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories( + int render_process_id, + int render_frame_id, + const std::optional& request_initiator_origin, + NonNetworkURLLoaderFactoryMap* factories) {} + +void ContentBrowserClient::WillCreateURLLoaderFactory( + BrowserContext* browser_context, + RenderFrameHost* frame, + int render_process_id, + URLLoaderFactoryType type, + const url::Origin& request_initiator, + const net::IsolationInfo& isolation_info, + std::optional navigation_id, + ukm::SourceIdObj ukm_source_id, + network::URLLoaderFactoryBuilder& factory_builder, + mojo::PendingRemote* + header_client, + bool* bypass_redirect_checks, + bool* disable_secure_dns, + network::mojom::URLLoaderFactoryOverridePtr* factory_override, + scoped_refptr navigation_response_task_runner) { + DCHECK(browser_context); +} + +bool ContentBrowserClient::WillInterceptWebSocket(RenderFrameHost*) { + return false; +} + +uint32_t ContentBrowserClient::GetWebSocketOptions(RenderFrameHost* frame) { + return network::mojom::kWebSocketOptionNone; +} + +void ContentBrowserClient::CreateWebSocket( + RenderFrameHost* frame, + WebSocketFactory factory, + const GURL& url, + const net::SiteForCookies& site_for_cookies, + const std::optional& user_agent, + mojo::PendingRemote + handshake_client) { + // NOTREACHED because WillInterceptWebSocket returns false. + NOTREACHED_IN_MIGRATION(); +} + +void ContentBrowserClient::WillCreateWebTransport( + int process_id, + int frame_routing_id, + const GURL& url, + const url::Origin& initiator_origin, + mojo::PendingRemote + handshake_client, + WillCreateWebTransportCallback callback) { + std::move(callback).Run(std::move(handshake_client), std::nullopt); +} + +bool ContentBrowserClient::WillCreateRestrictedCookieManager( + network::mojom::RestrictedCookieManagerRole role, + BrowserContext* browser_context, + const url::Origin& origin, + const net::IsolationInfo& isolation_info, + bool is_service_worker, + int process_id, + int frame_id, + mojo::PendingReceiver* receiver) { + return false; +} + +std::vector> +ContentBrowserClient::WillCreateURLLoaderRequestInterceptors( + content::NavigationUIData* navigation_ui_data, + int frame_tree_node_id, + int64_t navigation_id, + bool force_no_https_upgrade, + scoped_refptr navigation_response_task_runner) { + return std::vector>(); +} + +ContentBrowserClient::URLLoaderRequestHandler +ContentBrowserClient::CreateURLLoaderHandlerForServiceWorkerNavigationPreload( + int frame_tree_node_id, + const network::ResourceRequest& resource_request) { + return ContentBrowserClient::URLLoaderRequestHandler(); +} + +void ContentBrowserClient::OnNetworkServiceCreated( + network::mojom::NetworkService* network_service) {} + +void ContentBrowserClient::ConfigureNetworkContextParams( + BrowserContext* context, + bool in_memory, + const base::FilePath& relative_partition_path, + network::mojom::NetworkContextParams* network_context_params, + cert_verifier::mojom::CertVerifierCreationParams* + cert_verifier_creation_params) { + network_context_params->user_agent = GetUserAgentBasedOnPolicy(context); + network_context_params->accept_language = "en-us,en"; +} + +std::vector +ContentBrowserClient::GetNetworkContextsParentDirectory() { + return {}; +} + +base::Value::Dict ContentBrowserClient::GetNetLogConstants() { + return base::Value::Dict(); +} + +#if BUILDFLAG(IS_ANDROID) +bool ContentBrowserClient::ShouldOverrideUrlLoading( + int frame_tree_node_id, + bool browser_initiated, + const GURL& gurl, + const std::string& request_method, + bool has_user_gesture, + bool is_redirect, + bool is_outermost_main_frame, + bool is_prerendering, + ui::PageTransition transition, + bool* ignore_navigation) { + return true; +} +#endif + +bool ContentBrowserClient::AllowRenderingMhtmlOverHttp( + NavigationUIData* navigation_ui_data) { + return false; +} + +bool ContentBrowserClient::ShouldForceDownloadResource( + content::BrowserContext* browser_context, + const GURL& url, + const std::string& mime_type) { + return false; +} + +void ContentBrowserClient::CreateDeviceInfoService( + RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) {} + +void ContentBrowserClient::CreateManagedConfigurationService( + RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) { +} + +void ContentBrowserClient::CreatePaymentCredential( + RenderFrameHost* render_frame_host, + mojo::PendingReceiver receiver) {} + +#if !BUILDFLAG(IS_ANDROID) +SerialDelegate* ContentBrowserClient::GetSerialDelegate() { + return nullptr; +} +#endif + +HidDelegate* ContentBrowserClient::GetHidDelegate() { + return nullptr; +} + +BluetoothDelegate* ContentBrowserClient::GetBluetoothDelegate() { + return nullptr; +} + +UsbDelegate* ContentBrowserClient::GetUsbDelegate() { + return nullptr; +} + +PrivateNetworkDeviceDelegate* +ContentBrowserClient::GetPrivateNetworkDeviceDelegate() { + return nullptr; +} + +FontAccessDelegate* ContentBrowserClient::GetFontAccessDelegate() { + return nullptr; +} + +#if BUILDFLAG(IS_CHROMEOS) +SmartCardDelegate* ContentBrowserClient::GetSmartCardDelegate() { + return nullptr; +} +#endif + +bool ContentBrowserClient::ShowPaymentHandlerWindow( + content::BrowserContext* browser_context, + const GURL& url, + base::OnceCallback callback) { + DCHECK(browser_context); + return false; +} + +bool ContentBrowserClient::IsSecurityLevelAcceptableForWebAuthn( + content::RenderFrameHost* rfh, + const url::Origin& caller_origin) { + return true; +} + +#if !BUILDFLAG(IS_ANDROID) +WebAuthenticationDelegate* +ContentBrowserClient::GetWebAuthenticationDelegate() { + static base::NoDestructor delegate; + return delegate.get(); +} + +std::unique_ptr +ContentBrowserClient::GetWebAuthenticationRequestDelegate( + RenderFrameHost* render_frame_host) { + return std::make_unique(); +} +#endif + +std::unique_ptr +ContentBrowserClient::CreateClientCertStore(BrowserContext* browser_context) { + return nullptr; +} + +std::unique_ptr ContentBrowserClient::CreateLoginDelegate( + const net::AuthChallengeInfo& auth_info, + content::WebContents* web_contents, + BrowserContext* browser_context, + const GlobalRequestID& request_id, + bool is_request_for_primary_main_frame, + const GURL& url, + scoped_refptr response_headers, + bool first_auth_attempt, + LoginAuthRequiredCallback auth_required_callback) { + return nullptr; +} + +bool ContentBrowserClient::HandleExternalProtocol( + const GURL& url, + WebContents::Getter web_contents_getter, + int frame_tree_node_id, + NavigationUIData* navigation_data, + bool is_primary_main_frame, + bool is_in_fenced_frame_tree, + network::mojom::WebSandboxFlags sandbox_flags, + ui::PageTransition page_transition, + bool has_user_gesture, + const std::optional& initiating_origin, + RenderFrameHost* initiator_document, + mojo::PendingRemote* out_factory) { + return true; +} + +std::unique_ptr +ContentBrowserClient::CreateWindowForVideoPictureInPicture( + VideoPictureInPictureWindowController* controller) { + return nullptr; +} + +void ContentBrowserClient::RegisterRendererPreferenceWatcher( + BrowserContext* browser_context, + mojo::PendingRemote watcher) { + // |browser_context| may be null (e.g. during shutdown of a service worker). +} + +bool ContentBrowserClient::CanAcceptUntrustedExchangesIfNeeded() { + return false; +} + +void ContentBrowserClient::OnNetworkServiceDataUseUpdate( + GlobalRenderFrameHostId render_frame_host_id, + int32_t network_traffic_annotation_id_hash, + int64_t recv_bytes, + int64_t sent_bytes) {} + +base::FilePath ContentBrowserClient::GetSandboxedStorageServiceDataDirectory() { + return base::FilePath(); +} + +bool ContentBrowserClient::ShouldSandboxAudioService() { + return base::FeatureList::IsEnabled(features::kAudioServiceSandbox); +} + +bool ContentBrowserClient::ShouldSandboxNetworkService() { + return sandbox::policy::features::IsNetworkSandboxEnabled(); +} + +bool ContentBrowserClient::ShouldRunOutOfProcessSystemDnsResolution() { +// This is only useful on Linux desktop and Android where system DNS +// resolution cannot always run in a sandboxed network process. The Mac and +// Windows sandboxing systems allow us to specify system DNS resolution as an +// allowed action, and ChromeOS uses a simple, known system DNS configuration +// that can be adequately sandboxed. +// Currently Android's network service will not run out of process or sandboxed, +// so OutOfProcessSystemDnsResolution is not currently enabled on Android. +#if BUILDFLAG(IS_LINUX) + return true; +#else + return false; +#endif +} + +std::string ContentBrowserClient::GetProduct() { + return std::string(); +} + +std::string ContentBrowserClient::GetUserAgent() { + return std::string(); +} + +std::string ContentBrowserClient::GetUserAgentBasedOnPolicy( + content::BrowserContext* content) { + return GetUserAgent(); +} + +blink::UserAgentMetadata ContentBrowserClient::GetUserAgentMetadata() { + return blink::UserAgentMetadata(); +} + +std::optional ContentBrowserClient::GetProductLogo() { + return std::nullopt; +} + +bool ContentBrowserClient::IsBuiltinComponent(BrowserContext* browser_context, + const url::Origin& origin) { + return false; +} + +bool ContentBrowserClient::ShouldBlockRendererDebugURL( + const GURL& url, + BrowserContext* context, + RenderFrameHost* render_frame_host) { + return false; +} + +std::optional +ContentBrowserClient::GetSpareRendererDelayForSiteURL(const GURL& site_url) { + return std::nullopt; +} + +#if BUILDFLAG(IS_ANDROID) +ContentBrowserClient::WideColorGamutHeuristic +ContentBrowserClient::GetWideColorGamutHeuristic() { + return WideColorGamutHeuristic::kNone; +} + +std::unique_ptr +ContentBrowserClient::CreateTtsEnvironmentAndroid() { + return nullptr; +} + +bool ContentBrowserClient:: + ShouldObserveContainerViewLocationForDialogOverlays() { + return false; +} +#endif + +base::flat_set +ContentBrowserClient::GetPluginMimeTypesWithExternalHandlers( + BrowserContext* browser_context) { + return base::flat_set(); +} + +void ContentBrowserClient::AugmentNavigationDownloadPolicy( + RenderFrameHost* frame_host, + bool user_gesture, + blink::NavigationDownloadPolicy* download_policy) {} + +bool ContentBrowserClient::HandleTopicsWebApi( + const url::Origin& context_origin, + content::RenderFrameHost* main_frame, + browsing_topics::ApiCallerSource caller_source, + bool get_topics, + bool observe, + std::vector& topics) { + return true; +} + +int ContentBrowserClient::NumVersionsInTopicsEpochs( + content::RenderFrameHost* main_frame) const { + return 0; +} + +bool ContentBrowserClient::IsBluetoothScanningBlocked( + content::BrowserContext* browser_context, + const url::Origin& requesting_origin, + const url::Origin& embedding_origin) { + return false; +} + +void ContentBrowserClient::BlockBluetoothScanning( + content::BrowserContext* browser_context, + const url::Origin& requesting_origin, + const url::Origin& embedding_origin) {} + +void ContentBrowserClient::GetMediaDeviceIDSalt( + content::RenderFrameHost* rfh, + const net::SiteForCookies& site_for_cookies, + const blink::StorageKey& storage_key, + base::OnceCallback callback) { + std::move(callback).Run(false, rfh->GetBrowserContext()->UniqueId()); +} + +base::OnceClosure ContentBrowserClient::FetchRemoteSms( + content::WebContents* web_contents, + const std::vector& origin_list, + base::OnceCallback>, + std::optional, + std::optional)> + callback) { + return base::NullCallback(); +} + +void ContentBrowserClient::ReportLegacyTechEvent( + content::RenderFrameHost* render_frame_host, + const std::string type, + const GURL& url, + const GURL& frame_url, + const std::string& filename, + uint64_t line, + uint64_t column, + std::optional cookie_issue_details) {} + +bool ContentBrowserClient::IsClipboardPasteAllowed( + content::RenderFrameHost* render_frame_host) { + return true; +} + +void ContentBrowserClient::IsClipboardPasteAllowedByPolicy( + const ClipboardEndpoint& source, + const ClipboardEndpoint& destination, + const ClipboardMetadata& metadata, + ClipboardPasteData clipboard_paste_data, + IsClipboardPasteAllowedCallback callback) { + std::move(callback).Run(std::move(clipboard_paste_data)); +} + +void ContentBrowserClient::IsClipboardCopyAllowedByPolicy( + const ClipboardEndpoint& source, + const ClipboardMetadata& metadata, + const ClipboardPasteData& data, + IsClipboardCopyAllowedCallback callback) { + std::move(callback).Run(metadata.format_type, data, std::nullopt); +} + +#if BUILDFLAG(ENABLE_VR) +XrIntegrationClient* ContentBrowserClient::GetXrIntegrationClient() { + return nullptr; +} +#endif + +void ContentBrowserClient::BindBrowserControlInterface( + mojo::ScopedMessagePipeHandle pipe) {} + +bool ContentBrowserClient::ShouldInheritCrossOriginEmbedderPolicyImplicitly( + const GURL& url) { + return false; +} + +bool ContentBrowserClient::ShouldServiceWorkerInheritPolicyContainerFromCreator( + const GURL& url) { + return url.SchemeIsLocal(); +} + +void ContentBrowserClient::GrantAdditionalRequestPrivilegesToWorkerProcess( + int child_id, + const GURL& script_url) {} + +ContentBrowserClient::PrivateNetworkRequestPolicyOverride +ContentBrowserClient::ShouldOverridePrivateNetworkRequestPolicy( + BrowserContext* browser_context, + const url::Origin& origin) { + return PrivateNetworkRequestPolicyOverride::kDefault; +} + +bool ContentBrowserClient::IsJitDisabledForSite(BrowserContext* browser_context, + const GURL& site_url) { + return false; +} + +ukm::UkmService* ContentBrowserClient::GetUkmService() { + return nullptr; +} + +blink::mojom::OriginTrialsSettingsPtr +ContentBrowserClient::GetOriginTrialsSettings() { + return nullptr; +} + +void ContentBrowserClient::OnKeepaliveRequestStarted(BrowserContext*) {} + +void ContentBrowserClient::OnKeepaliveRequestFinished() {} + +#if BUILDFLAG(IS_MAC) +bool ContentBrowserClient::SetupEmbedderSandboxParameters( + sandbox::mojom::Sandbox sandbox_type, + sandbox::SandboxCompiler* compiler) { + return false; +} +#endif // BUILDFLAG(IS_MAC) + +void ContentBrowserClient::GetHyphenationDictionary( + base::OnceCallback) {} + +bool ContentBrowserClient::HasErrorPage(int http_status_code) { + return false; +} + +std::unique_ptr +ContentBrowserClient::CreateIdentityRequestDialogController( + WebContents* web_contents) { + return std::make_unique(); +} + +std::unique_ptr +ContentBrowserClient::CreateDigitalIdentityProvider() { + return nullptr; +} + +bool ContentBrowserClient::SuppressDifferentOriginSubframeJSDialogs( + BrowserContext* browser_context) { + return base::FeatureList::IsEnabled( + features::kSuppressDifferentOriginSubframeJSDialogs); +} + +std::unique_ptr +ContentBrowserClient::CreateAnchorElementPreconnectDelegate( + RenderFrameHost& render_frame_host) { + return nullptr; +} + +std::unique_ptr +ContentBrowserClient::CreateSpeculationHostDelegate( + RenderFrameHost& render_frame_host) { + return nullptr; +} + +std::unique_ptr +ContentBrowserClient::CreatePrefetchServiceDelegate( + BrowserContext* browser_context) { + return nullptr; +} + +std::unique_ptr +ContentBrowserClient::CreatePrerenderWebContentsDelegate() { + return std::make_unique(); +} + +bool ContentBrowserClient::IsFindInPageDisabledForOrigin( + const url::Origin& origin) { + return false; +} + +void ContentBrowserClient::OnWebContentsCreated(WebContents* web_contents) {} + +bool ContentBrowserClient::ShouldDisableOriginAgentClusterDefault( + BrowserContext* browser_context) { + return false; +} + +bool ContentBrowserClient::ShouldPreconnectNavigation( + RenderFrameHost* render_frame_host) { + return false; +} + +bool ContentBrowserClient::IsFirstPartySetsEnabled() { + return true; +} + +bool ContentBrowserClient::WillProvidePublicFirstPartySets() { + return false; +} + +mojom::AlternativeErrorPageOverrideInfoPtr +ContentBrowserClient::GetAlternativeErrorPageOverrideInfo( + const GURL& url, + content::RenderFrameHost* render_frame_host, + content::BrowserContext* browser_context, + int32_t error_code) { + return nullptr; +} + +bool ContentBrowserClient::ShouldSendOutermostOriginToRenderer( + const url::Origin& outermost_origin) { + return false; +} + +bool ContentBrowserClient::IsFileSystemURLNavigationAllowed( + content::BrowserContext* browser_context, + const GURL& url) { + return false; +} + +#if BUILDFLAG(IS_MAC) +std::string ContentBrowserClient::GetChildProcessSuffix(int child_flags) { + NOTIMPLEMENTED(); + return std::string(); +} +#endif + +bool ContentBrowserClient::AreIsolatedWebAppsEnabled( + BrowserContext* browser_context) { + // The whole logic of the IWAs lives in //chrome. So IWAs should be + // enabled at that layer. + return false; +} + +bool ContentBrowserClient::IsThirdPartyStoragePartitioningAllowed( + content::BrowserContext*, + const url::Origin&) { + return true; +} + +bool ContentBrowserClient::AreDeprecatedAutomaticBeaconCredentialsAllowed( + content::BrowserContext* browser_context, + const GURL& destination_url, + const url::Origin& top_frame_origin) { + return false; +} + +bool ContentBrowserClient:: + IsTransientActivationRequiredForShowFileOrDirectoryPicker( + WebContents* web_contents) { + return true; +} + +bool ContentBrowserClient::IsTransientActivationRequiredForHtmlFullscreen( + content::RenderFrameHost* render_frame_host) { + return true; +} + +bool ContentBrowserClient::ShouldUseFirstPartyStorageKey( + const url::Origin& origin) { + return false; +} + +std::unique_ptr +ContentBrowserClient::CreateResponsivenessCalculatorDelegate() { + return nullptr; +} + +bool ContentBrowserClient::CanBackForwardCachedPageReceiveCookieChanges( + content::BrowserContext& browser_context, + const GURL& url, + const net::SiteForCookies& site_for_cookies, + const std::optional& top_frame_origin, + const net::CookieSettingOverrides overrides) { + return true; +} + +void ContentBrowserClient::GetCloudIdentifiers( + const storage::FileSystemURL& url, + FileSystemAccessPermissionContext::HandleType handle_type, + GetCloudIdentifiersCallback callback) { + mojo::ReportBadMessage("Cloud identifiers not supported on this platform"); + std::move(callback).Run( + blink::mojom::FileSystemAccessError::New( + blink::mojom::FileSystemAccessStatus::kNotSupportedError, + base::File::Error::FILE_ERROR_FAILED, + "Cloud identifiers are not supported on this platform"), + {}); + return; +} + +bool ContentBrowserClient:: + ShouldAllowBackForwardCacheForCacheControlNoStorePage( + content::BrowserContext* browser_context) { + return true; +} + +bool ContentBrowserClient::UseOutermostMainFrameOrEmbedderForSubCaptureTargets() + const { + return false; +} + +#if !BUILDFLAG(IS_ANDROID) +void ContentBrowserClient::BindVideoEffectsManager( + const std::string& device_id, + BrowserContext* browser_context, + mojo::PendingReceiver + video_effects_manager) {} + +void ContentBrowserClient::BindVideoEffectsProcessor( + const std::string& device_id, + BrowserContext* browser_context, + mojo::PendingReceiver + video_effects_manager) {} +#endif // !BUILDFLAG(IS_ANDROID) + +void ContentBrowserClient::PreferenceRankAudioDeviceInfos( + BrowserContext* browser_context, + blink::WebMediaDeviceInfoArray& infos) {} +void ContentBrowserClient::PreferenceRankVideoDeviceInfos( + BrowserContext* browser_context, + blink::WebMediaDeviceInfoArray& infos) {} + +network::mojom::IpProtectionProxyBypassPolicy +ContentBrowserClient::GetIpProtectionProxyBypassPolicy() { + return network::mojom::IpProtectionProxyBypassPolicy::kNone; +} + +void ContentBrowserClient::MaybePrewarmHttpDiskCache( + BrowserContext& browser_context, + const std::optional& initiator_origin, + const GURL& navigation_url) {} + +void ContentBrowserClient::NotifyMultiCaptureStateChanged( + GlobalRenderFrameHostId capturer_rfh_id, + const std::string& label, + MultiCaptureChanged state) {} + +std::unique_ptr ContentBrowserClient::CreateDipsDelegate() { + return nullptr; +} + +bool ContentBrowserClient::ShouldSuppressAXLoadComplete(RenderFrameHost* rfh) { + return false; +} + +void ContentBrowserClient::BindAIManager( + BrowserContext* browser_context, + mojo::PendingReceiver receiver) { + EchoAIManagerImpl::Create(browser_context, std::move(receiver)); +} + +#if !BUILDFLAG(IS_ANDROID) +void ContentBrowserClient::QueryInstalledWebAppsByManifestId( + const GURL& frame_url, + const GURL& manifest_id, + content::BrowserContext* browser_context, + base::OnceCallback)> + callback) { + std::move(callback).Run(std::nullopt); +} +#endif // !BUILDFLAG(IS_ANDROID) + +} // namespace content diff --git a/tools/under-control/src/extensions/common/api/alarms.idl b/tools/under-control/src/extensions/common/api/alarms.idl new file mode 100755 index 000000000..c48c0f626 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/alarms.idl @@ -0,0 +1,104 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.alarms API to schedule code to run +// periodically or at a specified time in the future. +namespace alarms { + dictionary Alarm { + // Name of this alarm. + DOMString name; + + // Time at which this alarm was scheduled to fire, in milliseconds past the + // epoch (e.g. Date.now() + n). For performance reasons, the + // alarm may have been delayed an arbitrary amount beyond this. + double scheduledTime; + + // If not null, the alarm is a repeating alarm and will fire again in + // periodInMinutes minutes. + double? periodInMinutes; + }; + + // TODO(mpcomplete): rename to CreateInfo when http://crbug.com/123073 is + // fixed. + dictionary AlarmCreateInfo { + // Time at which the alarm should fire, in milliseconds past the epoch + // (e.g. Date.now() + n). + double? when; + + // Length of time in minutes after which the onAlarm event + // should fire. + // + // + double? delayInMinutes; + + // If set, the onAlarm event should fire every periodInMinutes + // minutes after the initial event specified by when or + // delayInMinutes. If not set, the alarm will only fire once. + // + // + double? periodInMinutes; + }; + + callback VoidCallback = void (); + callback AlarmCallback = void (optional Alarm alarm); + callback AlarmListCallback = void (Alarm[] alarms); + callback ClearCallback = void (boolean wasCleared); + + interface Functions { + // Creates an alarm. Near the time(s) specified by alarmInfo, + // the onAlarm event is fired. If there is another alarm with + // the same name (or no name if none is specified), it will be cancelled and + // replaced by this alarm. + // + // In order to reduce the load on the user's machine, Chrome limits alarms + // to at most once every 30 seconds but may delay them an arbitrary amount + // more. That is, setting delayInMinutes or + // periodInMinutes to less than 0.5 will not be + // honored and will cause a warning. when can be set to less + // than 30 seconds after "now" without warning but won't actually cause the + // alarm to fire for at least 30 seconds. + // + // To help you debug your app or extension, when you've loaded it unpacked, + // there's no limit to how often the alarm can fire. + // + // |name|: Optional name to identify this alarm. Defaults to the empty + // string. + // |alarmInfo|: Describes when the alarm should fire. The initial time must + // be specified by either when or delayInMinutes (but + // not both). If periodInMinutes is set, the alarm will repeat + // every periodInMinutes minutes after the initial event. If + // neither when or delayInMinutes is set for a + // repeating alarm, periodInMinutes is used as the default for + // delayInMinutes. + // |callback|: Invoked when the alarm has been created. + static void create( + optional DOMString name, + AlarmCreateInfo alarmInfo, + optional VoidCallback callback); + + // Retrieves details about the specified alarm. + // |name|: The name of the alarm to get. Defaults to the empty string. + static void get( + optional DOMString name, + AlarmCallback callback); + + // Gets an array of all the alarms. + static void getAll(AlarmListCallback callback); + + // Clears the alarm with the given name. + // |name|: The name of the alarm to clear. Defaults to the empty string. + static void clear( + optional DOMString name, + optional ClearCallback callback); + + // Clears all alarms. + static void clearAll(optional ClearCallback callback); + }; + + interface Events { + // Fired when an alarm has elapsed. Useful for event pages. + // |alarm|: The alarm that has elapsed. + static void onAlarm(Alarm alarm); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/app_current_window_internal.idl b/tools/under-control/src/extensions/common/api/app_current_window_internal.idl new file mode 100755 index 000000000..cfda8c438 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/app_current_window_internal.idl @@ -0,0 +1,66 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This is used by the app window API internally to pass through messages to +// the shell window. +namespace app.currentWindowInternal { + + // Null or undefined indicates that a value should not change. + dictionary Bounds { + long? left; + long? top; + long? width; + long? height; + }; + + // Null or undefined indicates that a value should not change. A value of 0 + // will clear the constraints. + dictionary SizeConstraints { + long? minWidth; + long? minHeight; + long? maxWidth; + long? maxHeight; + }; + + dictionary RegionRect { + long left; + long top; + long width; + long height; + }; + + dictionary Region { + RegionRect[]? rects; + }; + + interface Functions { + static void focus(); + static void fullscreen(); + static void minimize(); + static void maximize(); + static void restore(); + static void drawAttention(); + static void clearAttention(); + static void show(optional boolean focused); + static void hide(); + static void setBounds(DOMString boundsType, Bounds bounds); + static void setSizeConstraints(DOMString boundsType, + SizeConstraints constraints); + static void setIcon(DOMString icon_url); + static void setShape(Region region); + static void setAlwaysOnTop(boolean always_on_top); + static void setVisibleOnAllWorkspaces(boolean always_visible); + static void setActivateOnPointer(boolean activate_on_pointer); + }; + + interface Events { + static void onClosed(); + static void onBoundsChanged(); + static void onFullscreened(); + static void onMinimized(); + static void onMaximized(); + static void onRestored(); + static void onAlphaEnabledChanged(); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/app_runtime.idl b/tools/under-control/src/extensions/common/api/app_runtime.idl new file mode 100755 index 000000000..0edabe0cc --- /dev/null +++ b/tools/under-control/src/extensions/common/api/app_runtime.idl @@ -0,0 +1,165 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.app.runtime API to manage the app lifecycle. +// The app runtime manages app installation, controls the event page, and can +// shut down the app at anytime. +namespace app.runtime { + + [inline_doc] dictionary LaunchItem { + // Entry for the item. + [instanceOf=Entry] object entry; + + // The MIME type of the file. + DOMString? type; + }; + + // Enumeration of app launch sources. + // This should be kept in sync with AppLaunchSource in + // components/services/app_service/public/mojom/types.mojom, and + // GetLaunchSourceEnum() in + // extensions/browser/api/app_runtime/app_runtime_api.cc. + // Note the enumeration is used in UMA histogram so entries + // should not be re-ordered or removed. + enum LaunchSource { + untracked, + app_launcher, + new_tab_page, + reload, + restart, + load_and_launch, + command_line, + file_handler, + url_handler, + system_tray, + about_page, + keyboard, + extensions_page, + management_api, + ephemeral_app, + background, + kiosk, + chrome_internal, + test, + installed_notification, + context_menu, + arc, + intent_url, + app_home_page, + focus_mode, + sparky + }; + + // An app can be launched with a specific action in mind, for example, to + // create a new note. The type of action the app was launched + // with is available inside of the |actionData| field from the LaunchData + // instance. + enum ActionType { + // The user wants to quickly take a new note. + new_note + }; + + // Optional data that includes action-specific launch information. + dictionary ActionData { + ActionType actionType; + + //

Whether the action was requested on Chrome OS lock screen.

+ //

+ // Launch events with this valued set to true are fired + // in lock screen context, where apps have reduced access to extension + // APIs, but are able to create windows on lock screen. + //

+ //

+ // Note that this value will be set to true only if the app + // is set as the lock screen enabled action handler by the user. + //

+ [nodoc] boolean? isLockScreenAction; + + // Currently, used only with lock screen actions. If set, indicates whether + // the app should attempt to restore state from when the action was last + // handled. + [nodoc] boolean? restoreLastActionState; + }; + + // Optional data for the launch. Either items, or + // the pair (url, referrerUrl) can be present for any given + // launch. + [inline_doc] dictionary LaunchData { + // The ID of the file or URL handler that the app is being invoked with. + // Handler IDs are the top-level keys in the file_handlers + // and/or url_handlers dictionaries in the manifest. + DOMString? id; + + // The file entries for the onLaunched event triggered by a + // matching file handler in the file_handlers manifest key. + LaunchItem[]? items; + + // The URL for the onLaunched event triggered by a matching + // URL handler in the url_handlers manifest key. + DOMString? url; + + // The referrer URL for the onLaunched event triggered by a + // matching URL handler in the url_handlers manifest key. + DOMString? referrerUrl; + + // Whether the app is launched in a Chrome OS Demo Mode session. Used for + // default-installed Demo Mode Chrome apps. + [nodoc] boolean? isDemoSession; + + // Whether the app is being launched in a Chrome OS + // kiosk session. + boolean? isKioskSession; + + // Whether the app is being launched in a Chrome OS + // public session. + boolean? isPublicSession; + + // Where the app is launched from. + LaunchSource? source; + + // Contains data that specifies the ActionType this app was + // launched with. This is null if the app was not launched with a specific + // action intent. + ActionData? actionData; + }; + + // This object specifies details and operations to perform on the embedding + // request. The app to be embedded can make a decision on whether or not to + // allow the embedding and what to embed based on the embedder making the + // request. + dictionary EmbedRequest { + DOMString embedderId; + + // Optional developer specified data that the app to be embedded can use + // when making an embedding decision. + any? data; + + // Allows embedderId to embed this app in an <appview> + // element. The url specifies the content to embed. + [nocompile] static void allow(DOMString url); + + // Prevents embedderId from embedding this app in an + // <appview> element. + [nocompile] static void deny(); + }; + + interface Events { + // Fired when an embedding app requests to embed this app. This event is + // only available on dev channel with the flag --enable-app-view. + static void onEmbedRequested(EmbedRequest request); + + // Fired when an app is launched from the launcher. + static void onLaunched(optional LaunchData launchData); + + // Fired at Chrome startup to apps that were running when Chrome last shut + // down, or when apps have been requested to restart from their previous + // state for other reasons (e.g. when the user revokes access to an app's + // retained files the runtime will restart the app). In these situations if + // apps do not have an onRestarted handler they will be sent + // an onLaunched event instead. + static void onRestarted(); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/app_window.idl b/tools/under-control/src/extensions/common/api/app_window.idl new file mode 100755 index 000000000..78d93db13 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/app_window.idl @@ -0,0 +1,502 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.app.window API to create windows. Windows +// have an optional frame with title bar and size controls. They are not +// associated with any Chrome browser windows. See the +// Window State Sample for a demonstration of these options. +namespace app.window { + + // Previously named Bounds. + dictionary ContentBounds { + long? left; + long? top; + long? width; + long? height; + }; + + dictionary BoundsSpecification { + // The X coordinate of the content or window. + long? left; + + // The Y coordinate of the content or window. + long? top; + + // The width of the content or window. + long? width; + + // The height of the content or window. + long? height; + + // The minimum width of the content or window. + long? minWidth; + + // The minimum height of the content or window. + long? minHeight; + + // The maximum width of the content or window. + long? maxWidth; + + // The maximum height of the content or window. + long? maxHeight; + }; + + dictionary Bounds { + // This property can be used to read or write the current X coordinate of + // the content or window. + long left; + + // This property can be used to read or write the current Y coordinate of + // the content or window. + long top; + + // This property can be used to read or write the current width of the + // content or window. + long width; + + // This property can be used to read or write the current height of the + // content or window. + long height; + + // This property can be used to read or write the current minimum width of + // the content or window. A value of null indicates + // 'unspecified'. + long? minWidth; + + // This property can be used to read or write the current minimum height of + // the content or window. A value of null indicates + // 'unspecified'. + long? minHeight; + + // This property can be used to read or write the current maximum width of + // the content or window. A value of null indicates + // 'unspecified'. + long? maxWidth; + + // This property can be used to read or write the current maximum height of + // the content or window. A value of null indicates + // 'unspecified'. + long? maxHeight; + + // Set the left and top position of the content or window. + static void setPosition(long left, long top); + + // Set the width and height of the content or window. + static void setSize(long width, long height); + + // Set the minimum size constraints of the content or window. The minimum + // width or height can be set to null to remove the constraint. + // A value of undefined will leave a constraint unchanged. + static void setMinimumSize(long minWidth, long minHeight); + + // Set the maximum size constraints of the content or window. The maximum + // width or height can be set to null to remove the constraint. + // A value of undefined will leave a constraint unchanged. + static void setMaximumSize(long maxWidth, long maxHeight); + }; + + dictionary FrameOptions { + // Frame type: none or chrome (defaults to + // chrome). + // + // For none, the -webkit-app-region CSS property + // can be used to apply draggability to the app's window. + // + // -webkit-app-region: drag can be used to mark regions + // draggable. no-drag can be used to disable this style on + // nested elements. + DOMString? type; + // Allows the frame color to be set. Frame coloring is only available if the + // frame type is chrome. + // + // Frame coloring is new in Chrome 36. + DOMString? color; + // Allows the frame color of the window when active to be set. Frame + // coloring is only available if the frame type is chrome. + // + // Frame coloring is only available if the frame type is + // chrome. + // + // Frame coloring is new in Chrome 36. + DOMString? activeColor; + // Allows the frame color of the window when inactive to be set differently + // to the active color. Frame + // coloring is only available if the frame type is chrome. + // + // inactiveColor must be used in conjunction with + // color. + // + // Frame coloring is new in Chrome 36. + DOMString? inactiveColor; + }; + + // State of a window: normal, fullscreen, maximized, minimized. + enum State { normal, fullscreen, maximized, minimized }; + + // Specifies the type of window to create. + enum WindowType { + // Default window type. + shell, + // OS managed window (Deprecated). + panel + }; + + [noinline_doc] dictionary CreateWindowOptions { + // Id to identify the window. This will be used to remember the size + // and position of the window and restore that geometry when a window + // with the same id is later opened. + // If a window with a given id is created while another window with the same + // id already exists, the currently opened window will be focused instead of + // creating a new window. + DOMString? id; + + // Used to specify the initial position, initial size and constraints of the + // window's content (excluding window decorations). + // If an id is also specified and a window with a matching + // id has been shown before, the remembered bounds will be used + // instead. + // + // Note that the padding between the inner and outer bounds is determined by + // the OS. Therefore setting the same bounds property for both the + // innerBounds and outerBounds will result in an + // error. + // + // This property is new in Chrome 36. + BoundsSpecification? innerBounds; + + // Used to specify the initial position, initial size and constraints of the + // window (including window decorations such as the title bar and frame). + // If an id is also specified and a window with a matching + // id has been shown before, the remembered bounds will be used + // instead. + // + // Note that the padding between the inner and outer bounds is determined by + // the OS. Therefore setting the same bounds property for both the + // innerBounds and outerBounds will result in an + // error. + // + // This property is new in Chrome 36. + BoundsSpecification? outerBounds; + + // Default width of the window. + [nodoc, deprecated="Use $(ref:BoundsSpecification)."] long? defaultWidth; + + // Default height of the window. + [nodoc, deprecated="Use $(ref:BoundsSpecification)."] long? defaultHeight; + + // Default X coordinate of the window. + [nodoc, deprecated="Use $(ref:BoundsSpecification)."] long? defaultLeft; + + // Default Y coordinate of the window. + [nodoc, deprecated="Use $(ref:BoundsSpecification)."] long? defaultTop; + + // Width of the window. + [nodoc, deprecated="Use $(ref:BoundsSpecification)."] long? width; + + // Height of the window. + [nodoc, deprecated="Use $(ref:BoundsSpecification)."] long? height; + + // X coordinate of the window. + [nodoc, deprecated="Use $(ref:BoundsSpecification)."] long? left; + + // Y coordinate of the window. + [nodoc, deprecated="Use $(ref:BoundsSpecification)."] long? top; + + // Minimum width of the window. + [deprecated="Use innerBounds or outerBounds."] long? minWidth; + + // Minimum height of the window. + [deprecated="Use innerBounds or outerBounds."] long? minHeight; + + // Maximum width of the window. + [deprecated="Use innerBounds or outerBounds."] long? maxWidth; + + // Maximum height of the window. + [deprecated="Use innerBounds or outerBounds."] long? maxHeight; + + // Type of window to create. + [deprecated="All app windows use the 'shell' window type"] WindowType? type; + + // Creates a special ime window. This window is not focusable and can be + // stacked above virtual keyboard window. This is restriced to component ime + // extensions. + // Requires the app.window.ime API permission. + [nodoc] boolean? ime; + + // If true, the window will have its own shelf icon. Otherwise the window + // will be grouped in the shelf with other windows that are associated with + // the app. Defaults to false. If showInShelf is set to true you need to + // specify an id for the window. + boolean? showInShelf; + + // URL of the window icon. A window can have its own icon when showInShelf + // is set to true. The URL should be a global or an extension local URL. + DOMString? icon; + + // Frame type: none or chrome (defaults to + // chrome). For none, the + // -webkit-app-region CSS property can be used to apply + // draggability to the app's window. -webkit-app-region: drag + // can be used to mark regions draggable. no-drag can be used + // to disable this style on nested elements. + // + // Use of FrameOptions is new in M36. + (DOMString or FrameOptions)? frame; + + // Size and position of the content in the window (excluding the titlebar). + // If an id is also specified and a window with a matching id has been shown + // before, the remembered bounds of the window will be used instead. + [deprecated="Use innerBounds or outerBounds."] ContentBounds? bounds; + + // Enable window background transparency. + // Only supported in ash. Requires the app.window.alpha API + // permission. + [nodoc] boolean? alphaEnabled; + + // The initial state of the window, allowing it to be created already + // fullscreen, maximized, or minimized. Defaults to 'normal'. + State? state; + + // If true, the window will be created in a hidden state. Call show() on + // the window to show it once it has been created. Defaults to false. + boolean? hidden; + + // If true, the window will be resizable by the user. Defaults to true. + boolean? resizable; + + // By default if you specify an id for the window, the window will only be + // created if another window with the same id doesn't already exist. If a + // window with the same id already exists that window is activated instead. + // If you do want to create multiple windows with the same id, you can + // set this property to false. + [deprecated="Multiple windows with the same id is no longer supported."] boolean? singleton; + + // If true, the window will stay above most other windows. If there are + // multiple windows of this kind, the currently focused window will be in + // the foreground. Requires the alwaysOnTopWindows + // permission. Defaults to false. + // + // Call setAlwaysOnTop() on the window to change this property + // after creation. + boolean? alwaysOnTop; + + // If true, the window will be focused when created. Defaults to true. + boolean? focused; + + // If true, and supported by the platform, the window will be visible on all + // workspaces. + boolean? visibleOnAllWorkspaces; + + //

If set, the action that is intended to be handled by the window on + // lockscreen. This has to be set to create an app window visible on the + // lock screen. The app window should be created only in response to an + // app launch request for handling an action from the lock screen. App + // window creation will fail if the app was not launched to handle the + // action. + //

+ //

This is Chrome OS only.

+ [nodoc] app.runtime.ActionType? lockScreenAction; + }; + + // Called in the creating window (parent) before the load event is called in + // the created window (child). The parent can set fields or functions on the + // child usable from onload. E.g. background.js: + // + // function(createdWindow) { createdWindow.contentWindow.foo = + // function () { }; }; + // + // window.js: + // + // window.onload = function () { foo(); } + callback CreateWindowCallback = + void ([instanceOf=AppWindow] object createdWindow); + + [noinline_doc] dictionary AppWindow { + // Focus the window. + static void focus(); + + // Fullscreens the window. + // + // The user will be able to restore the window by pressing ESC. An + // application can prevent the fullscreen state to be left when ESC is + // pressed by requesting the app.window.fullscreen.overrideEsc + // permission and canceling the event by calling .preventDefault(), in the + // keydown and keyup handlers, like this: + // + // window.onkeydown = window.onkeyup = function(e) { if (e.keyCode == + // 27 /* ESC */) { e.preventDefault(); } }; + // + // Note window.fullscreen() will cause the entire window to + // become fullscreen and does not require a user gesture. The HTML5 + // fullscreen API can also be used to enter fullscreen mode (see + // Web APIs + // for more details). + static void fullscreen(); + + // Is the window fullscreen? This will be true if the window has been + // created fullscreen or was made fullscreen via the + // AppWindow or HTML5 fullscreen APIs. + static boolean isFullscreen(); + + // Minimize the window. + static void minimize(); + + // Is the window minimized? + static boolean isMinimized(); + + // Maximize the window. + static void maximize(); + + // Is the window maximized? + static boolean isMaximized(); + + // Restore the window, exiting a maximized, minimized, or fullscreen state. + static void restore(); + + // Move the window to the position (|left|, |top|). + [deprecated="Use outerBounds."] static void moveTo(long left, long top); + + // Resize the window to |width|x|height| pixels in size. + [deprecated="Use outerBounds."] static void resizeTo(long width, long height); + + // Draw attention to the window. + static void drawAttention(); + + // Clear attention to the window. + static void clearAttention(); + + // Close the window. + static void close(); + + // Show the window. Does nothing if the window is already visible. + // Focus the window if |focused| is set to true or omitted. + static void show(optional boolean focused); + + // Hide the window. Does nothing if the window is already hidden. + static void hide(); + + // Get the window's inner bounds as a $(ref:ContentBounds) object. + [nocompile, deprecated="Use innerBounds or outerBounds."] static ContentBounds getBounds(); + + // Set the window's inner bounds. + [nocompile, deprecated="Use innerBounds or outerBounds."] static void setBounds(ContentBounds bounds); + + // Set the app icon for the window (experimental). + // Currently this is only being implemented on Ash. + // TODO(stevenjb): Investigate implementing this on Windows and OSX. + [nodoc] static void setIcon(DOMString iconUrl); + + // Is the window always on top? + static boolean isAlwaysOnTop(); + + // Accessors for testing. + [nodoc] boolean hasFrameColor; + [nodoc] long activeFrameColor; + [nodoc] long inactiveFrameColor; + + // Set whether the window should stay above most other windows. Requires the + // alwaysOnTopWindows permission. + static void setAlwaysOnTop(boolean alwaysOnTop); + + // Can the window use alpha transparency? + // TODO(jackhou): Document this properly before going to stable. + [nodoc] static boolean alphaEnabled(); + + // Set whether the window is visible on all workspaces. (Only for platforms + // that support this). + static void setVisibleOnAllWorkspaces(boolean alwaysVisible); + + // The JavaScript 'window' object for the created child. + [instanceOf=Window] object contentWindow; + + // The id the window was created with. + DOMString id; + + // The position, size and constraints of the window's content, which does + // not include window decorations. + // This property is new in Chrome 36. + Bounds innerBounds; + + // The position, size and constraints of the window, which includes window + // decorations, such as the title bar and frame. + // This property is new in Chrome 36. + Bounds outerBounds; + }; + + interface Functions { + // The size and position of a window can be specified in a number of + // different ways. The most simple option is not specifying anything at + // all, in which case a default size and platform dependent position will + // be used. + // + // To set the position, size and constraints of the window, use the + // innerBounds or outerBounds properties. Inner + // bounds do not include window decorations. Outer bounds include the + // window's title bar and frame. Note that the padding between the inner and + // outer bounds is determined by the OS. Therefore setting the same property + // for both inner and outer bounds is considered an error (for example, + // setting both innerBounds.left and + // outerBounds.left). + // + // To automatically remember the positions of windows you can give them ids. + // If a window has an id, This id is used to remember the size and position + // of the window whenever it is moved or resized. This size and position is + // then used instead of the specified bounds on subsequent opening of a + // window with the same id. If you need to open a window with an id at a + // location other than the remembered default, you can create it hidden, + // move it to the desired location, then show it. + static void create( + DOMString url, + optional CreateWindowOptions options, + optional CreateWindowCallback callback); + + // Returns an $(ref:AppWindow) object for the + // current script context (ie JavaScript 'window' object). This can also be + // called on a handle to a script context for another page, for example: + // otherWindow.chrome.app.window.current(). + [nocompile] static AppWindow current(); + [nocompile, nodoc] static void initializeAppWindow(object state); + + // Gets an array of all currently created app windows. This method is new in + // Chrome 33. + [nocompile] static AppWindow[] getAll(); + + // Gets an $(ref:AppWindow) with the given id. If no window with the given id + // exists null is returned. This method is new in Chrome 33. + [nocompile] static AppWindow get(DOMString id); + + // Whether the current platform supports windows being visible on all + // workspaces. + [nocompile] static boolean canSetVisibleOnAllWorkspaces(); + }; + + interface Events { + // Fired when the window is resized. + [nocompile] static void onBoundsChanged(); + + // Fired when the window is closed. Note, this should be listened to from + // a window other than the window being closed, for example from the + // background page. This is because the window being closed will be in the + // process of being torn down when the event is fired, which means not all + // APIs in the window's script context will be functional. + [nocompile] static void onClosed(); + + // Fired when the window is fullscreened (either via the + // AppWindow or HTML5 APIs). + [nocompile] static void onFullscreened(); + + // Fired when the window is maximized. + [nocompile] static void onMaximized(); + + // Fired when the window is minimized. + [nocompile] static void onMinimized(); + + // Fired when the window is restored from being minimized or maximized. + [nocompile] static void onRestored(); + + // Fired when the window's ability to use alpha transparency changes. + [nocompile, nodoc] static void onAlphaEnabledChanged(); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/audio.idl b/tools/under-control/src/extensions/common/api/audio.idl new file mode 100755 index 000000000..d36cf6ca4 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/audio.idl @@ -0,0 +1,167 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.audio API is provided to allow users to +// get information about and control the audio devices attached to the +// system. +// This API is currently only available in kiosk mode for ChromeOS. +namespace audio { + + // Type of stream an audio device provides. + enum StreamType { + INPUT, + OUTPUT + }; + + // Available audio device types. + enum DeviceType { + HEADPHONE, + MIC, + USB, + BLUETOOTH, + HDMI, + INTERNAL_SPEAKER, + INTERNAL_MIC, + FRONT_MIC, + REAR_MIC, + KEYBOARD_MIC, + HOTWORD, + LINEOUT, + POST_MIX_LOOPBACK, + POST_DSP_LOOPBACK, + ALSA_LOOPBACK, + OTHER + }; + + dictionary AudioDeviceInfo { + // The unique identifier of the audio device. + DOMString id; + // Stream type associated with this device. + StreamType streamType; + // Type of the device. + DeviceType deviceType; + // The user-friendly name (e.g. "USB Microphone"). + DOMString displayName; + // Device name. + DOMString deviceName; + // True if this is the current active device. + boolean isActive; + // The sound level of the device, volume for output, gain for input. + long level; + // The stable/persisted device id string when available. + DOMString? stableDeviceId; + }; + + dictionary DeviceFilter { + // If set, only audio devices whose stream type is included in this list + // will satisfy the filter. + StreamType[]? streamTypes; + + // If set, only audio devices whose active state matches this value will + // satisfy the filter. + boolean? isActive; + }; + + dictionary DeviceProperties { + //

+ // The audio device's desired sound level. Defaults to the device's + // current sound level. + //

+ //

If used with audio input device, represents audio device gain.

+ //

If used with audio output device, represents audio device volume.

+ long? level; + }; + + dictionary DeviceIdLists { + //

List of input devices specified by their ID.

+ //

To indicate input devices should be unaffected, leave this property + // unset.

+ DOMString[]? input; + + //

List of output devices specified by their ID.

+ //

To indicate output devices should be unaffected, leave this property + // unset.

+ DOMString[]? output; + }; + + dictionary MuteChangedEvent { + // The type of the stream for which the mute value changed. The updated mute + // value applies to all devices with this stream type. + StreamType streamType; + + // Whether or not the stream is now muted. + boolean isMuted; + }; + + dictionary LevelChangedEvent { + // ID of device whose sound level has changed. + DOMString deviceId; + + // The device's new sound level. + long level; + }; + + callback GetDevicesCallback = void(AudioDeviceInfo[] devices); + callback GetMuteCallback = void(boolean value); + callback EmptyCallback = void(); + + interface Functions { + // Gets a list of audio devices filtered based on |filter|. + // |filter|: Device properties by which to filter the list of returned + // audio devices. If the filter is not set or set to {}, + // returned device list will contain all available audio devices. + // |callback|: Reports the requested list of audio devices. + static void getDevices( + optional DeviceFilter filter, + GetDevicesCallback callback); + + // Sets lists of active input and/or output devices. + // |ids|:

Specifies IDs of devices that should be active. If either the + // input or output list is not set, devices in that category are + // unaffected. + //

+ //

It is an error to pass in a non-existent device ID.

+ static void setActiveDevices( + DeviceIdLists ids, + EmptyCallback callback); + + // Sets the properties for the input or output device. + static void setProperties( + DOMString id, + DeviceProperties properties, + EmptyCallback callback); + + // Gets the system-wide mute state for the specified stream type. + // |streamType|: Stream type for which mute state should be fetched. + // |callback|: Callback reporting whether mute is set or not for specified + // stream type. + static void getMute( + StreamType streamType, + GetMuteCallback callback); + + // Sets mute state for a stream type. The mute state will apply to all audio + // devices with the specified audio stream type. + // |streamType|: Stream type for which mute state should be set. + // |isMuted|: New mute value. + static void setMute( + StreamType streamType, + boolean isMuted, + optional EmptyCallback callback); + }; + + interface Events { + // Fired when sound level changes for an active audio device. + static void onLevelChanged(LevelChangedEvent event); + + // Fired when the mute state of the audio input or output changes. + // Note that mute state is system-wide and the new value applies to every + // audio device with specified stream type. + static void onMuteChanged(MuteChangedEvent event); + + // Fired when audio devices change, either new devices being added, or + // existing devices being removed. + // |devices|: List of all present audio devices after the change. + static void onDeviceListChanged(AudioDeviceInfo[] devices); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/automation.idl b/tools/under-control/src/extensions/common/api/automation.idl new file mode 100755 index 000000000..4f30b05b6 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/automation.idl @@ -0,0 +1,1577 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.automation API allows developers to access the +// automation (accessibility) tree for the browser. The tree resembles the DOM +// tree, but only exposes the semantic structure of a page. It can be +// used to programmatically interact with a page by examining names, roles, and +// states, listening for events, and performing actions on nodes. +[nocompile] namespace automation { + // Keep the following enums in sync with 'ui/accessibility/ax_enums.mojom'. + // They are kept here purely for extension docs generation. + + // Possible events fired on an $(ref:automation.AutomationNode). + enum EventType { + accessKeyChanged, + activeDescendantChanged, + alert, + // TODO(crbug.com/1464633) Fully remove ariaAttributeChangedDeprecated + // starting in 122, because although it was removed in 118, it is still + // present in earlier versions of LaCros. + ariaAttributeChangedDeprecated, + ariaCurrentChanged, + ariaNotificationsPosted, + atomicChanged, + autoCompleteChanged, + autocorrectionOccured, + autofillAvailabilityChanged, + blur, + busyChanged, + caretBoundsChanged, + checkedStateChanged, + checkedStateDescriptionChanged, + childrenChanged, + clicked, + collapsed, + controlsChanged, + detailsChanged, + describedByChanged, + descriptionChanged, + documentSelectionChanged, + documentTitleChanged, + dropeffectChanged, + editableTextChanged, + enabledChanged, + endOfTest, + expanded, + expandedChanged, + flowFromChanged, + flowToChanged, + focus, + focusAfterMenuClose, + focusChanged, + focusContext, + grabbedChanged, + haspopupChanged, + hide, + hierarchicalLevelChanged, + hitTestResult, + hover, + ignoredChanged, + imageAnnotationChanged, + imageFrameUpdated, + invalidStatusChanged, + keyShortcutsChanged, + labeledByChanged, + languageChanged, + layoutComplete, + layoutInvalidated, // fired when aria-busy goes false + liveRegionChanged, + liveRegionCreated, + liveRegionNodeChanged, // fired on a node within a live region. + liveRelevantChanged, + liveStatusChanged, + loadComplete, + loadStart, + locationChanged, + mediaStartedPlaying, + mediaStoppedPlaying, + menuEnd, + menuItemSelected, + menuListValueChangedDeprecated, + menuPopupEnd, + menuPopupStart, + menuStart, + mouseCanceled, + mouseDragged, + mouseMoved, + mousePressed, + mouseReleased, + multilineStateChanged, + multiselectableStateChanged, + nameChanged, + objectAttributeChanged, + orientationChanged, + parentChanged, + placeholderChanged, + positionInSetChanged, + rangeValueChanged, + rangeValueMaxChanged, + rangeValueMinChanged, + rangeValueStepChanged, + readonlyChanged, + relatedNodeChanged, + requiredStateChanged, + roleChanged, + rowCollapsed, + rowCountChanged, + rowExpanded, + scrollHorizontalPositionChanged, + scrollPositionChanged, + scrollVerticalPositionChanged, + scrolledToAnchor, + selectedChanged, + selectedChildrenChanged, + selectedValueChanged, + selection, + selectionAdd, + selectionRemove, + setSizeChanged, + show, + sortChanged, + stateChanged, + subtreeCreated, + textAttributeChanged, + textSelectionChanged, + textChanged, + tooltipClosed, + tooltipOpened, + treeChanged, + valueInTextFieldChanged, + valueChanged, // Deprecated. + windowActivated, + windowDeactivated, + windowVisibilityChanged + }; + + // Describes the purpose of an $(ref:automation.AutomationNode). + enum RoleType { + abbr, + alert, + alertDialog, + application, + article, + audio, + banner, + blockquote, + button, + canvas, + caption, + caret, + cell, + checkBox, + client, + code, + colorWell, + column, + columnHeader, + comboBoxGrouping, + comboBoxMenuButton, + comboBoxSelect, + comment, + complementary, + contentDeletion, + contentInsertion, + contentInfo, + date, + dateTime, + definition, + descriptionList, + descriptionListDetailDeprecated, + descriptionListTermDeprecated, + desktop, + details, + dialog, + directoryDeprecated, + disclosureTriangle, + disclosureTriangleGrouped, + // -------------------------------------------------------------- + // DPub Roles: + // https://www.w3.org/TR/dpub-aam-1.0/#mapping_role_table + docAbstract, + docAcknowledgments, + docAfterword, + docAppendix, + docBackLink, + docBiblioEntry, + docBibliography, + docBiblioRef, + docChapter, + docColophon, + docConclusion, + docCover, + docCredit, + docCredits, + docDedication, + docEndnote, + docEndnotes, + docEpigraph, + docEpilogue, + docErrata, + docExample, + docFootnote, + docForeword, + docGlossary, + docGlossRef, + docIndex, + docIntroduction, + docNoteRef, + docNotice, + docPageBreak, + docPageFooter, + docPageHeader, + docPageList, + docPart, + docPreface, + docPrologue, + docPullquote, + docQna, + docSubtitle, + docTip, + docToc, + // End DPub roles. + // -------------------------------------------------------------- + document, + embeddedObject, + emphasis, + feed, + figcaption, + figure, + footer, + footerAsNonLandmark, + form, + genericContainer, + // -------------------------------------------------------------- + // ARIA Graphics module roles: + // https://rawgit.com/w3c/graphics-aam/master/#mapping_role_table + graphicsDocument, + graphicsObject, + graphicsSymbol, + // End ARIA Graphics module roles. + // -------------------------------------------------------------- + grid, + gridCell, + group, + header, + headerAsNonLandmark, + heading, + iframe, + iframePresentational, + image, + imeCandidate, + inlineTextBox, + inputTime, + keyboard, + labelText, + layoutTable, + layoutTableCell, + layoutTableRow, + legend, + lineBreak, + link, + list, + listBox, + listBoxOption, + listGrid, // Native + listItem, + listMarker, + log, + main, + mark, + marquee, + math, + mathMLFraction, + mathMLIdentifier, + mathMLMath, + mathMLMultiscripts, + mathMLNoneScript, + mathMLNumber, + mathMLOperator, + mathMLOver, + mathMLPrescriptDelimiter, + mathMLRoot, + mathMLRow, + mathMLSquareRoot, + mathMLStringLiteral, + mathMLSub, + mathMLSubSup, + mathMLSup, + mathMLTable, + mathMLTableCell, + mathMLTableRow, + mathMLText, + mathMLUnder, + mathMLUnderOver, + menu, + menuBar, + menuItem, + menuItemCheckBox, + menuItemRadio, + menuListOption, + menuListPopup, + meter, + navigation, + note, + pane, + paragraph, + pdfActionableHighlight, + pdfRoot, + pluginObject, + popUpButton, + portalDeprecated, + preDeprecated, + progressIndicator, + radioButton, + radioGroup, + region, + rootWebArea, + row, + rowGroup, + rowHeader, + ruby, + rubyAnnotation, + scrollBar, + scrollView, + search, + searchBox, + section, + sectionWithoutName, + slider, + spinButton, + splitter, + staticText, + status, + strong, + subscript, + suggestion, + superscript, + svgRoot, + switch, + tab, + tabList, + tabPanel, + table, + tableHeaderContainer, + term, + textField, + textFieldWithComboBox, + time, + timer, + titleBar, + toggleButton, + toolbar, + tooltip, + tree, + treeGrid, + treeItem, + unknown, + video, + webView, + window + }; + + // Describes characteristics of an $(ref:automation.AutomationNode). + enum StateType { + autofillAvailable, + collapsed, + default, + editable, + expanded, + focusable, + focused, + horizontal, + hovered, + ignored, + invisible, + linked, + multiline, + multiselectable, + offscreen, + protected, + required, + richlyEditable, + vertical, + visited + }; + + // All possible actions that can be performed on automation nodes. + enum ActionType { + annotatePageImages, + blur, + clearAccessibilityFocus, + collapse, + customAction, + decrement, + doDefault, + expand, + focus, + getImageData, + getTextLocation, + hideTooltip, + hitTest, + increment, + internalInvalidateTree, + loadInlineTextBoxes, + longClick, + replaceSelectedText, + resumeMedia, + scrollBackward, + scrollDown, + scrollForward, + scrollLeft, + scrollRight, + scrollUp, + scrollToMakeVisible, + scrollToPoint, + scrollToPositionAtRowColumn, + setAccessibilityFocus, + setScrollOffset, + setSelection, + setSequentialFocusNavigationStartingPoint, + setValue, + showContextMenu, + signalEndOfTest, + showTooltip, + stitchChildTree, + startDuckingMedia, + stopDuckingMedia, + suspendMedia + }; + + // Possible changes to the automation tree. For any given atomic change + // to the tree, each node that's added, removed, or changed, will appear + // in exactly one TreeChange, with one of these types. + // + // nodeCreated means that this node was added to the tree and its parent is + // new as well, so it's just one node in a new subtree that was added. + enum TreeChangeType { + /** + * This node was added to the tree and its parent is new as well, + * so it's just one node in a new subtree that was added. + */ + nodeCreated, + + /** + * This node was added to the tree but its parent was already in the + * tree, so it's possibly the root of a new subtree - it does not mean + * that it necessarily has children. + */ + subtreeCreated, + + /** + * This node changed. + */ + nodeChanged, + + /** + * This node's text (name) changed. + */ + textChanged, + + /** + * This node was removed. + */ + nodeRemoved, + /** + * This subtree has finished an update. + */ + subtreeUpdateEnd + }; + + // Where the node's name is from. + enum NameFromType { + attribute, + attributeExplicitlyEmpty, + caption, + contents, + placeholder, + popoverAttribute, + prohibited, + relatedElement, + title, + value + }; + + enum DescriptionFromType { + ariaDescription, + attributeExplicitlyEmpty, + buttonLabel, + popoverAttribute, + prohibitedNameRepair, + relatedElement, + rubyAnnotation, + summary, + svgDescElement, + tableCaption, + title + }; + + // The input restriction for a object -- even non-controls can be disabled. + enum Restriction { + disabled, + readOnly + }; + + // Availability and types for an interactive popup element. + enum HasPopup { + false, + true, + menu, + listbox, + tree, + grid, + dialog + }; + + // Indicates the ARIA-current state. + enum AriaCurrentState { + false, + true, + page, + step, + location, + date, + time + }; + + // Lists the values that `invalidState` can take on. + enum InvalidState { + false, + true + }; + + // Describes possible actions when performing a do default action. + enum DefaultActionVerb { + activate, + check, + click, + clickAncestor, + jump, + open, + press, + select, + uncheck +}; + + // Types of markers on text. See AutomationNode.markerTypes. +enum MarkerType { + spelling, + grammar, + textMatch, + activeSuggestion, + suggestion, + highlight +}; + +// The following three enums are associated with an $(ref:automation.AutomationIntent). + +// A command associated with an $(ref:automation.AutomationIntent). +enum IntentCommandType { + clearSelection, + delete, + dictate, + extendSelection, + format, + history, + insert, + marker, + moveSelection, + setSelection +}; + +// The type of an input event associated with an $(ref:automation.AutomationIntent). It describes an edit +// command, e.g. IntentCommandType.insert, in more detail. +enum IntentInputEventType { + // Insertion. + insertText, + insertLineBreak, + insertParagraph, + insertOrderedList, + insertUnorderedList, + insertHorizontalRule, + insertFromPaste, + insertFromDrop, + insertFromYank, + insertTranspose, + insertReplacementText, + insertCompositionText, + insertLink, + // Deletion. + deleteWordBackward, + deleteWordForward, + deleteSoftLineBackward, + deleteSoftLineForward, + deleteHardLineBackward, + deleteHardLineForward, + deleteContentBackward, + deleteContentForward, + deleteByCut, + deleteByDrag, + // History. + historyUndo, + historyRedo, + // Formatting. + formatBold, + formatItalic, + formatUnderline, + formatStrikeThrough, + formatSuperscript, + formatSubscript, + formatJustifyCenter, + formatJustifyFull, + formatJustifyRight, + formatJustifyLeft, + formatIndent, + formatOutdent, + formatRemove, + formatSetBlockTextDirection +}; + +// A text boundary associated with an $(ref:automation.AutomationIntent). +enum IntentTextBoundaryType { + character, + formatEnd, + formatStart, + formatStartOrEnd, + lineEnd, + lineStart, + lineStartOrEnd, + object, + pageEnd, + pageStart, + pageStartOrEnd, + paragraphEnd, + paragraphStart, + paragraphStartSkippingEmptyParagraphs, + paragraphStartOrEnd, + sentenceEnd, + sentenceStart, + sentenceStartOrEnd, + webPage, + wordEnd, + wordStart, + wordStartOrEnd +}; + +// A move direction associated with an $(ref:automation.AutomationIntent). +enum IntentMoveDirectionType { + backward, + forward +}; + +// A sort applied to a table row or column header. +enum SortDirectionType { + unsorted, + ascending, + descending, + other +}; + +// A type of AutomationPosition. +enum PositionType { + null, + text, + tree +}; + + dictionary Rect { + long left; + long top; + long width; + long height; + }; + + // Arguments for the find() and findAll() methods. + [nocompile, noinline_doc] dictionary FindParams { + RoleType? role; + + // A map of $(ref:automation.StateType) to boolean, indicating for each + // state whether it should be set or not. For example: + // { StateType.disabled: false } would only match if + // StateType.disabled was not present in the node's + // state object. + object? state; + + // A map of attribute name to expected value, for example + // { name: 'Root directory', checkbox_mixed: true }. + // String attribute values may be specified as a regex, for example + // { name: /stralia$/ }
. + // Unless specifying a regex, the expected value must be an exact match + // in type and value for the actual value. Thus, the type of expected value + // must be one of: + //
    + //
  • string
  • + //
  • integer
  • + //
  • float
  • + //
  • boolean
  • + //
+ object? attributes; + }; + + // Arguments for the setDocumentSelection() function. + [nocompile, noinline_doc] dictionary SetDocumentSelectionParams { + // The node where the selection begins. + [instanceOf=AutomationNode] object anchorObject; + + // The offset in the anchor node where the selection begins. + long anchorOffset; + + // The node where the selection ends. + [instanceOf=AutomationNode] object focusObject; + + // The offset within the focus node where the selection ends. + long focusOffset; + }; + + [nocompile, noinline_doc] dictionary AutomationIntent { + // A command associated with this AutomationIntent. + IntentCommandType command; + + // A text boundary associated with this AutomationIntent. + IntentTextBoundaryType textBoundary; + + // A move direction associated with this AutomationIntent. + IntentMoveDirectionType moveDirection; + }; + + // An event in the Automation tree. + [nocompile, noinline_doc] dictionary AutomationEvent { + // The $(ref:automation.AutomationNode) to which the event was targeted. + AutomationNode target; + + // The type of the event. + EventType type; + + // The source of this event. + DOMString eventFrom; + + // Any mouse coordinates associated with this event. + long mouseX; + long mouseY; + + // A list of $(ref:automation.AutomationIntent)s associated with this event. + AutomationIntent[] intents; + + // Stops this event from further processing except for any remaining + // listeners on $(ref:automation.AutomationEvent.target). + static void stopPropagation(); + }; + + // A listener for events on an AutomationNode. + callback AutomationListener = void(AutomationEvent event); + + // A change to the Automation tree. + [nocompile, noinline_doc] dictionary TreeChange { + // The $(ref:automation.AutomationNode) that changed. + AutomationNode target; + + // The type of change. + TreeChangeType type; + }; + + // Possible tree changes to listen to using addTreeChangeObserver. + // Note that listening to all tree changes can be expensive. + enum TreeChangeObserverFilter { + noTreeChanges, + liveRegionTreeChanges, + textMarkerChanges, + allTreeChanges + }; + + // A listener for changes on the AutomationNode tree. + callback TreeChangeObserver = void(TreeChange treeChange); + + // Callback called for actions with a response. + callback PerformActionCallback = void(boolean result); + callback PerformActionCallbackWithNode = void(AutomationNode node); + callback BoundsForRangeCallback = void(Rect bounds); + + [nocompile, noinline_doc] dictionary CustomAction { + long id; + DOMString description; + }; + + // A marker associated with an AutomationNode. + [nocompile, noinline_doc] dictionary Marker { + // The start offset within the text of the associated node. + long startOffset; + + // The end offset within the text of the associated node. + long endOffset; + + // A mapping of MarkerType to true or undefined indicating the marker types + // for this marker. + object flags; + }; + + // A position in the automation tree. + // See ui/accessibility/ax_position.h for documentation. All members need to + // be kept in sync with + // extensions/renderer/api/automation/automation_position.h. + // Some members there are kept private and not represented here. + [nocompile, noinline_doc] dictionary AutomationPosition { + + AutomationNode? node; + long childIndex; + long textOffset; + DOMString affinity; + + static boolean isNullPosition(); + static boolean isTreePosition(); + static boolean isTextPosition(); + static boolean isLeafTextPosition(); + static boolean atStartOfAnchor(); + static boolean atEndOfAnchor(); + static boolean atStartOfWord(); + static boolean atEndOfWord(); + static boolean atStartOfLine(); + static boolean atEndOfLine(); + static boolean atStartOfParagraph(); + static boolean atEndOfParagraph(); + static boolean atStartOfPage(); + static boolean atEndOfPage(); + static boolean atStartOfFormat(); + static boolean atEndOfFormat(); + static boolean atStartOfDocument(); + static boolean atEndOfDocument(); + static void asTreePosition(); + static void asTextPosition(); + static void asLeafTextPosition(); + static void moveToPositionAtStartOfAnchor(); + static void moveToPositionAtEndOfAnchor(); + static void moveToPositionAtStartOfDocument(); + static void moveToPositionAtEndOfDocument(); + static void moveToParentPosition(); + static void moveToNextLeafTreePosition(); + static void moveToPreviousLeafTreePosition(); + static void moveToNextLeafTextPosition(); + static void moveToPreviousLeafTextPosition(); + static void moveToNextCharacterPosition(); + static void moveToPreviousCharacterPosition(); + static void moveToNextWordStartPosition(); + static void moveToPreviousWordStartPosition(); + static void moveToNextWordEndPosition(); + static void moveToPreviousWordEndPosition(); + static void moveToNextLineStartPosition(); + static void moveToPreviousLineStartPosition(); + static void moveToNextLineEndPosition(); + static void moveToPreviousLineEndPosition(); + static void moveToNextFormatStartPosition(); + static void moveToPreviousFormatStartPosition(); + static void moveToNextFormatEndPosition(); + static void moveToPreviousFormatEndPosition(); + static void moveToNextParagraphStartPosition(); + static void moveToPreviousParagraphStartPosition(); + static void moveToNextParagraphEndPosition(); + static void moveToPreviousParagraphEndPosition(); + static void moveToNextPageStartPosition(); + static void moveToPreviousPageStartPosition(); + static void moveToNextPageEndPosition(); + static void moveToPreviousPageEndPosition(); + static void moveToNextAnchorPosition(); + static void moveToPreviousAnchorPosition(); + static long maxTextOffset(); + static boolean isInLineBreak(); + static boolean isInTextObject(); + static boolean isInWhiteSpace(); + static boolean isValid(); + static DOMString getText(); + }; + + // A single node in an Automation tree. + [nocompile, noinline_doc] dictionary AutomationNode { + // The root node of the tree containing this AutomationNode. + AutomationNode? root; + + // Whether this AutomationNode is a root node. + boolean isRootNode; + + // The role of this node. + RoleType? role; + + // The $(ref:automation.StateType)s describing this node. + // @type {Object} + // + object? state; + + // The rendered location (as a bounding box) of this node in global + // screen coordinates. + Rect location; + + // Determines the location of the text within the node specified by + // |startIndex| and |endIndex|, inclusively. Invokes |callback| with the + // bounding rectangle, in screen coordinates. |callback| can be invoked + // either synchronously or asynchronously. The bounds are clipped to + // ancestors. + static void boundsForRange(long startIndex, long endIndex, + BoundsForRangeCallback callback); + + // Determines the location of the text within the node specified by + // |startIndex| and |endIndex|, inclusively. Invokes |callback| with the + // bounding rectangle, in screen coordinates. |callback| can be invoked + // either synchronously or asynchronously. The bounds are not clipped to + // ancestors. + static void unclippedBoundsForRange(long startIndex, long endIndex, + BoundsForRangeCallback callback); + + // The location (as a bounding box) of this node in global screen + // coordinates without applying any clipping from ancestors. + Rect? unclippedLocation; + + // The purpose of the node, other than the role, if any. + DOMString? description; + + // Description of the state of the checkbox. + // Used only when the node is checkable. + DOMString? checkedStateDescription; + + // The placeholder for this text field, if any. + DOMString? placeholder; + + // The role description for this node. + DOMString? roleDescription; + + // The accessible name for this node, via the + // + // Accessible Name Calculation process. + DOMString? name; + + // Explains what will happen when the doDefault action is performed. + DOMString? doDefaultLabel; + + // Explains what will happen when the long click action is performed. + DOMString? longClickLabel; + + // The tooltip of the node, if any. + DOMString? tooltip; + + // The source of the name. + NameFromType? nameFrom; + + // The image annotation for image nodes, which may be a human-readable + // string that is the contextualized annotation or a status string related + // to annotations. + DOMString? imageAnnotation; + + // The value for this node: for example the value attribute of + // an <input> element. + DOMString? value; + + // The HTML id for this element, if this node is an HTML element. + DOMString? htmlId; + + // The HTML tag for this element, if this node is an HTML element. + DOMString? htmlTag; + + // The level of a heading or tree item. + long? hierarchicalLevel; + + // The current caret bounds in screen coordinates. + Rect? caretBounds; + + // The start and end index of each word in an inline text box. + long[]? wordStarts; + long[]? wordEnds; + + // The start indexes of each sentence within the node's name. + long[]? sentenceStarts; + + // The end indexes of each sentence within the node's name. For most nodes, + // the size of sentenceStarts array should be equal to the size of + // sentenceEnds array. Two exceptions are (1) node at the begining of a + // paragraph but the end of the node's sentences is in its following node. + // Such a node has one more start index. (2) Node at the end of a paragraph + // but the start of the node's sentences is in its previous node. Such a + // node has one more end index. For example,

Hello world.

has + // two nodes. The first one has one start index (i.e., 0) but no end index. + // The second node has one end index (i.e., 7) but no start index. + long[]? sentenceEnds; + + // The start index of each word within the node's name. This is different + // from wordStarts because it is not restricted to inline text boxes and can + // be used for any type of element. + long[]? nonInlineTextWordStarts; + + // The end index of each word within the node's name. This is different + // from wordEnds because it is not restricted to inline text boxes and can + // be used for any type of element. + long[]? nonInlineTextWordEnds; + + // The nodes, if any, which this node is specified to control via + // + // aria-controls. + AutomationNode[]? controls; + + // The nodes, if any, which form a description for this node. + AutomationNode[]? describedBy; + + // The nodes, if any, which may optionally be navigated to after this + // one. See + // + // aria-flowto. + AutomationNode[]? flowTo; + + // The nodes, if any, which form a label for this element. Generally, the + // text from these elements will also be exposed as the element's accessible + // name, via the $(ref:automation.AutomationNode.name) attribute. + AutomationNode[]? labelledBy; + + // The node referred to by aria-activedescendant, where + // applicable + AutomationNode? activeDescendant; + + // Reverse relationship for active descendant. + AutomationNode[]? activeDescendantFor; + + // The target of an in-page link. + AutomationNode? inPageLinkTarget; + + // A node that provides more details about the current node. + AutomationNode[]? details; + + // The nodes, if any, that provide an error message for the current node. + AutomationNode[]? errorMessages; + + // Reverse relationship for details. + AutomationNode[]? detailsFor; + + // Reverse relationship for errorMessage. + AutomationNode[]? errorMessageFor; + + // Reverse relationship for controls. + AutomationNode[]? controlledBy; + + // Reverse relationship for describedBy. + AutomationNode[]? descriptionFor; + + // Reverse relationship for flowTo. + AutomationNode[]? flowFrom; + + // Reverse relationship for labelledBy. + AutomationNode[]? labelFor; + + // The column header nodes for a table cell. + AutomationNode[]? tableCellColumnHeaders; + + // The row header nodes for a table cell. + AutomationNode[]? tableCellRowHeaders; + + // An array of standard actions available on this node. + ActionType[]? standardActions; + + // An array of custom actions. + CustomAction[]? customActions; + + // The action taken by calling doDefault. + DefaultActionVerb? defaultActionVerb; + + // + // Link attributes. + // + + // The URL that this link will navigate to. + DOMString? url; + + // + // Document attributes. + // + + // The URL of this document. + DOMString? docUrl; + + // The title of this document. + DOMString? docTitle; + + // Whether this document has finished loading. + boolean? docLoaded; + + // The proportion (out of 1.0) that this doc has completed loading. + double? docLoadingProgress; + + // + // Scrollable container attributes. + // + + long? scrollX; + long? scrollXMin; + long? scrollXMax; + long? scrollY; + long? scrollYMin; + long? scrollYMax; + + // Indicates whether this node is scrollable. + boolean? scrollable; + + // + // Editable text field attributes. + // + + // The character index of the start of the selection within this editable + // text element; -1 if no selection. + long? textSelStart; + + // The character index of the end of the selection within this editable + // text element; -1 if no selection. + long? textSelEnd; + + // An array of Marker objects for this node. + Marker[]? markers; + + // + // Tree selection attributes (available on root nodes only) + // + + // If a selection is present, whether the anchor of the selection comes + // after its focus in the accessibility tree. + boolean? isSelectionBackward; + // The anchor node of the tree selection, if any. + AutomationNode? anchorObject; + // The anchor offset of the tree selection, if any. + long? anchorOffset; + // The affinity of the tree selection anchor, if any. + DOMString? anchorAffinity; + // The focus node of the tree selection, if any. + AutomationNode? focusObject; + // The focus offset of the tree selection, if any. + long? focusOffset; + // The affinity of the tree selection focus, if any. + DOMString? focusAffinity; + + // The selection start node of the tree selection, if any. + AutomationNode? selectionStartObject; + // The selection start offset of the tree selection, if any. + long? selectionStartOffset; + // The affinity of the tree selection start, if any. + DOMString? selectionStartAffinity; + // The selection end node of the tree selection, if any. + AutomationNode? selectionEndObject; + // The selection end offset of the tree selection, if any. + long? selectionEndOffset; + // The affinity of the tree selection end, if any. + DOMString? selectionEndAffinity; + + // Indicates that the node is marked user-select:none + boolean? notUserSelectableStyle; + + // + // Range attributes. + // + + // The current value for this range. + double? valueForRange; + + // The minimum possible value for this range. + double? minValueForRange; + + // The maximum possible value for this range. + double? maxValueForRange; + + // + // List attributes. + // + + // The 1-based index of an item in a set. + long? posInSet; + + // The number of items in a set; + long? setSize; + + // + // Table attributes. + // + + // The number of rows in this table as specified in the DOM. + long? tableRowCount; + + // The number of rows in this table as specified by the page author. + long? ariaRowCount; + + // The number of columns in this table as specified in the DOM. + long? tableColumnCount; + + // The number of columns in this table as specified by the page author. + long? ariaColumnCount; + + // + // Table cell attributes. + // + + // The zero-based index of the column that this cell is in as specified in + // the DOM. + long? tableCellColumnIndex; + + // The ARIA column index as specified by the page author. + long? tableCellAriaColumnIndex; + + // The number of columns that this cell spans (default is 1). + long? tableCellColumnSpan; + + // The zero-based index of the row that this cell is in as specified in the + // DOM. + long? tableCellRowIndex; + + // The ARIA row index as specified by the page author. + long? tableCellAriaRowIndex; + + // The number of rows that this cell spans (default is 1). + long? tableCellRowSpan; + + // The corresponding column header for this cell. + AutomationNode? tableColumnHeader; + + // The corresponding row header for this cell. + AutomationNode? tableRowHeader; + + // The column index of this column node. + long? tableColumnIndex; + + // The row index of this row node. + long? tableRowIndex; + + // + // Live region attributes. + // + + // The type of region if this is the root of a live region. + // Possible values are 'polite' and 'assertive'. + DOMString? liveStatus; + + // The value of aria-relevant for a live region. + DOMString? liveRelevant; + + // The value of aria-atomic for a live region. + boolean? liveAtomic; + + // The value of aria-busy for a live region or any other element. + boolean? busy; + + // The type of live region if this node is inside a live region. + DOMString? containerLiveStatus; + + // The value of aria-relevant if this node is inside a live region. + DOMString? containerLiveRelevant; + + // The value of aria-atomic if this node is inside a live region. + boolean? containerLiveAtomic; + + // The value of aria-busy if this node is inside a live region. + boolean? containerLiveBusy; + + // + // Miscellaneous attributes. + // + + // Whether or not this node is a button. + boolean isButton; + + // Whether or not this node is a checkbox. + boolean isCheckBox; + + // Whether or not this node is a combobox. + boolean isComboBox; + + // Whether or not this node is an image. + boolean isImage; + + // Whether the node contains hidden nodes. + boolean hasHiddenOffscreenNodes; + + // Aria auto complete. + DOMString? autoComplete; + + // The name of the programmatic backing object. + DOMString? className; + + // Marks this subtree as modal. + boolean? modal; + + // A map containing all HTML attributes and their values + // @type {Object} + object? htmlAttributes; + + // The input type of a text field, such as "text" or "email". + DOMString? inputType; + + // The key that activates this widget. + DOMString? accessKey; + + // The value of the aria-invalid attribute, indicating the error type. + DOMString? ariaInvalidValue; + + // The CSS display attribute for this node, if applicable. + DOMString? display; + + // A data url with the contents of this object's image or thumbnail. + DOMString? imageDataUrl; + + // The author-provided language code for this subtree. + DOMString? language; + + // The detected language code for this subtree. + DOMString? detectedLanguage; + + // Indicates the availability and type of an interactive popup element. + HasPopup? hasPopup; + + // Input restriction, if any, such as readonly or disabled: + // undefined - enabled control or other object that is not disabled + // Restriction.DISABLED - disallows input in itself + any descendants + // Restriction.READONLY - allow focus/selection but not input + DOMString? restriction; + + // Tri-state describing checkbox or radio button: + // 'false' | 'true' | 'mixed' + DOMString? checked; + + // The inner html of this element. Only populated for math content. + DOMString? innerHtml; + + // The RGBA foreground color of this subtree, as an integer. + long? color; + + // The RGBA background color of this subtree, as an integer. + long? backgroundColor; + + // The RGBA color of an input element whose value is a color. + long? colorValue; + + // Indicates node text is subscript. + boolean subscript; + + // Indicates node text is superscript. + boolean superscript; + + // Indicates node text is bold. + boolean bold; + + // Indicates node text is italic. + boolean italic; + + // Indicates node text is underline. + boolean underline; + + // Indicates node text is line through. + boolean lineThrough; + + // Indicates whether this node is selected, unselected, or neither. + boolean? selected; + + // Indicates the font size of this node. + long? fontSize; + + // Indicates the font family. + DOMString fontFamily; + + // Indicates whether the object functions as a text field which exposes its + // descendants. Use cases include the root of a content-editable region, an + // ARIA textbox which isn't currently editable and which has interactive + // descendants, and a element that has "design-mode" set to "on". + boolean nonAtomicTextFieldRoot; + + // Indicates aria-current state. + AriaCurrentState? ariaCurrentState; + + // Indicates invalid-state. + InvalidState? invalidState; + + // The application id for a tree rooted at this node. + DOMString? appId; + + // + // Walking the tree. + // + + AutomationNode[] children; + AutomationNode? parent; + AutomationNode? firstChild; + AutomationNode? lastChild; + AutomationNode? previousSibling; + AutomationNode? nextSibling; + AutomationNode? previousOnLine; + AutomationNode? nextOnLine; + AutomationNode? previousFocus; + AutomationNode? nextFocus; + AutomationNode? previousWindowFocus; + AutomationNode? nextWindowFocus; + + // The index of this node in its parent node's list of children. If this is + // the root node, this will be undefined. + long? indexInParent; + + // The sort direction of this node. + SortDirectionType sortDirection; + + // Explicitly set to true when this node is clickable. + boolean clickable; + + // + // Actions. + // + + // Does the default action based on this node's role. This is generally + // the same action that would result from clicking the node such as + // expanding a treeitem, toggling a checkbox, selecting a radiobutton, + // or activating a button. + static void doDefault(); + + // Places focus on this node. + static void focus(); + + // Request a data url for the contents of an image, optionally + // resized. Pass zero for maxWidth and/or maxHeight for the + // original size. + static void getImageData(long maxWidth, long maxHeight); + + // Does a hit test of the given global screen coordinates, and fires + // eventToFire on the resulting object. + static void hitTest( + long x, + long y, + EventType eventToFire); + + // Does a $(ref:automation.AutomationNode.hitTest), and receives a callback + // with the resulting hit node. + static void hitTestWithReply( + long x, + long y, + PerformActionCallbackWithNode callback); + + // Scrolls this node to make it visible. + static void makeVisible(); + + // Performs custom action. + static void performCustomAction(long customActionId); + + // Convenience method to perform a standard action supported by this node. + // For actions requiring additional arguments, call the specific binding + // e.g. setSelection. + static void performStandardAction(ActionType actionType); + + // Replaces the selected text within a text field. + static void replaceSelectedText(DOMString value); + + // Sets accessibility focus. Accessibility focus is the node on which an + // extension tracks a user's focus. This may be conveyed through a focus + // ring or or speech output by the extension. Automation will dispatch more + // events to the accessibility focus such as location changes. + static void setAccessibilityFocus(); + + // Sets selection within a text field. + static void setSelection(long startIndex, long endIndex); + + // Clears focus and sets this node as the starting point for the next + // time the user presses Tab or Shift+Tab. + static void setSequentialFocusNavigationStartingPoint(); + + // Sets the value of a text field. + static void setValue(DOMString value); + + // Show the context menu for this element, as if the user right-clicked. + static void showContextMenu(); + + // Resume playing any media within this tree. + static void resumeMedia(); + + // Start ducking any media within this tree. + static void startDuckingMedia(); + + // Stop ducking any media within this tree. + static void stopDuckingMedia(); + + // Suspend any media playing within this tree. + static void suspendMedia(); + + // Simulates long click on node. + static void longClick(); + + // Scrolls this scrollable container backward. + static void scrollBackward(optional PerformActionCallback callback); + + // Scrolls this scrollable container forward. + static void scrollForward(optional PerformActionCallback callback); + + // Scrolls this scrollable container up. + static void scrollUp(optional PerformActionCallback callback); + + // Scrolls this scrollable container down. + static void scrollDown(optional PerformActionCallback callback); + + // Scrolls this scrollable container left. + static void scrollLeft(optional PerformActionCallback callback); + + // Scrolls this scrollable container right. + static void scrollRight(optional PerformActionCallback callback); + + // Scrolls this scrollable container to the given point. + static void scrollToPoint(long x, long y); + + // Sets this scrollable container's scroll offset. + static void setScrollOffset(long x, long y); + + // Adds a listener for the given event type and event phase. + static void addEventListener( + EventType eventType, AutomationListener listener, boolean capture); + + // Removes a listener for the given event type and event phase. + static void removeEventListener( + EventType eventType, AutomationListener listener, boolean capture); + + // Finds the first AutomationNode in this node's subtree which matches the + // given search parameters. + static AutomationNode find(FindParams params); + + // Finds all the AutomationNodes in this node's subtree which matches the + // given search parameters. + static AutomationNode[] findAll(FindParams params); + + // Returns whether this node matches the given $(ref:automation.FindParams). + static boolean matches(FindParams params); + + static AutomationNode getNextTextMatch( + DOMString searchStr, boolean backward); + + // Creates a position object backed by Chrome's accessibility position support. + static AutomationPosition createPosition(PositionType type, long offset, optional boolean isUpstream); + }; + + // Called when the AutomationNode for the page is available. + callback RootCallback = void(AutomationNode rootNode); + + // Called with the AutomationNode that currently has focus. + callback FocusCallback = void(AutomationNode focusedNode); + + // Called with the AutomationNode that currently has + // accessibility focus. + callback AccessibilityFocusCallback = void(AutomationNode focusedNode); + + interface Functions { + // Get the automation tree for the whole desktop which consists of all on + // screen views. Note this API is currently only supported on Chrome OS. + [nocompile] static void getDesktop(RootCallback callback); + + // Get the automation node that currently has focus, globally. Will return + // null if none of the nodes in any loaded trees have focus. + [nocompile] static void getFocus(FocusCallback callback); + + // Get the automation node that currently has accessibility focus, globally. + // Will return null if none of the nodes in any loaded trees have + // accessibility focus. + [nocompile] static void getAccessibilityFocus( + AccessibilityFocusCallback callback); + + // Add a tree change observer. Tree change observers are static/global, they + // listen to changes across all trees. Pass a filter to determine what + // specific tree changes to listen to, and note that listnening to all + // tree changes can be expensive. + [nocompile, trailingCallbackIsFunctionParameter] + static void addTreeChangeObserver( + TreeChangeObserverFilter filter, TreeChangeObserver observer); + + // Remove a tree change observer. + [nocompile, trailingCallbackIsFunctionParameter] + static void removeTreeChangeObserver( + TreeChangeObserver observer); + + // Sets the selection in a tree. This creates a selection in a single + // tree (anchorObject and focusObject must have the same root). + // Everything in the tree between the two node/offset pairs gets included + // in the selection. The anchor is where the user started the selection, + // while the focus is the point at which the selection gets extended + // e.g. when dragging with a mouse or using the keyboard. For nodes with + // the role staticText, the offset gives the character offset within + // the value where the selection starts or ends, respectively. + [nocompile] static void setDocumentSelection( + SetDocumentSelectionParams params); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/automation_internal.idl b/tools/under-control/src/extensions/common/api/automation_internal.idl new file mode 100755 index 000000000..85ef3ab0b --- /dev/null +++ b/tools/under-control/src/extensions/common/api/automation_internal.idl @@ -0,0 +1,167 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This is the implementation layer of the chrome.automation API, and is +// essentially a translation of the internal accessibility tree update system +// into an extension API. +namespace automationInternal { + // Data for an accessibility event and/or an atomic change to an accessibility + // tree. See ui/accessibility/ax_tree_update.h for an extended explanation of + // the tree update format. + [nocompile] dictionary AXEventParams { + // The tree id of the web contents that this update is for. + DOMString treeID; + + // ID of the node that the event applies to. + long targetID; + + // The type of event that this update represents. + DOMString eventType; + + // The source of this event. + DOMString eventFrom; + + // The mouse coordinates when this event fired. + double mouseX; + double mouseY; + + + // ID of an action request resulting in this event. + long actionRequestID; + }; + + dictionary AXTextLocationParams { + DOMString treeID; + long nodeID; + boolean result; + long left; + long top; + long width; + long height; + long requestID; + }; + + // Arguments required for all actions supplied to performAction. + dictionary PerformActionRequiredParams { + DOMString treeID; + long automationNodeID; + + // This can be either automation::ActionType or + // automation_internal::ActionTypePrivate. + DOMString actionType; + + long? requestID; + }; + + // Arguments for the customAction action. Those args are passed to + // performAction as opt_args. + dictionary PerformCustomActionParams { + long customActionID; + }; + + // Arguments for the setSelection action supplied to performAction. + dictionary SetSelectionParams { + // Reuses ActionRequiredParams automationNodeID to mean anchor node id, + // and treeID to apply to both anchor and focus node ids. + long focusNodeID; + long anchorOffset; + long focusOffset; + }; + + // Arguments for the replaceSelectedText action supplied to performAction. + dictionary ReplaceSelectedTextParams { + DOMString value; + }; + + // Arguments for the setValue action supplied to performAction. + dictionary SetValueParams { + DOMString value; + }; + + + // Arguments for the scrollToPoint action supplied to performAction. + dictionary ScrollToPointParams { + long x; + long y; + }; + + // Arguments for the scrollToPositionAtRowColumn action supplied to performAction. + dictionary ScrollToPositionAtRowColumnParams { + long row; + long column; + }; + + // Arguments for the SetScrollOffset action supplied to performAction. + dictionary SetScrollOffsetParams { + long x; + long y; + }; + + // Arguments for the getImageData action. + dictionary GetImageDataParams { + long maxWidth; + long maxHeight; + }; + + // Arguments for the hitTest action. + dictionary HitTestParams { + long x; + long y; + DOMString eventToFire; + }; + + // Arguments for getTextLocation action. + dictionary GetTextLocationDataParams { + long startIndex; + long endIndex; + }; + + // Callback called when enableDesktop() returns. Returns the accessibility + // tree id of the desktop tree. + callback EnableDesktopCallback = void(DOMString tree_id); + + // Callback called when disableDesktop() returns. It is safe to clear + // accessibility api state at that point. + callback DisableDesktopCallback = void(); + + interface Functions { + // Enable automation of the tree with the given id. + static void enableTree(DOMString tree_id); + + // Enables desktop automation. + static void enableDesktop( + EnableDesktopCallback callback); + + // Disables desktop automation. + static void disableDesktop(DisableDesktopCallback callback); + + // Performs an action on an automation node. + static void performAction(PerformActionRequiredParams args, + object opt_args); + }; + + interface Events { + // Fired when an accessibility event occurs + static void onAccessibilityEvent(AXEventParams update); + + static void onAccessibilityTreeDestroyed(DOMString treeID); + + static void onGetTextLocationResult(AXTextLocationParams params); + + static void onTreeChange(long observerID, + DOMString treeID, + long nodeID, + DOMString changeType); + + static void onChildTreeID(DOMString treeID); + + static void onNodesRemoved(DOMString treeID, long[] nodeIDs); + + static void onAccessibilityTreeSerializationError(DOMString treeID); + + static void onActionResult(DOMString treeID, long requestID, boolean result); + + static void onAllAutomationEventListenersRemoved(); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/bluetooth.idl b/tools/under-control/src/extensions/common/api/bluetooth.idl new file mode 100755 index 000000000..0000d129b --- /dev/null +++ b/tools/under-control/src/extensions/common/api/bluetooth.idl @@ -0,0 +1,187 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.bluetooth API to connect to a Bluetooth +// device. All functions report failures via chrome.runtime.lastError. +namespace bluetooth { + // Allocation authorities for Vendor IDs. + enum VendorIdSource {bluetooth, usb}; + + // Common device types recognized by Chrome. + enum DeviceType {computer, phone, modem, audio, carAudio, video, peripheral, + joystick, gamepad, keyboard, mouse, tablet, + keyboardMouseCombo}; + + // Types for filtering bluetooth devices. + enum FilterType {all, known}; + + // Transport type of the bluetooth device. + enum Transport {invalid, classic, le, dual}; + + // Information about the state of the Bluetooth adapter. + dictionary AdapterState { + // The address of the adapter, in the format 'XX:XX:XX:XX:XX:XX'. + DOMString address; + + // The human-readable name of the adapter. + DOMString name; + + // Indicates whether or not the adapter has power. + boolean powered; + + // Indicates whether or not the adapter is available (i.e. enabled). + boolean available; + + // Indicates whether or not the adapter is currently discovering. + boolean discovering; + }; + + // Callback from the getAdapterState method. + // |adapterInfo| : Object containing the adapter information. + callback AdapterStateCallback = void(AdapterState adapterInfo); + + // Information about the state of a known Bluetooth device. Note: this + // dictionary is also used in bluetooth_private.idl + dictionary Device { + // The address of the device, in the format 'XX:XX:XX:XX:XX:XX'. + DOMString address; + + // The human-readable name of the device. + DOMString? name; + + // The class of the device, a bit-field defined by + // http://www.bluetooth.org/en-us/specification/assigned-numbers/baseband. + long? deviceClass; + + // The Device ID record of the device, where available. + VendorIdSource? vendorIdSource; + long? vendorId; + long? productId; + long? deviceId; + + // The type of the device, if recognized by Chrome. This is obtained from + // the |deviceClass| field and only represents a small fraction of the + // possible device types. When in doubt you should use the |deviceClass| + // field directly. + DeviceType? type; + + // Indicates whether or not the device is paired with the system. + boolean? paired; + + // Indicates whether the device is currently connected to the system. + boolean? connected; + + // Indicates whether the device is currently connecting to the system. + boolean? connecting; + + // Indicates whether the device is connectable. + boolean? connectable; + + // UUIDs of protocols, profiles and services advertised by the device. + // For classic Bluetooth devices, this list is obtained from EIR data and + // SDP tables. For Low Energy devices, this list is obtained from AD and + // GATT primary services. For dual mode devices this may be obtained from + // both. + DOMString[]? uuids; + + // The received signal strength, in dBm. This field is avaliable and valid + // only during discovery. Outside of discovery it's value is not specified. + long? inquiryRssi; + + // The transmitted power level. This field is avaliable only for LE devices + // that include this field in AD. It is avaliable and valid only during + // discovery. + long? inquiryTxPower; + + // The transport type of the bluetooth device. + Transport? transport; + + // The remaining battery of the device. + long? batteryPercentage; + }; + + dictionary BluetoothFilter { + // Type of filter to apply to the device list. Default is all. + FilterType? filterType; + + // Maximum number of bluetooth devices to return. Default is 0 (no limit) + // if unspecified. + long? limit; + }; + + // Callback from the getDevice method. + // |deviceInfo| : Object containing the device information. + callback GetDeviceCallback = void(Device deviceInfo); + + // Callback from the getDevices method. + // |deviceInfos| : Array of object containing device information. + callback GetDevicesCallback = void(Device[] deviceInfos); + + // Callback from the startDiscovery method. + callback StartDiscoveryCallback = void(); + + // Callback from the stopDiscovery method. + callback StopDiscoveryCallback = void(); + + // These functions all report failures via chrome.runtime.lastError. + interface Functions { + // Get information about the Bluetooth adapter. + // |callback| : Called with an AdapterState object describing the adapter + // state. + static void getAdapterState( + AdapterStateCallback callback); + + // Get information about a Bluetooth device known to the system. + // |deviceAddress| : Address of device to get. + // |callback| : Called with the Device object describing the device. + static void getDevice( + DOMString deviceAddress, + GetDeviceCallback callback); + + // Get a list of Bluetooth devices known to the system, including paired + // and recently discovered devices. + // |filter|: Some criteria to filter the list of returned bluetooth devices. + // If the filter is not set or set to {}, returned device list + // will contain all bluetooth devices. Right now this is only supported in + // ChromeOS, for other platforms, a full list is returned. + // |callback| : Called when the search is completed. + static void getDevices( + optional BluetoothFilter filter, + GetDevicesCallback callback); + + // Start discovery. Newly discovered devices will be returned via the + // onDeviceAdded event. Previously discovered devices already known to + // the adapter must be obtained using getDevices and will only be updated + // using the |onDeviceChanged| event if information about them changes. + // + // Discovery will fail to start if this application has already called + // startDiscovery. Discovery can be resource intensive: stopDiscovery + // should be called as soon as possible. + // |callback| : Called to indicate success or failure. + static void startDiscovery( + optional StartDiscoveryCallback callback); + + // Stop discovery. + // |callback| : Called to indicate success or failure. + static void stopDiscovery( + optional StopDiscoveryCallback callback); + }; + + interface Events { + // Fired when the state of the Bluetooth adapter changes. + // |state| : The new state of the adapter. + static void onAdapterStateChanged(AdapterState state); + + // Fired when information about a new Bluetooth device is available. + static void onDeviceAdded(Device device); + + // Fired when information about a known Bluetooth device has changed. + static void onDeviceChanged(Device device); + + // Fired when a Bluetooth device that was previously discovered has been + // out of range for long enough to be considered unavailable again, and + // when a paired device is removed. + static void onDeviceRemoved(Device device); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/bluetooth_low_energy.idl b/tools/under-control/src/extensions/common/api/bluetooth_low_energy.idl new file mode 100755 index 000000000..9556cecf7 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/bluetooth_low_energy.idl @@ -0,0 +1,603 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.bluetoothLowEnergy API is used to communicate with +// Bluetooth Smart (Low Energy) devices using the +// +// Generic Attribute Profile (GATT). +namespace bluetoothLowEnergy { + // Values representing the possible properties of a characteristic. + // Characteristic permissions are inferred from these properties. + // Please see the Bluetooth 4.x spec to see the meaning of each individual + // property. + enum CharacteristicProperty { + broadcast, read, writeWithoutResponse, write, notify, indicate, + authenticatedSignedWrites, extendedProperties, reliableWrite, + writableAuxiliaries, encryptRead, encryptWrite, encryptAuthenticatedRead, + encryptAuthenticatedWrite + }; + + // Values representing possible permissions for a descriptor. + // Please see the Bluetooth 4.x spec to see the meaning of each individual + // permission. + enum DescriptorPermission { + read, write, encryptedRead, encryptedWrite, encryptedAuthenticatedRead, + encryptedAuthenticatedWrite + }; + + // Type of advertisement. If 'broadcast' is chosen, the sent advertisement + // type will be ADV_NONCONN_IND and the device will broadcast with a random + // MAC Address. If set to 'peripheral', the advertisement type will be + // ADV_IND or ADV_SCAN_IND and the device will broadcast with real Bluetooth + // Adapter's MAC Address. + enum AdvertisementType {broadcast, peripheral}; + + // Represents a bluetooth central device that is connected to the local GATT + // server. + dictionary Device { + // The address of the device, in the format 'XX:XX:XX:XX:XX:XX'. + DOMString address; + + // The human-readable name of the device. + DOMString? name; + + // The class of the device, a bit-field defined by + // http://www.bluetooth.org/en-us/specification/assigned-numbers/baseband. + long? deviceClass; + }; + + // Represents a peripheral's Bluetooth GATT Service, a collection of + // characteristics and relationships to other services that encapsulate + // the behavior of part of a device. + dictionary Service { + // The UUID of the service, e.g. 0000180d-0000-1000-8000-00805f9b34fb. + DOMString uuid; + + // Indicates whether the type of this service is primary or secondary. + boolean isPrimary; + + // Returns the identifier assigned to this service. Use the instance ID to + // distinguish between services from a peripheral with the same UUID and + // to make function calls that take in a service identifier. Present, if + // this instance represents a remote service. + DOMString? instanceId; + + // The device address of the remote peripheral that the GATT service belongs + // to. Present, if this instance represents a remote service. + DOMString? deviceAddress; + }; + + // Represents a GATT characteristic, which is a basic data element that + // provides further information about a peripheral's service. + dictionary Characteristic { + // The UUID of the characteristic, e.g. + // 00002a37-0000-1000-8000-00805f9b34fb. + DOMString uuid; + + // The GATT service this characteristic belongs to. + Service? service; + + // The properties of this characteristic. + CharacteristicProperty[] properties; + + // Returns the identifier assigned to this characteristic. Use the instance + // ID to distinguish between characteristics from a peripheral with the same + // UUID and to make function calls that take in a characteristic identifier. + // Present, if this instance represents a remote characteristic. + DOMString? instanceId; + + // The currently cached characteristic value. This value gets updated when + // the value of the characteristic is read or updated via a notification + // or indication. + ArrayBuffer? value; + }; + + // Represents a GATT characteristic descriptor, which provides further + // information about a characteristic's value. + dictionary Descriptor { + // The UUID of the characteristic descriptor, e.g. + // 00002902-0000-1000-8000-00805f9b34fb. + DOMString uuid; + + // The GATT characteristic this descriptor belongs to. + Characteristic? characteristic; + + // The permissions of this descriptor. + DescriptorPermission[] permissions; + + // Returns the identifier assigned to this descriptor. Use the instance ID + // to distinguish between descriptors from a peripheral with the same UUID + // and to make function calls that take in a descriptor identifier. Present, + // if this instance represents a remote characteristic. + DOMString? instanceId; + + // The currently cached descriptor value. This value gets updated when + // the value of the descriptor is read. + ArrayBuffer? value; + }; + + // The connection properties specified during a call to $(ref:connect). + dictionary ConnectProperties { + // Flag indicating whether a connection to the device is left open when the + // event page of the application is unloaded (see Manage App + // Lifecycle). The default value is false. + boolean persistent; + }; + + // Optional characteristic notification session properties specified during a + // call to $(ref:startCharacteristicNotifications). + dictionary NotificationProperties { + // Flag indicating whether the app should receive notifications when the + // event page of the application is unloaded (see Manage App + // Lifecycle). The default value is false. + boolean persistent; + }; + + // Represents an entry of the "Manufacturer Specific Data" field of Bluetooth + // LE advertisement data. + dictionary ManufacturerData { + long id; + long[] data; + }; + + // Represents an entry of the "Service Data" field of Bluetooth LE advertisement + // data. + dictionary ServiceData { + DOMString uuid; + long[] data; + }; + + // Represents a Bluetooth LE advertisement instance. + dictionary Advertisement { + // Type of advertisement. + AdvertisementType type; + + // List of UUIDs to include in the "Service UUIDs" field of the Advertising + // Data. These UUIDs can be of the 16bit, 32bit or 128 formats. + DOMString[]? serviceUuids; + + // List of manufacturer specific data to be included in "Manufacturer Specific + // Data" fields of the advertising data. + ManufacturerData[]? manufacturerData; + + // List of UUIDs to include in the "Solicit UUIDs" field of the Advertising + // Data. These UUIDs can be of the 16bit, 32bit or 128 formats. + DOMString[]? solicitUuids; + + // List of service data to be included in "Service Data" fields of the advertising + // data. + ServiceData[]? serviceData; + }; + + // Represents a an attribute read/write request. + dictionary Request { + // Unique ID for this request. Use this ID when responding to this request. + long requestId; + // Device that send this request. + Device device; + // Value to write (if this is a write request). + ArrayBuffer? value; + }; + + // Represents a response to an attribute read/write request. + dictionary Response { + // Id of the request this is a response to. + long requestId; + // If this is an error response, this should be true. + boolean isError; + // Response value. Write requests and error responses will ignore this + // parameter. + ArrayBuffer? value; + }; + + // Represents a notification to be sent to a remote device. + dictionary Notification { + // New value of the characteristic. + ArrayBuffer value; + // Optional flag for sending an indication instead of a notification. + boolean? shouldIndicate; + }; + + callback CharacteristicCallback = void(Characteristic result); + callback CreateCharacteristicCallback = void(DOMString characteristicId); + callback CharacteristicsCallback = void(Characteristic[] result); + callback DescriptorCallback = void(Descriptor result); + callback CreateDescriptorCallback = void(DOMString descriptorId); + callback DescriptorsCallback = void(Descriptor[] result); + callback ResultCallback = void(); + callback ServiceCallback = void(Service result); + callback CreateServiceCallback = void(DOMString serviceId); + callback ServicesCallback = void(Service[] result); + callback RegisterAdvertisementCallback = void (long advertisementId); + + // These functions all report failures via chrome.runtime.lastError. + interface Functions { + // Establishes a connection between the application and the device with the + // given address. A device may be already connected and its GATT services + // available without calling connect, however, an app that + // wants to access GATT services of a device should call this function to + // make sure that a connection to the device is maintained. If the device + // is not connected, all GATT services of the device will be discovered + // after a successful call to connect. + // |deviceAddress|: The Bluetooth address of the remote device to which a + // GATT connection should be opened. + // |properties|: Connection properties (optional). + // |callback|: Called when the connect request has completed. + static void connect( + DOMString deviceAddress, + optional ConnectProperties properties, + ResultCallback callback); + + // Closes the app's connection to the device with the given address. Note + // that this will not always destroy the physical link itself, since there + // may be other apps with open connections. + // |deviceAddress|: The Bluetooth address of the remote device. + // |callback|: Called when the disconnect request has completed. + static void disconnect( + DOMString deviceAddress, + optional ResultCallback callback); + + // Get the GATT service with the given instance ID. + // |serviceId|: The instance ID of the requested GATT service. + // |callback|: Called with the requested Service object. + static void getService( + DOMString serviceId, + ServiceCallback callback); + + // Create a locally hosted GATT service. This service can be registered + // to be available on a local GATT server. + // This function is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |service|: The service to create. + // |callback|: Called with the created services's unique ID. + static void createService( + Service service, + CreateServiceCallback callback); + + // Get all the GATT services that were discovered on the remote device with + // the given device address. + // + // Note: If service discovery is not yet complete on the device, + // this API will return a subset (possibly empty) of services. A work around + // is to add a time based delay and/or call repeatedly until the expected + // number of services is returned. + // + // |deviceAddress|: The Bluetooth address of the remote device whose GATT + // services should be returned. + // |callback|: Called with the list of requested Service objects. + static void getServices( + DOMString deviceAddress, + ServicesCallback callback); + + // Get the GATT characteristic with the given instance ID that belongs to + // the given GATT service, if the characteristic exists. + // |characteristicId|: The instance ID of the requested GATT + // characteristic. + // |callback|: Called with the requested Characteristic object. + static void getCharacteristic( + DOMString characteristicId, + CharacteristicCallback callback); + + // Create a locally hosted GATT characteristic. This characteristic must + // be hosted under a valid service. If the service ID is not valid, the + // lastError will be set. + // This function is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |characteristic|: The characteristic to create. + // |serviceId|: ID of the service to create this characteristic for. + // |callback|: Called with the created characteristic's unique ID. + static void createCharacteristic( + Characteristic characteristic, + DOMString serviceId, + CreateCharacteristicCallback callback); + + // Get a list of all discovered GATT characteristics that belong to the + // given service. + // |serviceId|: The instance ID of the GATT service whose characteristics + // should be returned. + // |callback|: Called with the list of characteristics that belong to the + // given service. + static void getCharacteristics( + DOMString serviceId, + CharacteristicsCallback callback); + + // Get a list of GATT services that are included by the given service. + // |serviceId|: The instance ID of the GATT service whose included + // services should be returned. + // |callback|: Called with the list of GATT services included from the + // given service. + static void getIncludedServices( + DOMString serviceId, + ServicesCallback callback); + + // Get the GATT characteristic descriptor with the given instance ID. + // |descriptorId|: The instance ID of the requested GATT characteristic + // descriptor. + // |callback|: Called with the requested Descriptor object. + static void getDescriptor( + DOMString descriptorId, + DescriptorCallback callback); + + // Create a locally hosted GATT descriptor. This descriptor must + // be hosted under a valid characteristic. If the characteristic ID is not + // valid, the lastError will be set. + // This function is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |descriptor|: The descriptor to create. + // |characteristicId|: ID of the characteristic to create this descriptor + // for. + // |callback|: Called with the created descriptor's unique ID. + static void createDescriptor( + Descriptor descriptor, + DOMString characteristicId, + CreateDescriptorCallback callback); + + // Get a list of GATT characteristic descriptors that belong to the given + // characteristic. + // |characteristicId|: The instance ID of the GATT characteristic whose + // descriptors should be returned. + // |callback|: Called with the list of descriptors that belong to the given + // characteristic. + static void getDescriptors( + DOMString characteristicId, + DescriptorsCallback callback); + + // Retrieve the value of a specified characteristic from a remote + // peripheral. + // |characteristicId|: The instance ID of the GATT characteristic whose + // value should be read from the remote device. + // |callback|: Called with the Characteristic object whose value was + // requested. The value field of the returned Characteristic + // object contains the result of the read request. + static void readCharacteristicValue( + DOMString characteristicId, + CharacteristicCallback callback); + + // Write the value of a specified characteristic from a remote peripheral. + // |characteristicId|: The instance ID of the GATT characteristic whose + // value should be written to. + // |value|: The value that should be sent to the remote characteristic as + // part of the write request. + // |callback|: Called when the write request has completed. + static void writeCharacteristicValue( + DOMString characteristicId, + ArrayBuffer value, + ResultCallback callback); + + // Enable value notifications/indications from the specified characteristic. + // Once enabled, an application can listen to notifications using the + // $(ref:onCharacteristicValueChanged) event. + // |characteristicId|: The instance ID of the GATT characteristic that + // notifications should be enabled on. + // |properties|: Notification session properties (optional). + // |callback|: Called when the request has completed. + static void startCharacteristicNotifications( + DOMString characteristicId, + optional NotificationProperties properties, + ResultCallback callback); + + // Disable value notifications/indications from the specified + // characteristic. After a successful call, the application will stop + // receiving notifications/indications from this characteristic. + // |characteristicId|: The instance ID of the GATT characteristic on which + // this app's notification session should be stopped. + // |callback|: Called when the request has completed (optional). + static void stopCharacteristicNotifications( + DOMString characteristicId, + optional ResultCallback callback); + + // Notify a remote device of a new value for a characteristic. If the + // shouldIndicate flag in the notification object is true, an indication + // will be sent instead of a notification. Note, the characteristic needs + // to correctly set the 'notify' or 'indicate' property during creation for + // this call to succeed. + // This function is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |characteristicId|: The characteristic to send the notication for. + // |notifcation|: The notification to send. + // |callback|: Callback called once the notification or indication has + // been sent successfully. + static void notifyCharacteristicValueChanged( + DOMString characteristicId, + Notification notification, + ResultCallback callback); + + // Retrieve the value of a specified characteristic descriptor from a remote + // peripheral. + // |descriptorId|: The instance ID of the GATT characteristic descriptor + // whose value should be read from the remote device. + // |callback|: Called with the Descriptor object whose value was requested. + // The value field of the returned Descriptor object contains + // the result of the read request. + static void readDescriptorValue( + DOMString descriptorId, + DescriptorCallback callback); + + // Write the value of a specified characteristic descriptor from a remote + // peripheral. + // |descriptorId|: The instance ID of the GATT characteristic descriptor + // whose value should be written to. + // |value|: The value that should be sent to the remote descriptor as part + // of the write request. + // |callback|: Called when the write request has completed. + static void writeDescriptorValue( + DOMString descriptorId, + ArrayBuffer value, + ResultCallback callback); + + // Register the given service with the local GATT server. If the service + // ID is invalid, the lastError will be set. + // This function is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |serviceId|: Unique ID of a created service. + // |callback|: Callback with the result of the register operation. + static void registerService( + DOMString serviceId, + ResultCallback callback); + + // Unregister the given service with the local GATT server. If the service + // ID is invalid, the lastError will be set. + // This function is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |serviceId|: Unique ID of a current registered service. + // |callback|: Callback with the result of the register operation. + static void unregisterService( + DOMString serviceId, + ResultCallback callback); + + // Remove the specified service, unregistering it if it was registered. + // If the service ID is invalid, the lastError will be set. + // This function is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |serviceId|: Unique ID of a current registered service. + // |callback|: Callback called once the service is removed. + static void removeService( + DOMString serviceId, + optional ResultCallback callback); + + // Create an advertisement and register it for advertising. To call this + // function, the app must have the bluetooth:low_energy and + // bluetooth:peripheral permissions set to true. Additionally this API + // is only available to auto launched apps in Kiosk Mode or by setting + // the '--enable-ble-advertising-in-apps' command-line switch. + // See https://developer.chrome.com/apps/manifest/bluetooth + // Note: On some hardware, central and peripheral modes at the same time is + // supported but on hardware that doesn't support this, making this call + // will switch the device to peripheral mode. In the case of hardware which + // does not support both central and peripheral mode, attempting to use the + // device in both modes will lead to undefined behavior or prevent other + // central-role applications from behaving correctly (including the + // discovery of Bluetooth Low Energy devices). + // |advertisement|: The advertisement to advertise. + // |callback|: Called once the registeration is done and we've started + // advertising. Returns the id of the created advertisement. + static void registerAdvertisement( + Advertisement advertisement, + RegisterAdvertisementCallback callback); + + // Unregisters an advertisement and stops its advertising. If the + // advertisement fails to unregister the only way to stop advertising + // might be to restart the device. + // |advertisementId|: Id of the advertisement to unregister. + // |callback|: Called once the advertisement is unregistered and is no + // longer being advertised. + static void unregisterAdvertisement( + long advertisementId, + ResultCallback callback); + + // Resets advertising on the current device. It will unregister and + // stop all existing advertisements. + // |callback|: Called once the advertisements are reset. + static void resetAdvertising(ResultCallback callback); + + // Set's the interval betweeen two consecutive advertisements. Note: + // This is a best effort. The actual interval may vary non-trivially + // from the requested intervals. On some hardware, there is a minimum + // interval of 100ms. The minimum and maximum values cannot exceed the + // the range allowed by the Bluetooth 4.2 specification. + // |minInterval|: Minimum interval between advertisments (in + // milliseconds). This cannot be lower than 20ms (as per the spec). + // |maxInterval|: Maximum interval between advertisments (in + // milliseconds). This cannot be more than 10240ms (as per the spec). + // |callback|: Called once the interval has been set. + static void setAdvertisingInterval( + long minInterval, + long maxInterval, + ResultCallback callback); + + // Sends a response for a characteristic or descriptor read/write + // request. + // This function is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |response|: The response to the request. + static void sendRequestResponse(Response response); + }; + + interface Events { + // Fired whan a new GATT service has been discovered on a remote device. + // |service|: The GATT service that was added. + static void onServiceAdded(Service service); + + // Fired when the state of a remote GATT service changes. This involves any + // characteristics and/or descriptors that get added or removed from the + // service, as well as "ServiceChanged" notifications from the remote + // device. + // |service|: The GATT service whose state has changed. + static void onServiceChanged(Service service); + + // Fired when a GATT service that was previously discovered on a remote + // device has been removed. + // |service|: The GATT service that was removed. + static void onServiceRemoved(Service service); + + // Fired when the value of a remote GATT characteristic changes, either as + // a result of a read request, or a value change notification/indication + // This event will only be sent if the app has enabled notifications by + // calling $(ref:startCharacteristicNotifications). + // |characteristic|: The GATT characteristic whose value has changed. + static void onCharacteristicValueChanged(Characteristic characteristic); + + // Fired when the value of a remote GATT characteristic descriptor changes, + // usually as a result of a read request. This event exists + // mostly for convenience and will always be sent after a successful + // call to $(ref:readDescriptorValue). + // |descriptor|: The GATT characteristic descriptor whose value has + // changed. + static void onDescriptorValueChanged(Descriptor descriptor); + + // Fired when a connected central device requests to read the value of a + // characteristic registered on the local GATT server. Not responding + // to this request for a long time may lead to a disconnection. + // This event is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |request|: Request data for this request. + // |characteristic|: The GATT characteristic whose value is requested. + static void onCharacteristicReadRequest( + Request request, DOMString characteristicId); + + // Fired when a connected central device requests to write the value of a + // characteristic registered on the local GATT server. Not responding + // to this request for a long time may lead to a disconnection. + // This event is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |request|: Request data for this request. + // |characteristic|: The GATT characteristic whose value is being written. + static void onCharacteristicWriteRequest( + Request request, DOMString characteristicId); + + // Fired when a connected central device requests to read the value of a + // descriptor registered on the local GATT server. Not responding to + // this request for a long time may lead to a disconnection. + // This event is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |request|: Request data for this request. + // |descriptor|: The GATT descriptor whose value is requested. + static void onDescriptorReadRequest( + Request request, DOMString descriptorId); + + // Fired when a connected central device requests to write the value of a + // descriptor registered on the local GATT server. Not responding to + // this request for a long time may lead to a disconnection. + // This event is only available if the app has both the + // bluetooth:low_energy and the bluetooth:peripheral permissions set to + // true. The peripheral permission may not be available to all apps. + // |request|: Request data for this request. + // |descriptor|: The GATT descriptor whose value is being written. + static void onDescriptorWriteRequest( + Request request, DOMString descriptorId); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/bluetooth_private.idl b/tools/under-control/src/extensions/common/api/bluetooth_private.idl new file mode 100755 index 000000000..b3afb9e5e --- /dev/null +++ b/tools/under-control/src/extensions/common/api/bluetooth_private.idl @@ -0,0 +1,197 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.bluetoothPrivate API to control the Bluetooth +// adapter state and handle device pairing. +// NOTE: This IDL is dependent on bluetooth.idl. + +[implemented_in = "extensions/browser/api/bluetooth/bluetooth_private_api.h"] +namespace bluetoothPrivate { + // Events that can occur during pairing. The method used for pairing varies + // depending on the capability of the two devices. + enum PairingEventType { + // An alphanumeric PIN code is required to be entered by the user. + requestPincode, + + // Display a PIN code to the user. + displayPincode, + + // A numeric passkey is required to be entered by the user. + requestPasskey, + + // Display a zero padded 6 digit numeric passkey that the user entered on + // the remote device. This event may occur multiple times during pairing to + // update the entered passkey. + displayPasskey, + + // The number of keys inputted by the user on the remote device when + // entering a passkey. This event may be called multiple times during + // pairing to update the number of keys inputted. + keysEntered, + + // Requests that a 6 digit passkey be displayed and the user confirms that + // both devies show the same passkey. + confirmPasskey, + + // Requests authorization for a pairing under the just-works model. It is up + // to the app to ask for user confirmation. + requestAuthorization, + + // Pairing is completed. + complete + }; + + // Results for connect(). See function declaration for details. + enum ConnectResultType { + alreadyConnected, + authCanceled, + authFailed, + authRejected, + authTimeout, + failed, + inProgress, + success, + unknownError, + unsupportedDevice, + notReady, + alreadyExists, + notConnected, + doesNotExist, + invalidArgs, + nonAuthTimeout, + noMemory, + jniEnvironment, + jniThreadAttach, + wakelock + }; + + // Valid pairing responses. + enum PairingResponse { + confirm, reject, cancel + }; + + enum TransportType { + le, bredr, dual + }; + + // A pairing event received from a Bluetooth device. + dictionary PairingEvent { + PairingEventType pairing; + bluetooth.Device device; + DOMString? pincode; + long? passkey; + long? enteredKey; + }; + + dictionary NewAdapterState { + // The human-readable name of the adapter. + DOMString? name; + + // Whether or not the adapter has power. + boolean? powered; + + // Whether the adapter is discoverable by other devices. + boolean? discoverable; + }; + + dictionary SetPairingResponseOptions { + // The remote device to send the pairing response. + bluetooth.Device device; + + // The response type. + PairingResponse response; + + // A 1-16 character alphanumeric set in response to + // requestPincode. + DOMString? pincode; + + // An integer between 0-999999 set in response to + // requestPasskey. + long? passkey; + }; + + dictionary DiscoveryFilter { + // Transport type. + TransportType? transport; + + // uuid of service or array of uuids + (DOMString or DOMString[])? uuids; + + // RSSI ranging value. Only devices with RSSI higher than this value will be + // reported. + long? rssi; + + // Pathloss ranging value. Only devices with pathloss lower than this value + // will be reported. + long? pathloss; + }; + + callback VoidCallback = void(); + callback ConnectCallback = void(ConnectResultType result); + + // These functions all report failures via chrome.runtime.lastError. + interface Functions { + // Changes the state of the Bluetooth adapter. + // |adapterState|: The new state of the adapter. + // |callback|: Called when all the state changes have been completed. + static void setAdapterState( + NewAdapterState adapterState, + optional VoidCallback callback); + + static void setPairingResponse( + SetPairingResponseOptions options, + optional VoidCallback callback); + + // Tears down all connections to the given device. + static void disconnectAll( + DOMString deviceAddress, + optional VoidCallback callback); + + // Forgets the given device. + static void forgetDevice( + DOMString deviceAddress, + optional VoidCallback callback); + + // Set or clear discovery filter. + static void setDiscoveryFilter( + DiscoveryFilter discoveryFilter, + optional VoidCallback callback); + + // Connects to the given device. This will only throw an error if the + // device address is invalid or the device is already connected. Otherwise + // this will succeed and invoke |callback| with ConnectResultType. + static void connect( + DOMString deviceAddress, + optional ConnectCallback callback); + + // Pairs the given device. + static void pair( + DOMString deviceAddress, + optional VoidCallback callback); + + // Record that a pairing attempt finished. Ignores cancellations. + static void recordPairing(bluetooth.Transport transport, + long pairingDurationMs, + optional ConnectResultType result); + + // Record that a user-initiated reconnection attempt to an already paired + // device finished. Ignores cancellations. + static void recordReconnection(optional ConnectResultType result); + + // Record that a user selected a device to connect to. + static void recordDeviceSelection(long selectionDurationMs, + boolean wasPaired, + bluetooth.Transport transport); + }; + + interface Events { + // Fired when a pairing event occurs. + // |pairingEvent|: A pairing event. + [maxListeners=1] static void onPairing(PairingEvent pairingEvent); + + // Fired when a Bluetooth device changed its address. + static void onDeviceAddressChanged(bluetooth.Device device, + DOMString oldAddress); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/bluetooth_socket.idl b/tools/under-control/src/extensions/common/api/bluetooth_socket.idl new file mode 100755 index 000000000..e7e93aa01 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/bluetooth_socket.idl @@ -0,0 +1,326 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.bluetoothSocket API to send and receive data +// to Bluetooth devices using RFCOMM and L2CAP connections. +namespace bluetoothSocket { + // The socket properties specified in the $ref:create or $ref:update + // function. Each property is optional. If a property value is not specified, + // a default value is used when calling $ref:create, or the existing value is + // preserved when calling $ref:update. + dictionary SocketProperties { + // Flag indicating whether the socket is left open when the event page of + // the application is unloaded (see Manage App + // Lifecycle). The default value is false. When the + // application is loaded, any sockets previously opened with persistent=true + // can be fetched with $ref:getSockets. + boolean? persistent; + + // An application-defined string associated with the socket. + DOMString? name; + + // The size of the buffer used to receive data. The default value is 4096. + long? bufferSize; + }; + + // Result of create call. + dictionary CreateInfo { + // The ID of the newly created socket. Note that socket IDs created + // from this API are not compatible with socket IDs created from other APIs, + // such as the $(ref:sockets.tcp) API. + long socketId; + }; + + // Callback from the create method. + // |createInfo| : The result of the socket creation. + callback CreateCallback = void (CreateInfo createInfo); + + // Callback from the update method. + callback UpdateCallback = void (); + + // Callback from the setPaused method. + callback SetPausedCallback = void (); + + // Options that may be passed to the listenUsingRfcomm and + // listenUsingL2cap methods. Each property is optional with a + // default being used if not specified. + dictionary ListenOptions { + // The RFCOMM Channel used by listenUsingRfcomm. If specified, + // this channel must not be previously in use or the method call will fail. + // When not specified, an unused channel will be automatically allocated. + long? channel; + + // The L2CAP PSM used by listenUsingL2cap. If specified, this + // PSM must not be previously in use or the method call with fail. When + // not specified, an unused PSM will be automatically allocated. + long? psm; + + // Length of the socket's listen queue. The default value depends on the + // operating system's host subsystem. + long? backlog; + }; + + // Callback from the listenUsingRfcomm and + // listenUsingL2cap methods. + callback ListenCallback = void (); + + // Callback from the connect method. + callback ConnectCallback = void (); + + // Callback from the disconnect method. + callback DisconnectCallback = void (); + + // Callback from the close method. + callback CloseCallback = void (); + + // Callback from the send method. + // |bytesSent| : The number of bytes sent. + callback SendCallback = void (long bytesSent); + + // Result of the getInfo method. + dictionary SocketInfo { + // The socket identifier. + long socketId; + + // Flag indicating if the socket remains open when the event page of the + // application is unloaded (see SocketProperties.persistent). + // The default value is "false". + boolean persistent; + + // Application-defined string associated with the socket. + DOMString? name; + + // The size of the buffer used to receive data. If no buffer size has been + // specified explictly, the value is not provided. + long? bufferSize; + + // Flag indicating whether a connected socket blocks its peer from sending + // more data, or whether connection requests on a listening socket are + // dispatched through the onAccept event or queued up in the + // listen queue backlog. + // See setPaused. The default value is "false". + boolean paused; + + // Flag indicating whether the socket is connected to a remote peer. + boolean connected; + + // If the underlying socket is connected, contains the Bluetooth address of + // the device it is connected to. + DOMString? address; + + // If the underlying socket is connected, contains information about the + // service UUID it is connected to, otherwise if the underlying socket is + // listening, contains information about the service UUID it is listening + // on. + DOMString? uuid; + }; + + // Callback from the getInfo method. + // |socketInfo| : Object containing the socket information. + callback GetInfoCallback = void (SocketInfo socketInfo); + + // Callback from the getSockets method. + // |socketInfos| : Array of object containing socket information. + callback GetSocketsCallback = void (SocketInfo[] sockets); + + // Data from an onAccept event. + dictionary AcceptInfo { + // The server socket identifier. + long socketId; + + // The client socket identifier, i.e. the socket identifier of the newly + // established connection. This socket identifier should be used only with + // functions from the chrome.bluetoothSocket namespace. Note + // the client socket is initially paused and must be explictly un-paused by + // the application to start receiving data. + long clientSocketId; + }; + + enum AcceptError { + // A system error occurred and the connection may be unrecoverable. + system_error, + + // The socket is not listening. + not_listening + }; + + // Data from an onAcceptError event. + dictionary AcceptErrorInfo { + // The server socket identifier. + long socketId; + + // The error message. + DOMString errorMessage; + + // An error code indicating what went wrong. + AcceptError error; + }; + + // Data from an onReceive event. + dictionary ReceiveInfo { + // The socket identifier. + long socketId; + + // The data received, with a maxium size of bufferSize. + ArrayBuffer data; + }; + + enum ReceiveError { + // The connection was disconnected. + disconnected, + + // A system error occurred and the connection may be unrecoverable. + system_error, + + // The socket has not been connected. + not_connected + }; + + // Data from an onReceiveError event. + dictionary ReceiveErrorInfo { + // The socket identifier. + long socketId; + + // The error message. + DOMString errorMessage; + + // An error code indicating what went wrong. + ReceiveError error; + }; + + // These functions all report failures via chrome.runtime.lastError. + interface Functions { + // Creates a Bluetooth socket. + // |properties| : The socket properties (optional). + // |callback| : Called when the socket has been created. + static void create( + optional SocketProperties properties, + CreateCallback callback); + + // Updates the socket properties. + // |socketId| : The socket identifier. + // |properties| : The properties to update. + // |callback| : Called when the properties are updated. + static void update( + long socketId, + SocketProperties properties, + optional UpdateCallback callback); + + // Enables or disables a connected socket from receiving messages from its + // peer, or a listening socket from accepting new connections. The default + // value is "false". Pausing a connected socket is typically used by an + // application to throttle data sent by its peer. When a connected socket + // is paused, no onReceiveevent is raised. When a socket is + // connected and un-paused, onReceive events are raised again + // when messages are received. When a listening socket is paused, new + // connections are accepted until its backlog is full then additional + // connection requests are refused. onAccept events are raised + // only when the socket is un-paused. + static void setPaused( + long socketId, + boolean paused, + optional SetPausedCallback callback); + + // Listen for connections using the RFCOMM protocol. + // |socketId| : The socket identifier. + // |uuid| : Service UUID to listen on. + // |options| : Optional additional options for the service. + // |callback| : Called when listen operation completes. + static void listenUsingRfcomm( + long socketId, + DOMString uuid, + optional ListenOptions options, + ListenCallback callback); + + // Listen for connections using the L2CAP protocol. + // |socketId| : The socket identifier. + // |uuid| : Service UUID to listen on. + // |options| : Optional additional options for the service. + // |callback| : Called when listen operation completes. + static void listenUsingL2cap( + long socketId, + DOMString uuid, + optional ListenOptions options, + ListenCallback callback); + + // Connects the socket to a remote Bluetooth device. When the + // connect operation completes successfully, + // onReceive events are raised when data is received from the + // peer. If a network error occur while the runtime is receiving packets, + // a onReceiveError event is raised, at which point no more + // onReceive event will be raised for this socket until the + // setPaused(false) method is called. + // |socketId| : The socket identifier. + // |address| : The address of the Bluetooth device. + // |uuid| : The UUID of the service to connect to. + // |callback| : Called when the connect attempt is complete. + static void connect( + long socketId, + DOMString address, + DOMString uuid, + ConnectCallback callback); + + // Disconnects the socket. The socket identifier remains valid. + // |socketId| : The socket identifier. + // |callback| : Called when the disconnect attempt is complete. + static void disconnect( + long socketId, + optional DisconnectCallback callback); + + // Disconnects and destroys the socket. Each socket created should be + // closed after use. The socket id is no longer valid as soon at the + // function is called. However, the socket is guaranteed to be closed only + // when the callback is invoked. + // |socketId| : The socket identifier. + // |callback| : Called when the close operation completes. + static void close( + long socketId, + optional CloseCallback callback); + + // Sends data on the given Bluetooth socket. + // |socketId| : The socket identifier. + // |data| : The data to send. + // |callback| : Called with the number of bytes sent. + static void send( + long socketId, + ArrayBuffer data, + optional SendCallback callback); + + // Retrieves the state of the given socket. + // |socketId| : The socket identifier. + // |callback| : Called when the socket state is available. + static void getInfo( + long socketId, + GetInfoCallback callback); + + // Retrieves the list of currently opened sockets owned by the application. + // |callback| : Called when the list of sockets is available. + static void getSockets(GetSocketsCallback callback); + }; + + interface Events { + // Event raised when a connection has been established for a given socket. + // |info| : The event data. + static void onAccept(AcceptInfo info); + + // Event raised when a network error occurred while the runtime was waiting + // for new connections on the given socket. Once this event is raised, the + // socket is set to paused and no more onAccept + // events are raised for this socket. + // |info| : The event data. + static void onAcceptError(AcceptErrorInfo info); + + // Event raised when data has been received for a given socket. + // |info| : The event data. + static void onReceive(ReceiveInfo info); + + // Event raised when a network error occured while the runtime was waiting + // for data on the socket. Once this event is raised, the socket is set to + // paused and no more onReceive events are raised + // for this socket. + // |info| : The event data. + static void onReceiveError(ReceiveErrorInfo info); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/cec_private.idl b/tools/under-control/src/extensions/common/api/cec_private.idl new file mode 100755 index 000000000..0a570a99c --- /dev/null +++ b/tools/under-control/src/extensions/common/api/cec_private.idl @@ -0,0 +1,65 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Private API for HDMI CEC functionality. +[platforms=("chromeos", "lacros")] +namespace cecPrivate { + + enum DisplayCecPowerState { + // There was an error querying the power state of the display. + error, + + // The kernel adapter for the CEC endpoint isn't configured (no EDID set). + adapterNotConfigured, + + // No device ACKed the request on the CEC bus. + noDevice, + + // The display is a powered on state. + on, + + // The display is in standby mode. + standby, + + // The display is currently transitioning to an awake state. It can't be + // relied on to show any output yet. + transitioningToOn, + + // The display is currently transitioning to standby. + transitioningToStandby, + + // Found a CEC endpoint but unable to determine the power state. + unknown + }; + + callback DisplayCecPowerStateCallback = + void(DisplayCecPowerState[] powerStates); + + callback ChangePowerStateCallback = void(); + + interface Functions { + // Attempt to put all HDMI CEC compatible devices in standby. + // + // This is not guaranteed to have any effect on the connected displays. + // Displays that do not support HDMI CEC will not be affected. + // + // |callback| will be run as soon as all displays have been requested to + // change their power state. + static void sendStandBy( + optional ChangePowerStateCallback callback); + + // Attempt to announce this device as the active input source towards all + // HDMI CEC enabled displays connected, waking them from standby if + // necessary. + // + // |callback| will be run as soon as all displays have been requested to + // change their power state. + static void sendWakeUp( + optional ChangePowerStateCallback callback); + + // Queries all HDMI CEC capable displays for their current power state. + static void queryDisplayCecPowerState( + DisplayCecPowerStateCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/clipboard.idl b/tools/under-control/src/extensions/common/api/clipboard.idl new file mode 100755 index 000000000..f503c88d8 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/clipboard.idl @@ -0,0 +1,55 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.clipboard API is provided to allow users to +// access data of the clipboard. This is a temporary solution for +// chromeos platform apps until open-web alternative is available. It will be +// deprecated once open-web solution is available, which could be in 2017 Q4. +[platforms=("chromeos", "lacros"), + implemented_in="extensions/browser/api/clipboard/clipboard_api.h"] +namespace clipboard { + // Supported image types. + enum ImageType {png, jpeg}; + + enum DataItemType {textPlain, textHtml}; + + // Additional data item to be added along with the |image_data| to describe + // the |image_data|. + dictionary AdditionalDataItem { + // Type of the additional data item. + DataItemType type; + + // Content of the additional data item. Either the plain text string if + // |type| is "textPlain" or markup string if |type| is "textHtml". The + // data can not exceed 2MB. + DOMString data; + }; + + interface Events { + // Fired when clipboard data changes. + // Requires clipboard and clipboardRead permissions for adding listener to + // chrome.clipboard.onClipboardDataChanged event. + // After this event fires, the clipboard data is available by calling + // document.execCommand('paste'). + static void onClipboardDataChanged(); + }; + + callback SetImageDataCallback = void(); + + interface Functions { + // Sets image data to clipboard. + // + // |imageData|: The encoded image data. + // |type|: The type of image being passed. + // |additionalItems|: Additional data items for describing image data. + // The callback is called with chrome.runtime.lastError + // set to error code if there is an error. + // Requires clipboard and clipboardWrite permissions. + static void setImageData( + ArrayBuffer imageData, + ImageType type, + optional AdditionalDataItem[] additionalItems, + optional SetImageDataCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/content_scripts.idl b/tools/under-control/src/extensions/common/api/content_scripts.idl new file mode 100755 index 000000000..a20b33227 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/content_scripts.idl @@ -0,0 +1,66 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Stub namespace for the "content_scripts" manifest key. +[generate_error_messages] +namespace contentScripts { + // Describes a content script to be injected into a web page. + dictionary ContentScript { + // Specifies which pages this content script will be injected into. See + // Match Patterns for more + // details on the syntax of these strings. + DOMString[] matches; + // Excludes pages that this content script would otherwise be injected into. + // See Match Patterns for more + // details on the syntax of these strings. + DOMString[]? exclude_matches; + // The list of CSS files to be injected into matching pages. These are + // injected in the order they appear in this array, before any DOM is + // constructed or displayed for the page. + DOMString[]? css; + // The list of JavaScript files to be injected into matching pages. These + // are injected in the order they appear in this array. + DOMString[]? js; + // If specified true, it will inject into all frames, even if the frame is + // not the top-most frame in the tab. Each frame is checked independently + // for URL requirements; it will not inject into child frames if the URL + // requirements are not met. Defaults to false, meaning that only the top + // frame is matched. + boolean? all_frames; + // Whether the script should inject into any frames where the URL belongs to + // a scheme that would never match a specified Match Pattern, including + // about:, data:, blob:, and filesystem: schemes. In these cases, in order + // to determine if the script should inject, the origin of the URL is + // checked. If the origin is `null` (as is the case for data: URLs), then + // the "initiator" or "creator" origin is used (i.e., the origin of the + // frame that created or navigated this frame). Note that this may not + // be the parent frame, if the frame was navigated by another frame in the + // document hierarchy. + boolean? match_origin_as_fallback; + // Whether the script should inject into an about:blank frame where the + // parent or opener frame matches one of the patterns declared in matches. + // Defaults to false. + boolean? match_about_blank; + // Applied after matches to include only those URLs that also match this + // glob. Intended to emulate the + // @include + // Greasemonkey keyword. + DOMString[]? include_globs; + // Applied after matches to exclude URLs that match this glob. Intended to + // emulate the + // @exclude + // Greasemonkey keyword. + DOMString[]? exclude_globs; + // Specifies when JavaScript files are injected into the web page. The + // preferred and default value is document_idle. + extensionTypes.RunAt? run_at; + // The JavaScript "world" to run the script in. Defaults to + // ISOLATED. Only available in Manifest V3 extensions. + extensionTypes.ExecutionWorld? world; + }; + + dictionary ManifestKeys { + ContentScript[] content_scripts; + }; +}; diff --git a/tools/under-control/src/extensions/common/api/cross_origin_isolation.idl b/tools/under-control/src/extensions/common/api/cross_origin_isolation.idl new file mode 100755 index 000000000..60b14525d --- /dev/null +++ b/tools/under-control/src/extensions/common/api/cross_origin_isolation.idl @@ -0,0 +1,16 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Stub namespace for manifest keys relating to the cross origin isolation +// response headers. +namespace crossOriginIsolation { + dictionary ResponseHeader { + DOMString? value; + }; + + dictionary ManifestKeys { + ResponseHeader? cross_origin_embedder_policy; + ResponseHeader? cross_origin_opener_policy; + }; +}; diff --git a/tools/under-control/src/extensions/common/api/declarative_net_request.idl b/tools/under-control/src/extensions/common/api/declarative_net_request.idl new file mode 100755 index 000000000..b63682503 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/declarative_net_request.idl @@ -0,0 +1,850 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.declarativeNetRequest API is used to block or modify +// network requests by specifying declarative rules. This lets extensions +// modify network requests without intercepting them and viewing their content, +// thus providing more privacy. +[generate_error_messages] +namespace declarativeNetRequest { + // This describes the resource type of the network request. + enum ResourceType { + main_frame, + sub_frame, + stylesheet, + script, + image, + font, + object, + xmlhttprequest, + ping, + csp_report, + media, + websocket, + webtransport, + webbundle, + other + }; + + // This describes the HTTP request method of a network request. + enum RequestMethod { + connect, + delete, + get, + head, + options, + patch, + post, + put, + other + }; + + // This describes whether the request is first or third party to the frame in + // which it originated. A request is said to be first party if it has the same + // domain (eTLD+1) as the frame in which the request originated. + enum DomainType { + // The network request is first party to the frame in which it originated. + firstParty, + // The network request is third party to the frame in which it originated. + thirdParty + }; + + // This describes the possible operations for a "modifyHeaders" rule. + enum HeaderOperation { + // Adds a new entry for the specified header. This operation is not + // supported for request headers. + append, + // Sets a new value for the specified header, removing any existing headers + // with the same name. + set, + // Removes all entries for the specified header. + remove + }; + + // Describes the kind of action to take if a given RuleCondition matches. + enum RuleActionType { + // Block the network request. + block, + // Redirect the network request. + redirect, + // Allow the network request. The request won't be intercepted if there is + // an allow rule which matches it. + allow, + // Upgrade the network request url's scheme to https if the request is http + // or ftp. + upgradeScheme, + // Modify request/response headers from the network request. + modifyHeaders, + // Allow all requests within a frame hierarchy, including the frame request + // itself. + allowAllRequests + }; + + // Describes the reason why a given regular expression isn't supported. + enum UnsupportedRegexReason { + // The regular expression is syntactically incorrect, or uses features + // not available in the + // RE2 syntax. + syntaxError, + // The regular expression exceeds the memory limit. + memoryLimitExceeded + }; + + // Describes a single static ruleset. + dictionary Ruleset { + // A non-empty string uniquely identifying the ruleset. IDs beginning with + // '_' are reserved for internal use. + DOMString id; + // The path of the JSON ruleset relative to the extension directory. + DOMString path; + // Whether the ruleset is enabled by default. + boolean enabled; + }; + + // Represents a query key-value pair. + dictionary QueryKeyValue { + DOMString key; + DOMString value; + + // If true, the query key is replaced only if it's already present. + // Otherwise, the key is also added if it's missing. Defaults to false. + boolean? replaceOnly; + }; + + // Describes modification to the url query. + dictionary QueryTransform { + // The list of query keys to be removed. + DOMString[]? removeParams; + // The list of query key-value pairs to be added or replaced. + QueryKeyValue[]? addOrReplaceParams; + }; + + // Describes modification to various url components. + [noinline_doc] + dictionary URLTransform { + // The new scheme for the request. Allowed values are "http", "https", + // "ftp" and "chrome-extension". + DOMString? scheme; + + // The new host for the request. + DOMString? host; + + // The new port for the request. If empty, the existing port is cleared. + DOMString? port; + + // The new path for the request. If empty, the existing path is cleared. + DOMString? path; + + // The new query for the request. Should be either empty, in which case the + // existing query is cleared; or should begin with '?'. + DOMString? query; + + // Add, remove or replace query key-value pairs. + QueryTransform? queryTransform; + + // The new fragment for the request. Should be either empty, in which case + // the existing fragment is cleared; or should begin with '#'. + DOMString? fragment; + + // The new username for the request. + DOMString? username; + + // The new password for the request. + DOMString? password; + }; + + dictionary Redirect { + // Path relative to the extension directory. Should start with '/'. + DOMString? extensionPath; + // Url transformations to perform. + URLTransform? transform; + // The redirect url. Redirects to JavaScript urls are not allowed. + DOMString? url; + + // Substitution pattern for rules which specify a regexFilter. + // The first match of regexFilter within the url will be + // replaced with this pattern. Within regexSubstitution, + // backslash-escaped digits (\1 to \9) can be used to insert the + // corresponding capture groups. \0 refers to the entire matching text. + DOMString? regexSubstitution; + }; + + dictionary HeaderInfo { + // The name of the header. This condition matches on the name + // only if both `values` and `excludedValues` are not specified. + DOMString header; + // If specified, this condition matches if the header's value matches at + // least one pattern in this list. This supports case-insensitive header + // value matching plus the following constructs: + // + // '*' : Matches any number of characters. + // + // '?' : Matches zero or one character(s). + // + // '*' and '?' can be escaped with a backslash, e.g. '\*' and '\?' + DOMString[]? values; + // If specified, this condition is not matched if the header exists but its + // value contains at least one element in this list. This uses the same + // match pattern syntax as `values`. + DOMString[]? excludedValues; + }; + + [noinline_doc] dictionary RuleCondition { + + // The pattern which is matched against the network request url. + // Supported constructs: + // + // '*' : Wildcard: Matches any number of characters. + // + // '|' : Left/right anchor: If used at either end of the pattern, + // specifies the beginning/end of the url respectively. + // + // '||' : Domain name anchor: If used at the beginning of the + // pattern, specifies the start of a (sub-)domain of the URL. + // + // '^' : Separator character: This matches anything except a letter, + // a digit, or one of the following: _, + // -, ., or %. This + // also match the end of the URL. + // + // Therefore urlFilter is composed of the following parts: + // (optional Left/Domain name anchor) + pattern + (optional Right anchor). + // + // If omitted, all urls are matched. An empty string is not allowed. + // + // A pattern beginning with ||* is not allowed. Use + // * instead. + // + // Note: Only one of urlFilter or regexFilter can + // be specified. + // + // Note: The urlFilter must be composed of only ASCII + // characters. This is matched against a url where the host is encoded in + // the punycode format (in case of internationalized domains) and any other + // non-ascii characters are url encoded in utf-8. + // For example, when the request url is + // http://abc.рф?q=ф, the + // urlFilter will be matched against the url + // http://abc.xn--p1ai/?q=%D1%84. + DOMString? urlFilter; + + // Regular expression to match against the network request url. This follows + // the RE2 syntax. + // + // Note: Only one of urlFilter or regexFilter can + // be specified. + // + // Note: The regexFilter must be composed of only ASCII + // characters. This is matched against a url where the host is encoded in + // the punycode format (in case of internationalized domains) and any other + // non-ascii characters are url encoded in utf-8. + DOMString? regexFilter; + + // Whether the urlFilter or regexFilter + // (whichever is specified) is case sensitive. Default is false. + boolean? isUrlFilterCaseSensitive; + + // The rule will only match network requests originating from the list of + // initiatorDomains. If the list is omitted, the rule is + // applied to requests from all domains. An empty list is not allowed. + // + // Notes: + //
    + //
  • Sub-domains like "a.example.com" are also allowed.
  • + //
  • The entries must consist of only ascii characters.
  • + //
  • Use punycode encoding for internationalized domains.
  • + //
  • + // This matches against the request initiator and not the request url. + //
  • + //
  • Sub-domains of the listed domains are also matched.
  • + //
+ DOMString[]? initiatorDomains; + + // The rule will not match network requests originating from the list of + // excludedInitiatorDomains. If the list is empty or omitted, + // no domains are excluded. This takes precedence over + // initiatorDomains. + // + // Notes: + //
    + //
  • Sub-domains like "a.example.com" are also allowed.
  • + //
  • The entries must consist of only ascii characters.
  • + //
  • Use punycode encoding for internationalized domains.
  • + //
  • + // This matches against the request initiator and not the request url. + //
  • + //
  • Sub-domains of the listed domains are also excluded.
  • + //
+ DOMString[]? excludedInitiatorDomains; + + // The rule will only match network requests when the domain matches one + // from the list of requestDomains. If the list is omitted, + // the rule is applied to requests from all domains. An empty list is not + // allowed. + // + // Notes: + //
    + //
  • Sub-domains like "a.example.com" are also allowed.
  • + //
  • The entries must consist of only ascii characters.
  • + //
  • Use punycode encoding for internationalized domains.
  • + //
  • Sub-domains of the listed domains are also matched.
  • + //
+ DOMString[]? requestDomains; + + // The rule will not match network requests when the domains matches one + // from the list of excludedRequestDomains. If the list is + // empty or omitted, no domains are excluded. This takes precedence over + // requestDomains. + // + // Notes: + //
    + //
  • Sub-domains like "a.example.com" are also allowed.
  • + //
  • The entries must consist of only ascii characters.
  • + //
  • Use punycode encoding for internationalized domains.
  • + //
  • Sub-domains of the listed domains are also excluded.
  • + //
+ DOMString[]? excludedRequestDomains; + + // The rule will only match network requests originating from the list of + // domains. + [deprecated="Use $(ref:initiatorDomains) instead"] + DOMString[]? domains; + + // The rule will not match network requests originating from the list of + // excludedDomains. + [deprecated="Use $(ref:excludedInitiatorDomains) instead"] + DOMString[]? excludedDomains; + + // List of resource types which the rule can match. An empty list is not + // allowed. + // + // Note: this must be specified for allowAllRequests rules and + // may only include the sub_frame and main_frame + // resource types. + ResourceType[]? resourceTypes; + + // List of resource types which the rule won't match. Only one of + // resourceTypes and excludedResourceTypes should + // be specified. If neither of them is specified, all resource types except + // "main_frame" are blocked. + ResourceType[]? excludedResourceTypes; + + // List of HTTP request methods which the rule can match. An empty list is + // not allowed. + // + // Note: Specifying a requestMethods rule condition will also + // exclude non-HTTP(s) requests, whereas specifying + // excludedRequestMethods will not. + RequestMethod[]? requestMethods; + + // List of request methods which the rule won't match. Only one of + // requestMethods and excludedRequestMethods + // should be specified. If neither of them is specified, all request methods + // are matched. + RequestMethod[]? excludedRequestMethods; + + // Specifies whether the network request is first-party or third-party to + // the domain from which it originated. If omitted, all requests are + // accepted. + DomainType? domainType; + + // List of $(ref:tabs.Tab.id) which the rule should match. An ID of + // $(ref:tabs.TAB_ID_NONE) matches requests which don't originate from a + // tab. An empty list is not allowed. Only supported for session-scoped + // rules. + long[]? tabIds; + + // List of $(ref:tabs.Tab.id) which the rule should not match. An ID of + // $(ref:tabs.TAB_ID_NONE) excludes requests which don't originate from a + // tab. Only supported for session-scoped rules. + long[]? excludedTabIds; + + // Rule matches if the request matches any response header condition in this + // list (if specified). + HeaderInfo[]? responseHeaders; + + // Rule does not match if the request matches any response header + // condition in this list (if specified). If both `excludedResponseHeaders` + // and `responseHeaders` are specified, then the `excludedResponseHeaders` + // property takes precedence. + HeaderInfo[]? excludedResponseHeaders; + }; + + dictionary ModifyHeaderInfo { + // The name of the header to be modified. + DOMString header; + + // The operation to be performed on a header. + HeaderOperation operation; + + // The new value for the header. Must be specified for append + // and set operations. + DOMString? value; + }; + + [noinline_doc] + dictionary RuleAction { + // The type of action to perform. + RuleActionType type; + + // Describes how the redirect should be performed. Only valid for redirect + // rules. + Redirect? redirect; + + // The request headers to modify for the request. Only valid if + // RuleActionType is "modifyHeaders". + ModifyHeaderInfo[]? requestHeaders; + + // The response headers to modify for the request. Only valid if + // RuleActionType is "modifyHeaders". + ModifyHeaderInfo[]? responseHeaders; + }; + + dictionary Rule { + // An id which uniquely identifies a rule. Mandatory and should be >= 1. + long id; + + // Rule priority. Defaults to 1. When specified, should be >= 1. + long? priority; + + // The condition under which this rule is triggered. + RuleCondition condition; + + // The action to take if this rule is matched. + RuleAction action; + }; + + // Uniquely describes a declarative rule specified by the extension. + dictionary MatchedRule { + // A matching rule's ID. + long ruleId; + + // ID of the $(ref:Ruleset) this rule belongs to. For a rule originating + // from the set of dynamic rules, this will be equal to + // $(ref:DYNAMIC_RULESET_ID). + DOMString rulesetId; + }; + + [noinline_doc] + dictionary GetRulesFilter { + // If specified, only rules with matching IDs are included. + long[]? ruleIds; + }; + + [noinline_doc] + dictionary MatchedRuleInfo { + MatchedRule rule; + + // The time the rule was matched. Timestamps will correspond to the + // Javascript convention for times, i.e. number of milliseconds since the + // epoch. + double timeStamp; + + // The tabId of the tab from which the request originated if the tab is + // still active. Else -1. + long tabId; + }; + + dictionary MatchedRulesFilter { + // If specified, only matches rules for the given tab. Matches rules not + // associated with any active tab if set to -1. + long? tabId; + + // If specified, only matches rules after the given timestamp. + double? minTimeStamp; + }; + + dictionary RulesMatchedDetails { + // Rules matching the given filter. + MatchedRuleInfo[] rulesMatchedInfo; + }; + + [noinline_doc] + dictionary RequestDetails { + // The ID of the request. Request IDs are unique within a browser session. + DOMString requestId; + + // The URL of the request. + DOMString url; + + // The origin where the request was initiated. This does not change through + // redirects. If this is an opaque origin, the string 'null' will be used. + DOMString? initiator; + + // Standard HTTP method. + DOMString method; + + // The value 0 indicates that the request happens in the main frame; a + // positive value indicates the ID of a subframe in which the request + // happens. If the document of a (sub-)frame is loaded (type is + // main_frame or sub_frame), frameId + // indicates the ID of this frame, not the ID of the outer frame. Frame IDs + // are unique within a tab. + long frameId; + + // The unique identifier for the frame's document, if this request is for a + // frame. + DOMString? documentId; + + // The type of the frame, if this request is for a frame. + extensionTypes.FrameType? frameType; + + // The lifecycle of the frame's document, if this request is for a + // frame. + extensionTypes.DocumentLifecycle? documentLifecycle; + + // ID of frame that wraps the frame which sent the request. Set to -1 if no + // parent frame exists. + long parentFrameId; + + // The unique identifier for the frame's parent document, if this request + // is for a frame and has a parent. + DOMString? parentDocumentId; + + // The ID of the tab in which the request takes place. Set to -1 if the + // request isn't related to a tab. + long tabId; + + // The resource type of the request. + ResourceType type; + }; + + dictionary TestMatchRequestDetails { + // The URL of the hypothetical request. + DOMString url; + + // The initiator URL (if any) for the hypothetical request. + DOMString? initiator; + + // Standard HTTP method of the hypothetical request. Defaults to "get" for + // HTTP requests and is ignored for non-HTTP requests. + RequestMethod? method; + + // The resource type of the hypothetical request. + ResourceType type; + + // The ID of the tab in which the hypothetical request takes place. Does + // not need to correspond to a real tab ID. Default is -1, meaning that + // the request isn't related to a tab. + long? tabId; + }; + + dictionary MatchedRuleInfoDebug { + MatchedRule rule; + + // Details about the request for which the rule was matched. + RequestDetails request; + }; + + [nodoc] dictionary DNRInfo { + Ruleset[] rule_resources; + }; + + [nodoc] dictionary ManifestKeys { + DNRInfo declarative_net_request; + }; + + dictionary RegexOptions { + // The regular expresson to check. + DOMString regex; + + // Whether the regex specified is case sensitive. Default is + // true. + boolean? isCaseSensitive; + + // Whether the regex specified requires capturing. Capturing is + // only required for redirect rules which specify a + // regexSubstition action. The default is false. + boolean? requireCapturing; + }; + + dictionary IsRegexSupportedResult { + boolean isSupported; + + // Specifies the reason why the regular expression is not supported. Only + // provided if isSupported is false. + UnsupportedRegexReason? reason; + }; + + dictionary TestMatchOutcomeResult { + // The rules (if any) that match the hypothetical request. + MatchedRule[] matchedRules; + }; + + dictionary UpdateRuleOptions { + // IDs of the rules to remove. Any invalid IDs will be ignored. + long[]? removeRuleIds; + // Rules to add. + Rule[]? addRules; + }; + + dictionary UpdateRulesetOptions { + // The set of ids corresponding to a static $(ref:Ruleset) that should be + // disabled. + DOMString[]? disableRulesetIds; + // The set of ids corresponding to a static $(ref:Ruleset) that should be + // enabled. + DOMString[]? enableRulesetIds; + }; + + dictionary UpdateStaticRulesOptions { + // The id corresponding to a static $(ref:Ruleset). + DOMString rulesetId; + // Set of ids corresponding to rules in the $(ref:Ruleset) to disable. + long[]? disableRuleIds; + // Set of ids corresponding to rules in the $(ref:Ruleset) to enable. + long[]? enableRuleIds; + }; + + dictionary GetDisabledRuleIdsOptions { + // The id corresponding to a static $(ref:Ruleset). + DOMString rulesetId; + }; + + dictionary TabActionCountUpdate { + // The tab for which to update the action count. + long tabId; + // The amount to increment the tab's action count by. Negative values will + // decrement the count. + long increment; + }; + + dictionary ExtensionActionOptions { + // Whether to automatically display the action count for a page as the + // extension's badge text. This preference is persisted across sessions. + boolean? displayActionCountAsBadgeText; + // Details of how the tab's action count should be adjusted. + TabActionCountUpdate? tabUpdate; + }; + + callback EmptyCallback = void(); + callback GetAllowedPagesCallback = void(DOMString[] result); + callback GetRulesCallback = void(Rule[] rules); + callback GetMatchedRulesCallback = void(RulesMatchedDetails details); + callback GetEnabledRulesetsCallback = void(DOMString[] rulesetIds); + callback GetDisabledRuleIdsCallback = void(long[] disabledRuleIds); + callback IsRegexSupportedCallback = void(IsRegexSupportedResult result); + callback GetAvailableStaticRuleCountCallback = void(long count); + callback TestMatchOutcomeCallback = void(TestMatchOutcomeResult result); + + interface Functions { + + // Modifies the current set of dynamic rules for the extension. + // The rules with IDs listed in options.removeRuleIds are first + // removed, and then the rules given in options.addRules are + // added. Notes: + //
    + //
  • This update happens as a single atomic operation: either all + // specified rules are added and removed, or an error is returned.
  • + //
  • These rules are persisted across browser sessions and across + // extension updates.
  • + //
  • Static rules specified as part of the extension package can not be + // removed using this function.
  • + //
  • $(ref:MAX_NUMBER_OF_DYNAMIC_RULES) is the maximum number + // of dynamic rules an extension can add. The number of + // unsafe rules must not exceed + // $(ref:MAX_NUMBER_OF_UNSAFE_DYNAMIC_RULES).
  • + //
+ // |callback|: Called once the update is complete or has failed. In case of + // an error, $(ref:runtime.lastError) will be set and no change will be made + // to the rule set. This can happen for multiple reasons, such as invalid + // rule format, duplicate rule ID, rule count limit exceeded, internal + // errors, and others. + static void updateDynamicRules( + UpdateRuleOptions options, + optional EmptyCallback callback); + + // Returns the current set of dynamic rules for the extension. Callers can + // optionally filter the list of fetched rules by specifying a + // filter. + // |filter|: An object to filter the list of fetched rules. + // |callback|: Called with the set of dynamic rules. An error might be + // raised in case of transient internal errors. + static void getDynamicRules( + optional GetRulesFilter filter, + GetRulesCallback callback); + + // Modifies the current set of session scoped rules for the extension. + // The rules with IDs listed in options.removeRuleIds are first + // removed, and then the rules given in options.addRules are + // added. Notes: + //
    + //
  • This update happens as a single atomic operation: either all + // specified rules are added and removed, or an error is returned.
  • + //
  • These rules are not persisted across sessions and are backed in + // memory.
  • + //
  • $(ref:MAX_NUMBER_OF_SESSION_RULES) is the maximum number + // of session rules an extension can add.
  • + //
+ // |callback|: Called once the update is complete or has failed. In case of + // an error, $(ref:runtime.lastError) will be set and no change will be made + // to the rule set. This can happen for multiple reasons, such as invalid + // rule format, duplicate rule ID, rule count limit exceeded, and others. + static void updateSessionRules( + UpdateRuleOptions options, + optional EmptyCallback callback); + + // Returns the current set of session scoped rules for the extension. + // Callers can optionally filter the list of fetched rules by specifying a + // filter. + // |filter|: An object to filter the list of fetched rules. + // |callback|: Called with the set of session scoped rules. + static void getSessionRules( + optional GetRulesFilter filter, + GetRulesCallback callback); + + // Updates the set of enabled static rulesets for the extension. The + // rulesets with IDs listed in options.disableRulesetIds are + // first removed, and then the rulesets listed in + // options.enableRulesetIds are added.
+ // Note that the set of enabled static rulesets is persisted across sessions + // but not across extension updates, i.e. the rule_resources + // manifest key will determine the set of enabled static rulesets on each + // extension update. + // |callback|: Called once the update is complete. In case of an error, + // $(ref:runtime.lastError) will be set and no change will be made to set of + // enabled rulesets. This can happen for multiple reasons, such as invalid + // ruleset IDs, rule count limit exceeded, or internal errors. + static void updateEnabledRulesets( + UpdateRulesetOptions options, + optional EmptyCallback callback); + + // Returns the ids for the current set of enabled static rulesets. + // |callback|: Called with a list of ids, where each id corresponds to an + // enabled static $(ref:Ruleset). + static void getEnabledRulesets( + GetEnabledRulesetsCallback callback); + + // Disables and enables individual static rules in a $(ref:Ruleset). + // Changes to rules belonging to a disabled $(ref:Ruleset) will take + // effect the next time that it becomes enabled. + // |callback|: Called once the update is complete. In case of an error, + // $(ref:runtime.lastError) will be set and no change will be made to the + // enabled static rules. + static void updateStaticRules( + UpdateStaticRulesOptions options, + optional EmptyCallback callback); + + // Returns the list of static rules in the given $(ref:Ruleset) that are + // currently disabled. + // |options|: Specifies the ruleset to query. + // |callback|: Called with a list of ids that correspond to the disabled + // rules in that ruleset. + static void getDisabledRuleIds( + GetDisabledRuleIdsOptions options, + GetDisabledRuleIdsCallback callback); + + // Returns all rules matched for the extension. Callers can optionally + // filter the list of matched rules by specifying a filter. + // This method is only available to extensions with the + // "declarativeNetRequestFeedback" permission or having the + // "activeTab" permission granted for the tabId + // specified in filter. + // Note: Rules not associated with an active document that were matched more + // than five minutes ago will not be returned. + // |filter|: An object to filter the list of matched rules. + // |callback|: Called once the list of matched rules has been fetched. In + // case of an error, $(ref:runtime.lastError) will be set and no rules will + // be returned. This can happen for multiple reasons, such as insufficient + // permissions, or exceeding the quota. + static void getMatchedRules( + optional MatchedRulesFilter filter, + GetMatchedRulesCallback callback); + + // Configures if the action count for tabs should be displayed as the + // extension action's badge text and provides a way for that action count to + // be incremented. + static void setExtensionActionOptions( + ExtensionActionOptions options, + optional EmptyCallback callback); + + // Checks if the given regular expression will be supported as a + // regexFilter rule condition. + // |regexOptions|: The regular expression to check. + // |callback|: Called with details consisting of whether the regular + // expression is supported and the reason if not. + static void isRegexSupported( + RegexOptions regexOptions, + IsRegexSupportedCallback callback); + + // Returns the number of static rules an extension can enable before the + // global static rule limit is + // reached. + static void getAvailableStaticRuleCount( + GetAvailableStaticRuleCountCallback callback); + + // Checks if any of the extension's declarativeNetRequest rules would match + // a hypothetical request. + // Note: Only available for unpacked extensions as this is only intended to + // be used during extension development. + // |requestDetails|: The request details to test. + // |callback|: Called with the details of matched rules. + static void testMatchOutcome( + TestMatchRequestDetails request, + TestMatchOutcomeCallback callback); + }; + + interface Properties { + // The minimum number of static rules guaranteed to an extension across its + // enabled static rulesets. Any rules above this limit will count towards + // the global static rule limit. + [value=30000] static long GUARANTEED_MINIMUM_STATIC_RULES(); + + // The maximum number of combined dynamic and session scoped rules an + // extension can add. + [nodoc, value=5000, deprecated="There is no longer a combined limit. See $(ref:MAX_NUMBER_OF_DYNAMIC_RULES) and $(ref:MAX_NUMBER_OF_SESSION_RULES)."] static long MAX_NUMBER_OF_DYNAMIC_AND_SESSION_RULES(); + + // The maximum number of dynamic rules that an extension can add. + [value=30000] static long MAX_NUMBER_OF_DYNAMIC_RULES(); + + // The maximum number of "unsafe" dynamic rules that an extension can add. + [value=5000] static long MAX_NUMBER_OF_UNSAFE_DYNAMIC_RULES(); + + // The maximum number of session scoped rules that an extension can add. + [value=5000] static long MAX_NUMBER_OF_SESSION_RULES(); + + // The maximum number of "unsafe" session scoped rules that an extension can + // add. + [value=5000] static long MAX_NUMBER_OF_UNSAFE_SESSION_RULES(); + + // Time interval within which MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL + // getMatchedRules calls can be made, specified in minutes. + // Additional calls will fail immediately and set $(ref:runtime.lastError). + // Note: getMatchedRules calls associated with a user gesture + // are exempt from the quota. + [value=10] static long GETMATCHEDRULES_QUOTA_INTERVAL(); + + // The number of times getMatchedRules can be called within a + // period of GETMATCHEDRULES_QUOTA_INTERVAL. + [value=20] static long MAX_GETMATCHEDRULES_CALLS_PER_INTERVAL(); + + // The maximum number of regular expression rules that an extension can + // add. This limit is evaluated separately for the set of dynamic rules and + // those specified in the rule resources file. + [value=1000] static long MAX_NUMBER_OF_REGEX_RULES(); + + // The maximum number of static Rulesets an extension can + // specify as part of the "rule_resources" manifest key. + [value=100] static long MAX_NUMBER_OF_STATIC_RULESETS(); + + // The maximum number of static Rulesets an extension can + // enable at any one time. + [value=50] static long MAX_NUMBER_OF_ENABLED_STATIC_RULESETS(); + + // Ruleset ID for the dynamic rules added by the extension. + [value="_dynamic"] static DOMString DYNAMIC_RULESET_ID(); + + // Ruleset ID for the session-scoped rules added by the extension. + [value="_session"] static DOMString SESSION_RULESET_ID(); + }; + + interface Events { + // Fired when a rule is matched with a request. Only available for unpacked + // extensions with the "declarativeNetRequestFeedback" permission + // as this is intended to be used for debugging purposes only. + // |info|: The rule that has been matched along with information about the + // associated request. + static void onRuleMatchedDebug(MatchedRuleInfoDebug info); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/diagnostics.idl b/tools/under-control/src/extensions/common/api/diagnostics.idl new file mode 100755 index 000000000..1f0ceaf2b --- /dev/null +++ b/tools/under-control/src/extensions/common/api/diagnostics.idl @@ -0,0 +1,38 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.diagnostics API to query various properties of +// the environment that may be useful for diagnostics. +namespace diagnostics { + dictionary SendPacketOptions { + // Target IP address. + DOMString ip; + // Packet time to live value. If omitted, the system default value will be + // used. + long? ttl; + // Packet timeout in seconds. If omitted, the system default value will be + // used. + long? timeout; + // Size of the payload. If omitted, the system default value will be used. + long? size; + }; + + dictionary SendPacketResult { + // The IP of the host which we receives the ICMP reply from. + // The IP may differs from our target IP if the packet's ttl is used up. + DOMString ip; + + // Latency in millisenconds. + double latency; + }; + + callback SendPacketCallback = void(SendPacketResult result); + + interface Functions { + // Send a packet of the given type with the given parameters. + static void sendPacket( + SendPacketOptions options, + SendPacketCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/dns.idl b/tools/under-control/src/extensions/common/api/dns.idl new file mode 100755 index 000000000..9f008e132 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/dns.idl @@ -0,0 +1,28 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.dns API for dns resolution. +namespace dns { + + dictionary ResolveCallbackResolveInfo { + // The result code. Zero indicates success. + long resultCode; + + // A string representing the IP address literal. Supplied only if resultCode + // indicates success. + DOMString? address; + }; + + callback ResolveCallback = void (ResolveCallbackResolveInfo resolveInfo); + + interface Functions { + // Resolves the given hostname or IP address literal. + // |hostname| : The hostname to resolve. + // |callback| : Called when the resolution operation completes. + static void resolve( + DOMString hostname, + ResolveCallback callback); + }; + +}; diff --git a/tools/under-control/src/extensions/common/api/extension_options_internal.idl b/tools/under-control/src/extensions/common/api/extension_options_internal.idl new file mode 100755 index 000000000..f2af79954 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/extension_options_internal.idl @@ -0,0 +1,24 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Internal API for the <extensiontoptions> tag +namespace extensionOptionsInternal { + dictionary SizeChangedOptions { + long oldWidth; + long oldHeight; + long newWidth; + long newHeight; + }; + + dictionary PreferredSizeChangedOptions { + double width; + double height; + }; + + interface Events { + static void onClose(); + static void onLoad(); + static void onPreferredSizeChanged(PreferredSizeChangedOptions options); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/feedback_private.idl b/tools/under-control/src/extensions/common/api/feedback_private.idl new file mode 100755 index 000000000..a8a98eafc --- /dev/null +++ b/tools/under-control/src/extensions/common/api/feedback_private.idl @@ -0,0 +1,288 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.feedbackPrivate API to provide Chrome [OS] +// feedback to the Google Feedback servers. +namespace feedbackPrivate { + + dictionary AttachedFile { + DOMString name; + [instanceOf=Blob] object? data; + }; + + dictionary LogsMapEntry { + DOMString key; + DOMString value; + }; + + // Supported feedback flows. + enum FeedbackFlow { + // Flow for regular user. This is the default. + regular, + + // Flow on the ChromeOS login screen. URL entry, file attaching and landing + // page is disabled for this flow. + login, + + // Flow when the feedback is requested from the sad tab ("Aw, Snap!") page + // when the renderer crashes. + sadTabCrash, + + // Flow for internal Google users. + googleInternal, + + // Flow for AI features. + ai + }; + + dictionary FeedbackInfo { + // File to attach to the feedback report. + AttachedFile? attachedFile; + + // An optional tag to label what type this feedback is. + DOMString? categoryTag; + + // The feedback text describing the user issue. + DOMString description; + + // The placeholder text that will be shown in the description field when + // it's empty. + DOMString? descriptionPlaceholder; + + // The e-mail of the user that initiated this feedback. + DOMString? email; + + // The URL of the page that this issue was being experienced on. + DOMString? pageUrl; + + // Optional product ID to override the Chrome [OS] product id that is + // usually passed to the feedback server. + long? productId; + + // Screenshot to send with this feedback. + [instanceOf=Blob] object? screenshot; + + // Optional id for performance trace data that can be included in this + // report. + long? traceId; + + // An array of key/value pairs providing system information for this + // feedback report. + LogsMapEntry[]? systemInformation; + + // True if we have permission to add histograms to this feedback report. + boolean? sendHistograms; + + // Optional feedback UI flow. Default is the regular user flow. + FeedbackFlow? flow; + + // TODO(rkc): Remove these once we have bindings to send blobs to Chrome. + // Used internally to store the blob uuid after parameter customization. + DOMString? attachedFileBlobUuid; + DOMString? screenshotBlobUuid; + + // Whether to use the system-provided window frame or custom frame controls. + boolean? useSystemWindowFrame; + + // Whether or not to send bluetooth logs with this report. + boolean? sendBluetoothLogs; + + // Whether or not to send tab titles with this report. + boolean? sendTabTitles; + + // Whether or not to send Assistant feedback to Assistant server. + boolean? assistantDebugInfoAllowed; + + // Whether or not triggered from Assistant. + boolean? fromAssistant; + + // Whether or not to include bluetooth logs. + boolean? includeBluetoothLogs; + + // Whether to show questionnaire in the report description based on detected + // domain-related keywords (crbug/1241169). + boolean? showQuestionnaire; + + // Whether or not triggered for Autofill. + boolean? fromAutofill; + + // A JSON formatted string containing autofill metadata for this + // feedback report. + DOMString? autofillMetadata; + + // Whether or not |autofillMetadata| should be included in the feedback + // report. + boolean? sendAutofillMetadata; + + // Whether or not the content is offensive or unsafe. + boolean? isOffensiveOrUnsafe; + + // A JSON formatted string containing ai metadata. + DOMString? aiMetadata; + }; + + // Possible statuses that can result from sending feedback. + enum Status {success, delayed}; + + // Landing page types that can be shown after sending feedback. + enum LandingPageType {normal, techstop, noLandingPage}; + + // Result returned from a $(ref:sendFeedback) call. + dictionary SendFeedbackResult { + // Status of the sending of a feedback report. + Status status; + + // The type of landing page shown to the use when the feedback report is + // successfully sent, if one should be shown. + LandingPageType landingPageType; + }; + + // Allowed log sources on Chrome OS. + enum LogSource { + // Chrome OS system messages. + messages, + + // Latest Chrome OS UI logs. + uiLatest, + + // Info about display connectors and connected displays from DRM subsystem. + drmModetest, + + // USB device list and connectivity graph. + lsusb, + + // Logs from daemon for Atrus device. + atrusLog, + + // Network log. + netLog, + + // Log of system events. + eventLog, + + // Update engine log. + updateEngineLog, + + // Log of the current power manager session. + powerdLatest, + + // Log of the previous power manager session. + powerdPrevious, + + // Info about system PCI buses devices. + lspci, + + // Info about system network interface. + ifconfig, + + // Info about system uptime. + uptime + }; + + // Source of the feedback. + enum FeedbackSource {quickoffice}; + + // Input parameters for a readLogSource() call. + dictionary ReadLogSourceParams { + // The log source from which to read. + LogSource source; + + // For file-based log sources, read from source without closing the file + // handle. The next time $(ref:readLogSource) is called, the file read will + // continue where it left off. $(ref:readLogSource) can be called with + // incremental=true repeatedly. To subsequently close the file + // handle, pass in incremental=false. + boolean incremental; + + // To read from an existing file handle, set this to a valid + // readerId value that was returned from a previous + // $(ref:readLogSource) call. The reader must previously have been created + // for the same value of source. If no readerId is + // provided, $(ref:readLogSource) will attempt to open a new log source + // reader handle. + long? readerId; + }; + + // Result returned from a $(ref:readLogSource) call. + dictionary ReadLogSourceResult { + // The ID of the log source reader that was created to read from the log + // source. If the reader was destroyed at the end of a read by passing in + // incremental=false, this is always set to 0. If the call was + // to use an existing reader with an existing ID, this will be set to the + // same readerId that was passed into $(ref:readLogSource). + long readerId; + + // Each DOMString in this array represents one line of logging that was + // fetched from the log source. + DOMString[] logLines; + }; + + callback GetUserEmailCallback = void(DOMString email); + callback GetSystemInformationCallback = + void(LogsMapEntry[] systemInformation); + callback SendFeedbackCallback = void(SendFeedbackResult result); + callback ReadLogSourceCallback = void (ReadLogSourceResult result); + + interface Functions { + // Returns the email of the currently active or logged in user. + static void getUserEmail(GetUserEmailCallback callback); + + // Returns the system information dictionary. + static void getSystemInformation(GetSystemInformationCallback callback); + + // Opens the feedback report window. + static void openFeedback(FeedbackSource source); + + // Sends a feedback report. + // |loadSystemInfo|: Optional flag when present and is true, the backend + // should load system information before sending the report. This is added + // to reduce user's wait time when sending reports because loading system + // information is slow. + // |formOpenTime|: The epoch time when the feedback form was opened. This is + // used for metrics. + static void sendFeedback( + FeedbackInfo feedback, + optional boolean loadSystemInfo, + optional double formOpenTime, + SendFeedbackCallback callback); + + // Reads from a log source indicated by source. + //

If incremental is false: + //

    + //
  • Returns the entire contents of the log file.
  • + //
  • Returns readerId value of 0 to callback.
  • + //
+ // If incremental is true, and no readerId is + // provided: + //
    + //
  • Returns the entire contents of the log file.
  • + //
  • Starts tracking the file read handle, which is returned as a + // nonzero readerId value in the callback. + //
  • + //
  • If can't create a new file handle, returns readerId + // value of 0 in the callback. + //
  • + //
+ // If incremental is true, and a valid non-zero + // readerId is provided: + //
    + //
  • Returns new lines written to the file since the last time this + // function was called for the same file and readerId. + //
  • + //
  • Returns the same readerId value to the callback.
  • + //
+ static void readLogSource( + ReadLogSourceParams params, + ReadLogSourceCallback callback); + + }; + + interface Events { + // Fired when the a user requests the launch of the feedback UI. We're + // using an event for this versus using the override API since we want + // to be invoked, but not showing a UI, so the feedback extension can + // take a screenshot of the user's desktop. + static void onFeedbackRequested(FeedbackInfo feedback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/file_handlers.idl b/tools/under-control/src/extensions/common/api/file_handlers.idl new file mode 100755 index 000000000..32708700e --- /dev/null +++ b/tools/under-control/src/extensions/common/api/file_handlers.idl @@ -0,0 +1,55 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// `file_handlers` manifest key defintion. File Handlers allow developers to +// let extensions interact with files on the operating system. This manifest key +// can be used by developers to register an extension to a given file type. +[generate_error_messages] namespace fileHandlers { + + // Icon specification similar to an ImageResource. + dictionary Icon { + // TODO(crbug.com/40238266) Add `DOMString? label;` for accessibility. + + // URL from which a user agent can fetch image data. + DOMString src; + + // Multiple space-separated size values to also accommodate image formats + // that can act as containers for multiple images of varying dimensions: + // e.g. "16x16", "16x16 32x32". + DOMString? sizes; + + // MIME type is purely advisory with no default value. + DOMString? type; + }; + + // A FileHandler registers the ability to read, stream, or edit files of given + // MIME types and/or file extensions. + dictionary FileHandler { + // A mapping of one or more MIME types to one or more file extensions. + // e.g. "accept": {"text/csv": ".csv"} or {"text/csv": [".csv", ".txt"]}. + object accept; + + // Specifies the url after the origin that is the navigation destination for + // file handling launches. + DOMString action; + + // Description of the file type. + DOMString name; + + // Array of ImageResources. Only icons declared at the manifest level are + // currently supported. The icon for the extension will appear in the "Open" + // menu. + Icon[]? icons; + + // Whether multiple files should be opened in a single client or multiple. + // Defaults to `single-client`, which makes all files available in only one + // tab. `multiple-client` opens a new tab for each file. + DOMString? launch_type; + }; + + dictionary ManifestKeys { + // File Handlers to register onto the target system. + FileHandler[] file_handlers; + }; +}; diff --git a/tools/under-control/src/extensions/common/api/file_system.idl b/tools/under-control/src/extensions/common/api/file_system.idl new file mode 100755 index 000000000..a9b5bdd05 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/file_system.idl @@ -0,0 +1,186 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.fileSystem API to create, read, navigate, +// and write to the user's local file system. With this API, Chrome Apps can +// read and write to a user-selected location. For example, a text editor app +// can use the API to read and write local documents. All failures are notified +// via chrome.runtime.lastError. +namespace fileSystem { + dictionary AcceptOption { + // This is the optional text description for this option. If not present, + // a description will be automatically generated; typically containing an + // expanded list of valid extensions (e.g. "text/html" may expand to + // "*.html, *.htm"). + DOMString? description; + + // Mime-types to accept, e.g. "image/jpeg" or "audio/*". One of mimeTypes or + // extensions must contain at least one valid element. + DOMString[]? mimeTypes; + + // Extensions to accept, e.g. "jpg", "gif", "crx". + DOMString[]? extensions; + }; + + enum ChooseEntryType { + + // Prompts the user to open an existing file and returns a FileEntry on + // success. From Chrome 31 onwards, the FileEntry will be writable if the + // application has the 'write' permission under 'fileSystem'; otherwise, the + // FileEntry will be read-only. + openFile, + + // Prompts the user to open an existing file and returns a writable + // FileEntry on success. Calls using this type will fail with a runtime + // error if the application doesn't have the 'write' permission under + // 'fileSystem'. + openWritableFile, + + // Prompts the user to open an existing file or a new file and returns a + // writable FileEntry on success. Calls using this type will fail with a + // runtime error if the application doesn't have the 'write' permission + // under 'fileSystem'. + saveFile, + + // Prompts the user to open a directory and returns a DirectoryEntry on + // success. Calls using this type will fail with a runtime error if the + // application doesn't have the 'directory' permission under 'fileSystem'. + // If the application has the 'write' permission under 'fileSystem', the + // returned DirectoryEntry will be writable; otherwise it will be read-only. + // New in Chrome 31. + openDirectory + }; + + dictionary ChooseEntryOptions { + // Type of the prompt to show. The default is 'openFile'. + ChooseEntryType? type; + + // The suggested file name that will be presented to the user as the + // default name to read or write. This is optional. + DOMString? suggestedName; + + // The optional list of accept options for this file opener. Each option + // will be presented as a unique group to the end-user. + AcceptOption[]? accepts; + + // Whether to accept all file types, in addition to the options specified + // in the accepts argument. The default is true. If the accepts field is + // unset or contains no valid entries, this will always be reset to true. + boolean? acceptsAllTypes; + + // Whether to accept multiple files. This is only supported for openFile and + // openWritableFile. The callback to chooseEntry will be called with a list + // of entries if this is set to true. Otherwise it will be called with a + // single Entry. + boolean? acceptsMultiple; + }; + + dictionary RequestFileSystemOptions { + // The ID of the requested volume. + DOMString volumeId; + + // Whether the requested file system should be writable. The default is + // read-only. + boolean? writable; + }; + + // Represents a mounted volume, which can be accessed via chrome. + // fileSystem.requestFileSystem. + dictionary Volume { + DOMString volumeId; + boolean writable; + }; + + // Event notifying about an inserted or a removed volume from the system. + dictionary VolumeListChangedEvent { + Volume[] volumes; + }; + + callback GetDisplayPathCallback = void (DOMString displayPath); + callback EntryCallback = void ([instanceOf=Entry] object entry); + callback EntriesCallback = void ( + [instanceOf=Entry] optional object entry, + [instanceOf=FileEntry] optional object[] fileEntries); + callback IsWritableCallback = void (boolean isWritable); + callback IsRestorableCallback = void (boolean isRestorable); + callback RequestFileSystemCallback = void( + [instanceOf=FileSystem] optional object fileSystem); + callback GetVolumeListCallback = void(optional Volume[] volumes); + + interface Functions { + // Get the display path of an Entry object. The display path is based on + // the full path of the file or directory on the local file system, but may + // be made more readable for display purposes. + static void getDisplayPath( + [instanceOf=Entry] object entry, + GetDisplayPathCallback callback); + + // Get a writable Entry from another Entry. This call will fail with a + // runtime error if the application does not have the 'write' permission + // under 'fileSystem'. If entry is a DirectoryEntry, this call will fail if + // the application does not have the 'directory' permission under + // 'fileSystem'. + [doesNotSupportPromises="Custom hook sets lastError crbug.com/1504349"] + static void getWritableEntry( + [instanceOf=Entry] object entry, + EntryCallback callback); + + // Gets whether this Entry is writable or not. + static void isWritableEntry( + [instanceOf=Entry] object entry, + IsWritableCallback callback); + + // Ask the user to choose a file or directory. + [doesNotSupportPromises="Multi-parameter callback crbug.com/1313625, + Custom hook sets lastError crbug.com/1504349"] + static void chooseEntry(optional ChooseEntryOptions options, + EntriesCallback callback); + + // Returns the file entry with the given id if it can be restored. This call + // will fail with a runtime error otherwise. + [doesNotSupportPromises="Custom hook sets lastError crbug.com/1504349"] + static void restoreEntry(DOMString id, + EntryCallback callback); + + // Returns whether the app has permission to restore the entry with the + // given id. + static void isRestorable( + DOMString id, + IsRestorableCallback callback); + + // Returns an id that can be passed to restoreEntry to regain access to a + // given file entry. Only the 500 most recently used entries are retained, + // where calls to retainEntry and restoreEntry count as use. If the app has + // the 'retainEntries' permission under 'fileSystem', entries are retained + // indefinitely. Otherwise, entries are retained only while the app is + // running and across restarts. + static DOMString retainEntry([instanceOf=Entry] object entry); + + // Requests access to a file system for a volume represented by + // options.volumeId. If options.writable is set to true, + // then the file system will be writable. Otherwise, it will be read-only. + // The writable option requires the + // "fileSystem": {"write"} permission in the manifest. Available to + // kiosk apps running in kiosk session only. For manual-launch kiosk mode, a + // confirmation dialog will be shown on top of the active app window. + // In case of an error, fileSystem will be undefined, and + // chrome.runtime.lastError will be set. + static void requestFileSystem( + RequestFileSystemOptions options, + RequestFileSystemCallback callback); + + // Returns a list of volumes available for requestFileSystem(). + // The "fileSystem": {"requestFileSystem"} manifest permission + // is required. Available to kiosk apps running in the kiosk session only. + // In case of an error, volumes will be undefined, and + // chrome.runtime.lastError will be set. + static void getVolumeList( + GetVolumeListCallback callback); + }; + + interface Events { + // Called when a list of available volumes is changed. + static void onVolumeListChanged(VolumeListChangedEvent event); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/hid.idl b/tools/under-control/src/extensions/common/api/hid.idl new file mode 100755 index 000000000..85377057a --- /dev/null +++ b/tools/under-control/src/extensions/common/api/hid.idl @@ -0,0 +1,159 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.hid API to interact with connected HID devices. +// This API provides access to HID operations from within the context of an app. +// Using this API, apps can function as drivers for hardware devices. +// +// Errors generated by this API are reported by setting +// $(ref:runtime.lastError) and executing the function's regular callback. The +// callback's regular parameters will be undefined in this case. +namespace hid { + dictionary HidCollectionInfo { + // HID usage page identifier. + long usagePage; + // Page-defined usage identifier. + long usage; + // Report IDs which belong to the collection and to its children. + long[] reportIds; + }; + + [noinline_doc] dictionary HidDeviceInfo { + // Opaque device ID. + long deviceId; + // Vendor ID. + long vendorId; + // Product ID. + long productId; + // The product name read from the device, if available. + DOMString productName; + // The serial number read from the device, if available. + DOMString serialNumber; + // Top-level collections from this device's report descriptors. + HidCollectionInfo[] collections; + // Top-level collection's maximum input report size. + long maxInputReportSize; + // Top-level collection's maximum output report size. + long maxOutputReportSize; + // Top-level collection's maximum feature report size. + long maxFeatureReportSize; + // Raw device report descriptor (not available on Windows). + ArrayBuffer reportDescriptor; + }; + + dictionary HidConnectInfo { + // The opaque ID used to identify this connection in all other functions. + long connectionId; + }; + + [noinline_doc] dictionary DeviceFilter { + // Device vendor ID. + long? vendorId; + // Device product ID, only checked only if the vendor ID matches. + long? productId; + // HID usage page identifier. + long? usagePage; + // HID usage identifier, checked only if the HID usage page matches. + long? usage; + }; + + dictionary GetDevicesOptions { + [deprecated="Equivalent to setting $(ref:DeviceFilter.vendorId)."] + long? vendorId; + [deprecated="Equivalent to setting $(ref:DeviceFilter.productId)."] + long? productId; + // A device matching any given filter will be returned. An empty filter list + // will return all devices the app has permission for. + DeviceFilter[]? filters; + }; + + callback GetDevicesCallback = void (HidDeviceInfo[] devices); + callback ConnectCallback = void (HidConnectInfo connection); + callback DisconnectCallback = void (); + + // |reportId|: The report ID or 0 if none. + // |data|: The report data, the report ID prefix (if present) is removed. + callback ReceiveCallback = void (long reportId, ArrayBuffer data); + + // |data|: The report data, including a report ID prefix if one is sent by the + // device. + callback ReceiveFeatureReportCallback = void (ArrayBuffer data); + + callback SendCallback = void(); + + interface Functions { + // Enumerate connected HID devices. + // |options|: The properties to search for on target devices. + static void getDevices( + GetDevicesOptions options, + GetDevicesCallback callback); + + // Open a connection to an HID device for communication. + // |deviceId|: The $(ref:HidDeviceInfo.deviceId) of the device to open. + static void connect( + long deviceId, + ConnectCallback callback); + + // Disconnect from a device. Invoking operations on a device after calling + // this is safe but has no effect. + // |connectionId|: The connectionId returned by $(ref:connect). + static void disconnect( + long connectionId, + optional DisconnectCallback callback); + + // Receive the next input report from the device. + // |connectionId|: The connectionId returned by $(ref:connect). + [doesNotSupportPromises="Multi-parameter callback crbug.com/1313625"] + static void receive(long connectionId, + ReceiveCallback callback); + + // Send an output report to the device. + // + // Note: Do not include a report ID prefix in data. + // It will be added if necessary. + // |connectionId|: The connectionId returned by $(ref:connect). + // |reportId|: The report ID to use, or 0 if none. + // |data|: The report data. + static void send( + long connectionId, + long reportId, + ArrayBuffer data, + SendCallback callback); + + // Request a feature report from the device. + // |connectionId|: The connectionId returned by $(ref:connect). + // |reportId|: The report ID, or 0 if none. + static void receiveFeatureReport( + long connectionId, + long reportId, + ReceiveFeatureReportCallback callback); + + // Send a feature report to the device. + // + // Note: Do not include a report ID prefix in data. + // It will be added if necessary. + // |connectionId|: The connectionId returned by $(ref:connect). + // |reportId|: The report ID to use, or 0 if none. + // |data|: The report data. + static void sendFeatureReport( + long connectionId, + long reportId, + ArrayBuffer data, + SendCallback callback); + }; + + interface Events { + // Event generated when a device is added to the system. Events are only + // broadcast to apps and extensions that have permission to access the + // device. Permission may have been granted at install time or when the user + // accepted an optional permission (see $(ref:permissions.request)). + static void onDeviceAdded(HidDeviceInfo device); + + // Event generated when a device is removed from the system. See + // $(ref:onDeviceAdded) for which events are delivered. + // |deviceId|: The deviceId property of the device passed to + // $(ref:onDeviceAdded). + static void onDeviceRemoved(long deviceId); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/icon_variants.idl b/tools/under-control/src/extensions/common/api/icon_variants.idl new file mode 100755 index 000000000..f5dfda89f --- /dev/null +++ b/tools/under-control/src/extensions/common/api/icon_variants.idl @@ -0,0 +1,23 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use `iconVariants` for icon declarations with support for color schemes. +// In addition to these keys, a size key is allowed with a value of the file +// path to the image. +[generate_error_messages, nodoc] namespace iconVariants { + enum ColorScheme { dark, light }; + + [additionalProperties] dictionary IconVariant { + // Optional DOMString path to an icon that should be used with any possible + // size. + DOMString? any; + + // Optional ColorScheme. + ColorScheme[]? color_schemes; + }; + + dictionary ManifestKeys { + IconVariant[] icon_variants; + }; +}; diff --git a/tools/under-control/src/extensions/common/api/lock_screen_data.idl b/tools/under-control/src/extensions/common/api/lock_screen_data.idl new file mode 100755 index 000000000..3d54cd508 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/lock_screen_data.idl @@ -0,0 +1,97 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +//

+// The API that can be used by an app to create and manage data on the +// Chrome OS lock screen. +//

+//

+// The API usability will depend on the user session state: +//

    +//
  • +// When the user session is locked, the API usage will only be allowed +// from the lock screen context. +//
  • +//
  • +// When the user session is not locked, the API usage will only be +// allowed outside the lock screen context - i.e. from the regular app +// context. +//
  • +//
+//

+//

+// Note that apps have reduced access to Chrome apps APIs from the lock screen +// context. +//

+namespace lockScreen.data { + // The basic information about available data items originating from the lock + // screen. + dictionary DataItemInfo { + // The data item ID that can later be used to retrieve and update the + // associated lock screen data. + DOMString id; + }; + + dictionary DataItemsAvailableEvent { + //

Whether the event was dispatched as a result of the user session + // getting unlocked. + //

+ //

For example: + //

    + //
  • If the app creates new data items while shown on + // the lock screen, when the user unlocks the screen, + // $(ref:onDataItemsAvailable) event will be dispatched with this + // property set to true. + //
  • + //
  • When the user logs in, if not previously reported lock screen + // data items are found, which could happen if the user session had + // been closed while it was locked, $(ref:onDataItemsAvailable) will + // be dispatched with this property set to false. + //
  • + //
+ //

+ boolean wasLocked; + }; + + callback DataItemCallback = void(DataItemInfo item); + callback DataItemListCallback = void(DataItemInfo[] items); + callback DataCallback = void(ArrayBuffer data); + callback VoidCallback = void(); + + interface Functions { + // Creates a new data item reference - available only in lock screen + // contexts. + static void create(DataItemCallback callback); + + // Gets references to all data items available to the app. + static void getAll(DataItemListCallback callback); + + // Retrieves content of the data item identified by |id|. + static void getContent( + DOMString id, + DataCallback callback); + + // Sets contents of a data item. + // |id| - Identifies the target data item. + // |data| - The data item contents to set. + static void setContent( + DOMString id, + ArrayBuffer data, + optional VoidCallback callback); + + // Deletes a data item. The data item will not be available through this + // API anymore. + // |id| - Identifies the data item to delete. + static void delete( + DOMString id, + optional VoidCallback callback); + }; + + interface Events { + // Dispatched when new data items become available to main, non-lock screen + // app context - this event is not expected to be dispatched to the app in + // the lock screen context. + static void onDataItemsAvailable(DataItemsAvailableEvent event); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/media_perception_private.idl b/tools/under-control/src/extensions/common/api/media_perception_private.idl new file mode 100755 index 000000000..7463178a8 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/media_perception_private.idl @@ -0,0 +1,609 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Private API for receiving real-time media perception information. +[platforms=("chromeos")] +namespace mediaPerceptionPrivate { + enum Status { + // The media analytics process is waiting to be launched. + UNINITIALIZED, + + // The analytics process is running and the media processing pipeline is + // started, but it is not yet receiving image frames. This is a + // transitional state between SUSPENDED and + // RUNNING for the time it takes to warm up the media + // processing pipeline, which can take anywhere from a few seconds to a + // minute. + // Note: STARTED is the initial reply to SetState + // RUNNING. + STARTED, + + // The analytics process is running and the media processing pipeling is + // injesting image frames. At this point, MediaPerception signals should + // be coming over D-Bus. + RUNNING, + + // Analytics process is running and the media processing pipeline is ready + // to be set to state RUNNING. The D-Bus communications + // are enabled but the media processing pipeline is suspended. + SUSPENDED, + + // Enum for restarting the media analytics process using Upstart. + // Calling setState RESTARTING will restart the media process + // to the SUSPENDED state. The app has to set the state to + // RUNNING in order to start receiving media perception + // information again. + RESTARTING, + + // Stops the media analytics process via Upstart. + STOPPED, + + // Indicates that a ServiceError has occurred. + SERVICE_ERROR + }; + + enum ServiceError { + // The media analytics process could not be reached. This is likely due to + // a faulty comms configuration or that the process crashed. + SERVICE_UNREACHABLE, + + // The media analytics process is not running. The MPP API knows that the + // process has not been started yet. + SERVICE_NOT_RUNNING, + + // The media analytics process is busy launching. Wait for setState + // RUNNING or setState RESTARTING callback. + SERVICE_BUSY_LAUNCHING, + + // The component is not installed properly. + SERVICE_NOT_INSTALLED, + + // Failed to establish a Mojo connection to the service. + MOJO_CONNECTION_FAILURE + }; + + enum Feature { + AUTOZOOM, + HOTWORD_DETECTION, + OCCUPANCY_DETECTION, + EDGE_EMBEDDINGS, + SOFTWARE_CROPPING + }; + + dictionary NamedTemplateArgument { + DOMString? name; + (DOMString or double)? value; + }; + + enum ComponentType { + // The smaller component with limited functionality (smaller size and + // limited models). + LIGHT, + // The fully-featured component with more functionality (larger size and + // more models). + FULL + }; + + // The status of the media analytics process component on the device. + enum ComponentStatus { + UNKNOWN, + // The component is successfully installed and the image is mounted. + INSTALLED, + // The component failed to download, install or load. + FAILED_TO_INSTALL + }; + + // Error code associated with a failure to install the media analytics + // component. + enum ComponentInstallationError { + // Component requested does not exist. + UNKNOWN_COMPONENT, + + // The update engine fails to install component. + INSTALL_FAILURE, + + // Component can not be mounted. + MOUNT_FAILURE, + + // The component is not compatible with the device. + COMPATIBILITY_CHECK_FAILED, + + // The component was not found - reported for load requests with kSkip + // update policy. + NOT_FOUND + }; + + dictionary Component { + ComponentType type; + }; + + // The state of the media analytics downloadable component. + dictionary ComponentState { + ComponentStatus status; + + // The version string for the current component. + DOMString? version; + + // If the component installation failed, the encountered installation + // error. Not set if the component installation succeeded. + ComponentInstallationError? installationErrorCode; + }; + + // ------------------- Start of process management definitions. ------------ + // New interface for managing the process state of the media perception + // service with the intention of eventually phasing out the setState() call. + enum ProcessStatus { + // The component process state is unknown, for example, if the process is + // waiting to be launched. This is the initial state before + // $(ref:setComponentProcessState) is first called. + UNKNOWN, + + // The component process has been started. + // This value can only be passed to $(ref:setComponentProcessState) if the + // process is currently in state STOPPED or + // UNKNOWN. + STARTED, + + // The component process has been stopped. + // This value can only be passed to $(ref:setComponentProcessState) if the + // process is currently in state STARTED. + // Note: the process is automatically stopped when the Chrome process + // is closed. + STOPPED, + + // Indicates that a ServiceError has occurred. + SERVICE_ERROR + }; + + dictionary ProcessState { + ProcessStatus? status; + + // Return parameter for $(ref:setComponentProcessState) that + // specifies the error type for failure cases. + ServiceError? serviceError; + }; + // ------------------- End of process management definitions. -------------- + + // The parameters for processing a particular video stream. + dictionary VideoStreamParam { + // Identifies the video stream described by these parameters. + DOMString? id; + + // Frame width in pixels. + long? width; + + // Frame height in pixels. + long? height; + + // The frame rate at which this video stream would be processed. + long? frameRate; + }; + + dictionary Point { + // The horizontal distance from the top left corner of the image. + double? x; + + // The vertical distance from the top left corner of the image. + double? y; + }; + + // The parameters for a whiteboard in the image frame. Corners are given in + // pixel coordinates normalized to the size of the image frame (i.e. in the + // range [(0.0, 0.0), (1.0, 1.0)]. The aspectRatio is the physical aspect + // ratio of the whiteboard (e.g. for a 1m high and 2m wide whiteboard, the + // aspect ratio would be 2). + dictionary Whiteboard { + // The top left corner of the whiteboard in the image frame. + Point? topLeft; + + // The top right corner of the whiteboard in the image frame. + Point? topRight; + + // The bottom left corner of the whiteboard in the image frame. + Point? bottomLeft; + + // The bottom right corner of the whiteboard in the image frame. + Point? bottomRight; + + // The physical aspect ratio of the whiteboard. + double? aspectRatio; + }; + + // The system and configuration state of the analytics process. + dictionary State { + Status status; + + // Optional $(ref:setState) parameter. Specifies the video device the media + // analytics process should open while the media processing pipeline is + // starting. To set this parameter, status has to be RUNNING. + DOMString? deviceContext; + + // Return parameter for $(ref:setState) or $(ref:getState) that + // specifies the error type for failure cases. + ServiceError? serviceError; + + // A list of video streams processed by the analytics process. To set this + // parameter, status has to be RUNNING. + VideoStreamParam[]? videoStreamParam; + + // Media analytics configuration. It can only be used when setting state to + // RUNNING. + DOMString? configuration; + + // Corners and aspect ratio of the whiteboard in the image frame. Should + // only be set when setting state to RUNNING and configuration + // to whiteboard. + Whiteboard? whiteboard; + + // A list of enabled media perception features. + Feature[]? features; + + // A list of named parameters to be substituted at start-up. Will + // only have effect when setting state to RUNNING. + NamedTemplateArgument[]? namedTemplateArguments; + }; + + dictionary BoundingBox { + // Specifies whether the points are normalized to the size of the image. + boolean? normalized; + + // The two points that define the corners of a bounding box. + Point? topLeft; + Point? bottomRight; + }; + + enum DistanceUnits { + UNSPECIFIED, + METERS, + PIXELS + }; + + // Generic dictionary to encapsulate a distance magnitude and units. + dictionary Distance { + // This field provides flexibility to report depths or distances of + // different entity types with different units. + DistanceUnits? units; + + double? magnitude; + }; + + enum EntityType { + UNSPECIFIED, + FACE, + PERSON, + MOTION_REGION, + LABELED_REGION + }; + + enum FramePerceptionType { + UNKNOWN_TYPE, + FACE_DETECTION, + PERSON_DETECTION, + MOTION_DETECTION + }; + + dictionary Entity { + // A unique id associated with the detected entity, which can be used to + // track the entity over time. + long? id; + + EntityType? type; + + // Label for this entity. + DOMString? entityLabel; + + // Minimum box which captures entire detected entity. + BoundingBox? boundingBox; + + // A value for the quality of this detection. + double? confidence; + + // The estimated depth of the entity from the camera. + Distance? depth; + }; + + dictionary PacketLatency { + // Label for this packet. + DOMString? packetLabel; + + // Packet processing latency in microseconds. + long? latencyUsec; + }; + + // Type of lighting conditions. + enum LightCondition { + UNSPECIFIED, + + // No noticeable change occurred. + NO_CHANGE, + + // Light was switched on in the room. + TURNED_ON, + + // Light was switched off in the room. + TURNED_OFF, + + // Light gradually got dimmer (for example, due to a sunset). + DIMMER, + + // Light gradually got brighter (for example, due to a sunrise). + BRIGHTER, + + // Black frame was detected - the current frame contains only noise. + BLACK_FRAME + }; + + // Detection of human presence close to the camera. + dictionary VideoHumanPresenceDetection { + // Indicates a probability in [0, 1] interval that a human is present in + // the video frame. + double? humanPresenceLikelihood; + + // Indicates a probability in [0, 1] that motion has been detected in the + // video frame. + double? motionDetectedLikelihood; + + // Indicates lighting condition in the video frame. + LightCondition? lightCondition; + + // Indicates a probablity in [0, 1] interval that + // lightCondition value is correct. + double? lightConditionLikelihood; + }; + + // The set of computer vision metadata for an image frame. + dictionary FramePerception { + long? frameId; + + long? frameWidthInPx; + long? frameHeightInPx; + + // The timestamp associated with the frame (when its recieved by the + // analytics process). + double? timestamp; + + // The list of entities detected in this frame. + Entity[]? entities; + + // Processing latency for a list of packets. + PacketLatency[]? packetLatency; + + // Human presence detection results for a video frame. + VideoHumanPresenceDetection? videoHumanPresenceDetection; + + // Indicates what types of frame perception were run. + FramePerceptionType[]? framePerceptionTypes; + }; + + // An estimate of the direction that the sound is coming from. + dictionary AudioLocalization { + // An angle in radians in the horizontal plane. It roughly points to the + // peak in the probability distribution of azimuth defined below. + double? azimuthRadians; + + // A probability distribution for the current snapshot in time that shows + // the likelihood of a sound source being at a particular azimuth. For + // example, azimuthScores = [0.1, 0.2, 0.3, 0.4] means that + // the probability that the sound is coming from an azimuth of 0, pi/2, pi, + // 3*pi/2 is 0.1, 0.2, 0.3 and 0.4, respectively. + double[]? azimuthScores; + }; + + // Spectrogram of an audio frame. + dictionary AudioSpectrogram { + double[]? values; + }; + + // Detection of human presence close to the microphone. + dictionary AudioHumanPresenceDetection { + // Indicates a probability in [0, 1] interval that a human has caused a + // sound close to the microphone. + double? humanPresenceLikelihood; + + // Estimate of the noise spectrogram. + AudioSpectrogram? noiseSpectrogram; + + // Spectrogram of an audio frame. + AudioSpectrogram? frameSpectrogram; + }; + + enum HotwordType { + UNKNOWN_TYPE, + OK_GOOGLE + }; + + // A hotword detected in the audio stream. + dictionary Hotword { + // Unique identifier for the hotword instance. Note that a single hotword + // instance can span more than one audio frame. In that case a single + // hotword instance can be reported in multiple Hotword or HotwordDetection + // results. Hotword results associated with the same hotword instance will + // have the same id. + long? id; + + // Indicates the type of this hotword. + HotwordType? type; + + // Id of the audio frame in which the hotword was detected. + long? frameId; + + // Indicates the start time of this hotword in the audio frame. + long? startTimestampMs; + + // Indicates the end time of this hotword in the audio frame. + long? endTimestampMs; + + // Indicates a probability in [0, 1] interval that this hotword is present + // in the audio frame. + double? confidence; + }; + + // Detection of hotword in the audio stream. + dictionary HotwordDetection { + Hotword[]? hotwords; + }; + + // Audio perception results for an audio frame. + dictionary AudioPerception { + // A timestamp in microseconds attached when this message was generated. + double? timestampUs; + + // Audio localization results for an audio frame. + AudioLocalization? audioLocalization; + + // Audio human presence detection results for an audio frame. + AudioHumanPresenceDetection? audioHumanPresenceDetection; + + // Hotword detection results. + HotwordDetection? hotwordDetection; + }; + + // Detection of human presence based on both audio and video inputs. + dictionary AudioVisualHumanPresenceDetection { + // Indicates a probability in [0, 1] interval that a human is present. + double? humanPresenceLikelihood; + }; + + // Perception results based on both audio and video inputs. + dictionary AudioVisualPerception { + // A timestamp in microseconds attached when this message was generated. + double? timestampUs; + + // Human presence detection results. + AudioVisualHumanPresenceDetection? audioVisualHumanPresenceDetection; + }; + + // Stores metadata such as version of media perception features. + dictionary Metadata { + DOMString? visualExperienceControllerVersion; + }; + + dictionary MediaPerception { + // The time the media perception data was emitted by the media processing + // pipeline. This value will be greater than the timestamp stored within + // the FramePerception dictionary and the difference between them can be + // viewed as the processing time for a single frame. + double? timestamp; + + // An array of framePerceptions. + FramePerception[]? framePerceptions; + + // An array of audio perceptions. + AudioPerception[]? audioPerceptions; + + // An array of audio-visual perceptions. + AudioVisualPerception[]? audioVisualPerceptions; + + // Stores metadata such as version of media perception features. + Metadata? metadata; + }; + + enum ImageFormat { + // Image represented by RGB data channels. + RAW, + PNG, + JPEG + }; + + dictionary ImageFrame { + long? width; + long? height; + + ImageFormat? format; + + long? dataLength; + + // The bytes of the image frame. + ArrayBuffer? frame; + }; + + dictionary PerceptionSample { + // The video analytics FramePerception for the associated image frame + // data. + FramePerception? framePerception; + + // The image frame data for the associated FramePerception object. + ImageFrame? imageFrame; + + // The audio perception results for an audio frame. + AudioPerception? audioPerception; + + // Perception results based on both audio and video inputs. + AudioVisualPerception? audioVisualPerception; + + // Stores metadata such as version of media perception features. + Metadata? metadata; + }; + + dictionary Diagnostics { + // Return parameter for $(ref:getDiagnostics) that specifies the error + // type for failure cases. + ServiceError? serviceError; + + // A buffer of image frames and the associated video analytics information + // that can be used to diagnose a malfunction. + PerceptionSample[]? perceptionSamples; + }; + + callback StateCallback = void(State state); + + callback DiagnosticsCallback = void(Diagnostics diagnostics); + + callback ComponentStateCallback = void(ComponentState componentState); + + callback ProcessStateCallback = void(ProcessState processState); + + interface Functions { + // Gets the status of the media perception process. + // |callback| : The current state of the system. + static void getState(StateCallback callback); + + // Sets the desired state of the system. + // |state| : A dictionary with the desired new state. The only settable + // states are RUNNING, SUSPENDED, and + // RESTARTING. + // |callback| : Invoked with the State of the system after setting it. Can + // be used to verify the state was set as desired. + static void setState( + State state, + StateCallback callback); + + // Get a diagnostics buffer out of the video analytics process. + // |callback| : Returns a Diagnostics dictionary object. + static void getDiagnostics(DiagnosticsCallback callback); + + // Attempts to download and load the media analytics component. This + // function should be called every time a client starts using this API. If + // the component is already loaded, the callback will simply return that + // information. The process must be STOPPED for this function + // to succeed. + // Note: If a different component type is desired, this function can + // be called with the new desired type and the new component will be + // downloaded and installed. + // |component| : The desired component to install and load. + // |callback| : Returns the state of the component. + static void setAnalyticsComponent( + Component component, + ComponentStateCallback callback); + + // Manages the lifetime of the component process. This function should + // only be used if the component is installed. It will fail if the + // component is not installed. + // |processState| : The desired state for the component process. + // |callback| : Reports the new state of the process, which is expected to + // be the same as the desired state, unless something goes wrong. + static void setComponentProcessState( + ProcessState processState, + ProcessStateCallback callback); + }; + + interface Events { + // Fired when media perception information is received from the media + // analytics process. + // |mediaPerception| : The dictionary which contains a dump of everything + // the analytics process has detected or determined from the incoming media + // streams. + static void onMediaPerception(MediaPerception mediaPerception); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/mime_handler_private.idl b/tools/under-control/src/extensions/common/api/mime_handler_private.idl new file mode 100755 index 000000000..6d20aa659 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/mime_handler_private.idl @@ -0,0 +1,71 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Mime handler API. +[nodoc] namespace mimeHandlerPrivate { + dictionary StreamInfo { + // The MIME type of the intercepted URL request. + DOMString mimeType; + + // The original URL that was intercepted. + DOMString originalUrl; + + // The URL that the stream can be read from. + DOMString streamUrl; + + // The ID of the tab that opened the stream. If the stream is not opened in + // a tab, it will be -1. + long tabId; + + // The HTTP response headers of the intercepted request stored as a + // dictionary mapping header name to header value. If a header name appears + // multiple times, the header values are merged in the dictionary and + // separated by a ", ". Non-ASCII headers are dropped. + object responseHeaders; + + // Whether the stream is embedded within another document. + boolean embedded; + }; + + dictionary PdfPluginAttributes { + // The background color in ARGB format for painting. Since the background + // color is an unsigned 32-bit integer which can be outside the range of + // "long" type, define it as a "double" type here. + double backgroundColor; + + // Indicates whether the plugin allows to execute JavaScript and maybe XFA. + // Loading XFA for PDF forms will automatically be disabled if this flag is + // false. + boolean allowJavascript; + }; + + callback GetStreamDetailsCallback = void (StreamInfo streamInfo); + callback SetShowBeforeUnloadDialogCallback = void (); + + interface Functions { + // Returns the StreamInfo for the stream for this context if there is one. + [nocompile, doesNotSupportPromises= + "Custom hook sets lastError crbug.com/1504349"] + static void getStreamInfo(GetStreamDetailsCallback callback); + + // Sets PDF plugin attributes in the stream for this context if there is + // one. + [nocompile] static void setPdfPluginAttributes( + PdfPluginAttributes pdfPluginAttributes); + + // Instructs the PluginDocument, if running in one, to show a dialog in + // response to beforeunload events. + [nocompile, doesNotSupportPromises= + "Custom hook sets lastError crbug.com/1504349"] + static void setShowBeforeUnloadDialog( + boolean showDialog, + optional SetShowBeforeUnloadDialogCallback callback); + }; + + interface Events { + // Fired when the browser wants the listener to perform a save. + // |streamUrl|: Unique ID for the instance that should perform the save. + static void onSave(DOMString streamUrl); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/mojo_private.idl b/tools/under-control/src/extensions/common/api/mojo_private.idl new file mode 100755 index 000000000..358456f87 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/mojo_private.idl @@ -0,0 +1,13 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.mojoPrivate API provides access to the mojo modules. +namespace mojoPrivate { + interface Functions { + // Returns a promise that will resolve to an asynchronously + // loaded module. + [nocompile] static any requireAsync(DOMString name); + }; + +}; diff --git a/tools/under-control/src/extensions/common/api/networking_onc.idl b/tools/under-control/src/extensions/common/api/networking_onc.idl new file mode 100755 index 000000000..e15647306 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/networking_onc.idl @@ -0,0 +1,1039 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +//

+// The chrome.networking.onc API is used for configuring +// network connections (Cellular, Ethernet, VPN or WiFi). +// This API is available in auto-launched Chrome OS kiosk sessions. +//

+//

+// Network connection configurations are specified following +// +// Open Network Configuration (ONC) specification. +//

+//

+// NOTE: Most dictionary properties and enum values use UpperCamelCase +// to match the ONC specification instead of the JavaScript lowerCamelCase +// convention. +//

+namespace networking.onc { + enum ActivationStateType { + Activated, Activating, NotActivated, PartiallyActivated + }; + + enum CaptivePortalStatus { + Unknown, Offline, Online, Portal, ProxyAuthRequired + }; + + enum ClientCertificateType { + Ref, Pattern + }; + + enum ConnectionStateType { + Connected, Connecting, NotConnected + }; + + enum DeviceStateType { + // Device is available but not initialized. + Uninitialized, + // Device is initialized but not enabled. + Disabled, + // Enabled state has been requested but has not completed. + Enabling, + // Device is enabled. + Enabled, + // Device is prohibited. + Prohibited + }; + + enum IPConfigType { + DHCP, Static + }; + + enum NetworkType { + All, Cellular, Ethernet, Tether, VPN, Wireless, WiFi + }; + + enum ProxySettingsType { + Direct, Manual, PAC, WPAD + }; + + dictionary ManagedBoolean { + // The active value currently used by the network configuration manager + // (e.g. Shill). + boolean? Active; + // The source from which the effective property value was determined. + DOMString? Effective; + // The property value provided by the user policy. + boolean? UserPolicy; + // The property value provided by the device policy. + boolean? DevicePolicy; + // The property value set by the logged in user. Only provided if + // |UserEditable| is true. + boolean? UserSetting; + // The value set for all users of the device. Only provided if + // |DeviceEditiable| is true. + boolean? SharedSetting; + // Whether a UserPolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? UserEditable; + // Whether a DevicePolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? DeviceEditable; + }; + + dictionary ManagedLong { + // The active value currently used by the network configuration manager + // (e.g. Shill). + long? Active; + // The source from which the effective property value was determined. + DOMString? Effective; + // The property value provided by the user policy. + long? UserPolicy; + // The property value provided by the device policy. + long? DevicePolicy; + // The property value set by the logged in user. Only provided if + // |UserEditable| is true. + long? UserSetting; + // The value set for all users of the device. Only provided if + // |DeviceEditiable| is true. + long? SharedSetting; + // Whether a UserPolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? UserEditable; + // Whether a DevicePolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? DeviceEditable; + }; + + dictionary ManagedDOMString { + // The active value currently used by the network configuration manager + // (e.g. Shill). + DOMString? Active; + // The source from which the effective property value was determined. + DOMString? Effective; + // The property value provided by the user policy. + DOMString? UserPolicy; + // The property value provided by the device policy. + DOMString? DevicePolicy; + // The property value set by the logged in user. Only provided if + // |UserEditable| is true. + DOMString? UserSetting; + // The value set for all users of the device. Only provided if + // |DeviceEditiable| is true. + DOMString? SharedSetting; + // Whether a UserPolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? UserEditable; + // Whether a DevicePolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? DeviceEditable; + }; + + dictionary ManagedDOMStringList { + // The active value currently used by the network configuration manager + // (e.g. Shill). + DOMString[]? Active; + // The source from which the effective property value was determined. + DOMString? Effective; + // The property value provided by the user policy. + DOMString[]? UserPolicy; + // The property value provided by the device policy. + DOMString[]? DevicePolicy; + // The property value set by the logged in user. Only provided if + // |UserEditable| is true. + DOMString[]? UserSetting; + // The value set for all users of the device. Only provided if + // |DeviceEditiable| is true. + DOMString[]? SharedSetting; + // Whether a UserPolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? UserEditable; + // Whether a DevicePolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? DeviceEditable; + }; + + dictionary ManagedIPConfigType { + // The active value currently used by the network configuration manager + // (e.g. Shill). + IPConfigType? Active; + // The source from which the effective property value was determined. + DOMString? Effective; + // The property value provided by the user policy. + IPConfigType? UserPolicy; + // The property value provided by the device policy. + IPConfigType? DevicePolicy; + // The property value set by the logged in user. Only provided if + // |UserEditable| is true. + IPConfigType? UserSetting; + // The value set for all users of the device. Only provided if + // |DeviceEditiable| is true. + IPConfigType? SharedSetting; + // Whether a UserPolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? UserEditable; + // Whether a DevicePolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? DeviceEditable; + }; + + dictionary ManagedProxySettingsType { + // The active value currently used by the network configuration manager + // (e.g. Shill). + ProxySettingsType? Active; + // The source from which the effective property value was determined. + DOMString? Effective; + // The property value provided by the user policy. + ProxySettingsType? UserPolicy; + // The property value provided by the device policy. + ProxySettingsType? DevicePolicy; + // The property value set by the logged in user. Only provided if + // |UserEditable| is true. + ProxySettingsType? UserSetting; + // The value set for all users of the device. Only provided if + // |DeviceEditiable| is true. + ProxySettingsType? SharedSetting; + // Whether a UserPolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? UserEditable; + // Whether a DevicePolicy for the property exists and allows the property to + // be edited (i.e. the policy set recommended property value). + // Defaults to false. + boolean? DeviceEditable; + }; + + // Sub-dictionary types. + + dictionary CellularProviderProperties { + // The operator name. + DOMString Name; + // Cellular network ID as a simple concatenation of the network's + // MCC (Mobile Country Code) and MNC (Mobile Network Code). + DOMString Code; + // The two-letter country code. + DOMString? Country; + }; + + dictionary IssuerSubjectPattern { + // If set, the value against which to match the certificate subject's + // common name. + DOMString? CommonName; + // If set, the value against which to match the certificate subject's + // common location. + DOMString? Locality; + // If set, the value against which to match the certificate subject's + // organizations. At least one organization should match the value. + DOMString? Organization; + // If set, the value against which to match the certificate subject's + // organizational units. At least one organizational unit should match the + // value. + DOMString? OrganizationalUnit; + }; + + dictionary CertificatePattern { + // List of URIs to which the user can be directed in case no certificates + // that match this pattern are found. + DOMString[]? EnrollmentURI; + // If set, pattern against which X.509 issuer settings should be matched. + IssuerSubjectPattern? Issuer; + // List of certificate issuer CA certificates. A certificate must be signed + // by one of them in order to match this pattern. + DOMString[]? IssuerCARef; + // If set, pattern against which X.509 subject settings should be matched. + IssuerSubjectPattern? Subject; + }; + + dictionary EAPProperties { + DOMString? AnonymousIdentity; + CertificatePattern? ClientCertPattern; + DOMString? ClientCertPKCS11Id; + DOMString? ClientCertProvisioningProfileId; + DOMString? ClientCertRef; + ClientCertificateType ClientCertType; + DOMString? Identity; + DOMString? Inner; + // The outer EAP type. Required by ONC, but may not be provided when + // translating from Shill. + DOMString? Outer; + DOMString? Password; + boolean? SaveCredentials; + DOMString[]? ServerCAPEMs; + DOMString[]? ServerCARefs; + ManagedDOMString? SubjectMatch; + boolean? UseProactiveKeyCaching; + boolean? UseSystemCAs; + }; + + dictionary FoundNetworkProperties { + // Network availability. + DOMString Status; + // Network ID. + DOMString NetworkId; + // Access technology used by the network. + DOMString Technology; + // The network operator's short-format name. + DOMString? ShortName; + // The network operator's long-format name. + DOMString? LongName; + }; + + dictionary IPConfigProperties { + // Gateway address used for the IP configuration. + DOMString? Gateway; + // The IP address for a connection. Can be IPv4 or IPv6 address, depending + // on value of Type. + DOMString? IPAddress; + // Array of IP blocks in CIDR notation, see onc_spec.md for details. + DOMString[]? ExcludedRoutes; + // Array of IP blocks in CIDR notation, see onc_spec.md for details. + DOMString[]? IncludedRoutes; + // Array of addresses used for name servers. + DOMString[]? NameServers; + // Array of strings for name resolution, see onc_spec.md for details. + DOMString[]? SearchDomains; + // The routing prefix. + long? RoutingPrefix; + // The IP configuration type. Can be IPv4 or IPv6. + DOMString? Type; + // The URL for WEb Proxy Auto-Discovery, as reported over DHCP. + DOMString? WebProxyAutoDiscoveryUrl; + }; + + dictionary ManagedIPConfigProperties { + // See $(ref:IPConfigProperties.Gateway). + ManagedDOMString? Gateway; + // See $(ref:IPConfigProperties.IPAddress). + ManagedDOMString? IPAddress; + // See $(ref:IPConfigProperties.NameServers). + ManagedDOMStringList? NameServers; + // See $(ref:IPConfigProperties.RoutingPrefix). + ManagedLong? RoutingPrefix; + // See $(ref:IPConfigProperties.Type). + ManagedDOMString? Type; + // See $(ref:IPConfigProperties.WebProxyAutoDiscoveryUrl). + ManagedDOMString? WebProxyAutoDiscoveryUrl; + }; + + dictionary PaymentPortal { + // The HTTP method to use for the payment portal. + DOMString Method; + // The post data to send to the payment portal. Ignored unless + // Method is POST. + DOMString? PostData; + // The payment portal URL. + DOMString? Url; + }; + + dictionary ProxyLocation { + // The proxy IP address host. + DOMString Host; + // The port to use for the proxy. + long Port; + }; + + dictionary ManagedProxyLocation { + // See $(ref:ProxyLocation.Host). + ManagedDOMString Host; + // See $(ref:ProxyLocation.Port). + ManagedLong Port; + }; + + [noinline_doc] dictionary ManualProxySettings { + // Settings for HTTP proxy. + ProxyLocation? HTTPProxy; + // Settings for secure HTTP proxy. + ProxyLocation? SecureHTTPProxy; + // Settings for FTP proxy. + ProxyLocation? FTPProxy; + // Settings for SOCKS proxy. + ProxyLocation? SOCKS; + }; + + dictionary ManagedManualProxySettings { + // See $(ref:ManualProxySettings.HTTPProxy). + ManagedProxyLocation? HTTPProxy; + // See $(ref:ManualProxySettings.SecureHTTPProxy). + ManagedProxyLocation? SecureHTTPProxy; + // See $(ref:ManualProxySettings.FTPProxy). + ManagedProxyLocation? FTPProxy; + // See $(ref:ManualProxySettings.SOCKS). + ManagedProxyLocation? SOCKS; + }; + + [noinline_doc] dictionary ProxySettings { + // The type of proxy settings. + ProxySettingsType Type; + // Manual proxy settings - used only for Manual proxy settings. + ManualProxySettings? Manual; + // Domains and hosts for which manual proxy settings are excluded. + DOMString[]? ExcludeDomains; + // URL for proxy auto-configuration file. + DOMString? PAC; + }; + + dictionary ManagedProxySettings { + // See $(ref:ProxySettings.Type). + ManagedProxySettingsType Type; + // See $(ref:ProxySettings.Manual). + ManagedManualProxySettings? Manual; + // See $(ref:ProxySettings.ExcludeDomains). + ManagedDOMStringList? ExcludeDomains; + // See $(ref:ProxySettings.PAC). + ManagedDOMString? PAC; + }; + + dictionary SIMLockStatus { + // The status of SIM lock - possible values are 'sim-pin', + // 'sim-puk' and ''. + DOMString LockType; + // Whether SIM lock is enabled. + boolean LockEnabled; + // Number of PIN lock tries allowed before PUK is required to unlock the + // SIM. + long? RetriesLeft; + }; + + dictionary ThirdPartyVPNProperties { + // ID of the third-party VPN provider extension. + DOMString ExtensionID; + // The VPN provider name. + DOMString? ProviderName; + }; + + dictionary ManagedThirdPartyVPNProperties { + // See $(ref:ThirdPartyVPNProperties.ExtensionID). + ManagedDOMString ExtensionID; + // See $(ref:ThirdPartyVPNProperties.ProviderName). + DOMString? ProviderName; + }; + + // Network type dictionary types. + + [noinline_doc] dictionary CellularProperties { + // Whether the cellular network should be connected automatically (when + // in range). + boolean? AutoConnect; + // The cellular network activation type. + DOMString? ActivationType; + // Carrier account activation state. + ActivationStateType? ActivationState; + // Whether roaming is allowed for the network. + boolean? AllowRoaming; + // Cellular device technology family - CDMA or + // GSM. + DOMString? Family; + // The firmware revision loaded in the cellular modem. + DOMString? FirmwareRevision; + // The list of networks found during the most recent network scan. + FoundNetworkProperties[]? FoundNetworks; + // The cellular modem hardware revision. + DOMString? HardwareRevision; + // Information about the operator that issued the SIM card currently + // installed in the modem. + CellularProviderProperties? HomeProvider; + // The cellular modem manufacturer. + DOMString? Manufacturer; + // The cellular modem model ID. + DOMString? ModelID; + // If the modem is registered on a network, the network technology + // currently in use. + DOMString? NetworkTechnology; + // Online payment portal a user can use to sign-up for or modify a mobile + // data plan. + PaymentPortal? PaymentPortal; + // The roaming state of the cellular modem on the current network. + DOMString? RoamingState; + // True when a cellular network scan is in progress. + boolean? Scanning; + // Information about the operator on whose network the modem is currently + // registered. + CellularProviderProperties? ServingOperator; + // The state of SIM lock for GSM family networks. + SIMLockStatus? SIMLockStatus; + // Whether a SIM card is present. + boolean? SIMPresent; + // The current network signal strength. + long? SignalStrength; + // Whether the cellular network supports scanning. + boolean? SupportNetworkScan; + }; + + dictionary ManagedCellularProperties { + // See $(ref:CellularProperties.AutoConnect). + ManagedBoolean? AutoConnect; + // See $(ref:CellularProperties.ActivationType). + DOMString? ActivationType; + // See $(ref:CellularProperties.ActivationState). + ActivationStateType? ActivationState; + // See $(ref:CellularProperties.AllowRoaming). + boolean? AllowRoaming; + // See $(ref:CellularProperties.Family). + DOMString? Family; + // See $(ref:CellularProperties.FirmwareRevision). + DOMString? FirmwareRevision; + // See $(ref:CellularProperties.FoundNetworks). + FoundNetworkProperties[]? FoundNetworks; + // See $(ref:CellularProperties.HardwareRevision). + DOMString? HardwareRevision; + // See $(ref:CellularProperties.HomeProvider). + CellularProviderProperties[]? HomeProvider; + // See $(ref:CellularProperties.Manufacturer). + DOMString? Manufacturer; + // See $(ref:CellularProperties.ModelID). + DOMString? ModelID; + // See $(ref:CellularProperties.NetworkTechnology). + DOMString? NetworkTechnology; + // See $(ref:CellularProperties.PaymentPortal). + PaymentPortal? PaymentPortal; + // See $(ref:CellularProperties.RoamingState). + DOMString? RoamingState; + // See $(ref:CellularProperties.Scanning). + boolean? Scanning; + // See $(ref:CellularProperties.ServingOperator). + CellularProviderProperties? ServingOperator; + // See $(ref:CellularProperties.SIMLockStatus). + SIMLockStatus? SIMLockStatus; + // See $(ref:CellularProperties.SIMPresent). + boolean? SIMPresent; + // See $(ref:CellularProperties.SignalStrength). + long? SignalStrength; + // See $(ref:CellularProperties.SupportNetworkScan). + boolean? SupportNetworkScan; + }; + + dictionary CellularStateProperties { + // See $(ref:CellularProperties.ActivationState). + ActivationStateType? ActivationState; + // See $(ref:CellularProperties.NetworkTechnology). + DOMString? NetworkTechnology; + // See $(ref:CellularProperties.RoamingState). + DOMString? RoamingState; + // See $(ref:CellularProperties.SIMPresent). + boolean? SIMPresent; + // See $(ref:CellularProperties.SignalStrength). + long? SignalStrength; + }; + + dictionary EthernetProperties { + // Whether the Ethernet network should be connected automatically. + boolean? AutoConnect; + // The authentication used by the Ethernet network. Possible values are + // None and 8021X. + DOMString? Authentication; + // Network's EAP settings. Required for 8021X authentication. + EAPProperties? EAP; + }; + + dictionary ManagedEthernetProperties { + // See $(ref:EthernetProperties.AutoConnect). + ManagedBoolean? AutoConnect; + // See $(ref:EthernetProperties.Authentication). + ManagedDOMString? Authentication; + }; + + dictionary EthernetStateProperties { + // See $(ref:EthernetProperties.Authentication). + DOMString Authentication; + }; + + dictionary VPNProperties { + // Whether the VPN network should be connected automatically. + boolean? AutoConnect; + // The VPN host. + DOMString? Host; + // The VPN type. This cannot be an enum because of 'L2TP-IPSec'. + // This is optional for NetworkConfigProperties which is passed to + // setProperties which may be used to set only specific properties. + DOMString? Type; + }; + + dictionary ManagedVPNProperties { + // See $(ref:VPNProperties.AutoConnect). + ManagedBoolean? AutoConnect; + // See $(ref:VPNProperties.Host). + ManagedDOMString? Host; + // See $(ref:VPNProperties.Type). + ManagedDOMString? Type; + }; + + dictionary VPNStateProperties { + // See $(ref:VPNProperties.Type). + DOMString Type; + }; + + [noinline_doc] dictionary WiFiProperties { + // Whether ARP polling of default gateway is allowed. Defaults to true. + boolean? AllowGatewayARPPolling; + // Whether the WiFi network should be connected automatically when in range. + boolean? AutoConnect; + // The BSSID of the associated access point.. + DOMString? BSSID; + // The network EAP properties. Required for WEP-8021X and + // WPA-EAP networks. + EAPProperties? EAP; + // The WiFi service operating frequency in MHz. For connected networks, the + // current frequency on which the network is connected. Otherwise, the + // frequency of the best available BSS. + long? Frequency; + // Contains all operating frequency recently seen for the WiFi network. + long[]? FrequencyList; + // HEX-encoded copy of the network SSID. + DOMString? HexSSID; + // Whether the network SSID will be broadcast. + boolean? HiddenSSID; + // The passphrase for WEP/WPA/WPA2 connections. This property can only be + // set - properties returned by $(ref:getProperties) will not contain this + // value. + DOMString? Passphrase; + // Deprecated, ignored. + long? RoamThreshold; + // The network SSID. + DOMString? SSID; + // The network security type. + DOMString? Security; + // The network signal strength. + long? SignalStrength; + }; + + dictionary ManagedWiFiProperties { + // See $(ref:WiFiProperties.AllowGatewayARPPolling). + ManagedBoolean? AllowGatewayARPPolling; + // See $(ref:WiFiProperties.AutoConnect). + ManagedBoolean? AutoConnect; + // See $(ref:WiFiProperties.BSSID). + DOMString? BSSID; + // See $(ref:WiFiProperties.Frequency). + long? Frequency; + // See $(ref:WiFiProperties.FrequencyList). + long[]? FrequencyList; + // See $(ref:WiFiProperties.HexSSID). + ManagedDOMString? HexSSID; + // See $(ref:WiFiProperties.HiddenSSID). + ManagedBoolean? HiddenSSID; + // Deprecated, ignored. See $(ref:WiFiProperties.RoamThreshold). + ManagedLong? RoamThreshold; + // See $(ref:WiFiProperties.SSID). + ManagedDOMString? SSID; + // See $(ref:WiFiProperties.Security). + ManagedDOMString Security; + // See $(ref:WiFiProperties.SignalStrength). + long? SignalStrength; + }; + + dictionary WiFiStateProperties { + // See $(ref:WiFiProperties.BSSID). + DOMString? BSSID; + // See $(ref:WiFiProperties.Frequency). + long? Frequency; + // See $(ref:WiFiProperties.HexSSID). + DOMString? HexSSID; + // See $(ref:WiFiProperties.Security). + DOMString Security; + // See $(ref:WiFiProperties.SignalStrength). + long? SignalStrength; + // See $(ref:WiFiProperties.SSID). + DOMString? SSID; + }; + + // Deprecated + dictionary WiMAXProperties { + // Whether the network should be connected automatically. + boolean? AutoConnect; + // The network EAP properties. + EAPProperties? EAP; + }; + + dictionary NetworkConfigProperties { + // See $(ref:NetworkProperties.Cellular). + CellularProperties? Cellular; + // See $(ref:NetworkProperties.Ethernet). + EthernetProperties? Ethernet; + // See $(ref:NetworkProperties.GUID). + DOMString? GUID; + // See $(ref:NetworkProperties.IPAddressConfigType). + IPConfigType? IPAddressConfigType; + // See $(ref:NetworkProperties.Name). + DOMString? Name; + // See $(ref:NetworkProperties.NameServersConfigType). + IPConfigType? NameServersConfigType; + // See $(ref:NetworkProperties.Priority). + long? Priority; + // See $(ref:NetworkProperties.Type). + NetworkType? Type; + // See $(ref:NetworkProperties.VPN). + VPNProperties? VPN; + // See $(ref:NetworkProperties.WiFi). + WiFiProperties? WiFi; + // Deprecated. + WiMAXProperties? WiMAX; + }; + + [noinline_doc] + dictionary NetworkProperties { + // For cellular networks, cellular network properties. + CellularProperties? Cellular; + // Whether the network is connectable. + boolean? Connectable; + // The network's current connection state. + ConnectionStateType? ConnectionState; + // The last recorded network error state. + DOMString? ErrorState; + // For Ethernet networks, the Ethernet network properties. + EthernetProperties? Ethernet; + // The network GUID. + DOMString GUID; + // The network's IP address configuration type. + IPConfigType? IPAddressConfigType; + // The network's IP configuration. + IPConfigProperties[]? IPConfigs; + // The network's MAC address. + DOMString? MacAddress; + // Whether the network is metered. + boolean? Metered; + // A user friendly network name. + DOMString? Name; + // The IP configuration type for the name servers used by the network. + IPConfigType? NameServersConfigType; + // The network priority. + long? Priority; + // The network's proxy settings. + ProxySettings? ProxySettings; + // For a connected network, whether the network connectivity to the + // Internet is limited, e.g. if the network is behind a portal, or a + // cellular network is not activated. + boolean? RestrictedConnectivity; + // The network's static IP configuration. + IPConfigProperties? StaticIPConfig; + // IP configuration that was received from the DHCP server before applying + // static IP configuration. + IPConfigProperties? SavedIPConfig; + // Indicates whether and how the network is configured. Possible values are: + //
    + //
  • Device
  • + //
  • DevicePolicy
  • + //
  • User
  • + //
  • UserPolicy
  • + //
  • None
  • + //
+ // 'None' conflicts with extension code generation so we must use a string + // for 'Source' instead of a SourceType enum. + DOMString? Source; + // When traffic counters were last reset. + double? TrafficCounterResetTime; + // The network type. + NetworkType Type; + // For VPN networks, the network VPN properties. + VPNProperties? VPN; + // For WiFi networks, the network WiFi properties. + WiFiProperties? WiFi; + }; + + [noinline_doc] + dictionary ManagedProperties { + // See $(ref:NetworkProperties.Cellular). + ManagedCellularProperties? Cellular; + // See $(ref:NetworkProperties.Connectable). + boolean? Connectable; + // See $(ref:NetworkProperties.ConnectionState). + ConnectionStateType? ConnectionState; + // See $(ref:NetworkProperties.ErrorState). + DOMString? ErrorState; + // See $(ref:NetworkProperties.Ethernet). + ManagedEthernetProperties? Ethernet; + // See $(ref:NetworkProperties.GUID). + DOMString GUID; + // See $(ref:NetworkProperties.IPAddressConfigType). + ManagedIPConfigType? IPAddressConfigType; + // See $(ref:NetworkProperties.IPConfigs). + IPConfigProperties[]? IPConfigs; + // See $(ref:NetworkProperties.MacAddress). + DOMString? MacAddress; + // See $(ref:NetworkProperties.Metered). + ManagedBoolean? Metered; + // See $(ref:NetworkProperties.Name). + ManagedDOMString? Name; + // See $(ref:NetworkProperties.NameServersConfigType). + ManagedIPConfigType? NameServersConfigType; + // See $(ref:NetworkProperties.Priority). + ManagedLong? Priority; + // See $(ref:NetworkProperties.ProxySettings). + ManagedProxySettings? ProxySettings; + // See $(ref:NetworkProperties.RestrictedConnectivity). + boolean? RestrictedConnectivity; + // See $(ref:NetworkProperties.StaticIPConfig). + ManagedIPConfigProperties? StaticIPConfig; + // See $(ref:NetworkProperties.SavedIPConfig). + IPConfigProperties? SavedIPConfig; + // See $(ref:NetworkProperties.Source). + DOMString? Source; + // See $(ref:NetworkProperties.TrafficCounterResetTime). + double? TrafficCounterResetTime; + // See $(ref:NetworkProperties.Type). + NetworkType Type; + // See $(ref:NetworkProperties.VPN). + ManagedVPNProperties? VPN; + // See $(ref:NetworkProperties.WiFi). + ManagedWiFiProperties? WiFi; + }; + + dictionary NetworkStateProperties { + // See $(ref:NetworkProperties.Cellular). + CellularStateProperties? Cellular; + // See $(ref:NetworkProperties.Connectable). + boolean? Connectable; + // See $(ref:NetworkProperties.ConnectionState). + ConnectionStateType? ConnectionState; + // See $(ref:NetworkProperties.Ethernet). + EthernetStateProperties? Ethernet; + // See $(ref:NetworkProperties.ErrorState). + DOMString? ErrorState; + // See $(ref:NetworkProperties.GUID). + DOMString GUID; + // See $(ref:NetworkProperties.Name). + DOMString? Name; + // See $(ref:NetworkProperties.Priority). + long? Priority; + // See $(ref:NetworkProperties.Source). + DOMString? Source; + // See $(ref:NetworkProperties.Type). + NetworkType Type; + // See $(ref:NetworkProperties.VPN). + VPNStateProperties? VPN; + // See $(ref:NetworkProperties.WiFi). + WiFiStateProperties? WiFi; + }; + + dictionary DeviceStateProperties { + // Set if the device is enabled. True if the device is currently scanning. + boolean? Scanning; + + // The SIM lock status if Type = Cellular and SIMPresent = True. + SIMLockStatus? SIMLockStatus; + + // Set to the SIM present state if the device type is Cellular. + boolean? SIMPresent; + + // The current state of the device. + DeviceStateType State; + + // The network type associated with the device (Cellular, Ethernet or WiFi). + NetworkType Type; + }; + + dictionary NetworkFilter { + // The type of networks to return. + NetworkType networkType; + + // If true, only include visible (physically connected or in-range) + // networks. Defaults to 'false'. + boolean? visible; + + // If true, only include configured (saved) networks. Defaults to 'false'. + boolean? configured; + + // Maximum number of networks to return. Defaults to 1000 if unspecified. + // Use 0 for no limit. + long? limit; + }; + + dictionary GlobalPolicy { + // If true, only policy networks may auto connect. Defaults to false. + boolean? AllowOnlyPolicyNetworksToAutoconnect; + + // If true, only policy networks may be connected to and no new networks may + // be added or configured. Defaults to false. + boolean? AllowOnlyPolicyNetworksToConnect; + + // If true and a managed network is available in the visible network list, + // only policy networks may be connected to and no new networks may be added + // or configured. Defaults to false. + boolean? AllowOnlyPolicyNetworksToConnectIfAvailable; + + // List of blocked networks. Connections to blocked networks are + // prohibited. Networks can be unblocked again by specifying an explicit + // network configuration. Defaults to an empty list. + DOMString[]? BlockedHexSSIDs; + }; + + callback VoidCallback = void(); + callback BooleanCallback = void(boolean result); + callback StringCallback = void(DOMString result); + callback GetPropertiesCallback = void(NetworkProperties result); + callback GetManagedPropertiesCallback = void(ManagedProperties result); + callback GetStatePropertiesCallback = void(NetworkStateProperties result); + callback GetNetworksCallback = void(NetworkStateProperties[] result); + callback GetDeviceStatesCallback = void(DeviceStateProperties[] result); + callback GetEnabledNetworkTypesCallback = void(NetworkType[] result); + callback CaptivePortalStatusCallback = void(CaptivePortalStatus result); + callback GetGlobalPolicyCallback = void(GlobalPolicy result); + + interface Functions { + // Gets all the properties of the network with id networkGuid. Includes all + // properties of the network (read-only and read/write values). + // |networkGuid|: The GUID of the network to get properties for. + // |callback|: Called with the network properties when received. + static void getProperties(DOMString networkGuid, + GetPropertiesCallback callback); + + // Gets the merged properties of the network with id networkGuid from the + // sources: User settings, shared settings, user policy, device policy and + // the currently active settings. + // |networkGuid|: The GUID of the network to get properties for. + // |callback|: Called with the managed network properties when received. + static void getManagedProperties(DOMString networkGuid, + GetManagedPropertiesCallback callback); + + // Gets the cached read-only properties of the network with id networkGuid. + // This is meant to be a higher performance function than + // $(ref:getProperties), which requires a round trip to query the networking + // subsystem. The following properties are returned for all networks: GUID, + // Type, Name, WiFi.Security. Additional properties are provided for visible + // networks: ConnectionState, ErrorState, WiFi.SignalStrength, + // Cellular.NetworkTechnology, Cellular.ActivationState, + // Cellular.RoamingState. + // |networkGuid|: The GUID of the network to get properties for. + // |callback|: Called immediately with the network state properties. + static void getState(DOMString networkGuid, + GetStatePropertiesCallback callback); + + // Sets the properties of the network with id |networkGuid|. This is only + // valid for configured networks (Source != None). Unconfigured visible + // networks should use $(ref:createNetwork) instead. + // + // In kiosk sessions, calling this method on a shared network will fail. + // + // |networkGuid|: The GUID of the network to set properties for. + // |properties|: The properties to set. + // |callback|: Called when the operation has completed. + static void setProperties(DOMString networkGuid, + NetworkConfigProperties properties, + optional VoidCallback callback); + + // Creates a new network configuration from properties. If a matching + // configured network already exists, this will fail. Otherwise returns the + // GUID of the new network. + // |shared|:

+ // If true, share this network configuration with + // other users. + //

+ //

+ // This option is exposed only to Chrome's Web UI. + // When called by apps, false is the only allowed value. + //

+ // |properties|: The properties to configure the new network with. + // |callback|: Called with the GUID for the new network configuration once + // the network has been created. + static void createNetwork(boolean shared, + NetworkConfigProperties properties, + optional StringCallback callback); + + //

+ // Forgets a network configuration by clearing any configured properties + // for the network with GUID networkGuid. This may also + // include any other networks with matching identifiers (e.g. WiFi SSID + // and Security). If no such configuration exists, an error will be set + // and the operation will fail. + //

+ //

+ // In kiosk sessions, this method will not be able to forget shared + // network configurations. + //

+ // |networkGuid|: The GUID of the network to forget. + // |callback|: Called when the operation has completed. + static void forgetNetwork(DOMString networkGuid, + optional VoidCallback callback); + + // Returns a list of network objects with the same properties provided by + // $(ref:getState). A filter is provided to specify the + // type of networks returned and to limit the number of networks. Networks + // are ordered by the system based on their priority, with connected or + // connecting networks listed first. + // |filter|: Describes which networks to return. + // |callback|: Called with a dictionary of networks and their state + // properties when received. + static void getNetworks(NetworkFilter filter, + GetNetworksCallback callback); + + // Returns states of available networking devices. + // |callback|: Called with a list of devices and their state. + static void getDeviceStates(GetDeviceStatesCallback callback); + + // Enables any devices matching the specified network type. Note, the type + // might represent multiple network types (e.g. 'Wireless'). + // |networkType|: The type of network to enable. + static void enableNetworkType(NetworkType networkType); + + // Disables any devices matching the specified network type. See note for + // $(ref:enableNetworkType). + // |networkType|: The type of network to disable. + static void disableNetworkType(NetworkType networkType); + + // Requests that the networking subsystem scan for new networks and + // update the list returned by $(ref:getVisibleNetworks). This is only a + // request: the network subsystem can choose to ignore it. If the list + // is updated, then the $(ref:onNetworkListChanged) event will be fired. + // |networkType|: If provided, requests a scan specific to the type. + // For Cellular a mobile network scan will be requested if supported. + static void requestNetworkScan(optional NetworkType networkType); + + // Starts a connection to the network with networkGuid. + // |networkGuid|: The GUID of the network to connect to. + // |callback|: Called when the connect request has been sent. Note: the + // connection may not have completed. Observe $(ref:onNetworksChanged) + // to be notified when a network state changes. If the connect request + // immediately failed (e.g. the network is unconfigured), + // $(ref:runtime.lastError) will be set with a failure reason. + static void startConnect(DOMString networkGuid, + optional VoidCallback callback); + + // Starts a disconnect from the network with networkGuid. + // |networkGuid|: The GUID of the network to disconnect from. + // |callback|: Called when the disconnect request has been sent. See note + // for $(ref:startConnect). + static void startDisconnect(DOMString networkGuid, + optional VoidCallback callback); + + // Returns captive portal status for the network matching 'networkGuid'. + // |networkGuid|: The GUID of the network to get captive portal status for. + // |callback|: A callback function that returns the results of the query for + // network captive portal status. + static void getCaptivePortalStatus(DOMString networkGuid, + CaptivePortalStatusCallback callback); + + // Gets the global policy properties. These properties are not expected to + // change during a session. + static void getGlobalPolicy(GetGlobalPolicyCallback callback); + }; + + interface Events { + // Fired when the properties change on any of the networks. Sends a list of + // GUIDs for networks whose properties have changed. + static void onNetworksChanged(DOMString[] changes); + + // Fired when the list of networks has changed. Sends a complete list of + // GUIDs for all the current networks. + static void onNetworkListChanged(DOMString[] changes); + + // Fired when the list of devices has changed or any device state properties + // have changed. + static void onDeviceStateListChanged(); + + // Fired when a portal detection for a network completes. Sends the GUID of + // the network and the corresponding captive portal status. + static void onPortalDetectionCompleted(DOMString networkGuid, + CaptivePortalStatus status); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/networking_private.idl b/tools/under-control/src/extensions/common/api/networking_private.idl new file mode 100755 index 000000000..8cfccf14f --- /dev/null +++ b/tools/under-control/src/extensions/common/api/networking_private.idl @@ -0,0 +1,1114 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.networkingPrivate API is used for configuring +// network connections (Cellular, Ethernet, VPN or WiFi). This private +// API is only valid if called from a browser or app associated with the +// primary user. See the Open Network Configuration (ONC) documentation for +// descriptions of properties: +// +// src/components/onc/docs/onc_spec.html, or the +// +// Open Network Configuration page at chromium.org. +//

+// NOTE: Most dictionary properties and enum values use UpperCamelCase to match +// the ONC spec instead of the JavaScript lowerCamelCase convention. +//

+// "State" properties describe just the ONC properties returned by +// $(ref:networkingPrivate.getState) and $(ref:networkingPrivate.getNetworks). +//

+// "Config" properties describe just the ONC properties that can be configured +// through this API. NOTE: Not all configuration properties are exposed at this +// time, only those currently required by the Chrome Settings UI. +// TODO(stevenjb): Provide all configuration properties and types, +// crbug.com/380937. +//

+// TODO(stevenjb/pneubeck): Merge the ONC documentation with this document and +// use it as the ONC specification. + +namespace networkingPrivate { + enum ActivationStateType { + Activated, Activating, NotActivated, PartiallyActivated + }; + + enum CaptivePortalStatus { + Unknown, Offline, Online, Portal, ProxyAuthRequired + }; + + enum ConnectionStateType { + Connected, Connecting, NotConnected + }; + + enum DeviceStateType { + // Device is available but not initialized. + Uninitialized, + // Device is initialized but not enabled. + Disabled, + // Enabled state has been requested but has not completed. + Enabling, + // Device is enabled. + Enabled, + // Device is prohibited. + Prohibited + }; + + enum IPConfigType { + DHCP, Static + }; + + enum NetworkType { + All, Cellular, Ethernet, Tether, VPN, Wireless, WiFi + }; + + enum ProxySettingsType { + Direct, Manual, PAC, WPAD + }; + + // Managed property types. These types all share a common structure: + // Active: For properties that are translated from the configuration + // manager (e.g. Shill), the 'active' value currently in use by the + // configuration manager. + // Effective: The effective source for the property: UserPolicy, DevicePolicy, + // UserSetting or SharedSetting. + // UserPolicy: The value provided by the user policy. + // DevicePolicy: The value provided by the device policy. + // UserSetting: The value set by the logged in user. Only provided if + // UserEditable is true (i.e. no policy affects the property or the + // policy provided value is recommened only). + // SharedSetting: The value set for all users of the device. Only provided if + // DeviceEditiable is true (i.e. no policy affects the property or the + // policy provided value is recommened only). + // UserEditable: True if a UserPolicy exists and allows the property to be + // edited (i.e. is a recommended value). Defaults to False. + // DeviceEditable: True if a DevicePolicy exists and allows the property to be + // edited (i.e. is a recommended value). Defaults to False. + + dictionary ManagedBoolean { + boolean? Active; + DOMString? Effective; + boolean? UserPolicy; + boolean? DevicePolicy; + boolean? UserSetting; + boolean? SharedSetting; + boolean? UserEditable; + boolean? DeviceEditable; + }; + + dictionary ManagedLong { + long? Active; + DOMString? Effective; + long? UserPolicy; + long? DevicePolicy; + long? UserSetting; + long? SharedSetting; + boolean? UserEditable; + boolean? DeviceEditable; + }; + + dictionary ManagedDOMString { + DOMString? Active; + DOMString? Effective; + DOMString? UserPolicy; + DOMString? DevicePolicy; + DOMString? UserSetting; + DOMString? SharedSetting; + boolean? UserEditable; + boolean? DeviceEditable; + }; + + dictionary ManagedDOMStringList { + DOMString[]? Active; + DOMString? Effective; + DOMString[]? UserPolicy; + DOMString[]? DevicePolicy; + DOMString[]? UserSetting; + DOMString[]? SharedSetting; + boolean? UserEditable; + boolean? DeviceEditable; + }; + + dictionary ManagedIPConfigType { + IPConfigType? Active; + DOMString? Effective; + IPConfigType? UserPolicy; + IPConfigType? DevicePolicy; + IPConfigType? UserSetting; + IPConfigType? SharedSetting; + boolean? UserEditable; + boolean? DeviceEditable; + }; + + dictionary ManagedProxySettingsType { + ProxySettingsType? Active; + DOMString? Effective; + ProxySettingsType? UserPolicy; + ProxySettingsType? DevicePolicy; + ProxySettingsType? UserSetting; + ProxySettingsType? SharedSetting; + boolean? UserEditable; + boolean? DeviceEditable; + }; + + // Sub-dictionary types. + + dictionary APNProperties { + DOMString AccessPointName; + DOMString? Authentication; + DOMString? Language; + DOMString? LocalizedName; + DOMString? Name; + DOMString? Password; + DOMString? Username; + }; + + dictionary ManagedAPNProperties { + ManagedDOMString AccessPointName; + ManagedDOMString? Authentication; + ManagedDOMString? Language; + ManagedDOMString? LocalizedName; + ManagedDOMString? Name; + ManagedDOMString? Password; + ManagedDOMString? Username; + }; + + dictionary ManagedAPNList { + APNProperties[]? Active; + DOMString? Effective; + APNProperties[]? UserPolicy; + APNProperties[]? DevicePolicy; + APNProperties[]? UserSetting; + APNProperties[]? SharedSetting; + boolean? UserEditable; + boolean? DeviceEditable; + }; + + dictionary CellularProviderProperties { + DOMString Name; + DOMString Code; + DOMString? Country; + }; + + dictionary CellularSimState { + // Whether or not a PIN should be required. + boolean requirePin; + + // The current PIN (required for any change, even when the SIM is unlocked). + DOMString currentPin; + + // If provided, change the PIN to |newPin|. |requirePin| must be true. + DOMString? newPin; + }; + + dictionary IssuerSubjectPattern { + DOMString? CommonName; + DOMString? Locality; + DOMString? Organization; + DOMString? OrganizationalUnit; + }; + + dictionary ManagedIssuerSubjectPattern { + ManagedDOMString? CommonName; + ManagedDOMString? Locality; + ManagedDOMString? Organization; + ManagedDOMString? OrganizationalUnit; + }; + + dictionary CertificatePattern { + DOMString[]? EnrollmentURI; + IssuerSubjectPattern? Issuer; + DOMString[]? IssuerCAPEMs; + DOMString[]? IssuerCARef; + IssuerSubjectPattern? Subject; + }; + + dictionary ManagedCertificatePattern { + ManagedDOMStringList? EnrollmentURI; + ManagedIssuerSubjectPattern? Issuer; + ManagedDOMStringList? IssuerCARef; + ManagedIssuerSubjectPattern? Subject; + }; + + dictionary EAPProperties { + DOMString? AnonymousIdentity; + CertificatePattern? ClientCertPattern; + DOMString? ClientCertPKCS11Id; + DOMString? ClientCertProvisioningProfileId; + DOMString? ClientCertRef; + DOMString? ClientCertType; + DOMString? Identity; + DOMString? Inner; + // The outer EAP type. Required by ONC, but may not be provided when + // translating from Shill. + DOMString? Outer; + DOMString? Password; + boolean? SaveCredentials; + DOMString[]? ServerCAPEMs; + DOMString[]? ServerCARefs; + DOMString? SubjectMatch; + DOMString? TLSVersionMax; + boolean? UseProactiveKeyCaching; + boolean? UseSystemCAs; + }; + + dictionary ManagedEAPProperties { + ManagedDOMString? AnonymousIdentity; + ManagedCertificatePattern? ClientCertPattern; + ManagedDOMString? ClientCertPKCS11Id; + ManagedDOMString? ClientCertProvisioningProfileId; + ManagedDOMString? ClientCertRef; + ManagedDOMString? ClientCertType; + ManagedDOMString? Identity; + ManagedDOMString? Inner; + // The outer EAP type. Required by ONC, but may not be provided when + // translating from Shill. + ManagedDOMString? Outer; + ManagedDOMString? Password; + ManagedBoolean? SaveCredentials; + ManagedDOMStringList? ServerCAPEMs; + ManagedDOMStringList? ServerCARefs; + ManagedDOMString? SubjectMatch; + ManagedDOMString? TLSVersionMax; + ManagedBoolean? UseProactiveKeyCaching; + ManagedBoolean? UseSystemCAs; + }; + + dictionary FoundNetworkProperties { + DOMString Status; + DOMString NetworkId; + DOMString Technology; + DOMString? ShortName; + DOMString? LongName; + }; + + dictionary IPConfigProperties { + DOMString? Gateway; + DOMString? IPAddress; + DOMString[]? ExcludedRoutes; + DOMString[]? IncludedRoutes; + DOMString[]? NameServers; + DOMString[]? SearchDomains; + long? RoutingPrefix; + DOMString? Type; + DOMString? WebProxyAutoDiscoveryUrl; + }; + + dictionary ManagedIPConfigProperties { + ManagedDOMString? Gateway; + ManagedDOMString? IPAddress; + ManagedDOMStringList? NameServers; + ManagedLong? RoutingPrefix; + ManagedDOMString? Type; + ManagedDOMString? WebProxyAutoDiscoveryUrl; + }; + + dictionary XAUTHProperties { + DOMString? Password; + boolean? SaveCredentials; + DOMString? Username; + }; + + dictionary ManagedXAUTHProperties { + ManagedDOMString? Password; + ManagedBoolean? SaveCredentials; + ManagedDOMString? Username; + }; + + dictionary IPSecProperties { + DOMString AuthenticationType; + CertificatePattern? ClientCertPattern; + DOMString? ClientCertPKCS11Id; + DOMString? ClientCertProvisioningProfileId; + DOMString? ClientCertRef; + DOMString? ClientCertType; + EAPProperties? EAP; + DOMString? Group; + long? IKEVersion; + DOMString? LocalIdentity; + DOMString? PSK; + DOMString? RemoteIdentity; + boolean? SaveCredentials; + DOMString[]? ServerCAPEMs; + DOMString[]? ServerCARefs; + XAUTHProperties? XAUTH; + }; + + dictionary ManagedIPSecProperties { + ManagedDOMString AuthenticationType; + ManagedCertificatePattern? ClientCertPattern; + ManagedDOMString? ClientCertPKCS11Id; + ManagedDOMString? ClientCertProvisioningProfileId; + ManagedDOMString? ClientCertRef; + ManagedDOMString? ClientCertType; + ManagedEAPProperties? EAP; + ManagedDOMString? Group; + ManagedLong? IKEVersion; + ManagedDOMString? PSK; + ManagedBoolean? SaveCredentials; + ManagedDOMStringList? ServerCAPEMs; + ManagedDOMStringList? ServerCARefs; + ManagedXAUTHProperties? XAUTH; + }; + + dictionary L2TPProperties { + boolean? LcpEchoDisabled; + DOMString? Password; + boolean? SaveCredentials; + DOMString? Username; + }; + + dictionary ManagedL2TPProperties { + ManagedBoolean? LcpEchoDisabled; + ManagedDOMString? Password; + ManagedBoolean? SaveCredentials; + ManagedDOMString? Username; + }; + + dictionary PaymentPortal { + DOMString Method; + DOMString? PostData; + DOMString? Url; + }; + + dictionary ProxyLocation { + DOMString Host; + long Port; + }; + + dictionary ManagedProxyLocation { + ManagedDOMString Host; + ManagedLong Port; + }; + + dictionary ManualProxySettings { + ProxyLocation? HTTPProxy; + ProxyLocation? SecureHTTPProxy; + ProxyLocation? FTPProxy; + ProxyLocation? SOCKS; + }; + + dictionary ManagedManualProxySettings { + ManagedProxyLocation? HTTPProxy; + ManagedProxyLocation? SecureHTTPProxy; + ManagedProxyLocation? FTPProxy; + ManagedProxyLocation? SOCKS; + }; + + dictionary ProxySettings { + ProxySettingsType Type; + ManualProxySettings? Manual; + DOMString[]? ExcludeDomains; + DOMString? PAC; + }; + + dictionary ManagedProxySettings { + ManagedProxySettingsType Type; + ManagedManualProxySettings? Manual; + ManagedDOMStringList? ExcludeDomains; + ManagedDOMString? PAC; + }; + + dictionary VerifyX509 { + DOMString? Name; + DOMString? Type; + }; + + dictionary ManagedVerifyX509 { + ManagedDOMString? Name; + ManagedDOMString? Type; + }; + + dictionary OpenVPNProperties { + DOMString? Auth; + DOMString? AuthRetry; + boolean? AuthNoCache; + DOMString? Cipher; + DOMString? ClientCertPKCS11Id; + CertificatePattern? ClientCertPattern; + DOMString? ClientCertProvisioningProfileId; + DOMString? ClientCertRef; + DOMString? ClientCertType; + DOMString? CompLZO; + boolean? CompNoAdapt; + DOMString[]? ExtraHosts; + boolean? IgnoreDefaultRoute; + DOMString? KeyDirection; + DOMString? NsCertType; + DOMString? OTP; + DOMString? Password; + long? Port; + DOMString? Proto; + boolean? PushPeerInfo; + DOMString? RemoteCertEKU; + DOMString[]? RemoteCertKU; + DOMString? RemoteCertTLS; + long? RenegSec; + boolean? SaveCredentials; + DOMString[]? ServerCAPEMs; + DOMString[]? ServerCARefs; + DOMString? ServerCertRef; + long? ServerPollTimeout; + long? Shaper; + DOMString? StaticChallenge; + DOMString? TLSAuthContents; + DOMString? TLSRemote; + DOMString? TLSVersionMin; + DOMString? UserAuthenticationType; + DOMString? Username; + DOMString? Verb; + DOMString? VerifyHash; + VerifyX509? VerifyX509; + }; + + dictionary ManagedOpenVPNProperties { + ManagedDOMString? Auth; + ManagedDOMString? AuthRetry; + ManagedBoolean? AuthNoCache; + ManagedDOMString? Cipher; + ManagedDOMString? ClientCertPKCS11Id; + ManagedCertificatePattern? ClientCertPattern; + ManagedDOMString? ClientCertProvisioningProfileId; + ManagedDOMString? ClientCertRef; + ManagedDOMString? ClientCertType; + ManagedDOMString? CompLZO; + ManagedBoolean? CompNoAdapt; + ManagedDOMStringList? ExtraHosts; + ManagedBoolean? IgnoreDefaultRoute; + ManagedDOMString? KeyDirection; + ManagedDOMString? NsCertType; + ManagedDOMString? OTP; + ManagedDOMString? Password; + ManagedLong? Port; + ManagedDOMString? Proto; + ManagedBoolean? PushPeerInfo; + ManagedDOMString? RemoteCertEKU; + ManagedDOMStringList? RemoteCertKU; + ManagedDOMString? RemoteCertTLS; + ManagedLong? RenegSec; + ManagedBoolean? SaveCredentials; + ManagedDOMStringList? ServerCAPEMs; + ManagedDOMStringList? ServerCARefs; + ManagedDOMString? ServerCertRef; + ManagedLong? ServerPollTimeout; + ManagedLong? Shaper; + ManagedDOMString? StaticChallenge; + ManagedDOMString? TLSAuthContents; + ManagedDOMString? TLSRemote; + ManagedDOMString? TLSVersionMin; + ManagedDOMString? UserAuthenticationType; + ManagedDOMString? Username; + ManagedDOMString? Verb; + ManagedDOMString? VerifyHash; + ManagedVerifyX509? VerifyX509; + }; + + dictionary SIMLockStatus { + DOMString LockType; // sim-pin, sim-puk, or '' + boolean LockEnabled; + long? RetriesLeft; + }; + + dictionary ThirdPartyVPNProperties { + DOMString ExtensionID; + DOMString? ProviderName; + }; + + dictionary ManagedThirdPartyVPNProperties { + ManagedDOMString ExtensionID; + DOMString? ProviderName; + }; + + // Network type dictionary types. + + dictionary CellularProperties { + boolean? AutoConnect; + APNProperties? APN; + APNProperties[]? APNList; + DOMString? ActivationType; + ActivationStateType? ActivationState; + boolean? AllowRoaming; + DOMString? ESN; + DOMString? Family; + DOMString? FirmwareRevision; + FoundNetworkProperties[]? FoundNetworks; + DOMString? HardwareRevision; + CellularProviderProperties? HomeProvider; + DOMString? ICCID; + DOMString? IMEI; + APNProperties? LastGoodAPN; + DOMString? Manufacturer; + DOMString? MDN; + DOMString? MEID; + DOMString? MIN; + DOMString? ModelID; + DOMString? NetworkTechnology; + PaymentPortal? PaymentPortal; + DOMString? RoamingState; + boolean? Scanning; + CellularProviderProperties? ServingOperator; + SIMLockStatus? SIMLockStatus; + boolean? SIMPresent; + long? SignalStrength; + boolean? SupportNetworkScan; + }; + + dictionary ManagedCellularProperties { + ManagedBoolean? AutoConnect; + ManagedAPNProperties? APN; + ManagedAPNList? APNList; + DOMString? ActivationType; + ActivationStateType? ActivationState; + boolean? AllowRoaming; + DOMString? ESN; + DOMString? Family; + DOMString? FirmwareRevision; + FoundNetworkProperties[]? FoundNetworks; + DOMString? HardwareRevision; + CellularProviderProperties? HomeProvider; + DOMString? ICCID; + DOMString? IMEI; + APNProperties? LastGoodAPN; + DOMString? Manufacturer; + DOMString? MDN; + DOMString? MEID; + DOMString? MIN; + DOMString? ModelID; + DOMString? NetworkTechnology; + PaymentPortal? PaymentPortal; + DOMString? RoamingState; + boolean? Scanning; + CellularProviderProperties? ServingOperator; + SIMLockStatus? SIMLockStatus; + boolean? SIMPresent; + long? SignalStrength; + boolean? SupportNetworkScan; + }; + + dictionary CellularStateProperties { + ActivationStateType? ActivationState; + DOMString? EID; + DOMString? ICCID; + DOMString? NetworkTechnology; + DOMString? RoamingState; + boolean? Scanning; + boolean? SIMPresent; + long? SignalStrength; + }; + + dictionary EAPStateProperties { + DOMString? Outer; + }; + + dictionary EthernetProperties { + boolean? AutoConnect; + DOMString? Authentication; + EAPProperties? EAP; + }; + + dictionary ManagedEthernetProperties { + ManagedBoolean? AutoConnect; + ManagedDOMString? Authentication; + ManagedEAPProperties? EAP; + }; + + dictionary EthernetStateProperties { + DOMString Authentication; + }; + + dictionary TetherProperties { + long? BatteryPercentage; + DOMString? Carrier; + boolean HasConnectedToHost; + long? SignalStrength; + }; + + dictionary VPNProperties { + boolean? AutoConnect; + DOMString? Host; + IPSecProperties? IPsec; + L2TPProperties? L2TP; + OpenVPNProperties? OpenVPN; + ThirdPartyVPNProperties? ThirdPartyVPN; + // The VPN type. This cannot be an enum because of 'L2TP-IPSec'. + // This is optional for NetworkConfigProperties which is passed to + // setProperties which may be used to set only specific properties. + DOMString? Type; + }; + + dictionary ManagedVPNProperties { + ManagedBoolean? AutoConnect; + ManagedDOMString? Host; + ManagedIPSecProperties? IPsec; + ManagedL2TPProperties? L2TP; + ManagedOpenVPNProperties? OpenVPN; + ManagedThirdPartyVPNProperties? ThirdPartyVPN; + ManagedDOMString? Type; + }; + + dictionary VPNStateProperties { + DOMString Type; + IPSecProperties? IPsec; + ThirdPartyVPNProperties? ThirdPartyVPN; + }; + + dictionary WiFiProperties { + boolean? AllowGatewayARPPolling; + boolean? AutoConnect; + DOMString? BSSID; + EAPProperties? EAP; + long? Frequency; + long[]? FrequencyList; + DOMString? HexSSID; + boolean? HiddenSSID; + DOMString? Passphrase; + DOMString? SSID; + DOMString? Security; + long? SignalStrength; + }; + + dictionary ManagedWiFiProperties { + ManagedBoolean? AllowGatewayARPPolling; + ManagedBoolean? AutoConnect; + DOMString? BSSID; + ManagedEAPProperties? EAP; + long? Frequency; + long[]? FrequencyList; + ManagedDOMString? HexSSID; + ManagedBoolean? HiddenSSID; + ManagedDOMString? Passphrase; + ManagedDOMString? SSID; + ManagedDOMString Security; + long? SignalStrength; + }; + + dictionary WiFiStateProperties { + DOMString? BSSID; + EAPStateProperties? EAP; + long? Frequency; + DOMString? HexSSID; + DOMString Security; + long? SignalStrength; + DOMString? SSID; + }; + + dictionary NetworkConfigProperties { + CellularProperties? Cellular; + EthernetProperties? Ethernet; + DOMString? GUID; + IPConfigType? IPAddressConfigType; + DOMString? Name; + IPConfigType? NameServersConfigType; + long? Priority; + ProxySettings? ProxySettings; + IPConfigProperties? StaticIPConfig; + NetworkType? Type; + VPNProperties? VPN; + WiFiProperties? WiFi; + }; + + dictionary NetworkProperties { + CellularProperties? Cellular; + boolean? Connectable; + ConnectionStateType? ConnectionState; + DOMString? ErrorState; + EthernetProperties? Ethernet; + DOMString GUID; + IPConfigType? IPAddressConfigType; + IPConfigProperties[]? IPConfigs; + DOMString? MacAddress; + boolean? Metered; + DOMString? Name; + IPConfigType? NameServersConfigType; + long? Priority; + ProxySettings? ProxySettings; + boolean? RestrictedConnectivity; + IPConfigProperties? StaticIPConfig; + IPConfigProperties? SavedIPConfig; + // Indicates whether and how the network is configured. + // 'Source' can be Device, DevicePolicy, User, UserPolicy or None. + // 'None' conflicts with extension code generation so we must use a string + // for 'Source' instead of a SourceType enum. + DOMString? Source; + TetherProperties? Tether; + double? TrafficCounterResetTime; + NetworkType Type; + VPNProperties? VPN; + WiFiProperties? WiFi; + }; + + dictionary ManagedProperties { + ManagedCellularProperties? Cellular; + boolean? Connectable; + ConnectionStateType? ConnectionState; + DOMString? ErrorState; + ManagedEthernetProperties? Ethernet; + DOMString GUID; + ManagedIPConfigType? IPAddressConfigType; + IPConfigProperties[]? IPConfigs; + DOMString? MacAddress; + ManagedBoolean? Metered; + ManagedDOMString? Name; + ManagedIPConfigType? NameServersConfigType; + ManagedLong? Priority; + ManagedProxySettings? ProxySettings; + boolean? RestrictedConnectivity; + ManagedIPConfigProperties? StaticIPConfig; + IPConfigProperties? SavedIPConfig; + // See $(ref:NetworkProperties.Source). + DOMString? Source; + TetherProperties? Tether; + double? TrafficCounterResetTime; + NetworkType Type; + ManagedVPNProperties? VPN; + ManagedWiFiProperties? WiFi; + }; + + dictionary NetworkStateProperties { + CellularStateProperties? Cellular; + boolean? Connectable; + ConnectionStateType? ConnectionState; + EthernetStateProperties? Ethernet; + DOMString? ErrorState; + DOMString GUID; + DOMString? Name; + long? Priority; + // See $(ref:NetworkProperties.Source). + DOMString? Source; + TetherProperties? Tether; + NetworkType Type; + VPNStateProperties? VPN; + WiFiStateProperties? WiFi; + }; + + dictionary DeviceStateProperties { + // Set if the device is enabled. True if the device is currently scanning. + boolean? Scanning; + + // The SIM lock status if Type = Cellular and SIMPresent = True. + SIMLockStatus? SIMLockStatus; + + // Set to the SIM present state if the device type is Cellular. + boolean? SIMPresent; + + // The current state of the device. + DeviceStateType State; + + // The network type associated with the device (Cellular, Ethernet or WiFi). + NetworkType Type; + + // Whether or not any managed networks are available/visible. + boolean? ManagedNetworkAvailable; + }; + + dictionary NetworkFilter { + // The type of networks to return. + NetworkType networkType; + + // If true, only include visible (physically connected or in-range) + // networks. Defaults to 'false'. + boolean? visible; + + // If true, only include configured (saved) networks. Defaults to 'false'. + boolean? configured; + + // Maximum number of networks to return. Defaults to 1000 if unspecified. + // Use 0 for no limit. + long? limit; + }; + + dictionary GlobalPolicy { + // If true, only policy networks may auto connect. Defaults to false. + boolean? AllowOnlyPolicyNetworksToAutoconnect; + + // If true, only policy networks may be connected to and no new networks may + // be added or configured. Defaults to false. + boolean? AllowOnlyPolicyNetworksToConnect; + + // If true and a managed network is available in the visible network list, + // only policy networks may be connected to and no new networks may be added + // or configured. Defaults to false. + boolean? AllowOnlyPolicyNetworksToConnectIfAvailable; + + // List of blocked networks. Connections to blocked networks are + // prohibited. Networks can be allowed again by specifying an explicit + // network configuration. Defaults to an empty list. + DOMString[]? BlockedHexSSIDs; + }; + + dictionary Certificate { + // Unique hash for the certificate. + DOMString hash; + + // Certificate issuer common name. + DOMString issuedBy; + + // Certificate name or nickname. + DOMString issuedTo; + + // PEM for server CA certificates. + DOMString? pem; + + // PKCS#11 id for user certificates. + DOMString? PKCS11Id; + + // Whether or not the certificate is hardware backed. + boolean hardwareBacked; + + // Whether or not the certificate is device wide. + boolean deviceWide; + }; + + dictionary CertificateLists { + // List of avaliable server CA certificates. + Certificate[] serverCaCertificates; + + // List of available user certificates. + Certificate[] userCertificates; + }; + + callback VoidCallback = void(); + callback BooleanCallback = void(boolean result); + callback StringCallback = void(DOMString result); + // TODO(stevenjb): Use NetworkProperties for |result| once defined. + callback GetPropertiesCallback = void(NetworkProperties result); + // TODO(stevenjb): Use ManagedNetworkProperties for |result| once defined. + callback GetManagedPropertiesCallback = void(ManagedProperties result); + callback GetStatePropertiesCallback = void(NetworkStateProperties result); + callback GetNetworksCallback = void(NetworkStateProperties[] result); + callback GetDeviceStatesCallback = void(DeviceStateProperties[] result); + callback GetEnabledNetworkTypesCallback = void(NetworkType[] result); + callback CaptivePortalStatusCallback = void(CaptivePortalStatus result); + callback GetGlobalPolicyCallback = void(GlobalPolicy result); + callback GetCertificateListsCallback = void(CertificateLists result); + + // These functions all report failures either via $(ref:runtime.lastError) + // when using callbacks or passed to the rejection handler when using + // promises. + interface Functions { + // Gets all the properties of the network with id networkGuid. Includes all + // properties of the network (read-only and read/write values). + // |networkGuid|: The GUID of the network to get properties for. + // |callback|: Called with the network properties when received. + static void getProperties( + DOMString networkGuid, + GetPropertiesCallback callback); + + // Gets the merged properties of the network with id networkGuid from the + // sources: User settings, shared settings, user policy, device policy and + // the currently active settings. + // |networkGuid|: The GUID of the network to get properties for. + // |callback|: Called with the managed network properties when received. + static void getManagedProperties( + DOMString networkGuid, + GetManagedPropertiesCallback callback); + + // Gets the cached read-only properties of the network with id networkGuid. + // This is meant to be a higher performance function than + // $(ref:getProperties), which requires a round trip to query the networking + // subsystem. The following properties are returned for all networks: GUID, + // Type, Name, WiFi.Security. Additional properties are provided for visible + // networks: ConnectionState, ErrorState, WiFi.SignalStrength, + // Cellular.NetworkTechnology, Cellular.ActivationState, + // Cellular.RoamingState. + // |networkGuid|: The GUID of the network to get properties for. + // |callback|: Called immediately with the network state properties. + static void getState( + DOMString networkGuid, + GetStatePropertiesCallback callback); + + // Sets the properties of the network with id |networkGuid|. This is only + // valid for configured networks (Source != None). Unconfigured visible + // networks should use createNetwork instead. + // |networkGuid|: The GUID of the network to set properties for. + // |properties|: The properties to set. + // |callback|: Called when the operation has completed. + static void setProperties( + DOMString networkGuid, + NetworkConfigProperties properties, + optional VoidCallback callback); + + // Creates a new network configuration from properties. If a matching + // configured network already exists, this will fail. Otherwise returns the + // guid of the new network. + // |shared|: If true, share this network configuration with other users. + // |properties|: The properties to configure the new network with. + // |callback|: Called with the GUID for the new network configuration once + // the network has been created. + static void createNetwork( + boolean shared, + NetworkConfigProperties properties, + optional StringCallback callback); + + // Forgets a network configuration by clearing any configured properties for + // the network with GUID 'networkGuid'. This may also include any other + // networks with matching identifiers (e.g. WiFi SSID and Security). If no + // such configuration exists, an error will be set and the operation will + // fail. + // |networkGuid|: The GUID of the network to forget. + // |callback|: Called when the operation has completed. + static void forgetNetwork( + DOMString networkGuid, + optional VoidCallback callback); + + // Returns a list of network objects with the same properties provided by + // $(ref:networkingPrivate.getState). A filter is provided to specify the + // type of networks returned and to limit the number of networks. Networks + // are ordered by the system based on their priority, with connected or + // connecting networks listed first. + // |filter|: Describes which networks to return. + // |callback|: Called with a dictionary of networks and their state + // properties when received. + static void getNetworks( + NetworkFilter filter, + GetNetworksCallback callback); + + // Deprecated. Please use $(ref:networkingPrivate.getNetworks) with + // filter.visible = true instead. + [deprecated="Use getNetworks."] static void getVisibleNetworks( + NetworkType networkType, + GetNetworksCallback callback); + + // Deprecated. Please use $(ref:networkingPrivate.getDeviceStates) instead. + [deprecated="Use getDeviceStates."] static void getEnabledNetworkTypes( + GetEnabledNetworkTypesCallback callback); + + // Returns a list of $(ref:networkingPrivate.DeviceStateProperties) objects. + // |callback|: Called with a list of devices and their state. + static void getDeviceStates( + GetDeviceStatesCallback callback); + + // Enables any devices matching the specified network type. Note, the type + // might represent multiple network types (e.g. 'Wireless'). + // |networkType|: The type of network to enable. + static void enableNetworkType(NetworkType networkType); + + // Disables any devices matching the specified network type. See note for + // $(ref:networkingPrivate.enableNetworkType). + // |networkType|: The type of network to disable. + static void disableNetworkType(NetworkType networkType); + + // Requests that the networking subsystem scan for new networks and + // update the list returned by $(ref:getVisibleNetworks). This is only a + // request: the network subsystem can choose to ignore it. If the list + // is updated, then the $(ref:onNetworkListChanged) event will be fired. + // |networkType|: If provided, requests a scan specific to the type. + // For Cellular a mobile network scan will be requested if supported. + static void requestNetworkScan(optional NetworkType networkType); + + // Starts a connection to the network with networkGuid. + // |networkGuid|: The GUID of the network to connect to. + // |callback|: Called when the connect request has been sent. Note: the + // connection may not have completed. Observe $(ref:onNetworksChanged) + // to be notified when a network state changes. If the connect request + // immediately failed (e.g. the network is unconfigured), + // $(ref:runtime.lastError) will be set with a failure reason. + static void startConnect( + DOMString networkGuid, + optional VoidCallback callback); + + // Starts a disconnect from the network with networkGuid. + // |networkGuid|: The GUID of the network to disconnect from. + // |callback|: Called when the disconnect request has been sent. See note + // for $(ref:startConnect). + static void startDisconnect( + DOMString networkGuid, + optional VoidCallback callback); + + // Starts activation of the Cellular network with networkGuid. If called + // for a network that is already activated, or for a network with a carrier + // that can not be directly activated, this will show the account details + // page for the carrier if possible. + // |networkGuid|: The GUID of the Cellular network to activate. + // |carrier|: Optional name of carrier to activate. + // |callback|: Called when the activation request has been sent. See note + // for $(ref:startConnect). + static void startActivate( + DOMString networkGuid, + optional DOMString carrier, + optional VoidCallback callback); + + // Returns captive portal status for the network matching 'networkGuid'. + // |networkGuid|: The GUID of the network to get captive portal status for. + // |callback|: A callback function that returns the results of the query for + // network captive portal status. + static void getCaptivePortalStatus( + DOMString networkGuid, + CaptivePortalStatusCallback callback); + + // Unlocks a Cellular SIM card. + // * If the SIM is PIN locked, |pin| will be used to unlock the SIM and + // the |puk| argument will be ignored if provided. + // * If the SIM is PUK locked, |puk| and |pin| must be provided. If the + // operation succeeds (|puk| is valid), the PIN will be set to |pin|. + // (If |pin| is empty or invalid the operation will fail). + // |networkGuid|: The GUID of the cellular network to unlock. + // If empty, the default cellular device will be used. + // |pin|: The current SIM PIN, or the new PIN if PUK is provided. + // |puk|: The operator provided PUK for unblocking a blocked SIM. + // |callback|: Called when the operation has completed. + static void unlockCellularSim( + DOMString networkGuid, + DOMString pin, + optional DOMString puk, + optional VoidCallback callback); + + // Sets whether or not SIM locking is enabled (i.e a PIN will be required + // when the device is powered) and changes the PIN if a new PIN is + // specified. If the new PIN is provided but not valid (e.g. too short) + // the operation will fail. This will not lock the SIM; that is handled + // automatically by the device. NOTE: If the SIM is locked, it must first be + // unlocked with unlockCellularSim() before this can be called (otherwise it + // will fail and $(ref:runtime.lastError) will be set to Error.SimLocked). + // |networkGuid|: The GUID of the cellular network to set the SIM state of. + // If empty, the default cellular device will be used. + // |simState|: The SIM state to set. + // |callback|: Called when the operation has completed. + static void setCellularSimState( + DOMString networkGuid, + CellularSimState simState, + optional VoidCallback callback); + + // Selects which Cellular Mobile Network to use. |networkId| must be the + // NetworkId property of a member of Cellular.FoundNetworks from the + // network properties for the specified Cellular network. + // |networkGuid|: The GUID of the cellular network to select the network + // for. If empty, the default cellular device will be used. + // |networkId|: The networkId to select. + // |callback|: Called when the operation has completed. + static void selectCellularMobileNetwork( + DOMString networkGuid, + DOMString networkId, + optional VoidCallback callback); + + // Gets the global policy properties. These properties are not expected to + // change during a session. + static void getGlobalPolicy( + GetGlobalPolicyCallback callback); + + // Gets the lists of certificates available for network configuration. + static void getCertificateLists( + GetCertificateListsCallback callback); + }; + + interface Events { + // Fired when the properties change on any of the networks. Sends a list of + // GUIDs for networks whose properties have changed. + static void onNetworksChanged(DOMString[] changes); + + // Fired when the list of networks has changed. Sends a complete list of + // GUIDs for all the current networks. + static void onNetworkListChanged(DOMString[] changes); + + // Fired when the list of devices has changed or any device state properties + // have changed. + static void onDeviceStateListChanged(); + + // Fired when a portal detection for a network completes. Sends the guid of + // the network and the corresponding captive portal status. + static void onPortalDetectionCompleted(DOMString networkGuid, + CaptivePortalStatus status); + + // Fired when any certificate list has changed. + static void onCertificateListsChanged(); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/oauth2.idl b/tools/under-control/src/extensions/common/api/oauth2.idl new file mode 100755 index 000000000..41fc9a17b --- /dev/null +++ b/tools/under-control/src/extensions/common/api/oauth2.idl @@ -0,0 +1,22 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Stub namespace for the "oauth2" manifest key. +namespace oauth2 { + dictionary OAuth2Info { + // Whether the approval UI should be skipped. Only available to allowlisted + // extensions/apps. + [nodoc] boolean? auto_approve; + + // Client ID of the corresponding extension/app. + DOMString? client_id; + + // Scopes the extension/app needs access to. + DOMString[] scopes; + }; + + dictionary ManifestKeys { + OAuth2Info oauth2; + }; +}; diff --git a/tools/under-control/src/extensions/common/api/offscreen.idl b/tools/under-control/src/extensions/common/api/offscreen.idl new file mode 100755 index 000000000..1a4d399e3 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/offscreen.idl @@ -0,0 +1,88 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the offscreen API to create and manage offscreen documents. +namespace offscreen { + enum Reason { + // A reason used for testing purposes only. + TESTING, + // Specifies that the offscreen document is responsible for playing audio. + AUDIO_PLAYBACK, + // Specifies that the offscreen document needs to embed and script an + // iframe in order to modify the iframe's content. + IFRAME_SCRIPTING, + // Specifies that the offscreen document needs to embed an iframe and + // scrape its DOM to extract information. + DOM_SCRAPING, + // Specifies that the offscreen document needs to interact with Blob + // objects (including URL.createObjectURL()). + BLOBS, + // Specifies that the offscreen document needs to use the + // DOMParser API. + DOM_PARSER, + // Specifies that the offscreen document needs to interact with + // media streams from user media (e.g. getUserMedia()). + USER_MEDIA, + // Specifies that the offscreen document needs to interact with + // media streams from display media (e.g. getDisplayMedia()). + DISPLAY_MEDIA, + // Specifies that the offscreen document needs to use + // WebRTC APIs. + WEB_RTC, + // Specifies that the offscreen document needs to interact with the + // Clipboard API. + CLIPBOARD, + // Specifies that the offscreen document needs access to + // localStorage. + LOCAL_STORAGE, + // Specifies that the offscreen document needs to spawn workers. + WORKERS, + // Specifies that the offscreen document needs to use + // navigator.getBattery. + BATTERY_STATUS, + // Specifies that the offscreen document needs to use + // window.matchMedia. + MATCH_MEDIA, + // Specifies that the offscreen document needs to use + // navigator.geolocation. + GEOLOCATION + }; + + dictionary CreateParameters { + // The reason(s) the extension is creating the offscreen document. + Reason[] reasons; + // The (relative) URL to load in the document. + DOMString url; + // A developer-provided string that explains, in more detail, the need for + // the background context. The user agent _may_ use this in display to the + // user. + DOMString justification; + }; + + callback VoidCallback = void(); + callback BooleanCallback = void(boolean result); + + interface Functions { + // Creates a new offscreen document for the extension. + // |parameters|: The parameters describing the offscreen document to create. + // |callback|: Invoked when the offscreen document is created and has + // completed its initial page load. + static void createDocument( + CreateParameters parameters, + VoidCallback callback); + + // Closes the currently-open offscreen document for the extension. + // |callback|: Invoked when the offscreen document has been closed. + static void closeDocument(VoidCallback callback); + + // Determines whether the extension has an active document. + // TODO(crbug.com/40849649): This probably isn't something we want to + // ship in its current form (hence the nodoc). Instead of this, we should + // integrate offscreen documents into a service worker-compatible getViews() + // alternative. But this is pretty useful in testing environments. + // |callback|: Invoked with the result of whether the extension has an + // active offscreen document. + [nodoc] static void hasDocument(BooleanCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/power.idl b/tools/under-control/src/extensions/common/api/power.idl new file mode 100755 index 000000000..497e7d39e --- /dev/null +++ b/tools/under-control/src/extensions/common/api/power.idl @@ -0,0 +1,35 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.power API to override the system's power +// management features. +namespace power { + callback VoidCallback = void (); + + [noinline_doc] enum Level { + // Prevents the system from sleeping in response to user inactivity. + system, + + // Prevents the display from being turned off or dimmed, or the system + // from sleeping in response to user inactivity. + display + }; + + interface Functions { + // Requests that power management be temporarily disabled. |level| + // describes the degree to which power management should be disabled. + // If a request previously made by the same app is still active, it + // will be replaced by the new request. + static void requestKeepAwake(Level level); + + // Releases a request previously made via requestKeepAwake(). + static void releaseKeepAwake(); + + // Reports a user activity in order to awake the screen from a dimmed or + // turned off state or from a screensaver. Exits the screensaver if it is + // currently active. + [platforms=("chromeos", "lacros")] static void reportActivity( + optional VoidCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/printer_provider.idl b/tools/under-control/src/extensions/common/api/printer_provider.idl new file mode 100755 index 000000000..920f82ae6 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/printer_provider.idl @@ -0,0 +1,114 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.printerProvider API exposes events used by print +// manager to query printers controlled by extensions, to query their +// capabilities and to submit print jobs to these printers. +namespace printerProvider { + // Error codes returned in response to $(ref:onPrintRequested) event. + enum PrintError { + // Specifies that the operation was completed successfully. + OK, + + // Specifies that a general failure occured. + FAILED, + + // Specifies that the print ticket is invalid. For example, the ticket is + // inconsistent with some capabilities, or the extension is not able to + // handle all settings from the ticket. + INVALID_TICKET, + + // Specifies that the document is invalid. For example, data may be + // corrupted or the format is incompatible with the extension. + INVALID_DATA + }; + + // Printer description for $(ref:onGetPrintersRequested) event. + dictionary PrinterInfo { + // Unique printer ID. + DOMString id; + + // Printer's human readable name. + DOMString name; + + // Printer's human readable description. + DOMString? description; + }; + + // Printing request parameters. Passed to $(ref:onPrintRequested) event. + [noinline_doc] dictionary PrintJob { + // ID of the printer which should handle the job. + DOMString printerId; + + // The print job title. + DOMString title; + + // Print ticket in + // + // CJT format. + // + object ticket; + + // The document content type. Supported formats are + // "application/pdf" and "image/pwg-raster". + DOMString contentType; + + // Blob containing the document data to print. Format must match + // |contentType|. + [instanceOf=Blob] object document; + }; + + callback PrintersCallback = void(PrinterInfo[] printerInfo); + + callback PrinterInfoCallback = void(optional PrinterInfo printerInfo); + + // |capabilities|: Device capabilities in + // CDD + // format. + callback CapabilitiesCallback = void(object capabilities); + + callback PrintCallback = void(PrintError result); + + interface Events { + // Event fired when print manager requests printers provided by extensions. + // |resultCallback|: Callback to return printer list. Every listener must + // call callback exactly once. + static void onGetPrintersRequested(PrintersCallback resultCallback); + + // Event fired when print manager requests information about a USB device + // that may be a printer. + //

Note: An application should not rely on this event being + // fired more than once per device. If a connected device is supported it + // should be returned in the $(ref:onGetPrintersRequested) event.

+ // |device|: The USB device. + // |resultCallback|: Callback to return printer info. The receiving listener + // must call callback exactly once. If the parameter to this callback is + // undefined that indicates that the application has determined that the + // device is not supported. + static void onGetUsbPrinterInfoRequested( + usb.Device device, + PrinterInfoCallback resultCallback); + + // Event fired when print manager requests printer capabilities. + // |printerId|: Unique ID of the printer whose capabilities are requested. + // |resultCallback|: Callback to return device capabilities in + // CDD + // format. + // The receiving listener must call callback exectly once. + static void onGetCapabilityRequested(DOMString printerId, + CapabilitiesCallback resultCallback); + + // Event fired when print manager requests printing. + // |printJob|: The printing request parameters. + // |resultCallback|: Callback that should be called when the printing + // request is completed. + static void onPrintRequested(PrintJob printJob, + PrintCallback resultCallback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/printer_provider_internal.idl b/tools/under-control/src/extensions/common/api/printer_provider_internal.idl new file mode 100755 index 000000000..b9d2d1ded --- /dev/null +++ b/tools/under-control/src/extensions/common/api/printer_provider_internal.idl @@ -0,0 +1,58 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// printerProviderInternal +// Internal API used to run callbacks passed to chrome.printerProvider API +// events. +// When dispatching a chrome.printerProvider API event, its arguments will be +// massaged in custom bindings so a callback is added. The callback uses +// chrome.printerProviderInternal API to report the event results. +// In order to identify the event for which the callback is called, the event +// is internally dispatched having a requestId argument (which is removed from +// the argument list before the event actually reaches the event listeners). The +// requestId is forwarded to the chrome.printerProviderInternal API functions. +[implemented_in="extensions/browser/api/printer_provider/printer_provider_internal_api.h"] +namespace printerProviderInternal { + // Same as in printerProvider.PrintError enum API. + enum PrintError { OK, FAILED, INVALID_TICKET, INVALID_DATA }; + + // Callback carrying a blob. + callback BlobCallback = void([instanceOf=Blob] object blob); + + interface Functions { + // Runs callback to printerProvider.onGetPrintersRequested event. + // |requestId|: Parameter identifying the event instance for which the + // callback is run. + // |printers|: List of printers reported by the extension. + void reportPrinters(long requestId, + optional printerProvider.PrinterInfo[] printers); + + // Runs callback to printerProvider.onUsbAccessGranted event. + // |requestId|: Parameter identifying the event instance for which the + // callback is run. + // |printerInfo|: Printer information reported by the extension. + void reportUsbPrinterInfo(long requestId, + optional printerProvider.PrinterInfo printerInfo); + + // Runs callback to printerProvider.onGetCapabilityRequested event. + // |requestId|: Parameter identifying the event instance for which the + // callback is run. + // |error|: The printer capability returned by the extension. + void reportPrinterCapability(long request_id, optional object capability); + + // Runs callback to printerProvider.onPrintRequested event. + // |requestId|: Parameter identifying the event instance for which the + // callback is run. + // |error|: The requested print job result. + void reportPrintResult(long request_id, optional PrintError error); + + // Gets information needed to create a print data blob for a print request. + // The blob will be dispatched to the extension via + // printerProvider.onPrintRequested event. + // |requestId|: The request id for the print request for which data is + // needed. + // |callback|: Callback called with a blob of print data. + void getPrintData(long requestId, BlobCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/scripts_internal.idl b/tools/under-control/src/extensions/common/api/scripts_internal.idl new file mode 100755 index 000000000..57fa71a86 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/scripts_internal.idl @@ -0,0 +1,72 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Internal namespace for representing content scripts. +namespace scriptsInternal { + // The source of the user script. This will also determine certain + // capabilities of the script (such as whether it can use globs, raw strings + // for code, etc). + enum Source { + DYNAMIC_CONTENT_SCRIPT, + DYNAMIC_USER_SCRIPT, + MANIFEST_CONTENT_SCRIPT + }; + + // The source of the script to inject. + dictionary ScriptSource { + // A string containing the JavaScript code to inject. Exactly one of + // file or code must be specified. + DOMString? code; + // The path of the JavaScript file to inject relative to the extension's + // root directory. Exactly one of file or code + // must be specified. + DOMString? file; + }; + + // Describes a serialized script, intended for storage and persistence across + // browser sessions. + // Note: Though it is called "UserScript", this is used for scripts through + // the scripting API (dynamic content scripts), content scripts in the + // manifest (static content scripts), and user scripts through the userScripts + // API. "UserScript" was chosen because it matches the correspodning + // extenisons::UserScript object (the runtime representation of this) and + // because "Script" is ambiguous (e.g. background script, general JS script, + // etc). + dictionary SerializedUserScript { + // Whether the script will inject into all frames, regardless if it is not + // the top-most frame in the tab. + boolean? allFrames; + // The list of CSS files to be injected into matching pages. Note that, + // today, we only expect these to contain files. It is represented as a + // ScriptSource for compatibility and consistency with `js`. + ScriptSource[]? css; + // Excludes pages that this user script would otherwise be injected into. + DOMString[]? excludeMatches; + // Specifies wildcard patterns for pages this user script will NOT be + // injected into. + DOMString[]? excludeGlobs; + // The ID of the script. + DOMString id; + // Specifies wildcard patterns for pages this user script will be injected + // into. + DOMString[]? includeGlobs; + // The list of sources of javascript to be injected into matching pages. + ScriptSource[]? js; + // Specifies which pages this user script will be injected into. + DOMString[] matches; + // Whether the script should inject into any frames where the URL belongs to + // a scheme that would never match a specified Match Pattern, including + // about:, data:, blob:, and filesystem: schemes. + boolean? matchOriginAsFallback; + // Specifies when JavaScript files are injected into the web page. + extensionTypes.RunAt? runAt; + // The "source" of the user script. + Source source; + // The JavaScript "world" to run the script in. + extensionTypes.ExecutionWorld world; + // The ID of the world into which to inject. If omitted, uses the default + // world. + DOMString? worldId; + }; +}; diff --git a/tools/under-control/src/extensions/common/api/serial.idl b/tools/under-control/src/extensions/common/api/serial.idl new file mode 100755 index 000000000..9236f342e --- /dev/null +++ b/tools/under-control/src/extensions/common/api/serial.idl @@ -0,0 +1,371 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.serial API to read from and write to a device +// connected to a serial port. +namespace serial { + + dictionary DeviceInfo { + // The device's system path. This should be passed as the path + // argument to chrome.serial.connect in order to connect to + // this device. + DOMString path; + + // A PCI or USB vendor ID if one can be determined for the underlying + // device. + long? vendorId; + + // A USB product ID if one can be determined for the underlying device. + long? productId; + + // A human-readable display name for the underlying device if one can be + // queried from the host driver. + DOMString? displayName; + }; + + callback GetDevicesCallback = void (DeviceInfo[] ports); + + enum DataBits { seven, eight }; + enum ParityBit { no, odd, even }; + enum StopBits { one, two }; + + dictionary ConnectionOptions { + // Flag indicating whether or not the connection should be left open when + // the application is suspended (see + // Manage App + // Lifecycle). The default value is "false." When the application is + // loaded, any serial connections previously opened with persistent=true + // can be fetched with getConnections. + boolean? persistent; + + // An application-defined string to associate with the connection. + DOMString? name; + + // The size of the buffer used to receive data. The default value is 4096. + long? bufferSize; + + // The requested bitrate of the connection to be opened. For compatibility + // with the widest range of hardware, this number should match one of + // commonly-available bitrates, such as 110, 300, 1200, 2400, 4800, 9600, + // 14400, 19200, 38400, 57600, 115200. There is no guarantee, of course, + // that the device connected to the serial port will support the requested + // bitrate, even if the port itself supports that bitrate. 9600 + // will be passed by default. + long? bitrate; + + // "eight" will be passed by default. + DataBits? dataBits; + + // "no" will be passed by default. + ParityBit? parityBit; + + // "one" will be passed by default. + StopBits? stopBits; + + // Flag indicating whether or not to enable RTS/CTS hardware flow control. + // Defaults to false. + boolean? ctsFlowControl; + + // The maximum amount of time (in milliseconds) to wait for new data before + // raising an onReceiveError event with a "timeout" error. + // If zero, receive timeout errors will not be raised for the connection. + // Defaults to 0. + long? receiveTimeout; + + // The maximum amount of time (in milliseconds) to wait for a + // send operation to complete before calling the callback with + // a "timeout" error. If zero, send timeout errors will not be triggered. + // Defaults to 0. + long? sendTimeout; + }; + + // Result of the getInfo method. + dictionary ConnectionInfo { + // The id of the serial port connection. + long connectionId; + + // Flag indicating whether the connection is blocked from firing onReceive + // events. + boolean paused; + + // See ConnectionOptions.persistent + boolean persistent; + + // See ConnectionOptions.name + DOMString name; + + // See ConnectionOptions.bufferSize + long bufferSize; + + // See ConnectionOptions.receiveTimeout + long receiveTimeout; + + // See ConnectionOptions.sendTimeout + long sendTimeout; + + // See ConnectionOptions.bitrate. This field may be omitted + // or inaccurate if a non-standard bitrate is in use, or if an error + // occurred while querying the underlying device. + long? bitrate; + + // See ConnectionOptions.dataBits. This field may be omitted + // if an error occurred while querying the underlying device. + DataBits? dataBits; + + // See ConnectionOptions.parityBit. This field may be omitted + // if an error occurred while querying the underlying device. + ParityBit? parityBit; + + // See ConnectionOptions.stopBits. This field may be omitted + // if an error occurred while querying the underlying device. + StopBits? stopBits; + + // See ConnectionOptions.ctsFlowControl. This field may be + // omitted if an error occurred while querying the underlying device. + boolean? ctsFlowControl; + }; + + // Callback from the connect method; + callback ConnectCallback = void (ConnectionInfo connectionInfo); + + // Callback from the update method. + callback UpdateCallback = void (boolean result); + + // Callback from the disconnect method. Returns true if the + // operation was successful. + callback DisconnectCallback = void (boolean result); + + // Callback from the setPaused method. + callback SetPausedCallback = void (); + + // Callback from the getInfo method. + callback GetInfoCallback = void (ConnectionInfo connectionInfo); + + // Callback from the getConnections method. + callback GetConnectionsCallback = void (ConnectionInfo[] connectionInfos); + + enum SendError { + // The connection was disconnected. + disconnected, + + // A send was already pending. + pending, + + // The send timed out. + timeout, + + // A system error occurred and the connection may be unrecoverable. + system_error + }; + + dictionary SendInfo { + // The number of bytes sent. + long bytesSent; + + // An error code if an error occurred. + SendError? error; + }; + + callback SendCallback = void (SendInfo sendInfo); + + callback FlushCallback = void (boolean result); + + callback SetBreakCallback = void (boolean result); + + callback ClearBreakCallback = void (boolean result); + + // The set of control signals which may be sent to a connected serial device + // using setControlSignals. Note that support for these signals + // is device-dependent. + dictionary HostControlSignals { + // DTR (Data Terminal Ready). + boolean? dtr; + + // RTS (Request To Send). + boolean? rts; + }; + + // The set of control signals which may be set by a connected serial device. + // These can be queried using getControlSignals. Note that + // support for these signals is device-dependent. + dictionary DeviceControlSignals { + // DCD (Data Carrier Detect) or RLSD (Receive Line Signal/ Detect). + boolean dcd; + + // CTS (Clear To Send). + boolean cts; + + // RI (Ring Indicator). + boolean ri; + + // DSR (Data Set Ready). + boolean dsr; + }; + + // Returns a snapshot of current control signals. + callback GetControlSignalsCallback = void (DeviceControlSignals signals); + + // Returns true if operation was successful. + callback SetControlSignalsCallback = void (boolean result); + + // Data from an onReceive event. + dictionary ReceiveInfo { + // The connection identifier. + long connectionId; + + // The data received. + ArrayBuffer data; + }; + + enum ReceiveError { + // The connection was disconnected. + disconnected, + + // No data has been received for receiveTimeout milliseconds. + timeout, + + // The device was most likely disconnected from the host. + device_lost, + + // The device detected a break condition. + break, + + // The device detected a framing error. + frame_error, + + // A character-buffer overrun has occurred. The next character is lost. + overrun, + + // An input buffer overflow has occurred. There is either no room in the + // input buffer, or a character was received after the end-of-file (EOF) + // character. + buffer_overflow, + + // The device detected a parity error. + parity_error, + + // A system error occurred and the connection may be unrecoverable. + system_error + }; + + // Data from an onReceiveError event. + dictionary ReceiveErrorInfo { + // The connection identifier. + long connectionId; + + // An error code indicating what went wrong. + ReceiveError error; + }; + + interface Functions { + // Returns information about available serial devices on the system. + // The list is regenerated each time this method is called. + // |callback| : Called with the list of DeviceInfo objects. + static void getDevices(GetDevicesCallback callback); + + // Connects to a given serial port. + // |path| : The system path of the serial port to open. + // |options| : Port configuration options. + // |callback| : Called when the connection has been opened. + static void connect( + DOMString path, + optional ConnectionOptions options, + ConnectCallback callback); + + // Update the option settings on an open serial port connection. + // |connectionId| : The id of the opened connection. + // |options| : Port configuration options. + // |callback| : Called when the configuation has completed. + static void update( + long connectionId, + ConnectionOptions options, + UpdateCallback callback); + + // Disconnects from a serial port. + // |connectionId| : The id of the opened connection. + // |callback| : Called when the connection has been closed. + static void disconnect( + long connectionId, + DisconnectCallback callback); + + // Pauses or unpauses an open connection. + // |connectionId| : The id of the opened connection. + // |paused| : Flag to indicate whether to pause or unpause. + // |callback| : Called when the connection has been successfully paused or + // unpaused. + static void setPaused( + long connectionId, + boolean paused, + SetPausedCallback callback); + + // Retrieves the state of a given connection. + // |connectionId| : The id of the opened connection. + // |callback| : Called with connection state information when available. + static void getInfo( + long connectionId, + GetInfoCallback callback); + + // Retrieves the list of currently opened serial port connections owned by + // the application. + // |callback| : Called with the list of connections when available. + static void getConnections( + GetConnectionsCallback callback); + + // Writes data to the given connection. + // |connectionId| : The id of the connection. + // |data| : The data to send. + // |callback| : Called when the operation has completed. + static void send( + long connectionId, + ArrayBuffer data, + SendCallback callback); + + // Flushes all bytes in the given connection's input and output buffers. + static void flush( + long connectionId, + FlushCallback callback); + + // Retrieves the state of control signals on a given connection. + // |connectionId| : The id of the connection. + // |callback| : Called when the control signals are available. + static void getControlSignals( + long connectionId, + GetControlSignalsCallback callback); + + // Sets the state of control signals on a given connection. + // |connectionId| : The id of the connection. + // |signals| : The set of signal changes to send to the device. + // |callback| : Called once the control signals have been set. + static void setControlSignals( + long connectionId, + HostControlSignals signals, + SetControlSignalsCallback callback); + + // Suspends character transmission on a given connection and places the + // transmission line in a break state until the clearBreak is called. + // |connectionId| : The id of the connection. + static void setBreak( + long connectionId, + SetBreakCallback callback); + + // Restore character transmission on a given connection and place the + // transmission line in a nonbreak state. + // |connectionId| : The id of the connection. + static void clearBreak( + long connectionId, + ClearBreakCallback callback); + }; + + interface Events { + // Event raised when data has been read from the connection. + // |info| : Event data. + static void onReceive(ReceiveInfo info); + + // Event raised when an error occurred while the runtime was waiting for + // data on the serial port. Once this event is raised, the connection may be + // set to paused. A "timeout" error does not pause + // the connection. + static void onReceiveError(ReceiveErrorInfo info); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/shared_module.idl b/tools/under-control/src/extensions/common/api/shared_module.idl new file mode 100755 index 000000000..4125f8da1 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/shared_module.idl @@ -0,0 +1,32 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Stub namespace for the "import" and "export" manifest keys. +[generate_error_messages] +namespace sharedModule { + dictionary Import { + // Extension ID of the shared module this extension or app depends on. + DOMString id; + + // Minimum supported version of the shared module. + DOMString? minimum_version; + }; + + dictionary Export { + // Optional list of extension IDs explicitly allowed to import this Shared + // Module's resources. If no allowlist is given, all extensions are allowed + // to import it. + DOMString[]? allowlist; + }; + + dictionary ManifestKeys { + // The import field is used by extensions and apps to declare that they + // depend on the resources from particular Shared Modules. + Import[]? import; + + // The export field indicates an extension is a Shared Module that exports + // its resources. + Export? export; + }; +}; diff --git a/tools/under-control/src/extensions/common/api/socket.idl b/tools/under-control/src/extensions/common/api/socket.idl new file mode 100755 index 000000000..0d42717d1 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/socket.idl @@ -0,0 +1,397 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.socket API to send and receive data over the +// network using TCP and UDP connections. Note: Starting with Chrome 33, +// this API is deprecated in favor of the $(ref:sockets.udp), $(ref:sockets.tcp) and +// $(ref:sockets.tcpServer) APIs. +namespace socket { + enum SocketType { + tcp, + udp + }; + + // The socket options. + dictionary CreateOptions { + }; + + dictionary CreateInfo { + // The id of the newly created socket. + long socketId; + }; + + callback CreateCallback = void (CreateInfo createInfo); + + callback ConnectCallback = void (long result); + + callback BindCallback = void (long result); + + callback ListenCallback = void (long result); + + callback SecureCallback = void (long result); + + dictionary AcceptInfo { + long resultCode; + // The id of the accepted socket. + long? socketId; + }; + + callback AcceptCallback = void (AcceptInfo acceptInfo); + + dictionary ReadInfo { + // The resultCode returned from the underlying read() call. + long resultCode; + + ArrayBuffer data; + }; + + callback ReadCallback = void (ReadInfo readInfo); + + dictionary WriteInfo { + // The number of bytes sent, or a negative error code. + long bytesWritten; + }; + + callback WriteCallback = void (WriteInfo writeInfo); + + dictionary RecvFromInfo { + // The resultCode returned from the underlying recvfrom() call. + long resultCode; + + ArrayBuffer data; + + // The address of the remote machine. + DOMString address; + + long port; + }; + + dictionary SocketInfo { + // The type of the passed socket. This will be tcp or + // udp. + SocketType socketType; + + // Whether or not the underlying socket is connected. + // + // For tcp sockets, this will remain true even if the remote + // peer has disconnected. Reading or writing to the socket may then result + // in an error, hinting that this socket should be disconnected via + // disconnect(). + // + // For udp sockets, this just represents whether a default + // remote address has been specified for reading and writing packets. + boolean connected; + + // If the underlying socket is connected, contains the IPv4/6 address of + // the peer. + DOMString? peerAddress; + + // If the underlying socket is connected, contains the port of the + // connected peer. + long? peerPort; + + // If the underlying socket is bound or connected, contains its local + // IPv4/6 address. + DOMString? localAddress; + + // If the underlying socket is bound or connected, contains its local port. + long? localPort; + }; + + dictionary NetworkInterface { + // The underlying name of the adapter. On *nix, this will typically be + // "eth0", "lo", etc. + DOMString name; + + // The available IPv4/6 address. + DOMString address; + + // The prefix length + long prefixLength; + }; + + dictionary TLSVersionConstraints { + // The minimum and maximum acceptable versions of TLS. Supported values are + // tls1.2 or tls1.3. + // + // The values tls1 and tls1.1 are no longer + // supported. If |min| is set to one of these values, it will be silently + // clamped to tls1.2. If |max| is set to one of those values, + // or any other unrecognized value, it will be silently ignored. + DOMString? min; + DOMString? max; + }; + + dictionary SecureOptions { + TLSVersionConstraints? tlsVersion; + }; + + callback RecvFromCallback = void (RecvFromInfo recvFromInfo); + + callback SendToCallback = void (WriteInfo writeInfo); + + callback SetKeepAliveCallback = void (boolean result); + + callback SetNoDelayCallback = void (boolean result); + + callback GetInfoCallback = void (SocketInfo result); + + callback GetNetworkCallback = void (NetworkInterface[] result); + + callback JoinGroupCallback = void (long result); + + callback LeaveGroupCallback = void (long result); + + callback SetMulticastTimeToLiveCallback = void (long result); + + callback SetMulticastLoopbackModeCallback = void (long result); + + callback GetJoinedGroupsCallback = void (DOMString[] groups); + + interface Functions { + // Creates a socket of the specified type that will connect to the specified + // remote machine. + // |type| : The type of socket to create. Must be tcp or + // udp. + // |options| : The socket options. + // |callback| : Called when the socket has been created. + static void create(SocketType type, + optional CreateOptions options, + CreateCallback callback); + + // Destroys the socket. Each socket created should be destroyed after use. + // |socketId| : The socketId. + static void destroy(long socketId); + + // Connects the socket to the remote machine (for a tcp + // socket). For a udp socket, this sets the default address + // which packets are sent to and read from for read() + // and write() calls. + // |socketId| : The socketId. + // |hostname| : The hostname or IP address of the remote machine. + // |port| : The port of the remote machine. + // |callback| : Called when the connection attempt is complete. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void connect(long socketId, + DOMString hostname, + long port, + ConnectCallback callback); + + // Binds the local address for socket. Currently, it does not support + // TCP socket. + // |socketId| : The socketId. + // |address| : The address of the local machine. + // |port| : The port of the local machine. + // |callback| : Called when the bind attempt is complete. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void bind(long socketId, + DOMString address, + long port, + BindCallback callback); + + // Disconnects the socket. For UDP sockets, disconnect is a + // non-operation but is safe to call. + // |socketId| : The socketId. + static void disconnect(long socketId); + + // Reads data from the given connected socket. + // |socketId| : The socketId. + // |bufferSize| : The read buffer size. + // |callback| : Delivers data that was available to be read without + // blocking. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void read(long socketId, + optional long bufferSize, + ReadCallback callback); + + // Writes data on the given connected socket. + // |socketId| : The socketId. + // |data| : The data to write. + // |callback| : Called when the write operation completes without blocking + // or an error occurs. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void write(long socketId, + ArrayBuffer data, + WriteCallback callback); + + // Receives data from the given UDP socket. + // |socketId| : The socketId. + // |bufferSize| : The receive buffer size. + // |callback| : Returns result of the recvFrom operation. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void recvFrom(long socketId, + optional long bufferSize, + RecvFromCallback callback); + + // Sends data on the given UDP socket to the given address and port. + // |socketId| : The socketId. + // |data| : The data to write. + // |address| : The address of the remote machine. + // |port| : The port of the remote machine. + // |callback| : Called when the send operation completes without blocking + // or an error occurs. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void sendTo(long socketId, + ArrayBuffer data, + DOMString address, + long port, + SendToCallback callback); + + // This method applies to TCP sockets only. + // Listens for connections on the specified port and address. This + // effectively makes this a server socket, and client socket + // functions (connect, read, write) can no longer be used on this socket. + // |socketId| : The socketId. + // |address| : The address of the local machine. + // |port| : The port of the local machine. + // |backlog| : Length of the socket's listen queue. + // |callback| : Called when listen operation completes. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void listen(long socketId, + DOMString address, + long port, + optional long backlog, + ListenCallback callback); + + // This method applies to TCP sockets only. + // Registers a callback function to be called when a connection is + // accepted on this listening server socket. Listen must be called first. + // If there is already an active accept callback, this callback will be + // invoked immediately with an error as the resultCode. + // |socketId| : The socketId. + // |callback| : The callback is invoked when a new socket is accepted. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void accept(long socketId, + AcceptCallback callback); + + // Enables or disables the keep-alive functionality for a TCP connection. + // |socketId| : The socketId. + // |enable| : If true, enable keep-alive functionality. + // |delay| : Set the delay seconds between the last data packet received + // and the first keepalive probe. Default is 0. + // |callback| : Called when the setKeepAlive attempt is complete. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void setKeepAlive(long socketId, + boolean enable, + optional long delay, + SetKeepAliveCallback callback); + + // Sets or clears TCP_NODELAY for a TCP connection. Nagle's + // algorithm will be disabled when TCP_NODELAY is set. + // |socketId| : The socketId. + // |noDelay| : If true, disables Nagle's algorithm. + // |callback| : Called when the setNoDelay attempt is complete. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void setNoDelay(long socketId, + boolean noDelay, + SetNoDelayCallback callback); + + // Retrieves the state of the given socket. + // |socketId| : The socketId. + // |callback| : Called when the state is available. + static void getInfo(long socketId, + GetInfoCallback callback); + + // Retrieves information about local adapters on this system. + // |callback| : Called when local adapter information is available. + static void getNetworkList(GetNetworkCallback callback); + + // Join the multicast group and start to receive packets from that group. + // The socket must be of UDP type and must be bound to a local port + // before calling this method. + // |socketId| : The socketId. + // |address| : The group address to join. Domain names are not supported. + // |callback| : Called when the join group operation is done with an + // integer parameter indicating the platform-independent error code. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void joinGroup(long socketId, + DOMString address, + JoinGroupCallback callback); + + // Leave the multicast group previously joined using joinGroup. + // It's not necessary to leave the multicast group before destroying the + // socket or exiting. This is automatically called by the OS. + // + // Leaving the group will prevent the router from sending multicast + // datagrams to the local host, presuming no other process on the host is + // still joined to the group. + // + // |socketId| : The socketId. + // |address| : The group address to leave. Domain names are not supported. + // |callback| : Called when the leave group operation is done with an + // integer parameter indicating the platform-independent error code. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void leaveGroup(long socketId, DOMString address, + LeaveGroupCallback callback); + + // Set the time-to-live of multicast packets sent to the multicast group. + // + // Calling this method does not require multicast permissions. + // + // |socketId| : The socketId. + // |ttl| : The time-to-live value. + // |callback| : Called when the configuration operation is done. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void setMulticastTimeToLive( + long socketId, + long ttl, + SetMulticastTimeToLiveCallback callback); + + // Set whether multicast packets sent from the host to the multicast + // group will be looped back to the host. + // + // Note: the behavior of setMulticastLoopbackMode is slightly + // different between Windows and Unix-like systems. The inconsistency + // happens only when there is more than one application on the same host + // joined to the same multicast group while having different settings on + // multicast loopback mode. On Windows, the applications with loopback off + // will not RECEIVE the loopback packets; while on Unix-like systems, the + // applications with loopback off will not SEND the loopback packets to + // other applications on the same host. See MSDN: http://goo.gl/6vqbj + // + // Calling this method does not require multicast permissions. + // + // |socketId| : The socketId. + // |enabled| : Indicate whether to enable loopback mode. + // |callback| : Called when the configuration operation is done. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void setMulticastLoopbackMode( + long socketId, + boolean enabled, + SetMulticastLoopbackModeCallback callback); + + // Get the multicast group addresses the socket is currently joined to. + // |socketId| : The socketId. + // |callback| : Called with an array of strings of the result. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void getJoinedGroups(long socketId, + GetJoinedGroupsCallback callback); + + // Start a TLS client connection over a connected TCP client socket. + // |socketId| : The connected socket to use. + // |options| : Constraints and parameters for the TLS connection. + // |callback| : Called when the TLS connection attempt is complete. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void secure(long socketId, + optional SecureOptions options, + SecureCallback callback); + }; + +}; diff --git a/tools/under-control/src/extensions/common/api/sockets_tcp.idl b/tools/under-control/src/extensions/common/api/sockets_tcp.idl new file mode 100755 index 000000000..964794d79 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/sockets_tcp.idl @@ -0,0 +1,295 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.sockets.tcp API to send and receive data over the +// network using TCP connections. This API supersedes the TCP functionality +// previously found in the chrome.socket API. +namespace sockets.tcp { + // The socket properties specified in the create or + // update function. Each property is optional. If a property + // value is not specified, a default value is used when calling + // create, or the existing value if preserved when calling + // update. + dictionary SocketProperties { + // Flag indicating if the socket is left open when the event page of + // the application is unloaded (see + // Manage App + // Lifecycle). The default value is "false." When the application is + // loaded, any sockets previously opened with persistent=true can be fetched + // with getSockets. + boolean? persistent; + + // An application-defined string associated with the socket. + DOMString? name; + + // The size of the buffer used to receive data. The default value is 4096. + long? bufferSize; + }; + + // Result of create call. + dictionary CreateInfo { + // The ID of the newly created socket. Note that socket IDs created from + // this API are not compatible with socket IDs created from other APIs, such + // as the deprecated $(ref:socket) API. + long socketId; + }; + + // Callback from the create method. + // |createInfo| : The result of the socket creation. + callback CreateCallback = void (CreateInfo createInfo); + + // DNS resolution preferences. The default is any and uses the + // current OS config which may return IPv4 or IPv6. ipv4 forces + // IPv4, and ipv6 forces IPv6. + enum DnsQueryType { any, ipv4, ipv6 }; + + // Callback from the connect method. + // |result| : The result code returned from the underlying network call. + // A negative value indicates an error. + callback ConnectCallback = void (long result); + + // Callback from the disconnect method. + callback DisconnectCallback = void (); + + // Result of the send method. + dictionary SendInfo { + // The result code returned from the underlying network call. + // A negative value indicates an error. + long resultCode; + + // The number of bytes sent (if result == 0) + long? bytesSent; + }; + + // Callback from the send method. + // |sendInfo| : Result of the send method. + callback SendCallback = void (SendInfo sendInfo); + + // Callback from the close method. + callback CloseCallback = void (); + + // Callback from the update method. + callback UpdateCallback = void (); + + // Callback from the setPaused method. + callback SetPausedCallback = void (); + + // Callback from the setKeepAliveCallback method. + // |result| : The result code returned from the underlying network call. + // A negative value indicates an error. + callback SetKeepAliveCallback = void (long result); + + // Callback from the setNodeDelay method. + // |result| : The result code returned from the underlying network call. + // A negative value indicates an error. + callback SetNoDelayCallback = void (long result); + + dictionary TLSVersionConstraints { + // The minimum and maximum acceptable versions of TLS. Supported values are + // tls1.2 or tls1.3. + // + // The values tls1 and tls1.1 are no longer + // supported. If |min| is set to one of these values, it will be silently + // clamped to tls1.2. If |max| is set to one of those values, + // or any other unrecognized value, it will be silently ignored. + DOMString? min; + DOMString? max; + }; + + dictionary SecureOptions { + TLSVersionConstraints? tlsVersion; + }; + + callback SecureCallback = void (long result); + + // Result of the getInfo method. + dictionary SocketInfo { + // The socket identifier. + long socketId; + + // Flag indicating whether the socket is left open when the application is + // suspended (see SocketProperties.persistent). + boolean persistent; + + // Application-defined string associated with the socket. + DOMString? name; + + // The size of the buffer used to receive data. If no buffer size has been + // specified explictly, the value is not provided. + long? bufferSize; + + // Flag indicating whether a connected socket blocks its peer from sending + // more data (see setPaused). + boolean paused; + + // Flag indicating whether the socket is connected to a remote peer. + boolean connected; + + // If the underlying socket is connected, contains its local IPv4/6 address. + DOMString? localAddress; + + // If the underlying socket is connected, contains its local port. + long? localPort; + + // If the underlying socket is connected, contains the peer/ IPv4/6 address. + DOMString? peerAddress; + + // If the underlying socket is connected, contains the peer port. + long? peerPort; + }; + + // Callback from the getInfo method. + // |socketInfo| : Object containing the socket information. + callback GetInfoCallback = void (SocketInfo socketInfo); + + // Callback from the getSockets method. + // |socketInfos| : Array of object containing socket information. + callback GetSocketsCallback = void (SocketInfo[] socketInfos); + + // Data from an onReceive event. + dictionary ReceiveInfo { + // The socket identifier. + long socketId; + + // The data received, with a maxium size of bufferSize. + ArrayBuffer data; + }; + + // Data from an onReceiveError event. + dictionary ReceiveErrorInfo { + // The socket identifier. + long socketId; + + // The result code returned from the underlying network call. + long resultCode; + }; + + interface Functions { + // Creates a TCP socket. + // |properties| : The socket properties (optional). + // |callback| : Called when the socket has been created. + static void create(optional SocketProperties properties, + CreateCallback callback); + + // Updates the socket properties. + // |socketId| : The socket identifier. + // |properties| : The properties to update. + // |callback| : Called when the properties are updated. + static void update(long socketId, + SocketProperties properties, + optional UpdateCallback callback); + + // Enables or disables the application from receiving messages from its + // peer. The default value is "false". Pausing a socket is typically used + // by an application to throttle data sent by its peer. When a socket is + // paused, no onReceive event is raised. When a socket is + // connected and un-paused, onReceive events are raised again + // when messages are received. + static void setPaused(long socketId, + boolean paused, + optional SetPausedCallback callback); + + // Enables or disables the keep-alive functionality for a TCP connection. + // |socketId| : The socket identifier. + // |enable| : If true, enable keep-alive functionality. + // |delay| : Set the delay seconds between the last data packet received + // and the first keepalive probe. Default is 0. + // |callback| : Called when the setKeepAlive attempt is complete. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void setKeepAlive(long socketId, + boolean enable, + optional long delay, + SetKeepAliveCallback callback); + + // Sets or clears TCP_NODELAY for a TCP connection. Nagle's + // algorithm will be disabled when TCP_NODELAY is set. + // |socketId| : The socket identifier. + // |noDelay| : If true, disables Nagle's algorithm. + // |callback| : Called when the setNoDelay attempt is complete. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void setNoDelay(long socketId, + boolean noDelay, + SetNoDelayCallback callback); + + // Connects the socket to a remote machine. When the connect + // operation completes successfully, onReceive events are + // raised when data is received from the peer. If a network error occurs + // while the runtime is receiving packets, a onReceiveError + // event is raised, at which point no more onReceive event will + // be raised for this socket until the resume method is called. + // |socketId| : The socket identifier. + // |peerAddress| : The address of the remote machine. DNS name, IPv4 and + // IPv6 formats are supported. + // |peerPort| : The port of the remote machine. + // |dnsQueryType| : The address resolution preference. + // |callback| : Called when the connect attempt is complete. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void connect(long socketId, + DOMString peerAddress, + long peerPort, + optional DnsQueryType dnsQueryType, + ConnectCallback callback); + + // Disconnects the socket. + // |socketId| : The socket identifier. + // |callback| : Called when the disconnect attempt is complete. + static void disconnect(long socketId, + optional DisconnectCallback callback); + + // Start a TLS client connection over the connected TCP client socket. + // |socketId| : The existing, connected socket to use. + // |options| : Constraints and parameters for the TLS connection. + // |callback| : Called when the connection attempt is complete. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void secure(long socketId, + optional SecureOptions options, + SecureCallback callback); + + // Sends data on the given TCP socket. + // |socketId| : The socket identifier. + // |data| : The data to send. + // |callback| : Called when the send operation completes. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void send(long socketId, + ArrayBuffer data, + SendCallback callback); + + // Closes the socket and releases the address/port the socket is bound to. + // Each socket created should be closed after use. The socket id is no + // no longer valid as soon at the function is called. However, the socket is + // guaranteed to be closed only when the callback is invoked. + // |socketId| : The socket identifier. + // |callback| : Called when the close operation completes. + static void close(long socketId, + optional CloseCallback callback); + + // Retrieves the state of the given socket. + // |socketId| : The socket identifier. + // |callback| : Called when the socket state is available. + static void getInfo(long socketId, + GetInfoCallback callback); + + // Retrieves the list of currently opened sockets owned by the application. + // |callback| : Called when the list of sockets is available. + static void getSockets(GetSocketsCallback callback); + }; + + interface Events { + // Event raised when data has been received for a given socket. + // |info| : The event data. + static void onReceive(ReceiveInfo info); + + // Event raised when a network error occured while the runtime was waiting + // for data on the socket address and port. Once this event is raised, the + // socket is set to paused and no more onReceive + // events are raised for this socket. + // |info| : The event data. + static void onReceiveError(ReceiveErrorInfo info); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/sockets_tcp_server.idl b/tools/under-control/src/extensions/common/api/sockets_tcp_server.idl new file mode 100755 index 000000000..063521649 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/sockets_tcp_server.idl @@ -0,0 +1,197 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.sockets.tcpServer API to create server +// applications using TCP connections. This API supersedes the TCP functionality +// previously found in the chrome.socket API. +namespace sockets.tcpServer { + // The socket properties specified in the create or + // update function. Each property is optional. If a property + // value is not specified, a default value is used when calling + // create, or the existing value if preserved when calling + // update. + dictionary SocketProperties { + // Flag indicating if the socket remains open when the event page of the + // application is unloaded (see + // Manage App + // Lifecycle). The default value is "false." When the application is + // loaded, any sockets previously opened with persistent=true can be fetched + // with getSockets. + boolean? persistent; + + // An application-defined string associated with the socket. + DOMString? name; + }; + + // Result of create call. + dictionary CreateInfo { + // The ID of the newly created server socket. Note that socket IDs created + // from this API are not compatible with socket IDs created from other APIs, + // such as the deprecated $(ref:socket) API. + long socketId; + }; + + // Callback from the create method. + // |createInfo| : The result of the socket creation. + callback CreateCallback = void (CreateInfo createInfo); + + // Callback from the listen method. + // |result| : The result code returned from the underlying network call. + // A negative value indicates an error. + callback ListenCallback = void (long result); + + // Callback from the disconnect method. + callback DisconnectCallback = void (); + + // Callback from the close method. + callback CloseCallback = void (); + + // Callback from the update method. + callback UpdateCallback = void (); + + // Callback from the setPaused method. + callback SetPausedCallback = void (); + + // Result of the getInfo method. + dictionary SocketInfo { + // The socket identifier. + long socketId; + + // Flag indicating if the socket remains open when the event page of the + // application is unloaded (see SocketProperties.persistent). + // The default value is "false". + boolean persistent; + + // Application-defined string associated with the socket. + DOMString? name; + + // Flag indicating whether connection requests on a listening socket are + // dispatched through the onAccept event or queued up in the + // listen queue backlog. + // See setPaused. The default value is "false". + boolean paused; + + // If the socket is listening, contains its local IPv4/6 address. + DOMString? localAddress; + + // If the socket is listening, contains its local port. + long? localPort; + }; + + // Callback from the getInfo method. + // |socketInfo| : Object containing the socket information. + callback GetInfoCallback = void (SocketInfo socketInfo); + + // Callback from the getSockets method. + // |socketInfos| : Array of object containing socket information. + callback GetSocketsCallback = void (SocketInfo[] socketInfos); + + // Data from an onAccept event. + dictionary AcceptInfo { + // The server socket identifier. + long socketId; + + // The client socket identifier, i.e. the socket identifier of the newly + // established connection. This socket identifier should be used only with + // functions from the chrome.sockets.tcp namespace. Note the + // client socket is initially paused and must be explictly un-paused by the + // application to start receiving data. + long clientSocketId; + }; + + // Data from an onAcceptError event. + dictionary AcceptErrorInfo { + // The server socket identifier. + long socketId; + + // The result code returned from the underlying network call. + long resultCode; + }; + + interface Functions { + // Creates a TCP server socket. + // |properties| : The socket properties (optional). + // |callback| : Called when the socket has been created. + static void create(optional SocketProperties properties, + CreateCallback callback); + + // Updates the socket properties. + // |socketId| : The socket identifier. + // |properties| : The properties to update. + // |callback| : Called when the properties are updated. + static void update(long socketId, + SocketProperties properties, + optional UpdateCallback callback); + + // Enables or disables a listening socket from accepting new connections. + // When paused, a listening socket accepts new connections until its backlog + // (see listen function) is full then refuses additional + // connection requests. onAccept events are raised only when + // the socket is un-paused. + static void setPaused(long socketId, + boolean paused, + optional SetPausedCallback callback); + + // Listens for connections on the specified port and address. + // If the port/address is in use, the callback indicates a failure. + // |socketId| : The socket identifier. + // |address| : The address of the local machine. + // |port| : The port of the local machine. When set to 0, a + // free port is chosen dynamically. The dynamically allocated port can be + // found by calling getInfo. + // |backlog| : Length of the socket's listen queue. The default value + // depends on the Operating System (SOMAXCONN), which ensures a reasonable + // queue length for most applications. + // |callback| : Called when listen operation completes. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void listen(long socketId, + DOMString address, + long port, + optional long backlog, + ListenCallback callback); + + // Disconnects the listening socket, i.e. stops accepting new connections + // and releases the address/port the socket is bound to. The socket + // identifier remains valid, e.g. it can be used with listen to + // accept connections on a new port and address. + // |socketId| : The socket identifier. + // |callback| : Called when the disconnect attempt is complete. + static void disconnect(long socketId, + optional DisconnectCallback callback); + + // Disconnects and destroys the socket. Each socket created should be + // closed after use. The socket id is no longer valid as soon at the + // function is called. However, the socket is guaranteed to be closed only + // when the callback is invoked. + // |socketId| : The socket identifier. + // |callback| : Called when the close operation completes. + static void close(long socketId, + optional CloseCallback callback); + + // Retrieves the state of the given socket. + // |socketId| : The socket identifier. + // |callback| : Called when the socket state is available. + static void getInfo(long socketId, + GetInfoCallback callback); + + // Retrieves the list of currently opened sockets owned by the application. + // |callback| : Called when the list of sockets is available. + static void getSockets(GetSocketsCallback callback); + }; + + interface Events { + // Event raised when a connection has been made to the server socket. + // |info| : The event data. + static void onAccept(AcceptInfo info); + + // Event raised when a network error occured while the runtime was waiting + // for new connections on the socket address and port. Once this event is + // raised, the socket is set to paused and no more + // onAccept events are raised for this socket until the socket + // is resumed. + // |info| : The event data. + static void onAcceptError(AcceptErrorInfo info); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/sockets_udp.idl b/tools/under-control/src/extensions/common/api/sockets_udp.idl new file mode 100755 index 000000000..5dbcb6012 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/sockets_udp.idl @@ -0,0 +1,342 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.sockets.udp API to send and receive data over the +// network using UDP connections. This API supersedes the UDP functionality +// previously found in the "socket" API. +namespace sockets.udp { + // The socket properties specified in the create or + // update function. Each property is optional. If a property + // value is not specified, a default value is used when calling + // create, or the existing value if preserved when calling + // update. + dictionary SocketProperties { + // Flag indicating if the socket is left open when the event page of the + // application is unloaded (see + // Manage App + // Lifecycle). The default value is "false." When the application is + // loaded, any sockets previously opened with persistent=true can be fetched + // with getSockets. + boolean? persistent; + + // An application-defined string associated with the socket. + DOMString? name; + + // The size of the buffer used to receive data. If the buffer is too small + // to receive the UDP packet, data is lost. The default value is 4096. + long? bufferSize; + }; + + // Result of create call. + dictionary CreateInfo { + // The ID of the newly created socket. Note that socket IDs created from + // this API are not compatible with socket IDs created from other APIs, such + // as the deprecated $(ref:socket) API. + long socketId; + }; + + // Callback from the create method. + // |createInfo| : The result of the socket creation. + callback CreateCallback = void (CreateInfo createInfo); + + // Callback from the bind method. + // |result| : The result code returned from the underlying network call. + // A negative value indicates an error. + callback BindCallback = void (long result); + + // DNS resolution preferences. The default is any and uses the + // current OS config which may return IPv4 or IPv6. ipv4 forces + // IPv4, and ipv6 forces IPv6. + enum DnsQueryType { any, ipv4, ipv6 }; + + // Result of the send method. + dictionary SendInfo { + // The result code returned from the underlying network call. + // A negative value indicates an error. + long resultCode; + + // The number of bytes sent (if result == 0) + long? bytesSent; + }; + + // Callback from the send method. + // |sendInfo| : Result of the send method. + callback SendCallback = void (SendInfo sendInfo); + + // Callback from the close method. + callback CloseCallback = void (); + + // Callback from the update method. + callback UpdateCallback = void (); + + // Callback from the setPaused method. + callback SetPausedCallback = void (); + + // Result of the getInfo method. + dictionary SocketInfo { + // The socket identifier. + long socketId; + + // Flag indicating whether the socket is left open when the application is + // suspended (see SocketProperties.persistent). + boolean persistent; + + // Application-defined string associated with the socket. + DOMString? name; + + // The size of the buffer used to receive data. If no buffer size has been + // specified explictly, the value is not provided. + long? bufferSize; + + // Flag indicating whether the socket is blocked from firing onReceive + // events. + boolean paused; + + // If the underlying socket is bound, contains its local + // IPv4/6 address. + DOMString? localAddress; + + // If the underlying socket is bound, contains its local port. + long? localPort; + }; + + // Callback from the getInfo method. + // |socketInfo| : Object containing the socket information. + callback GetInfoCallback = void (SocketInfo socketInfo); + + // Callback from the getSockets method. + // |socketInfos| : Array of object containing socket information. + callback GetSocketsCallback = void (SocketInfo[] socketInfos); + + // Callback from the joinGroup method. + // |result| : The result code returned from the underlying network call. + // A negative value indicates an error. + callback JoinGroupCallback = void (long result); + + // Callback from the leaveGroup method. + // |result| : The result code returned from the underlying network call. + // A negative value indicates an error. + callback LeaveGroupCallback = void (long result); + + // Callback from the setMulticastTimeToLive method. + // |result| : The result code returned from the underlying network call. + // A negative value indicates an error. + callback SetMulticastTimeToLiveCallback = void (long result); + + // Callback from the setMulticastLoopbackMode method. + // |result| : The result code returned from the underlying network call. + // A negative value indicates an error. + callback SetMulticastLoopbackModeCallback = void (long result); + + // Callback from the getJoinedGroupsCallback method. + // |groups| : Array of groups the socket joined. + callback GetJoinedGroupsCallback = void (DOMString[] groups); + + // Callback from the setBroadcast method. + // |result| : The result code returned from the underlying network call. + callback SetBroadcastCallback = void (long result); + + // Data from an onReceive event. + dictionary ReceiveInfo { + // The socket ID. + long socketId; + + // The UDP packet content (truncated to the current buffer size). + ArrayBuffer data; + + // The address of the host the packet comes from. + DOMString remoteAddress; + + // The port of the host the packet comes from. + long remotePort; + }; + + // Data from an onReceiveError event. + dictionary ReceiveErrorInfo { + // The socket ID. + long socketId; + + // The result code returned from the underlying recvfrom() call. + long resultCode; + }; + + interface Functions { + // Creates a UDP socket with the given properties. + // |properties| : The socket properties (optional). + // |callback| : Called when the socket has been created. + static void create(optional SocketProperties properties, + CreateCallback callback); + + // Updates the socket properties. + // |socketId| : The socket ID. + // |properties| : The properties to update. + // |callback| : Called when the properties are updated. + static void update(long socketId, + SocketProperties properties, + optional UpdateCallback callback); + + // Pauses or unpauses a socket. A paused socket is blocked from firing + // onReceive events. + // |connectionId| : The socket ID. + // |paused| : Flag to indicate whether to pause or unpause. + // |callback| : Called when the socket has been successfully paused or + // unpaused. + static void setPaused(long socketId, + boolean paused, + optional SetPausedCallback callback); + + // Binds the local address and port for the socket. For a client socket, it + // is recommended to use port 0 to let the platform pick a free port. + // + // Once the bind operation completes successfully, + // onReceive events are raised when UDP packets arrive on the + // address/port specified -- unless the socket is paused. + // + // |socketId| : The socket ID. + // |address| : The address of the local machine. DNS name, IPv4 and IPv6 + // formats are supported. Use "0.0.0.0" to accept packets from all local + // available network interfaces. + // |port| : The port of the local machine. Use "0" to bind to a free port. + // |callback| : Called when the bind operation completes. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void bind(long socketId, + DOMString address, + long port, + BindCallback callback); + + // Sends data on the given socket to the given address and port. The socket + // must be bound to a local port before calling this method. + // |socketId| : The socket ID. + // |data| : The data to send. + // |address| : The address of the remote machine. + // |port| : The port of the remote machine. + // |dnsQueryType| : The address resolution preference. + // |callback| : Called when the send operation completes. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void send(long socketId, + ArrayBuffer data, + DOMString address, + long port, + optional DnsQueryType dnsQueryType, + SendCallback callback); + + // Closes the socket and releases the address/port the socket is bound to. + // Each socket created should be closed after use. The socket id is no + // longer valid as soon at the function is called. However, the socket is + // guaranteed to be closed only when the callback is invoked. + // |socketId| : The socket ID. + // |callback| : Called when the close operation completes. + static void close(long socketId, + optional CloseCallback callback); + + // Retrieves the state of the given socket. + // |socketId| : The socket ID. + // |callback| : Called when the socket state is available. + static void getInfo(long socketId, + GetInfoCallback callback); + + // Retrieves the list of currently opened sockets owned by the application. + // |callback| : Called when the list of sockets is available. + static void getSockets(GetSocketsCallback callback); + + // Joins the multicast group and starts to receive packets from that group. + // The socket must be bound to a local port before calling this method. + // |socketId| : The socket ID. + // |address| : The group address to join. Domain names are not supported. + // |callback| : Called when the joinGroup operation completes. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void joinGroup(long socketId, + DOMString address, + JoinGroupCallback callback); + + // Leaves the multicast group previously joined using + // joinGroup. This is only necessary to call if you plan to + // keep using the socketafterwards, since it will be done automatically by + // the OS when the socket is closed. + // + // Leaving the group will prevent the router from sending multicast + // datagrams to the local host, presuming no other process on the host is + // still joined to the group. + // + // |socketId| : The socket ID. + // |address| : The group address to leave. Domain names are not supported. + // |callback| : Called when the leaveGroup operation completes. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void leaveGroup(long socketId, + DOMString address, + LeaveGroupCallback callback); + + // Sets the time-to-live of multicast packets sent to the multicast group. + // + // Calling this method does not require multicast permissions. + // + // |socketId| : The socket ID. + // |ttl| : The time-to-live value. + // |callback| : Called when the configuration operation completes. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void setMulticastTimeToLive( + long socketId, + long ttl, + SetMulticastTimeToLiveCallback callback); + + // Sets whether multicast packets sent from the host to the multicast group + // will be looped back to the host. + // + // Note: the behavior of setMulticastLoopbackMode is slightly + // different between Windows and Unix-like systems. The inconsistency + // happens only when there is more than one application on the same host + // joined to the same multicast group while having different settings on + // multicast loopback mode. On Windows, the applications with loopback off + // will not RECEIVE the loopback packets; while on Unix-like systems, the + // applications with loopback off will not SEND the loopback packets to + // other applications on the same host. See MSDN: http://goo.gl/6vqbj + // + // Calling this method does not require multicast permissions. + // + // |socketId| : The socket ID. + // |enabled| : Indicate whether to enable loopback mode. + // |callback| : Called when the configuration operation completes. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void setMulticastLoopbackMode( + long socketId, + boolean enabled, + SetMulticastLoopbackModeCallback callback); + + // Gets the multicast group addresses the socket is currently joined to. + // |socketId| : The socket ID. + // |callback| : Called with an array of strings of the result. + static void getJoinedGroups(long socketId, + GetJoinedGroupsCallback callback); + + // Enables or disables broadcast packets on this socket. + // + // |socketId| : The socket ID. + // |enabled| : true to enable broadcast packets, + // false to disable them. + [doesNotSupportPromises= + "Sets error along with callback arguments crbug.com/1504372"] + static void setBroadcast(long socketId, + boolean enabled, + SetBroadcastCallback callback); + }; + + interface Events { + // Event raised when a UDP packet has been received for the given socket. + // |info| : The event data. + static void onReceive(ReceiveInfo info); + + // Event raised when a network error occured while the runtime was waiting + // for data on the socket address and port. Once this event is raised, the + // socket is paused and no more onReceive events will be raised + // for this socket until the socket is resumed. + // |info| : The event data. + static void onReceiveError(ReceiveErrorInfo info); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/system_cpu.idl b/tools/under-control/src/extensions/common/api/system_cpu.idl new file mode 100755 index 000000000..875e98e17 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/system_cpu.idl @@ -0,0 +1,61 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the system.cpu API to query CPU metadata. +namespace system.cpu { + + // Counters for assessing CPU utilization. Each field is monotonically + // increasing while the processor is powered on. Values are in milliseconds. + dictionary CpuTime { + // The cumulative time used by userspace programs on this processor. + double user; + + // The cumulative time used by kernel programs on this processor. + double kernel; + + // The cumulative time spent idle by this processor. + double idle; + + // The total cumulative time for this processor. This value is equal to + // user + kernel + idle. + double total; + }; + + dictionary ProcessorInfo { + // Cumulative usage info for this logical processor. + CpuTime usage; + }; + + dictionary CpuInfo { + // The number of logical processors. + long numOfProcessors; + + // The architecture name of the processors. + DOMString archName; + + // The model name of the processors. + DOMString modelName; + + // A set of feature codes indicating some of the processor's capabilities. + // The currently supported codes are "mmx", "sse", "sse2", "sse3", "ssse3", + // "sse4_1", "sse4_2", and "avx". + DOMString[] features; + + // Information about each logical processor. + ProcessorInfo[] processors; + + // List of CPU temperature readings from each thermal zone of the CPU. + // Temperatures are in degrees Celsius. + // + // Currently supported on Chrome OS only. + double[] temperatures; + }; + + callback CpuInfoCallback = void (CpuInfo info); + + interface Functions { + // Queries basic CPU information of the system. + static void getInfo(CpuInfoCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/system_display.idl b/tools/under-control/src/extensions/common/api/system_display.idl new file mode 100755 index 000000000..1d49e1333 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/system_display.idl @@ -0,0 +1,457 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the system.display API to query display metadata. +namespace system.display { + + dictionary Bounds { + // The x-coordinate of the upper-left corner. + long left; + + // The y-coordinate of the upper-left corner. + long top; + + // The width of the display in pixels. + long width; + + // The height of the display in pixels. + long height; + }; + + dictionary Insets { + // The x-axis distance from the left bound. + long left; + + // The y-axis distance from the top bound. + long top; + + // The x-axis distance from the right bound. + long right; + + // The y-axis distance from the bottom bound. + long bottom; + }; + + dictionary Point { + // The x-coordinate of the point. + long x; + + // The y-coordinate of the point. + long y; + }; + + dictionary TouchCalibrationPair { + // The coordinates of the display point. + Point displayPoint; + + // The coordinates of the touch point corresponding to the display point. + Point touchPoint; + }; + + dictionary TouchCalibrationPairQuad { + // First pair of touch and display point required for touch calibration. + TouchCalibrationPair pair1; + + // Second pair of touch and display point required for touch calibration. + TouchCalibrationPair pair2; + + // Third pair of touch and display point required for touch calibration. + TouchCalibrationPair pair3; + + // Fourth pair of touch and display point required for touch calibration. + TouchCalibrationPair pair4; + }; + + dictionary DisplayMode { + // The display mode width in device independent (user visible) pixels. + long width; + + // The display mode height in device independent (user visible) pixels. + long height; + + // The display mode width in native pixels. + long widthInNativePixels; + + // The display mode height in native pixels. + long heightInNativePixels; + + // The display mode UI scale factor. + [deprecated="Use $(ref: displayZoomFactor)"] double? uiScale; + + // The display mode device scale factor. + double deviceScaleFactor; + + // The display mode refresh rate in hertz. + double refreshRate; + + // True if the mode is the display's native mode. + boolean isNative; + + // True if the display mode is currently selected. + boolean isSelected; + + // True if this mode is interlaced, false if not provided. + boolean? isInterlaced; + }; + + // Layout position, i.e. edge of parent that the display is attached to. + enum LayoutPosition { top, right, bottom, left }; + + dictionary DisplayLayout { + // The unique identifier of the display. + DOMString id; + + // The unique identifier of the parent display. Empty if this is the root. + DOMString parentId; + + // The layout position of this display relative to the parent. This will + // be ignored for the root. + LayoutPosition position; + + // The offset of the display along the connected edge. 0 indicates that + // the topmost or leftmost corners are aligned. + long offset; + }; + + // EDID extracted parameters. Field description refers to "VESA ENHANCED + // EXTENDED DISPLAY IDENTIFICATION DATA STANDARD (Defines EDID Structure + // Version 1, Revision 4)" Release A, Revision 2 September 25, 2006. + // https://www.vesa.org/vesa-standards + dictionary Edid { + // 3 character manufacturer code. See Sec. 3.4.1 page 21. Required in v1.4. + DOMString manufacturerId; + + // 2 byte manufacturer-assigned code, Sec. 3.4.2 page 21. Required in v1.4. + DOMString productId; + + // Year of manufacturer, Sec. 3.4.4 page 22. Required in v1.4. + long yearOfManufacture; + }; + + // An enum to tell if the display is detected and used by the + // system. The display is considered 'inactive', if it is not + // detected by the system (maybe disconnected, or considered + // disconnected due to sleep mode, etc). This state is used to keep + // existing display when the all displays are disconnected, for + // example. + enum ActiveState { active, inactive }; + + dictionary DisplayUnitInfo { + // The unique identifier of the display. + DOMString id; + + // The user-friendly name (e.g. "HP LCD monitor"). + DOMString name; + + // NOTE: This is only available to Chrome OS Kiosk apps and Web UI. + Edid? edid; + + // Chrome OS only. Identifier of the display that is being mirrored if + // mirroring is enabled, otherwise empty. This will be set for all displays + // (including the display being mirrored). + DOMString mirroringSourceId; + + // Chrome OS only. Identifiers of the displays to which the source display + // is being mirrored. Empty if no displays are being mirrored. This will be + // set to the same value for all displays. This must not include + // |mirroringSourceId|. + DOMString[] mirroringDestinationIds; + + // True if this is the primary display. + boolean isPrimary; + + // True if this is an internal display. + boolean isInternal; + + // True if this display is enabled. + boolean isEnabled; + + // Active if the display is detected and used by the system. + ActiveState activeState; + + // True for all displays when in unified desktop mode. See documentation + // for $(ref:enableUnifiedDesktop). + boolean isUnified; + + // True when the auto-rotation is allowed. It happens when the device is in + // a tablet physical state or kSupportsClamshellAutoRotation is set. + // Provided for ChromeOS Settings UI only. TODO(stevenjb): Remove when + // Settings switches to a mojo API. + [nodoc] boolean? isAutoRotationAllowed; + + // The number of pixels per inch along the x-axis. + double dpiX; + + // The number of pixels per inch along the y-axis. + double dpiY; + + // The display's clockwise rotation in degrees relative to the vertical + // position. + // Currently exposed only on ChromeOS. Will be set to 0 on other platforms. + // A value of -1 will be interpreted as auto-rotate when the device is in + // a physical tablet state. + long rotation; + + // The display's logical bounds. + Bounds bounds; + + // The display's insets within its screen's bounds. + // Currently exposed only on ChromeOS. Will be set to empty insets on + // other platforms. + Insets overscan; + + // The usable work area of the display within the display bounds. The work + // area excludes areas of the display reserved for OS, for example taskbar + // and launcher. + Bounds workArea; + + // The list of available display modes. The current mode will have + // isSelected=true. Only available on Chrome OS. Will be set to an empty + // array on other platforms. + DisplayMode[] modes; + + // True if this display has a touch input device associated with it. + boolean hasTouchSupport; + + // True if this display has an accelerometer associated with it. + // Provided for ChromeOS Settings UI only. TODO(stevenjb): Remove when + // Settings switches to a mojo API. NOTE: The name of this may change. + [nodoc] boolean hasAccelerometerSupport; + + // A list of zoom factor values that can be set for the display. + double[] availableDisplayZoomFactors; + + // The ratio between the display's current and default zoom. + // For example, value 1 is equivalent to 100% zoom, and value 1.5 is + // equivalent to 150% zoom. + double displayZoomFactor; + }; + + dictionary DisplayProperties { + // Chrome OS only. If set to true, changes the display mode to unified + // desktop (see $(ref:enableUnifiedDesktop) for details). If set to false, + // unified desktop mode will be disabled. This is only valid for the + // primary display. If provided, mirroringSourceId must not be provided and + // other properties will be ignored. This is has no effect if not provided. + boolean? isUnified; + + // Chrome OS only. If set and not empty, enables mirroring for this display + // only. Otherwise disables mirroring for all displays. This value should + // indicate the id of the source display to mirror, which must not be the + // same as the id passed to setDisplayProperties. If set, no other property + // may be set. + [deprecated="Use $(ref:setMirrorMode)."] DOMString? mirroringSourceId; + + // If set to true, makes the display primary. No-op if set to false. + // Note: If set, the display is considered primary for all other properties + // (i.e. $(ref:isUnified) may be set and bounds origin may not). + boolean? isPrimary; + + // If set, sets the display's overscan insets to the provided values. Note + // that overscan values may not be negative or larger than a half of the + // screen's size. Overscan cannot be changed on the internal monitor. + Insets? overscan; + + // If set, updates the display's rotation. + // Legal values are [0, 90, 180, 270]. The rotation is set clockwise, + // relative to the display's vertical position. + long? rotation; + + // If set, updates the display's logical bounds origin along the x-axis. + // Applied together with $(ref:boundsOriginY). Defaults to the current value + // if not set and $(ref:boundsOriginY) is set. Note that when updating the + // display origin, some constraints will be applied, so the final bounds + // origin may be different than the one set. The final bounds can be + // retrieved using $(ref:getInfo). The bounds origin cannot be changed on + // the primary display. + long? boundsOriginX; + + // If set, updates the display's logical bounds origin along the y-axis. + // See documentation for $(ref:boundsOriginX) parameter. + long? boundsOriginY; + + // If set, updates the display mode to the mode matching this value. + // If other parameters are invalid, this will not be applied. If the + // display mode is invalid, it will not be applied and an error will be + // set, but other properties will still be applied. + DisplayMode? displayMode; + + // If set, updates the zoom associated with the display. This zoom performs + // re-layout and repaint thus resulting in a better quality zoom than just + // performing a pixel by pixel stretch enlargement. + double? displayZoomFactor; + }; + + dictionary GetInfoFlags { + // If set to true, only a single $(ref:DisplayUnitInfo) will be returned + // by $(ref:getInfo) when in unified desktop mode (see + // $(ref:enableUnifiedDesktop)). Defaults to false. + boolean? singleUnified; + }; + + // Mirror mode, i.e. different ways of how a display is mirrored to other + // displays. + enum MirrorMode { + // Specifies the default mode (extended or unified desktop). + off, + + // Specifies that the default source display will be mirrored to all other + // displays. + normal, + + // Specifies that the specified source display will be mirrored to the + // provided destination displays. All other connected displays will be + // extended. + mixed + }; + + dictionary MirrorModeInfo { + // The mirror mode that should be set. + MirrorMode mode; + + // The id of the mirroring source display. This is only valid for 'mixed'. + DOMString? mirroringSourceId; + + // The ids of the mirroring destination displays. This is only valid for + // 'mixed'. + DOMString[]? mirroringDestinationIds; + }; + + callback DisplayInfoCallback = void (DisplayUnitInfo[] displayInfo); + callback DisplayLayoutCallback = void (DisplayLayout[] layouts); + callback SetDisplayUnitInfoCallback = void(); + callback SetDisplayLayoutCallback = void(); + callback NativeTouchCalibrationCallback = void(boolean success); + callback SetMirrorModeCallback = void(); + + interface Functions { + // Requests the information for all attached display devices. + // |flags|: Options affecting how the information is returned. + // |callback|: The callback to invoke with the results. + static void getInfo( + optional GetInfoFlags flags, + DisplayInfoCallback callback); + + // Requests the layout info for all displays. + // NOTE: This is only available to Chrome OS Kiosk apps and Web UI. + // |callback|: The callback to invoke with the results. + static void getDisplayLayout( + DisplayLayoutCallback callback); + + // Updates the properties for the display specified by |id|, according to + // the information provided in |info|. On failure, $(ref:runtime.lastError) + // will be set. + // NOTE: This is only available to Chrome OS Kiosk apps and Web UI. + // |id|: The display's unique identifier. + // |info|: The information about display properties that should be changed. + // A property will be changed only if a new value for it is specified in + // |info|. + // |callback|: Empty function called when the function finishes. To find out + // whether the function succeeded, $(ref:runtime.lastError) should be + // queried. + static void setDisplayProperties( + DOMString id, + DisplayProperties info, + optional SetDisplayUnitInfoCallback callback); + + // Set the layout for all displays. Any display not included will use the + // default layout. If a layout would overlap or be otherwise invalid it + // will be adjusted to a valid layout. After layout is resolved, an + // onDisplayChanged event will be triggered. + // NOTE: This is only available to Chrome OS Kiosk apps and Web UI. + // |layouts|: The layout information, required for all displays except + // the primary display. + // |callback|: Empty function called when the function finishes. To find out + // whether the function succeeded, $(ref:runtime.lastError) should be + // queried. + static void setDisplayLayout( + DisplayLayout[] layouts, + optional SetDisplayLayoutCallback callback); + + // Enables/disables the unified desktop feature. If enabled while mirroring + // is active, the desktop mode will not change until mirroring is turned + // off. Otherwise, the desktop mode will switch to unified immediately. + // NOTE: This is only available to Chrome OS Kiosk apps and Web UI. + // |enabled|: True if unified desktop should be enabled. + static void enableUnifiedDesktop(boolean enabled); + + // Starts overscan calibration for a display. This will show an overlay + // on the screen indicating the current overscan insets. If overscan + // calibration for display |id| is in progress this will reset calibration. + // |id|: The display's unique identifier. + static void overscanCalibrationStart(DOMString id); + + // Adjusts the current overscan insets for a display. Typically this should + // either move the display along an axis (e.g. left+right have the same + // value) or scale it along an axis (e.g. top+bottom have opposite values). + // Each Adjust call is cumulative with previous calls since Start. + // |id|: The display's unique identifier. + // |delta|: The amount to change the overscan insets. + static void overscanCalibrationAdjust(DOMString id, Insets delta); + + // Resets the overscan insets for a display to the last saved value (i.e + // before Start was called). + // |id|: The display's unique identifier. + static void overscanCalibrationReset(DOMString id); + + // Complete overscan adjustments for a display by saving the current values + // and hiding the overlay. + // |id|: The display's unique identifier. + static void overscanCalibrationComplete(DOMString id); + + // Displays the native touch calibration UX for the display with |id| as + // display id. This will show an overlay on the screen with required + // instructions on how to proceed. The callback will be invoked in case of + // successful calibration only. If the calibration fails, this will throw an + // error. + // |id|: The display's unique identifier. + // |callback|: Optional callback to inform the caller that the touch + // calibration has ended. The argument of the callback informs if the + // calibration was a success or not. + static void showNativeTouchCalibration( + DOMString id, + optional NativeTouchCalibrationCallback callback); + + // Starts custom touch calibration for a display. This should be called when + // using a custom UX for collecting calibration data. If another touch + // calibration is already in progress this will throw an error. + // |id|: The display's unique identifier. + static void startCustomTouchCalibration(DOMString id); + + // Sets the touch calibration pairs for a display. These |pairs| would be + // used to calibrate the touch screen for display with |id| called in + // startCustomTouchCalibration(). Always call |startCustomTouchCalibration| + // before calling this method. If another touch calibration is already in + // progress this will throw an error. + // |pairs|: The pairs of point used to calibrate the display. + // |bounds|: Bounds of the display when the touch calibration was performed. + // |bounds.left| and |bounds.top| values are ignored. + static void completeCustomTouchCalibration(TouchCalibrationPairQuad pairs, + Bounds bounds); + + // Resets the touch calibration for the display and brings it back to its + // default state by clearing any touch calibration data associated with the + // display. + // |id|: The display's unique identifier. + static void clearTouchCalibration(DOMString id); + + // Sets the display mode to the specified mirror mode. Each call resets the + // state from previous calls. Calling setDisplayProperties() will fail for + // the mirroring destination displays. + // NOTE: This is only available to Chrome OS Kiosk apps and Web UI. + // |info|: The information of the mirror mode that should be applied to the + // display mode. + // |callback|: Empty function called when the function finishes. To find out + // whether the function succeeded, $(ref:runtime.lastError) should be + // queried. + static void setMirrorMode( + MirrorModeInfo info, + optional SetMirrorModeCallback callback); + }; + + interface Events { + // Fired when anything changes to the display configuration. + static void onDisplayChanged(); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/system_memory.idl b/tools/under-control/src/extensions/common/api/system_memory.idl new file mode 100755 index 000000000..fb31ae859 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/system_memory.idl @@ -0,0 +1,21 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.system.memory API. +namespace system.memory { + + dictionary MemoryInfo { + // The total amount of physical memory capacity, in bytes. + double capacity; + // The amount of available capacity, in bytes. + double availableCapacity; + }; + + callback MemoryInfoCallback = void (MemoryInfo info); + + interface Functions { + // Get physical memory information. + static void getInfo(MemoryInfoCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/system_network.idl b/tools/under-control/src/extensions/common/api/system_network.idl new file mode 100755 index 000000000..b6a83e596 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/system_network.idl @@ -0,0 +1,31 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.system.network API. +namespace system.network { + dictionary NetworkInterface { + // The underlying name of the adapter. On *nix, this will typically be + // "eth0", "wlan0", etc. + DOMString name; + + // The available IPv4/6 address. + DOMString address; + + // The prefix length + long prefixLength; + }; + + // Callback from the getNetworkInterfaces method. + // |networkInterfaces| : Array of object containing network interfaces + // information. + callback GetNetworkInterfacesCallback = + void (NetworkInterface[] networkInterfaces); + + interface Functions { + // Retrieves information about local adapters on this system. + // |callback| : Called when local adapter information is available. + static void getNetworkInterfaces( + GetNetworkInterfacesCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/system_storage.idl b/tools/under-control/src/extensions/common/api/system_storage.idl new file mode 100755 index 000000000..2d52be2e1 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/system_storage.idl @@ -0,0 +1,86 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.system.storage API to query storage device +// information and be notified when a removable storage device is attached and +// detached. +namespace system.storage { + + enum StorageUnitType { + // The storage has fixed media, e.g. hard disk or SSD. + fixed, + // The storage is removable, e.g. USB flash drive. + removable, + // The storage type is unknown. + unknown + }; + + dictionary StorageUnitInfo { + // The transient ID that uniquely identifies the storage device. + // This ID will be persistent within the same run of a single application. + // It will not be a persistent identifier between different runs of an + // application, or between different applications. + DOMString id; + // The name of the storage unit. + DOMString name; + // The media type of the storage unit. + StorageUnitType type; + // The total amount of the storage space, in bytes. + double capacity; + }; + + dictionary StorageAvailableCapacityInfo { + // A copied |id| of getAvailableCapacity function parameter |id|. + DOMString id; + // The available capacity of the storage device, in bytes. + double availableCapacity; + }; + + [inline_doc] enum EjectDeviceResultCode { + // The ejection command is successful -- the application can prompt the user + // to remove the device. + success, + // The device is in use by another application. The ejection did not + // succeed; the user should not remove the device until the other + // application is done with the device. + in_use, + // There is no such device known. + no_such_device, + // The ejection command failed. + failure + }; + + callback EjectDeviceCallback = void (EjectDeviceResultCode result); + + callback StorageInfoCallback = void (StorageUnitInfo[] info); + + callback GetAvailableCapacityCallback = void ( + StorageAvailableCapacityInfo info); + + interface Functions { + // Get the storage information from the system. The argument passed to the + // callback is an array of StorageUnitInfo objects. + static void getInfo(StorageInfoCallback callback); + + // Ejects a removable storage device. + static void ejectDevice( + DOMString id, + EjectDeviceCallback callback); + + // Get the available capacity of a specified |id| storage device. + // The |id| is the transient device ID from StorageUnitInfo. + static void getAvailableCapacity( + DOMString id, + GetAvailableCapacityCallback callback); + }; + + interface Events { + // Fired when a new removable storage is attached to the system. + static void onAttached(StorageUnitInfo info); + + // Fired when a removable storage is detached from the system. + static void onDetached(DOMString id); + }; + +}; diff --git a/tools/under-control/src/extensions/common/api/usb.idl b/tools/under-control/src/extensions/common/api/usb.idl new file mode 100755 index 000000000..f96139517 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/usb.idl @@ -0,0 +1,423 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the chrome.usb API to interact with connected USB +// devices. This API provides access to USB operations from within the context +// of an app. Using this API, apps can function as drivers for hardware devices. +// +// Errors generated by this API are reported by setting +// $(ref:runtime.lastError) and executing the function's regular callback. The +// callback's regular parameters will be undefined in this case. +namespace usb { + + // Direction, Recipient, RequestType, and TransferType all map to their + // namesakes within the USB specification. + enum Direction {in, out}; + enum Recipient {device, _interface, endpoint, other}; + enum RequestType {standard, class, vendor, reserved}; + enum TransferType {control, interrupt, isochronous, bulk}; + + // For interrupt and isochronous modes, SynchronizationType and UsageType map + // to their namesakes within the USB specification. + enum SynchronizationType {asynchronous, adaptive, synchronous}; + enum UsageType {data, feedback, explicitFeedback, periodic, notification}; + + dictionary Device { + // An opaque ID for the USB device. It remains unchanged until the device is + // unplugged. + long device; + // The device vendor ID. + long vendorId; + // The product ID. + long productId; + // The device version (bcdDevice field). + long version; + // The iProduct string read from the device, if available. + DOMString productName; + // The iManufacturer string read from the device, if available. + DOMString manufacturerName; + // The iSerialNumber string read from the device, if available. + DOMString serialNumber; + }; + + dictionary ConnectionHandle { + // An opaque handle representing this connection to the USB device and all + // associated claimed interfaces and pending transfers. A new handle is + // created each time the device is opened. The connection handle is + // different from $(ref:Device.device). + long handle; + // The device vendor ID. + long vendorId; + // The product ID. + long productId; + }; + + [noinline_doc] dictionary EndpointDescriptor { + // Endpoint address. + long address; + // Transfer type. + TransferType type; + // Transfer direction. + Direction direction; + // Maximum packet size. + long maximumPacketSize; + // Transfer synchronization mode (isochronous only). + SynchronizationType? synchronization; + // Endpoint usage hint. + UsageType? usage; + // Polling interval (interrupt and isochronous only). + long? pollingInterval; + // Extra descriptor data associated with this endpoint. + ArrayBuffer extra_data; + }; + + [noinline_doc] dictionary InterfaceDescriptor { + // The interface number. + long interfaceNumber; + // The interface alternate setting number (defaults to 0"in" or "out"). + Direction direction; + + // The transfer target. The target given by index must be + // claimed if "interface" or "endpoint". + Recipient recipient; + + // The request type. + RequestType requestType; + + // The bRequest field, see Universal Serial Bus + // Specification Revision 1.1 § 9.3. + long request; + // The wValue field, see Ibid. + long value; + // The wIndex field, see Ibid. + long index; + + // The maximum number of bytes to receive (required only by input + // transfers). + long? length; + + // The data to transmit (required only by output transfers). + ArrayBuffer? data; + + // Request timeout (in milliseconds). The default value 0 + // indicates no timeout. + long? timeout; + }; + + dictionary GenericTransferInfo { + // The transfer direction ("in" or "out"). + Direction direction; + + // The target endpoint address. The interface containing this endpoint must + // be claimed. + long endpoint; + + // The maximum number of bytes to receive (required only by input + // transfers). + long? length; + + // The data to transmit (required only by output transfers). + ArrayBuffer? data; + + // Request timeout (in milliseconds). The default value 0 + // indicates no timeout. + long? timeout; + }; + + dictionary IsochronousTransferInfo { + // Transfer parameters. The transfer length or data buffer specified in this + // parameter block is split along packetLength boundaries to + // form the individual packets of the transfer. + GenericTransferInfo transferInfo; + + // The total number of packets in this transfer. + long packets; + + // The length of each of the packets in this transfer. + long packetLength; + }; + + dictionary TransferResultInfo { + // A value of 0 indicates that the transfer was a success. + // Other values indicate failure. + long? resultCode; + + // The data returned by an input transfer. undefined for output + // transfers. + ArrayBuffer? data; + }; + + [noinline_doc] dictionary DeviceFilter { + // Device vendor ID. + long? vendorId; + // Device product ID, checked only if the vendor ID matches. + long? productId; + // USB interface class, matches any interface on the device. + long? interfaceClass; + // USB interface sub-class, checked only if the interface class matches. + long? interfaceSubclass; + // USB interface protocol, checked only if the interface sub-class matches. + long? interfaceProtocol; + }; + + dictionary EnumerateDevicesOptions { + [deprecated="Equivalent to setting $(ref:DeviceFilter.vendorId)."] + long? vendorId; + [deprecated="Equivalent to setting $(ref:DeviceFilter.productId)."] + long? productId; + // A device matching any given filter will be returned. An empty filter list + // will return all devices the app has permission for. + DeviceFilter[]? filters; + }; + + dictionary EnumerateDevicesAndRequestAccessOptions { + // The device vendor ID. + long vendorId; + // The product ID. + long productId; + // The interface ID to request access to. + // Only available on Chrome OS. It has no effect on other platforms. + long? interfaceId; + }; + + dictionary DevicePromptOptions { + // Allow the user to select multiple devices. + boolean? multiple; + // Filter the list of devices presented to the user. If multiple filters are + // provided devices matching any filter will be displayed. + DeviceFilter[]? filters; + }; + + callback VoidCallback = void (); + callback GetDevicesCallback = void (Device[] devices); + callback GetConfigurationsCallback = void (ConfigDescriptor[] configs); + callback RequestAccessCallback = void (boolean success); + callback OpenDeviceCallback = void (ConnectionHandle handle); + callback FindDevicesCallback = void (ConnectionHandle[] handles); + callback GetConfigurationCallback = void (ConfigDescriptor config); + callback ListInterfacesCallback = void (InterfaceDescriptor[] descriptors); + callback CloseDeviceCallback = void (); + callback TransferCallback = void (TransferResultInfo info); + callback ResetDeviceCallback = void(boolean success); + + interface Functions { + // Enumerates connected USB devices. + // |options|: The properties to search for on target devices. + static void getDevices( + EnumerateDevicesOptions options, + GetDevicesCallback callback); + + // Presents a device picker to the user and returns the $(ref:Device)s + // selected. + // If the user cancels the picker devices will be empty. A user gesture + // is required for the dialog to display. Without a user gesture, the + // callback will run as though the user cancelled. + // |options|: Configuration of the device picker dialog box. + // |callback|: Invoked with a list of chosen $(ref:Device)s. + static void getUserSelectedDevices( + DevicePromptOptions options, + GetDevicesCallback callback); + + // Returns the full set of device configuration descriptors. + // |device|: The $(ref:Device) to fetch descriptors from. + static void getConfigurations( + Device device, + GetConfigurationsCallback callback); + + // Requests access from the permission broker to a device claimed by + // Chrome OS if the given interface on the device is not claimed. + // + // |device|: The $(ref:Device) to request access to. + // |interfaceId|: The particular interface requested. + [deprecated="This function was Chrome OS specific and calling it on other + platforms would fail. This operation is now implicitly performed as part of + $(ref:openDevice) and this function will return true on all + platforms."] + static void requestAccess(Device device, + long interfaceId, + RequestAccessCallback callback); + + // Opens a USB device returned by $(ref:getDevices). + // |device|: The $(ref:Device) to open. + static void openDevice( + Device device, + OpenDeviceCallback callback); + + // Finds USB devices specified by the vendor, product and (optionally) + // interface IDs and if permissions allow opens them for use. + // + // If the access request is rejected or the device fails to be opened a + // connection handle will not be created or returned. + // + // Calling this method is equivalent to calling $(ref:getDevices) followed + // by $(ref:openDevice) for each device. + // + // |options|: The properties to search for on target devices. + static void findDevices( + EnumerateDevicesAndRequestAccessOptions options, + FindDevicesCallback callback); + + // Closes a connection handle. Invoking operations on a handle after it + // has been closed is a safe operation but causes no action to be taken. + // |handle|: The $(ref:ConnectionHandle) to close. + static void closeDevice( + ConnectionHandle handle, + optional CloseDeviceCallback callback); + + // Select a device configuration. + // + // This function effectively resets the device by selecting one of the + // device's available configurations. Only configuration values greater + // than 0 are valid however some buggy devices have a working + // configuration 0 and so this value is allowed. + // |handle|: An open connection to the device. + static void setConfiguration( + ConnectionHandle handle, + long configurationValue, + VoidCallback callback); + + // Gets the configuration descriptor for the currently selected + // configuration. + // |handle|: An open connection to the device. + static void getConfiguration( + ConnectionHandle handle, + GetConfigurationCallback callback); + + // Lists all interfaces on a USB device. + // |handle|: An open connection to the device. + static void listInterfaces( + ConnectionHandle handle, + ListInterfacesCallback callback); + + // Claims an interface on a USB device. + // Before data can be transfered to an interface or associated endpoints the + // interface must be claimed. Only one connection handle can claim an + // interface at any given time. If the interface is already claimed, this + // call will fail. + // + // $(ref:releaseInterface) should be called when the interface is no longer + // needed. + // + // |handle|: An open connection to the device. + // |interfaceNumber|: The interface to be claimed. + static void claimInterface( + ConnectionHandle handle, + long interfaceNumber, + VoidCallback callback); + + // Releases a claimed interface. + // |handle|: An open connection to the device. + // |interfaceNumber|: The interface to be released. + static void releaseInterface( + ConnectionHandle handle, + long interfaceNumber, + VoidCallback callback); + + // Selects an alternate setting on a previously claimed interface. + // |handle|: An open connection to the device where this interface has been + // claimed. + // |interfaceNumber|: The interface to configure. + // |alternateSetting|: The alternate setting to configure. + static void setInterfaceAlternateSetting( + ConnectionHandle handle, + long interfaceNumber, + long alternateSetting, + VoidCallback callback); + + // Performs a control transfer on the specified device. + // + // Control transfers refer to either the device, an interface or an + // endpoint. Transfers to an interface or endpoint require the interface to + // be claimed. + // + // |handle|: An open connection to the device. + static void controlTransfer( + ConnectionHandle handle, + ControlTransferInfo transferInfo, + TransferCallback callback); + + // Performs a bulk transfer on the specified device. + // |handle|: An open connection to the device. + // |transferInfo|: The transfer parameters. + static void bulkTransfer( + ConnectionHandle handle, + GenericTransferInfo transferInfo, + TransferCallback callback); + + // Performs an interrupt transfer on the specified device. + // |handle|: An open connection to the device. + // |transferInfo|: The transfer parameters. + static void interruptTransfer( + ConnectionHandle handle, + GenericTransferInfo transferInfo, + TransferCallback callback); + + // Performs an isochronous transfer on the specific device. + // |handle|: An open connection to the device. + static void isochronousTransfer( + ConnectionHandle handle, + IsochronousTransferInfo transferInfo, + TransferCallback callback); + + // Tries to reset the USB device. + // If the reset fails, the given connection handle will be closed and the + // USB device will appear to be disconnected then reconnected. + // In this case $(ref:getDevices) or $(ref:findDevices) must be called again + // to acquire the device. + // + // |handle|: A connection handle to reset. + static void resetDevice( + ConnectionHandle handle, + ResetDeviceCallback callback); + }; + + interface Events { + // Event generated when a device is added to the system. Events are only + // broadcast to apps and extensions that have permission to access the + // device. Permission may have been granted at install time, when the user + // accepted an optional permission (see $(ref:permissions.request)), or + // through $(ref:getUserSelectedDevices). + static void onDeviceAdded(Device device); + + // Event generated when a device is removed from the system. See + // $(ref:onDeviceAdded) for which events are delivered. + static void onDeviceRemoved(Device device); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/user_scripts.idl b/tools/under-control/src/extensions/common/api/user_scripts.idl new file mode 100755 index 000000000..47d03d3c3 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/user_scripts.idl @@ -0,0 +1,180 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the userScripts API to execute user scripts in the User +// Scripts context. +namespace userScripts { + // The JavaScript world for a user script to execute within. + enum ExecutionWorld { + // Specifies the execution environment of the DOM, which is the execution + // environment shared with the host page's JavaScript. + MAIN, + // Specifies the execution environment that is specific to user scripts and + // is exempt from the page's CSP. + USER_SCRIPT + }; + + // The source of the script to inject. + dictionary ScriptSource { + // A string containing the JavaScript code to inject. Exactly one of + // file or code must be specified. + DOMString? code; + // The path of the JavaScript file to inject relative to the extension's + // root directory. Exactly one of file or code + // must be specified. + DOMString? file; + }; + + // Describes a user script to be injected into a web page registered through + // this API. The script is injected into a page if its URL matches any of + // "matches" or "include_globs" patterns, and the URL doesn't match + // "exclude_matches" and "exclude_globs" patterns. + dictionary RegisteredUserScript { + // If true, it will inject into all frames, even if the frame is not the + // top-most frame in the tab. Each frame is checked independently for URL + // requirements; it will not inject into child frames if the URL + // requirements are not met. Defaults to false, meaning that only the top + // frame is matched. + boolean? allFrames; + // Excludes pages that this user script would otherwise be injected into. + // See Match Patterns for more details on + // the syntax of these strings. + DOMString[]? excludeMatches; + // The ID of the user script specified in the API call. This property must + // not start with a '_' as it's reserved as a prefix for generated script + // IDs. + DOMString id; + // Specifies wildcard patterns for pages this user script will be injected + // into. + DOMString[]? includeGlobs; + // Specifies wildcard patterns for pages this user script will NOT be + // injected into. + DOMString[]? excludeGlobs; + // The list of ScriptSource objects defining sources of scripts to be + // injected into matching pages. + ScriptSource[] js; + // Specifies which pages this user script will be injected into. See + // Match Patterns for more details on the + // syntax of these strings. This property must be specified for + // ${ref:register}. + DOMString[]? matches; + // Specifies when JavaScript files are injected into the web page. The + // preferred and default value is document_idle. + extensionTypes.RunAt? runAt; + // The JavaScript execution environment to run the script in. The default is + // `USER_SCRIPT`. + ExecutionWorld? world; + + // If specified, specifies a specific user script world ID to execute in. + // Only valid if `world` is omitted or is `USER_SCRIPT`. If omitted, the + // script will execute in the default user script world. + // Values with leading underscores (`_`) are reserved. + // TODO(https://crbug.com/331680187): Remove nodoc. + [nodoc] DOMString? worldId; + }; + + // An object used to filter user scripts for ${ref:getScripts}. + dictionary UserScriptFilter { + // $(ref:getScripts) only returns scripts with the IDs specified in this + // list. + DOMString[]? ids; + }; + + // An object used to update the `USER_SCRIPT` world + // configuration. If a property is not specified, it will reset it to its + // default value. + dictionary WorldProperties{ + // Specifies the ID of the specific user script world to update. + // If not provided, updates the properties of the default user script world. + // Values with leading underscores (`_`) are reserved. + // TODO(https://crbug.com/331680187): Remove nodoc. + [nodoc] DOMString? worldId; + + // Specifies the world csp. The default is the `ISOLATED` + // world csp. + DOMString? csp; + + // Specifies whether messaging APIs are exposed. The default is + // false. + boolean? messaging; + }; + + callback RegisterCallback = void(); + + callback GetScriptsCallback = void(RegisteredUserScript[] scripts); + + callback UnregisterCallback = void(); + + callback UpdateCallback = void(); + + callback ConfigureWorldCallback = void(); + + callback GetAllWorldConfigurationsCallback = void(WorldProperties[] worlds); + + callback ResetWorldConfigurationCallback = void(); + + interface Functions { + // Registers one or more user scripts for this extension. + // |scripts|: Contains a list of user scripts to be registered. + // |callback|: Called once scripts have been fully registered or if an error + // has ocurred. + static void register( + RegisteredUserScript[] scripts, + optional RegisterCallback callback); + + // Returns all dynamically-registered user scripts for this extension. + // |filter|: If specified, this method returns only the user scripts that + // match it. + // |callback|: Called once scripts have been fully registered or if an error + // occurs. + static void getScripts( + optional UserScriptFilter filter, + GetScriptsCallback callback); + + // Unregisters all dynamically-registered user scripts for this extension. + // |filter|: If specified, this method unregisters only the user scripts + // that match it. + // |callback|: Called once scripts have been fully unregistered or if an + // error ocurs + static void unregister( + optional UserScriptFilter filter, + UnregisterCallback callback); + + // Updates one or more user scripts for this extension. + // |scripts|: Contains a list of user scripts to be updated. A property is + // only updated for the existing script if it is specified in this object. + // If there are errors during script parsing/file validation, or if the IDs + // specified do not correspond to a fully registered script, then no scripts + // are updated. + // |callback|: Called once scripts have been fully updated or if an error + // occurs. + static void update( + RegisteredUserScript[] scripts, + optional UpdateCallback callback); + + // Configures the `USER_SCRIPT` execution environment. + // |properties|: Contains the user script world configuration. + // |callback|: Called once world hase been configured. + static void configureWorld( + WorldProperties properties, + optional ConfigureWorldCallback callback); + + // Retrieves all registered world configurations. + // |callback|: Called with the registered world configurations. + // TODO(https://crbug.com/331680187): Remove nodoc. + [nodoc] static void getWorldConfigurations( + GetAllWorldConfigurationsCallback callback); + + // Resets the configuration for a user script world. Any scripts that inject + // into the world with the specified ID will use the default world + // configuration. + // |worldId|: The ID of the user script world to reset. If omitted, resets + // the default world's configuration. + // |callback|: Called when the configuration is reset. + // TODO(https://crbug.com/331680187): Remove nodoc. + [nodoc] static void resetWorldConfiguration( + optional DOMString worldId, + ResetWorldConfigurationCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/virtual_keyboard.idl b/tools/under-control/src/extensions/common/api/virtual_keyboard.idl new file mode 100755 index 000000000..8ac7469ea --- /dev/null +++ b/tools/under-control/src/extensions/common/api/virtual_keyboard.idl @@ -0,0 +1,39 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// The chrome.virtualKeyboard API is a kiosk only API used to +// configure virtual keyboard layout and behavior in kiosk sessions. +[platforms=("chromeos", "lacros")] +namespace virtualKeyboard { + //

Determines whether advanced virtual keyboard features should be enabled + // or not. They are enabled by default.

+ //

On Chrome 58 all properties are expected to have the same value. + //

+ //

From Chrome 63 the properties can be distinct and are optional. + // If omitted, the current value is preserved.

+ dictionary FeatureRestrictions { + // Whether virtual keyboards can provide auto-complete. + boolean? autoCompleteEnabled; + // Whether virtual keyboards can provide auto-correct. + boolean? autoCorrectEnabled; + // Whether virtual keyboards can provide input via handwriting recognition. + boolean? handwritingEnabled; + // Whether virtual keyboards can provide spell-check. + boolean? spellCheckEnabled; + // Whether virtual keyboards can provide voice input. + boolean? voiceInputEnabled; + }; + + callback RestrictFeaturesCallback = void(FeatureRestrictions update); + + interface Functions { + // Sets restrictions on features provided by the virtual keyboard. + // |restrictions|: the preferences to enabled/disabled virtual keyboard + // features. + // |callback|: Invoked with the values which were updated. + void restrictFeatures( + FeatureRestrictions restrictions, + optional RestrictFeaturesCallback callback); + }; +}; diff --git a/tools/under-control/src/extensions/common/api/web_accessible_resources.idl b/tools/under-control/src/extensions/common/api/web_accessible_resources.idl new file mode 100755 index 000000000..7ee7e03ad --- /dev/null +++ b/tools/under-control/src/extensions/common/api/web_accessible_resources.idl @@ -0,0 +1,35 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Stub namespace for the "web_accessible_resources" manifest key. +[generate_error_messages] namespace webAccessibleResources { + dictionary WebAccessibleResource { + // Relative paths within the extension package representing web accessible + // resources. + DOMString[] resources; + + // List of + // match patterns to which "resources" are accessible. These patterns should + // have an effective path of "*". Each match will be checked against the + // initiating origin. + DOMString[]? matches; + + // List of extension IDs the "resources" are accessible to. A wildcard can + // be used, denoted by "*". + DOMString[]? extension_ids; + + // If true, the web accessible resources will only be accessible through a + // dynamic ID. This is an identifier that uniquely identifies the extension + // and is generated each session. The corresponding dynamic extension URL + // is available through $(ref:runtime.getURL). + // Dynamic resources can be loaded regardless of the value. However, if + // true, resources must be can only be loaded using the dynamic URL. + boolean? use_dynamic_url; + }; + + dictionary ManifestKeys { + WebAccessibleResource[] web_accessible_resources; + }; +}; diff --git a/tools/under-control/src/extensions/common/api/web_accessible_resources_mv2.idl b/tools/under-control/src/extensions/common/api/web_accessible_resources_mv2.idl new file mode 100755 index 000000000..42b15d339 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/web_accessible_resources_mv2.idl @@ -0,0 +1,12 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Stub namespace for the "web_accessible_resources" manifest key. +[generate_error_messages] namespace webAccessibleResourcesMv2 { + dictionary ManifestKeys { + // Relative paths within the extension package representing web accessible + // resources. + DOMString[] web_accessible_resources; + }; +}; diff --git a/tools/under-control/src/extensions/common/api/webcam_private.idl b/tools/under-control/src/extensions/common/api/webcam_private.idl new file mode 100755 index 000000000..d4b3d8d71 --- /dev/null +++ b/tools/under-control/src/extensions/common/api/webcam_private.idl @@ -0,0 +1,101 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Webcam Private API. +namespace webcamPrivate { + enum PanDirection { stop, right, left }; + enum TiltDirection { stop, up, down }; + enum Protocol { visca }; + enum AutofocusState { on, off }; + + dictionary ProtocolConfiguration { + Protocol? protocol; + }; + + dictionary WebcamConfiguration { + double? pan; + double? panSpeed; + PanDirection? panDirection; + double? tilt; + double? tiltSpeed; + TiltDirection? tiltDirection; + double? zoom; + AutofocusState? autofocusState; + double? focus; + }; + + dictionary Range { double min; double max; }; + + dictionary WebcamCurrentConfiguration { + double pan; + double tilt; + double zoom; + double focus; + + // Supported range of pan, tilt and zoom values. + Range? panRange; + Range? tiltRange; + Range? zoomRange; + Range? focusRange; + }; + + callback WebcamIdCallback = void(DOMString webcamId); + callback WebcamConfigurationCallback = + void(WebcamCurrentConfiguration configuration); + + interface Functions { + // Open a serial port that controls a webcam. + static void openSerialWebcam( + DOMString path, + ProtocolConfiguration protocol, + WebcamIdCallback callback); + + // Close a serial port connection to a webcam. + static void closeWebcam(DOMString webcamId); + + // Retrieve webcam parameters. Will respond with a config holding the + // requested values that are available, or default values for those that + // aren't. If none of the requests succeed, will respond with an error. + static void get( + DOMString webcamId, + WebcamConfigurationCallback callback); + + // A callback is included here which is invoked when the function responds. + // No configuration is returned through it. + static void set( + DOMString webcamId, + WebcamConfiguration config, + WebcamConfigurationCallback callback); + + // Reset a webcam. Note: the value of the parameter have no effect, it's the + // presence of the parameter that matters. E.g.: reset(webcamId, {pan: 0, + // tilt: 1}); will reset pan & tilt, but not zoom. + // A callback is included here which is invoked when the function responds. + // No configuration is returned through it. + static void reset( + DOMString webcamId, + WebcamConfiguration config, + WebcamConfigurationCallback callback); + + // Set home preset for a webcam. A callback is included here which is + // invoked when the function responds. + static void setHome( + DOMString webcamId, + WebcamConfigurationCallback callback); + + // Restore the camera's position to that of the specified preset. A callback + // is included here which is invoked when the function responds. + static void restoreCameraPreset( + DOMString webcamId, + double presetNumber, + WebcamConfigurationCallback callback); + + // Set the current camera's position to be stored for the specified preset. + // A callback is included here which is invoked when the function responds. + static void setCameraPreset( + DOMString webcamId, + double presetNumber, + WebcamConfigurationCallback callback); + }; +}; diff --git a/tools/under-control/src/gin/v8_initializer.cc b/tools/under-control/src/gin/v8_initializer.cc new file mode 100755 index 000000000..5d020cdea --- /dev/null +++ b/tools/under-control/src/gin/v8_initializer.cc @@ -0,0 +1,667 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gin/v8_initializer.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "base/allocator/partition_allocator/src/partition_alloc/page_allocator.h" +#include "base/allocator/partition_allocator/src/partition_alloc/partition_address_space.h" +#include "base/bits.h" +#include "base/check.h" +#include "base/check_op.h" +#include "base/containers/span.h" +#include "base/debug/alias.h" +#include "base/debug/crash_logging.h" +#include "base/feature_list.h" +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/files/memory_mapped_file.h" +#include "base/lazy_instance.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "base/notreached.h" +#include "base/path_service.h" +#include "base/rand_util.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/system/sys_info.h" +#include "base/threading/platform_thread.h" +#include "base/time/time.h" +#include "build/build_config.h" +#include "gin/array_buffer.h" +#include "gin/gin_features.h" +#include "tools/v8_context_snapshot/buildflags.h" +#include "v8/include/v8-initialization.h" +#include "v8/include/v8-snapshot.h" + +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) +#if BUILDFLAG(IS_ANDROID) +#include "base/android/apk_assets.h" +#elif BUILDFLAG(IS_MAC) +#include "base/apple/foundation_util.h" +#endif +#endif // V8_USE_EXTERNAL_STARTUP_DATA + +namespace gin { + +namespace { + +// This global is never freed nor closed. +base::MemoryMappedFile* g_mapped_snapshot = nullptr; + +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) +std::optional g_snapshot_file_type; +#endif + +bool GenerateEntropy(unsigned char* buffer, size_t amount) { + base::RandBytes( + // SAFETY: This depends on callers providing a valid pointer/size pair. + // + // TODO(crbug.com/338574383): The signature is fixed as it's a callback + // from v8, but maybe v8 can use a span. + UNSAFE_BUFFERS(base::span(buffer, amount))); + return true; +} + +void GetMappedFileData(base::MemoryMappedFile* mapped_file, + v8::StartupData* data) { + if (mapped_file) { + data->data = reinterpret_cast(mapped_file->data()); + data->raw_size = static_cast(mapped_file->length()); + } else { + data->data = nullptr; + data->raw_size = 0; + } +} + +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) + +#if BUILDFLAG(IS_ANDROID) +const char kV8ContextSnapshotFileName64[] = "v8_context_snapshot_64.bin"; +const char kV8ContextSnapshotFileName32[] = "v8_context_snapshot_32.bin"; +const char kSnapshotFileName64[] = "snapshot_blob_64.bin"; +const char kSnapshotFileName32[] = "snapshot_blob_32.bin"; + +#if defined(__LP64__) +#define kV8ContextSnapshotFileName kV8ContextSnapshotFileName64 +#define kSnapshotFileName kSnapshotFileName64 +#else +#define kV8ContextSnapshotFileName kV8ContextSnapshotFileName32 +#define kSnapshotFileName kSnapshotFileName32 +#endif + +#else // BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(USE_V8_CONTEXT_SNAPSHOT) +const char kV8ContextSnapshotFileName[] = + BUILDFLAG(V8_CONTEXT_SNAPSHOT_FILENAME); +#endif +const char kSnapshotFileName[] = "snapshot_blob.bin"; +#endif // BUILDFLAG(IS_ANDROID) + +const char* GetSnapshotFileName(const V8SnapshotFileType file_type) { + switch (file_type) { + case V8SnapshotFileType::kDefault: + return kSnapshotFileName; + case V8SnapshotFileType::kWithAdditionalContext: +#if BUILDFLAG(USE_V8_CONTEXT_SNAPSHOT) + return kV8ContextSnapshotFileName; +#else + NOTREACHED_IN_MIGRATION(); + return nullptr; +#endif + } + NOTREACHED_IN_MIGRATION(); + return nullptr; +} + +void GetV8FilePath(const char* file_name, base::FilePath* path_out) { +#if BUILDFLAG(IS_ANDROID) + // This is the path within the .apk. + *path_out = + base::FilePath(FILE_PATH_LITERAL("assets")).AppendASCII(file_name); +#elif BUILDFLAG(IS_MAC) + *path_out = base::apple::PathForFrameworkBundleResource(file_name); +#else + base::FilePath data_path; + bool r = base::PathService::Get(base::DIR_ASSETS, &data_path); + DCHECK(r); + *path_out = data_path.AppendASCII(file_name); +#endif +} + +bool MapV8File(base::File file, + base::MemoryMappedFile::Region region, + base::MemoryMappedFile** mmapped_file_out) { + DCHECK(*mmapped_file_out == NULL); + std::unique_ptr mmapped_file( + new base::MemoryMappedFile()); + if (mmapped_file->Initialize(std::move(file), region)) { + *mmapped_file_out = mmapped_file.release(); + return true; + } + return false; +} + +base::File OpenV8File(const char* file_name, + base::MemoryMappedFile::Region* region_out) { + // Re-try logic here is motivated by http://crbug.com/479537 + // for A/V on Windows (https://support.microsoft.com/en-us/kb/316609). + + base::FilePath path; + GetV8FilePath(file_name, &path); + +#if BUILDFLAG(IS_ANDROID) + base::File file(base::android::OpenApkAsset(path.value(), region_out)); +#else + // Re-try logic here is motivated by http://crbug.com/479537 + // for A/V on Windows (https://support.microsoft.com/en-us/kb/316609). + const int kMaxOpenAttempts = 5; + const int kOpenRetryDelayMillis = 250; + + int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; + base::File file; + for (int attempt = 0; attempt < kMaxOpenAttempts; attempt++) { + file.Initialize(path, flags); + if (file.IsValid()) { + *region_out = base::MemoryMappedFile::Region::kWholeFile; + break; + } else if (file.error_details() != base::File::FILE_ERROR_IN_USE) { + break; + } else if (kMaxOpenAttempts - 1 != attempt) { + base::PlatformThread::Sleep(base::Milliseconds(kOpenRetryDelayMillis)); + } + } +#endif // BUILDFLAG(IS_ANDROID) + return file; +} + +#endif // defined(V8_USE_EXTERNAL_STARTUP_DATA) + +template +void SetV8Flags(const char (&flag)[LENGTH]) { + v8::V8::SetFlagsFromString(flag, LENGTH - 1); +} + +void SetV8FlagsFormatted(const char* format, ...) { + char buffer[128]; + va_list args; + va_start(args, format); + int length = base::vsnprintf(buffer, sizeof(buffer), format, args); + if (length <= 0 || sizeof(buffer) <= static_cast(length)) { + PLOG(ERROR) << "Invalid formatted V8 flag: " << format; + return; + } + v8::V8::SetFlagsFromString(buffer, length); +} + +template +void SetV8FlagsIfOverridden(const base::Feature& feature, + const char (&enabling_flag)[N], + const char (&disabling_flag)[M]) { + auto overridden_state = base::FeatureList::GetStateIfOverridden(feature); + if (!overridden_state.has_value()) { + return; + } + if (overridden_state.value()) { + SetV8Flags(enabling_flag); + } else { + SetV8Flags(disabling_flag); + } +} + +void SetFlags(IsolateHolder::ScriptMode mode, + const std::string js_command_line_flags) { + // We assume that all feature flag defaults correspond to the default + // values of the corresponding V8 flags. + SetV8FlagsIfOverridden(features::kV8CompactCodeSpaceWithStack, + "--compact-code-space-with-stack", + "--no-compact-code-space-with-stack"); + SetV8FlagsIfOverridden(features::kV8CompactWithStack, "--compact-with-stack", + "--no-compact-with-stack"); + SetV8FlagsIfOverridden(features::kV8OptimizeJavascript, "--opt", "--no-opt"); + SetV8FlagsIfOverridden(features::kV8FlushBytecode, "--flush-bytecode", + "--no-flush-bytecode"); + SetV8FlagsIfOverridden(features::kV8FlushBaselineCode, + "--flush-baseline-code", "--no-flush-baseline-code"); + SetV8FlagsIfOverridden(features::kV8FlushCodeBasedOnTabVisibility, + "--flush-code-based-on-tab-visibility", + "--no-flush-code-based-on-tab-visibility"); + SetV8FlagsIfOverridden(features::kV8FlushCodeBasedOnTime, + "--flush-code-based-on-time", + "--no-flush-code-based-on-time"); + SetV8FlagsIfOverridden(features::kV8OffThreadFinalization, + "--finalize-streaming-on-background", + "--no-finalize-streaming-on-background"); + if (base::FeatureList::IsEnabled(features::kV8DelayMemoryReducer)) { + SetV8FlagsFormatted( + "--gc-memory-reducer-start-delay-ms=%i", + static_cast( + features::kV8MemoryReducerStartDelay.Get().InMilliseconds())); + } + SetV8FlagsIfOverridden(features::kV8ConcurrentMarkingHighPriorityThreads, + "--concurrent-marking-high-priority-threads", + "--no-concurrent-marking-high-priority-threads"); + SetV8FlagsIfOverridden(features::kV8LazyFeedbackAllocation, + "--lazy-feedback-allocation", + "--no-lazy-feedback-allocation"); + SetV8FlagsIfOverridden(features::kV8PerContextMarkingWorklist, + "--stress-per-context-marking-worklist", + "--no-stress-per-context-marking-worklist"); + SetV8FlagsIfOverridden(features::kV8FlushEmbeddedBlobICache, + "--experimental-flush-embedded-blob-icache", + "--no-experimental-flush-embedded-blob-icache"); + SetV8FlagsIfOverridden(features::kV8ReduceConcurrentMarkingTasks, + "--gc-experiment-reduce-concurrent-marking-tasks", + "--no-gc-experiment-reduce-concurrent-marking-tasks"); + SetV8FlagsIfOverridden(features::kV8NoReclaimUnmodifiedWrappers, + "--no-reclaim-unmodified-wrappers", + "--reclaim-unmodified-wrappers"); + SetV8FlagsIfOverridden( + features::kV8ExperimentalRegexpEngine, + "--enable-experimental-regexp-engine-on-excessive-backtracks", + "--no-enable-experimental-regexp-engine-on-excessive-backtracks"); + SetV8FlagsIfOverridden(features::kV8TurboFastApiCalls, + "--turbo-fast-api-calls", "--no-turbo-fast-api-calls"); + SetV8FlagsIfOverridden(features::kV8MegaDomIC, "--mega-dom-ic", + "--no-mega-dom-ic"); + SetV8FlagsIfOverridden(features::kV8Maglev, "--maglev", "--no-maglev"); + SetV8FlagsIfOverridden(features::kV8ConcurrentMaglevHighPriorityThreads, + "--concurrent-maglev-high-priority-threads", + "--no-concurrent-maglev-high-priority-threads"); + if (base::FeatureList::IsEnabled(features::kV8MemoryReducer)) { + SetV8FlagsFormatted("--memory-reducer-gc-count=%i", + features::kV8MemoryReducerGCCount.Get()); + } + SetV8FlagsIfOverridden(features::kV8IdleGcOnContextDisposal, + "--idle-gc-on-context-disposal", + "--no-idle-gc-on-context-disposal"); + SetV8FlagsIfOverridden(features::kV8GCOptimizeSweepForMutator, + "--cppheap-optimize-sweep-for-mutator", + "--no-cppheap-optimize-sweep-for-mutator"); + SetV8FlagsIfOverridden(features::kV8MinorMS, "--minor-ms", "--no-minor-ms"); + if (base::FeatureList::IsEnabled(features::kV8ScavengerHigherCapacity)) { + SetV8FlagsFormatted("--scavenger-max-new-space-capacity-mb=%i", + features::kV8ScavengerMaxCapacity.Get()); + } + SetV8FlagsIfOverridden(features::kV8Sparkplug, "--sparkplug", + "--no-sparkplug"); + SetV8FlagsIfOverridden(features::kV8Turbofan, "--turbofan", "--no-turbofan"); + SetV8FlagsIfOverridden(features::kV8Turboshaft, "--turboshaft", + "--no-turboshaft"); + SetV8FlagsIfOverridden(features::kV8TurboshaftInstructionSelection, + "--turboshaft-instruction-selection", + "--no-turboshaft-instruction-selection"); + SetV8FlagsIfOverridden(features::kV8ConcurrentSparkplug, + "--concurrent-sparkplug", "--no-concurrent-sparkplug"); + SetV8FlagsIfOverridden(features::kV8SparkplugNeedsShortBuiltinCalls, + "--sparkplug-needs-short-builtins", + "--no-sparkplug-needs-short-builtins"); + SetV8FlagsIfOverridden(features::kV8BaselineBatchCompilation, + "--baseline-batch-compilation", + "--no-baseline-batch-compilation"); + SetV8FlagsIfOverridden(features::kV8ShortBuiltinCalls, + "--short-builtin-calls", "--no-short-builtin-calls"); + SetV8FlagsIfOverridden(features::kV8CodeMemoryWriteProtection, + "--write-protect-code-memory", + "--no-write-protect-code-memory"); + SetV8FlagsIfOverridden(features::kV8SlowHistograms, "--slow-histograms", + "--no-slow-histograms"); + SetV8FlagsIfOverridden(features::kV8SideStepTransitions, + "--clone_object_sidestep_transitions", + "--noclone_object_sidestep_transitions"); + SetV8FlagsIfOverridden(features::kV8SingleThreadedGCInBackground, + "--single-threaded-gc-in-background", + "--no-single-threaded-gc-in-background"); + SetV8FlagsIfOverridden(features::kV8SingleThreadedGCInBackgroundParallelPause, + "--parallel-pause-for-gc-in-background", + "--no-parallel-pause-for-gc-in-background"); + SetV8FlagsIfOverridden( + features::kV8SingleThreadedGCInBackgroundNoIncrementalMarking, + "--no-incremental-marking-for-gc-in-background", + "--incremental-marking-for-gc-in-background"); + SetV8FlagsIfOverridden(features::kV8DecommitPooledPages, + "--decommit-pooled-pages", + "--no-decommit-pooled-pages"); + + if (base::FeatureList::IsEnabled(features::kV8ConcurrentSparkplug)) { + if (int max_threads = features::kV8ConcurrentSparkplugMaxThreads.Get()) { + SetV8FlagsFormatted("--concurrent-sparkplug-max-threads=%i", max_threads); + } + SetV8FlagsIfOverridden(features::kV8ConcurrentSparkplugHighPriorityThreads, + "--concurrent-sparkplug-high-priority-threads", + "--no-concurrent-sparkplug-high-priority-threads"); + } + + if (base::FeatureList::IsEnabled(features::kV8FlushBytecode)) { + if (int old_age = features::kV8FlushBytecodeOldAge.Get()) { + SetV8FlagsFormatted("--bytecode-old-age=%i", old_age); + } + } + + if (base::FeatureList::IsEnabled(features::kV8FlushCodeBasedOnTime)) { + if (int old_time = features::kV8FlushCodeOldTime.Get()) { + SetV8FlagsFormatted("--bytecode-old-time=%i", old_time); + } + } + + if (base::FeatureList::IsEnabled(features::kV8EfficiencyModeTiering)) { + int delay = features::kV8EfficiencyModeTieringDelayTurbofan.Get(); + if (delay == 0) { + SetV8FlagsFormatted( + "--efficiency-mode-for-tiering-heuristics " + "--efficiency-mode-disable-turbofan"); + } else { + SetV8FlagsFormatted( + "--efficiency-mode-for-tiering-heuristics " + "--noefficiency-mode-disable-turbofan " + "--efficiency-mode-delay-turbofan=%i", + delay); + } + } else { + SetV8FlagsFormatted("--no-efficiency-mode-for-tiering-heuristics"); + } + + if (base::FeatureList::IsEnabled( + features::kWebAssemblyMoreAggressiveCodeCaching)) { + SetV8FlagsFormatted( + "--wasm-caching-threshold=%d --wasm-caching-hard-threshold=%d " + "--wasm-caching-timeout-ms=%d", + features::kWebAssemblyMoreAggressiveCodeCachingThreshold.Get(), + features::kWebAssemblyMoreAggressiveCodeCachingHardThreshold.Get(), + features::kWebAssemblyMoreAggressiveCodeCachingTimeoutMs.Get()); + } + + // Make sure aliases of kV8SlowHistograms only enable the feature to + // avoid contradicting settings between multiple finch experiments. + bool any_slow_histograms_alias = + base::FeatureList::IsEnabled( + features::kV8SlowHistogramsCodeMemoryWriteProtection) || + base::FeatureList::IsEnabled( + features::kV8SlowHistogramsIntelJCCErratumMitigation) || + base::FeatureList::IsEnabled(features::kV8SlowHistogramsSparkplug) || + base::FeatureList::IsEnabled( + features::kV8SlowHistogramsSparkplugAndroid) || + base::FeatureList::IsEnabled(features::kV8SlowHistogramsNoTurbofan); + if (any_slow_histograms_alias) { + SetV8Flags("--slow-histograms"); + } else { + SetV8FlagsIfOverridden(features::kV8SlowHistograms, "--slow-histograms", + "--no-slow-histograms"); + } + + SetV8FlagsIfOverridden(features::kV8IgnitionElideRedundantTdzChecks, + "--ignition-elide-redundant-tdz-checks", + "--no-ignition-elide-redundant-tdz-checks"); + + SetV8FlagsIfOverridden(features::kV8IntelJCCErratumMitigation, + "--intel-jcc-erratum-mitigation", + "--no-intel-jcc-erratum-mitigation"); + + SetV8FlagsIfOverridden(features::kV8UpdateLimitAfterLoading, + "--update-allocation-limits-after-loading", + "--no-update-allocation-limits-after-loading"); + + SetV8FlagsIfOverridden(features::kV8UseLibmTrigFunctions, + "--use-libm-trig-functions", + "--no-use-libm-trig-functions"); + + SetV8FlagsIfOverridden(features::kV8UseOriginalMessageForStackTrace, + "--use-original-message-for-stack-trace", + "--no-use-original-message-for-stack-trace"); + + // JavaScript language features. + SetV8FlagsIfOverridden(features::kJavaScriptIteratorHelpers, + "--harmony-iterator-helpers", + "--no-harmony-iterator-helpers"); + SetV8FlagsIfOverridden(features::kJavaScriptPromiseWithResolvers, + "--js-promise-withresolvers", + "--no-js-promise-withresolvers"); + SetV8FlagsIfOverridden(features::kJavaScriptRegExpModifiers, + "--js-regexp-modifiers", "--no-js-regexp-modifiers"); + SetV8FlagsIfOverridden(features::kJavaScriptImportAttributes, + "--harmony-import-attributes", + "--no-harmony-import-attributes"); + SetV8FlagsIfOverridden(features::kJavaScriptSetMethods, + "--harmony-set-methods", "--no-harmony-set-methods"); + SetV8FlagsIfOverridden(features::kJavaScriptRegExpDuplicateNamedGroups, + "--js-regexp-duplicate-named-groups", + "--no-js-duplicate-named-groups"); + SetV8FlagsIfOverridden(features::kJavaScriptPromiseTry, "--js-promise-try", + "--no-js-promise-try"); + + if (IsolateHolder::kStrictMode == mode) { + SetV8Flags("--use_strict"); + } + + SetV8FlagsIfOverridden(features::kJavaScriptCompileHintsMagic, + "--compile-hints-magic", "--no-compile-hints-magic"); + + // WebAssembly features. + + SetV8FlagsIfOverridden(features::kWebAssemblyInlining, + "--experimental-wasm-inlining", + "--no-experimental-wasm-inlining"); + SetV8FlagsIfOverridden(features::kWebAssemblyInliningCallIndirect, + "--wasm-inlining-call-indirect", + "--no-wasm-inlining-call-indirect"); + SetV8FlagsIfOverridden(features::kWebAssemblyLiftoffCodeFlushing, + "--flush-liftoff-code", "--no-flush-liftoff-code"); + SetV8FlagsIfOverridden(features::kWebAssemblyGenericWrapper, + "--wasm-to-js-generic-wrapper", + "--no-wasm-to-js-generic-wrapper"); + SetV8FlagsIfOverridden(features::kWebAssemblyMultipleMemories, + "--experimental-wasm-multi-memory", + "--no-experimental-wasm-multi-memory"); + SetV8FlagsIfOverridden(features::kWebAssemblyTurboshaft, "--turboshaft-wasm", + "--no-turboshaft-wasm"); + SetV8FlagsIfOverridden(features::kWebAssemblyTurboshaftInstructionSelection, + "--turboshaft-wasm-instruction-selection-staged", + "--no-turboshaft-wasm-instruction-selection-staged"); + + if (js_command_line_flags.empty()) + return; + + // Allow the --js-flags switch to override existing flags: + std::vector flag_list = + base::SplitStringPiece(js_command_line_flags, ",", base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + for (const auto& flag : flag_list) { + v8::V8::SetFlagsFromString(std::string(flag).c_str(), flag.size()); + } +} + +} // namespace + +// static +void V8Initializer::Initialize(IsolateHolder::ScriptMode mode, + const std::string js_command_line_flags, + v8::OOMErrorCallback oom_error_callback) { + static bool v8_is_initialized = false; + if (v8_is_initialized) + return; + + // Flags need to be set before InitializePlatform as they are used for + // system instrumentation initialization. + // See https://crbug.com/v8/11043 + SetFlags(mode, js_command_line_flags); + + v8::V8::InitializePlatform(V8Platform::Get()); + + // Set this as early as possible in order to ensure OOM errors are reported + // correctly. + v8::V8::SetFatalMemoryErrorCallback(oom_error_callback); + + // Set this early on as some initialization steps, such as the initialization + // of the virtual memory cage, already use V8's random number generator. + v8::V8::SetEntropySource(&GenerateEntropy); + +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) + if (g_mapped_snapshot) { + v8::StartupData snapshot; + GetMappedFileData(g_mapped_snapshot, &snapshot); + v8::V8::SetSnapshotDataBlob(&snapshot); + } +#endif // V8_USE_EXTERNAL_STARTUP_DATA + + v8::V8::Initialize(); + + v8_is_initialized = true; + +#if defined(V8_ENABLE_SANDBOX) + // Record some sandbox statistics into UMA. + // The main reason for capturing these histograms here instead of having V8 + // do it is that there are no Isolates available yet, which are required + // for recording histograms in V8. + + // Record the mode of the sandbox. + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. This should match enum + // V8SandboxMode in tools/metrics/histograms/enums.xml. + enum class V8SandboxMode { + kSecure = 0, + kInsecure = 1, + kMaxValue = kInsecure, + }; + base::UmaHistogramEnumeration("V8.SandboxMode", + v8::V8::IsSandboxConfiguredSecurely() + ? V8SandboxMode::kSecure + : V8SandboxMode::kInsecure); + + // Record the size of the address space reservation backing the sandbox. + // The size will always be one of a handful of values, so use a sparse + // histogram to capture it. + size_t size = v8::V8::GetSandboxReservationSizeInBytes(); + DCHECK_GT(size, 0U); + size_t sizeInGB = size >> 30; + DCHECK_EQ(sizeInGB << 30, size); + base::UmaHistogramSparse("V8.SandboxReservationSizeGB", sizeInGB); + + // When the sandbox is enabled, ArrayBuffers must be allocated inside of + // it. To achieve that, PA's ConfigurablePool is created inside the sandbox + // and Blink then creates the ArrayBuffer partition in that Pool. + v8::VirtualAddressSpace* sandbox_address_space = + v8::V8::GetSandboxAddressSpace(); + const size_t max_pool_size = partition_alloc::internal:: + PartitionAddressSpace::ConfigurablePoolMaxSize(); + const size_t min_pool_size = partition_alloc::internal:: + PartitionAddressSpace::ConfigurablePoolMinSize(); + size_t pool_size = max_pool_size; + // Try to reserve the maximum size of the pool at first, then keep halving + // the size on failure until it succeeds. + uintptr_t pool_base = 0; + while (!pool_base && pool_size >= min_pool_size) { + pool_base = sandbox_address_space->AllocatePages( + 0, pool_size, pool_size, v8::PagePermissions::kNoAccess); + if (!pool_base) { + pool_size /= 2; + } + } + // The V8 sandbox is guaranteed to be large enough to host the pool. + CHECK(pool_base); + partition_alloc::internal::PartitionAddressSpace::InitConfigurablePool( + pool_base, pool_size); + // TODO(saelo) maybe record the size of the Pool into UMA. +#endif // V8_ENABLE_SANDBOX + + // Initialize the partition used by gin::ArrayBufferAllocator instances. This + // needs to happen now, after the V8 sandbox has been initialized, so that + // the partition is placed inside the configurable pool initialized above. + ArrayBufferAllocator::InitializePartition(); +} + +// static +void V8Initializer::GetV8ExternalSnapshotData(v8::StartupData* snapshot) { + GetMappedFileData(g_mapped_snapshot, snapshot); +} + +// static +void V8Initializer::GetV8ExternalSnapshotData(const char** snapshot_data_out, + int* snapshot_size_out) { + v8::StartupData snapshot; + GetV8ExternalSnapshotData(&snapshot); + *snapshot_data_out = snapshot.data; + *snapshot_size_out = snapshot.raw_size; +} + +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) + +// static +void V8Initializer::LoadV8Snapshot(V8SnapshotFileType snapshot_file_type) { + if (g_mapped_snapshot) { + // TODO(crbug.com/40558459): Confirm not loading different type of snapshot + // files in a process. + return; + } + + base::MemoryMappedFile::Region file_region; + base::File file = + OpenV8File(GetSnapshotFileName(snapshot_file_type), &file_region); + LoadV8SnapshotFromFile(std::move(file), &file_region, snapshot_file_type); +} + +// static +void V8Initializer::LoadV8SnapshotFromFile( + base::File snapshot_file, + base::MemoryMappedFile::Region* snapshot_file_region, + V8SnapshotFileType snapshot_file_type) { + if (g_mapped_snapshot) + return; + + if (!snapshot_file.IsValid()) { + LOG(FATAL) << "Error loading V8 startup snapshot file"; + } + + g_snapshot_file_type = snapshot_file_type; + base::MemoryMappedFile::Region region = + base::MemoryMappedFile::Region::kWholeFile; + if (snapshot_file_region) { + region = *snapshot_file_region; + } + + if (!MapV8File(std::move(snapshot_file), region, &g_mapped_snapshot)) { + LOG(FATAL) << "Error mapping V8 startup snapshot file"; + } +} + +#if BUILDFLAG(IS_ANDROID) +// static +base::FilePath V8Initializer::GetSnapshotFilePath( + bool abi_32_bit, + V8SnapshotFileType snapshot_file_type) { + base::FilePath path; + const char* filename = nullptr; + switch (snapshot_file_type) { + case V8SnapshotFileType::kDefault: + filename = abi_32_bit ? kSnapshotFileName32 : kSnapshotFileName64; + break; + case V8SnapshotFileType::kWithAdditionalContext: + filename = abi_32_bit ? kV8ContextSnapshotFileName32 + : kV8ContextSnapshotFileName64; + break; + } + CHECK(filename); + + GetV8FilePath(filename, &path); + return path; +} +#endif // BUILDFLAG(IS_ANDROID) + +V8SnapshotFileType GetLoadedSnapshotFileType() { + DCHECK(g_snapshot_file_type.has_value()); + return *g_snapshot_file_type; +} + +#endif // defined(V8_USE_EXTERNAL_STARTUP_DATA) + +} // namespace gin diff --git a/tools/under-control/src/media/base/video_codecs.h b/tools/under-control/src/media/base/video_codecs.h new file mode 100755 index 000000000..8ca35120e --- /dev/null +++ b/tools/under-control/src/media/base/video_codecs.h @@ -0,0 +1,152 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef MEDIA_BASE_VIDEO_CODECS_H_ +#define MEDIA_BASE_VIDEO_CODECS_H_ + +#include + +#include + +#include "media/base/media_export.h" + +namespace media { + +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.media +enum class VideoCodec { + // These values are histogrammed over time; do not change their ordinal + // values. When deleting a codec replace it with a dummy value; when adding a + // codec, do so at the bottom (and update kMaxValue). + kUnknown = 0, + kH264, + kVC1, + kMPEG2, + kMPEG4, + kTheora, + kVP8, + kVP9, + kHEVC, + kDolbyVision, + kAV1, + // DO NOT ADD RANDOM VIDEO CODECS! + // + // The only acceptable time to add a new codec is if there is production code + // that uses said codec in the same CL. + + kMaxValue = kAV1, // Must equal the last "real" codec above. +}; + +// Video codec profiles. Keep in sync with mojo::VideoCodecProfile (see +// media/mojo/mojom/media_types.mojom), gpu::VideoCodecProfile (see +// gpu/config/gpu_info.h), and PP_VideoDecoder_Profile (translation is performed +// in content/renderer/pepper/ppb_video_decoder_impl.cc). +// NOTE: These values are histogrammed over time in UMA so the values must never +// ever change (add new values to tools/metrics/histograms/histograms.xml) +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.media +enum VideoCodecProfile { + // Keep the values in this enum unique, as they imply format (h.264 vs. VP8, + // for example), and keep the values for a particular format grouped + // together for clarity. + VIDEO_CODEC_PROFILE_UNKNOWN = -1, + VIDEO_CODEC_PROFILE_MIN = VIDEO_CODEC_PROFILE_UNKNOWN, + H264PROFILE_MIN = 0, + H264PROFILE_BASELINE = H264PROFILE_MIN, + H264PROFILE_MAIN = 1, + H264PROFILE_EXTENDED = 2, + H264PROFILE_HIGH = 3, + H264PROFILE_HIGH10PROFILE = 4, + H264PROFILE_HIGH422PROFILE = 5, + H264PROFILE_HIGH444PREDICTIVEPROFILE = 6, + H264PROFILE_SCALABLEBASELINE = 7, + H264PROFILE_SCALABLEHIGH = 8, + H264PROFILE_STEREOHIGH = 9, + H264PROFILE_MULTIVIEWHIGH = 10, + H264PROFILE_MAX = H264PROFILE_MULTIVIEWHIGH, + VP8PROFILE_MIN = 11, + VP8PROFILE_ANY = VP8PROFILE_MIN, + VP8PROFILE_MAX = VP8PROFILE_ANY, + VP9PROFILE_MIN = 12, + VP9PROFILE_PROFILE0 = VP9PROFILE_MIN, + VP9PROFILE_PROFILE1 = 13, + VP9PROFILE_PROFILE2 = 14, + VP9PROFILE_PROFILE3 = 15, + VP9PROFILE_MAX = VP9PROFILE_PROFILE3, + HEVCPROFILE_MIN = 16, + HEVCPROFILE_MAIN = HEVCPROFILE_MIN, + HEVCPROFILE_MAIN10 = 17, + HEVCPROFILE_MAIN_STILL_PICTURE = 18, + HEVCPROFILE_MAX = HEVCPROFILE_MAIN_STILL_PICTURE, + DOLBYVISION_PROFILE0 = 19, + // Deprecated: DOLBYVISION_PROFILE4 = 20, + DOLBYVISION_PROFILE5 = 21, + DOLBYVISION_PROFILE7 = 22, + THEORAPROFILE_MIN = 23, + THEORAPROFILE_ANY = THEORAPROFILE_MIN, + THEORAPROFILE_MAX = THEORAPROFILE_ANY, + AV1PROFILE_MIN = 24, + AV1PROFILE_PROFILE_MAIN = AV1PROFILE_MIN, + AV1PROFILE_PROFILE_HIGH = 25, + AV1PROFILE_PROFILE_PRO = 26, + AV1PROFILE_MAX = AV1PROFILE_PROFILE_PRO, + DOLBYVISION_PROFILE8 = 27, + DOLBYVISION_PROFILE9 = 28, + HEVCPROFILE_EXT_MIN = 29, + HEVCPROFILE_REXT = HEVCPROFILE_EXT_MIN, + HEVCPROFILE_HIGH_THROUGHPUT = 30, + HEVCPROFILE_MULTIVIEW_MAIN = 31, + HEVCPROFILE_SCALABLE_MAIN = 32, + HEVCPROFILE_3D_MAIN = 33, + HEVCPROFILE_SCREEN_EXTENDED = 34, + HEVCPROFILE_SCALABLE_REXT = 35, + HEVCPROFILE_HIGH_THROUGHPUT_SCREEN_EXTENDED = 36, + HEVCPROFILE_EXT_MAX = HEVCPROFILE_HIGH_THROUGHPUT_SCREEN_EXTENDED, + VVCPROFILE_MIN = 37, + VVCPROFILE_MAIN10 = VVCPROFILE_MIN, + VVCPROFILE_MAIN12 = 38, + VVCPROFILE_MAIN12_INTRA = 39, + VVCPROIFLE_MULTILAYER_MAIN10 = 40, + VVCPROFILE_MAIN10_444 = 41, + VVCPROFILE_MAIN12_444 = 42, + VVCPROFILE_MAIN16_444 = 43, + VVCPROFILE_MAIN12_444_INTRA = 44, + VVCPROFILE_MAIN16_444_INTRA = 45, + VVCPROFILE_MULTILAYER_MAIN10_444 = 46, + VVCPROFILE_MAIN10_STILL_PICTURE = 47, + VVCPROFILE_MAIN12_STILL_PICTURE = 48, + VVCPROFILE_MAIN10_444_STILL_PICTURE = 49, + VVCPROFILE_MAIN12_444_STILL_PICTURE = 50, + VVCPROFILE_MAIN16_444_STILL_PICTURE = 51, + VVCPROFILE_MAX = VVCPROFILE_MAIN16_444_STILL_PICTURE, + VIDEO_CODEC_PROFILE_MAX = VVCPROFILE_MAIN16_444_STILL_PICTURE, +}; + +using VideoCodecLevel = uint32_t; +constexpr VideoCodecLevel kNoVideoCodecLevel = 0; + +struct CodecProfileLevel { + VideoCodec codec; + VideoCodecProfile profile; + VideoCodecLevel level; +}; + +// Returns a name for `codec` for logging and display purposes. +MEDIA_EXPORT std::string GetCodecName(VideoCodec codec); + +// Returns a name for `codec` to be used for UMA reporting. +MEDIA_EXPORT std::string GetCodecNameForUMA(VideoCodec codec); + +MEDIA_EXPORT std::string GetProfileName(VideoCodecProfile profile); + +MEDIA_EXPORT std::string BuildH264MimeSuffix(VideoCodecProfile profile, + uint8_t level); + +MEDIA_EXPORT VideoCodec +VideoCodecProfileToVideoCodec(VideoCodecProfile profile); + +MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, + const VideoCodec& codec); + +} // namespace media + +#endif // MEDIA_BASE_VIDEO_CODECS_H_ diff --git a/tools/under-control/src/services/network/network_context.cc b/tools/under-control/src/services/network/network_context.cc new file mode 100755 index 000000000..5c20e5b79 --- /dev/null +++ b/tools/under-control/src/services/network/network_context.cc @@ -0,0 +1,3261 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "services/network/network_context.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "base/barrier_closure.h" +#include "base/base64.h" +#include "base/build_time.h" +#include "base/callback_list.h" +#include "base/check.h" +#include "base/command_line.h" +#include "base/containers/unique_ptr_adapters.h" +#include "base/dcheck_is_on.h" +#include "base/feature_list.h" +#include "base/functional/bind.h" +#include "base/functional/callback_helpers.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "base/metrics/histogram_functions.h" +#include "base/not_fatal_until.h" +#include "base/ranges/algorithm.h" +#include "base/sequence_checker.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "base/task/current_thread.h" +#include "base/task/sequenced_task_runner.h" +#include "base/task/single_thread_task_runner.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool.h" +#include "base/time/time.h" +#include "base/types/optional_util.h" +#include "build/build_config.h" +#include "build/chromecast_buildflags.h" +#include "build/chromeos_buildflags.h" +#include "components/cookie_config/cookie_store_util.h" +#include "components/domain_reliability/features.h" +#include "components/domain_reliability/monitor.h" +#include "components/network_session_configurator/browser/network_session_configurator.h" +#include "components/network_session_configurator/common/network_switches.h" +#include "components/os_crypt/async/common/encryptor.h" +#include "components/prefs/json_pref_store.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/pref_service_factory.h" +#include "components/url_matcher/url_matcher.h" +#include "components/url_matcher/url_util.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "net/base/features.h" +#include "net/base/isolation_info.h" +#include "net/base/load_flags.h" +#include "net/base/net_errors.h" +#include "net/base/network_anonymization_key.h" +#include "net/base/network_delegate.h" +#include "net/base/network_isolation_key.h" +#include "net/base/port_util.h" +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" +#include "net/cert/caching_cert_verifier.h" +#include "net/cert/cert_verifier.h" +#include "net/cert/coalescing_cert_verifier.h" +#include "net/cookies/cookie_access_delegate.h" +#include "net/cookies/cookie_constants.h" +#include "net/cookies/cookie_monster.h" +#include "net/cookies/cookie_setting_override.h" +#include "net/dns/host_cache.h" +#include "net/dns/mapped_host_resolver.h" +#include "net/extras/sqlite/cookie_crypto_delegate.h" +#include "net/extras/sqlite/sqlite_persistent_cookie_store.h" +#include "net/first_party_sets/first_party_set_metadata.h" +#include "net/http/http_auth.h" +#include "net/http/http_auth_handler_factory.h" +#include "net/http/http_auth_preferences.h" +#include "net/http/http_auth_scheme.h" +#include "net/http/http_cache.h" +#include "net/http/http_network_session.h" +#include "net/http/http_request_headers.h" +#include "net/http/http_server_properties.h" +#include "net/http/http_transaction_factory.h" +#include "net/net_buildflags.h" +#include "net/proxy_resolution/configured_proxy_resolution_service.h" +#include "net/proxy_resolution/proxy_config.h" +#include "net/shared_dictionary/shared_dictionary_isolation_key.h" +#include "net/storage_access_api/status.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "net/url_request/static_http_user_agent_settings.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_builder.h" +#include "services/network/brokered_client_socket_factory.h" +#include "services/network/cookie_manager.h" +#include "services/network/data_remover_util.h" +#include "services/network/disk_cache/mojo_backend_file_operations_factory.h" +#include "services/network/host_resolver.h" +#include "services/network/http_auth_cache_copier.h" +#include "services/network/http_server_properties_pref_delegate.h" +#include "services/network/ignore_errors_cert_verifier.h" +#include "services/network/ip_protection/ip_protection_config_cache_impl.h" +#include "services/network/ip_protection/ip_protection_proxy_delegate.h" +#include "services/network/ip_protection/ip_protection_token_cache_manager_impl.h" +#include "services/network/is_browser_initiated.h" +#include "services/network/net_log_exporter.h" +#include "services/network/network_service.h" +#include "services/network/network_service_network_delegate.h" +#include "services/network/network_service_proxy_delegate.h" +#include "services/network/oblivious_http_request_handler.h" +#include "services/network/prefetch_cache.h" +#include "services/network/prefetch_matching_url_loader_factory.h" +#include "services/network/prefetch_url_loader_client.h" +#include "services/network/proxy_config_service_mojo.h" +#include "services/network/proxy_lookup_request.h" +#include "services/network/proxy_resolving_socket_factory_mojo.h" +#include "services/network/public/cpp/cert_verifier/mojo_cert_verifier.h" +#include "services/network/public/cpp/content_security_policy/content_security_policy.h" +#include "services/network/public/cpp/features.h" +#include "services/network/public/cpp/network_switches.h" +#include "services/network/public/cpp/parsed_headers.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/public/cpp/simple_host_resolver.h" +#include "services/network/public/mojom/clear_data_filter.mojom.h" +#include "services/network/public/mojom/cookie_encryption_provider.mojom.h" +#include "services/network/public/mojom/network_context.mojom.h" +#include "services/network/public/mojom/reporting_service.mojom.h" +#include "services/network/public/mojom/trust_tokens.mojom-forward.h" +#include "services/network/public/mojom/url_loader_factory.mojom.h" +#include "services/network/resolve_host_request.h" +#include "services/network/resource_scheduler/resource_scheduler_client.h" +#include "services/network/restricted_cookie_manager.h" +#include "services/network/session_cleanup_cookie_store.h" +#include "services/network/shared_dictionary/shared_dictionary_constants.h" +#include "services/network/shared_dictionary/shared_dictionary_manager.h" +#include "services/network/shared_dictionary/shared_dictionary_storage.h" +#include "services/network/ssl_config_service_mojo.h" +#include "services/network/throttling/network_conditions.h" +#include "services/network/throttling/throttling_controller.h" +#include "services/network/throttling/throttling_network_transaction_factory.h" +#include "services/network/trust_tokens/expiry_inspecting_record_expiry_delegate.h" +#include "services/network/trust_tokens/in_memory_trust_token_persister.h" +#include "services/network/trust_tokens/pending_trust_token_store.h" +#include "services/network/trust_tokens/sqlite_trust_token_persister.h" +#include "services/network/trust_tokens/suitable_trust_token_origin.h" +#include "services/network/trust_tokens/trust_token_parameterization.h" +#include "services/network/trust_tokens/trust_token_query_answerer.h" +#include "services/network/trust_tokens/trust_token_store.h" +#include "services/network/url_loader.h" +#include "services/network/url_request_context_builder_mojo.h" +#include "services/network/web_transport.h" +#include "url/gurl.h" + +#if BUILDFLAG(IS_CT_SUPPORTED) +// gn check does not account for BUILDFLAG(). So, for iOS builds, it will +// complain about a missing dependency on the target exposing this header. Add a +// nogncheck to stop it from yelling. +#include "components/certificate_transparency/chrome_require_ct_delegate.h" // nogncheck +#include "services/network/sct_auditing/sct_auditing_cache.h" +#include "services/network/sct_auditing/sct_auditing_handler.h" +#endif // BUILDFLAG(IS_CT_SUPPORTED) + +#if BUILDFLAG(IS_CHROMEOS) +#include "services/network/cert_verifier_with_trust_anchors.h" +#endif // BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(ENABLE_WEBSOCKETS) +#include "services/network/websocket_factory.h" +#endif // BUILDFLAG(ENABLE_WEBSOCKETS) + +#if BUILDFLAG(ENABLE_REPORTING) +#include "net/base/http_user_agent_settings.h" +#include "net/extras/sqlite/sqlite_persistent_reporting_and_nel_store.h" +#include "net/network_error_logging/network_error_logging_service.h" +#include "net/reporting/reporting_browsing_data_remover.h" +#include "net/reporting/reporting_policy.h" +#include "net/reporting/reporting_service.h" +#endif // BUILDFLAG(ENABLE_REPORTING) + +#if BUILDFLAG(ENABLE_MDNS) +#include "services/network/mdns_responder.h" +#endif // BUILDFLAG(ENABLE_MDNS) + +#if BUILDFLAG(IS_P2P_ENABLED) +#include "services/network/p2p/socket_manager.h" +#endif // BUILDFLAG(IS_P2P_ENABLED) + +#if BUILDFLAG(IS_ANDROID) +#include "base/android/application_status_listener.h" +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) +#include "net/device_bound_sessions/session_service.h" +#endif // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) + +namespace network { + +namespace { + +net::CertVerifier* g_cert_verifier_for_testing = nullptr; + +// A CertVerifier that forwards all requests to |g_cert_verifier_for_testing|. +// This is used to allow NetworkContexts to have their own +// std::unique_ptr while forwarding calls to the shared +// verifier. +class WrappedTestingCertVerifier : public net::CertVerifier { + public: + ~WrappedTestingCertVerifier() override = default; + + // CertVerifier implementation + int Verify(const RequestParams& params, + net::CertVerifyResult* verify_result, + net::CompletionOnceCallback callback, + std::unique_ptr* out_req, + const net::NetLogWithSource& net_log) override { + verify_result->Reset(); + if (!g_cert_verifier_for_testing) + return net::ERR_FAILED; + return g_cert_verifier_for_testing->Verify( + params, verify_result, std::move(callback), out_req, net_log); + } + void SetConfig(const Config& config) override { + if (!g_cert_verifier_for_testing) + return; + g_cert_verifier_for_testing->SetConfig(config); + } + void AddObserver(Observer* observer) override { + if (!g_cert_verifier_for_testing) { + return; + } + g_cert_verifier_for_testing->AddObserver(observer); + } + void RemoveObserver(Observer* observer) override { + if (!g_cert_verifier_for_testing) { + return; + } + g_cert_verifier_for_testing->RemoveObserver(observer); + } +}; + +// This implementation initializes an OSCryptAsync Encryptor instance and uses +// that. +class CookieOSCryptAsyncDelegate : public net::CookieCryptoDelegate { + public: + explicit CookieOSCryptAsyncDelegate( + mojo::PendingRemote provider); + + CookieOSCryptAsyncDelegate(const CookieOSCryptAsyncDelegate&) = delete; + CookieOSCryptAsyncDelegate& operator=(const CookieOSCryptAsyncDelegate&) = + delete; + + void Init(base::OnceClosure callback) override; + bool EncryptString(const std::string& plaintext, + std::string* ciphertext) override; + bool DecryptString(const std::string& ciphertext, + std::string* plaintext) override; + + private: + void InitCallback( + mojo::Remote lifetime, + os_crypt_async::Encryptor encryptor); + + std::optional instance_; + mojo::PendingRemote provider_ + GUARDED_BY_CONTEXT(sequence_checker_); + base::OnceClosureList callbacks_ GUARDED_BY_CONTEXT(sequence_checker_); + bool is_initializing_ GUARDED_BY_CONTEXT(sequence_checker_) = false; + bool is_initialized_ GUARDED_BY_CONTEXT(sequence_checker_) = false; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory weak_ptr_factory_{this}; +}; + +CookieOSCryptAsyncDelegate::CookieOSCryptAsyncDelegate( + mojo::PendingRemote provider) + : provider_(std::move(provider)) { + DETACH_FROM_SEQUENCE(sequence_checker_); +} + +bool CookieOSCryptAsyncDelegate::EncryptString(const std::string& plaintext, + std::string* ciphertext) { + return instance_->EncryptString(plaintext, ciphertext); +} + +bool CookieOSCryptAsyncDelegate::DecryptString(const std::string& ciphertext, + std::string* plaintext) { + return instance_->DecryptString(ciphertext, plaintext); +} + +void CookieOSCryptAsyncDelegate::InitCallback( + mojo::Remote lifetime, + os_crypt_async::Encryptor encryptor) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + instance_.emplace(std::move(encryptor)); + is_initialized_ = true; + callbacks_.Notify(); +} + +void CookieOSCryptAsyncDelegate::Init(base::OnceClosure callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (is_initialized_) { + std::move(callback).Run(); + return; + } + + // AddUnsafe is safe here because it's always called with a callback that is + // owned by a refcounted object. See SQLitePersistentCookieStore::Backend. + callbacks_.AddUnsafe(std::move(callback)); + + if (is_initializing_) { + return; + } + + is_initializing_ = true; + mojo::Remote remote( + std::move(provider_)); + auto* raw_remote = remote.get(); + raw_remote->GetEncryptor( + base::BindOnce(&CookieOSCryptAsyncDelegate::InitCallback, + weak_ptr_factory_.GetWeakPtr(), std::move(remote))); +} + +// Predicate function to determine if the given |domain| matches the +// |filter_type| and |filter_domains| from a |mojom::ClearDataFilter|. +bool MatchesDomainFilter(mojom::ClearDataFilter_Type filter_type, + std::set filter_domains, + const std::string& domain) { + bool found_domain = filter_domains.find(domain) != filter_domains.end(); + return (filter_type == mojom::ClearDataFilter_Type::DELETE_MATCHES) == + found_domain; +} + +// Returns a callback that checks if a domain matches the |filter|. |filter| +// must contain no origins. A null filter matches everything. +base::RepeatingCallback MakeDomainFilter( + mojom::ClearDataFilter* filter) { + if (!filter) + return base::BindRepeating([](const std::string&) { return true; }); + + DCHECK(filter->origins.empty()) + << "Origin filtering not allowed in a domain-only filter"; + + std::set filter_domains; + filter_domains.insert(filter->domains.begin(), filter->domains.end()); + return base::BindRepeating(&MatchesDomainFilter, filter->type, + std::move(filter_domains)); +} + +// Predicate function to determine if the given |origin| matches the +// |filter_type|, |filter_domains| and |filter_origins| from a +// |mojom::ClearDataFilter|. +bool MatchesOriginFilter(mojom::ClearDataFilter_Type filter_type, + std::set filter_domains, + std::set filter_origins, + const url::Origin& origin) { + std::string url_registrable_domain = + net::registry_controlled_domains::GetDomainAndRegistry( + origin, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); + bool found_domain = + (filter_domains.find(url_registrable_domain != "" + ? url_registrable_domain + : origin.host()) != filter_domains.end()); + + bool found_origin = (filter_origins.find(origin) != filter_origins.end()); + + return (filter_type == mojom::ClearDataFilter_Type::DELETE_MATCHES) == + (found_domain || found_origin); +} + +// Builds a generic Origin-matching predicate function based on |filter|. If +// |filter| is null, creates an always-true predicate. +base::RepeatingCallback BuildOriginFilter( + mojom::ClearDataFilterPtr filter) { + if (!filter) { + return base::BindRepeating([](const url::Origin&) { return true; }); + } + + std::set filter_domains; + filter_domains.insert(filter->domains.begin(), filter->domains.end()); + + std::set filter_origins; + filter_origins.insert(filter->origins.begin(), filter->origins.end()); + + return base::BindRepeating(&MatchesOriginFilter, filter->type, + std::move(filter_domains), + std::move(filter_origins)); +} + +// Builds a generic URL-matching predicate function based on |filter|. +// If |filter| is null, creates an always-true predicate. +base::RepeatingCallback BuildUrlFilter( + mojom::ClearDataFilterPtr filter) { + return filter ? base::BindRepeating( + &DoesUrlMatchFilter, filter->type, + std::set(filter->origins.begin(), + filter->origins.end()), + std::set(filter->domains.begin(), + filter->domains.end())) + : base::NullCallback(); +} + +#if BUILDFLAG(IS_ANDROID) +class NetworkContextApplicationStatusListener + : public base::android::ApplicationStatusListener { + public: + // Sets `get_callback` to be a callback that returns nullptr if the created + // NetworkContextApplicationStatusListener has been destroyed, and the + // listener itself, otherwise. It's a constructor argument to avoid needing + // a cast, moving this into the header, or other complexities around + // `app_status_listeners_` being a vector of the parent class. + explicit NetworkContextApplicationStatusListener( + disk_cache::ApplicationStatusListenerGetter& get_callback) { + get_callback = + base::BindRepeating(&NetworkContextApplicationStatusListener:: + ReturnAppStatusListenerIfAlive, + weak_ptr_factory_.GetWeakPtr()); + } + + // base::android::ApplicationStatusListener implementation: + void SetCallback(const ApplicationStateChangeCallback& callback) override { + DCHECK(!callback_); + DCHECK(callback); + callback_ = callback; + } + + void Notify(base::android::ApplicationState state) override { + if (callback_) + callback_.Run(state); + } + + private: + static base::android::ApplicationStatusListener* + ReturnAppStatusListenerIfAlive( + base::WeakPtr listener) { + return listener.get(); + } + + ApplicationStateChangeCallback callback_; + base::WeakPtrFactory + weak_ptr_factory_{this}; +}; + +#endif // BUILDFLAG(IS_ANDROID) + +struct TestVerifyCertState { + net::CertVerifyResult result; + std::unique_ptr request; +}; + +void TestVerifyCertCallback( + std::unique_ptr request, + NetworkContext::VerifyCertificateForTestingCallback callback, + int result) { + std::move(callback).Run(result); +} + +std::string HashesToBase64String(const net::HashValueVector& hashes) { + std::vector strings; + strings.reserve(hashes.size()); + for (const auto& hash : hashes) { + strings.push_back(hash.ToString()); + } + return base::JoinString(strings, ","); +} + +#if BUILDFLAG(IS_CT_SUPPORTED) +// SCTAuditingDelegate is an implementation of the delegate interface that is +// aware of per-NetworkContext details (to allow the cache to notify the +// associated NetworkContextClient of new reports, and to apply +// per-NetworkContext enabled/disabled status for the auditing feature). +class SCTAuditingDelegate : public net::SCTAuditingDelegate { + public: + explicit SCTAuditingDelegate(const base::WeakPtr& context); + ~SCTAuditingDelegate() override; + + // net::SCTAuditingDelegate: + void MaybeEnqueueReport( + const net::HostPortPair& host_port_pair, + const net::X509Certificate* validated_certificate_chain, + const net::SignedCertificateTimestampAndStatusList& + signed_certificate_timestamps) override; + + private: + base::WeakPtr context_; +}; + +SCTAuditingDelegate::SCTAuditingDelegate( + const base::WeakPtr& context) + : context_(context) {} + +SCTAuditingDelegate::~SCTAuditingDelegate() = default; + +void SCTAuditingDelegate::MaybeEnqueueReport( + const net::HostPortPair& host_port_pair, + const net::X509Certificate* validated_certificate_chain, + const net::SignedCertificateTimestampAndStatusList& + signed_certificate_timestamps) { + if (!context_) + return; + context_->MaybeEnqueueSCTReport(host_port_pair, validated_certificate_chain, + signed_certificate_timestamps); +} +#endif // BUILDFLAG(IS_CT_SUPPORTED) + +// Obtains a full data file path from a NetworkContextFilePaths, a class member +// pointer to the data file. If valid, then returns true and places the full +// path into `full_path` otherwise returns false. +bool GetFullDataFilePath( + const mojom::NetworkContextFilePathsPtr& file_paths, + std::optional network::mojom::NetworkContextFilePaths::* + field_name, + base::FilePath& full_path) { + if (!file_paths) + return false; + + std::optional relative_file_path = + file_paths.get()->*field_name; + if (!relative_file_path.has_value()) + return false; + + // Path to a data file should always be a plain filename. + DCHECK_EQ(relative_file_path->BaseName(), *relative_file_path); + + full_path = + file_paths->data_directory.path().Append(relative_file_path->value()); + return true; +} + +// Produces URLLoaderFactoryParams suitable for a prefetch. Generally this +// should match the params that are used for subresource fetches to render +// processes. +mojom::URLLoaderFactoryParamsPtr CreateURLLoaderFactoryParamsForPrefetch() { + auto params = mojom::URLLoaderFactoryParams::New(); + params->process_id = mojom::kBrowserProcessId; + // We want to be able to use TrustedParams to set the IsolationInfo for each + // prefetch separately, so make it trusted. + // TODO(crbug.com/342445996): Maybe stop using TrustedParams and lock this + // down? + params->is_trusted = true; + + // This can be set to true by the content::switches::kDisableWebSecurity + // switch, but that's not available in the network service. The consequences + // of this being disabled should just be that prefetches fail where this flag + // would have taken effect. + // TODO(crbug.com/342445996): Pass this through from the caller. + // + // Android WebView also disables web security when the + // `allow_universal_access_from_file_urls` flag is set, however, WebView + // doesn't currently support prefetch anyway. + params->disable_web_security = false; + + // TODO(crbug.com/342445996): Find out if we need to set anything here. + params->client_security_state = mojom::ClientSecurityState::New(); + + // TODO(crbug.com/342445996): params->coep_reporter + + // --disable-web-security also disables Opaque Response Blocking (ORB). + params->is_orb_enabled = !params->disable_web_security; + + // TODO(crbug.com/342445996): trust_token_issuance_policy, + // trust_token_redemption_policy + + // TODO(crbug.com/342445996): Add observers as needed for DevTools support, + // etc. + + // TODO(crbug.com/342445996): params->cookie_setting_overrides + + params->debug_tag = "CreateURLLoaderFactoryParamsForPrefetch"; + + // TODO(crbug.com/342445996): params->require_cross_site_requests_for_cookies + + return params; +} + +} // namespace + +constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess; + +NetworkContext::NetworkContextHttpAuthPreferences:: + NetworkContextHttpAuthPreferences(NetworkService* network_service) + : network_service_(network_service) {} + +NetworkContext::NetworkContextHttpAuthPreferences:: + ~NetworkContextHttpAuthPreferences() = default; + +#if BUILDFLAG(IS_LINUX) +bool NetworkContext::NetworkContextHttpAuthPreferences::AllowGssapiLibraryLoad() + const { + if (network_service_) { + network_service_->OnBeforeGssapiLibraryLoad(); + } + return net::HttpAuthPreferences::AllowGssapiLibraryLoad(); +} +#endif // BUILDFLAG(IS_LINUX) + +NetworkContext::PendingCertVerify::PendingCertVerify() = default; +NetworkContext::PendingCertVerify::~PendingCertVerify() = default; + +NetworkContext::NetworkContext( + NetworkService* network_service, + mojo::PendingReceiver receiver, + mojom::NetworkContextParamsPtr params, + OnConnectionCloseCallback on_connection_close_callback) + : NetworkContext(base::PassKey(), + network_service, + std::move(receiver), + std::move(params), + std::move(on_connection_close_callback), + OnURLRequestContextBuilderConfiguredCallback()) {} + +// net::NetworkDelegate that wraps +NetworkContext::NetworkContext( + base::PassKey pass_key, + NetworkService* network_service, + mojo::PendingReceiver receiver, + mojom::NetworkContextParamsPtr params, + OnConnectionCloseCallback on_connection_close_callback, + OnURLRequestContextBuilderConfiguredCallback + on_url_request_context_builder_configured) + : network_service_(network_service), + url_request_context_(nullptr), +#if BUILDFLAG(ENABLE_REPORTING) + is_observing_reporting_service_(false), +#endif // BUILDFLAG(ENABLE_REPORTING) + params_(std::move(params)), + on_connection_close_callback_(std::move(on_connection_close_callback)), + receiver_(this, std::move(receiver)), + first_party_sets_access_delegate_( + std::move(params_->first_party_sets_access_delegate_receiver), + std::move(params_->first_party_sets_access_delegate_params), + network_service_->first_party_sets_manager()), + cors_preflight_controller_(network_service), + http_auth_merged_preferences_(network_service), + ohttp_handler_(this), + prefetch_enabled_( + base::FeatureList::IsEnabled(features::kNetworkContextPrefetch)), + cors_non_wildcard_request_headers_support_(base::FeatureList::IsEnabled( + features::kCorsNonWildcardRequestHeadersSupport)), + prefetch_cache_(prefetch_enabled_ ? std::make_unique() + : nullptr) { +#if BUILDFLAG(IS_WIN) && DCHECK_IS_ON() + if (params_->file_paths) { + DCHECK(params_->win_permissions_set) + << "Permissions not set on files. Network context should be created " + "using CreateNetworkContextInNetworkService rather than directly on " + "the network service."; + } +#endif // BUILDFLAG(IS_WIN) && DCHECK_IS_ON() + +#if BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED) + if (params_->file_paths) { + if (params_->file_paths->http_cache_directory) { + EnsureMounted(&*params_->file_paths->http_cache_directory); + } + if (params_->file_paths->shared_dictionary_directory) { + EnsureMounted(&*params_->file_paths->shared_dictionary_directory); + } + EnsureMounted(¶ms_->file_paths->data_directory); + } +#endif // BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED) + + if (params_->shared_dictionary_enabled) { + if (params_->file_paths && + params_->file_paths->shared_dictionary_directory && + !params_->file_paths->shared_dictionary_directory->path().empty()) { +#if BUILDFLAG(IS_ANDROID) + disk_cache::ApplicationStatusListenerGetter get_callback; + app_status_listeners_.push_back( + std::make_unique( + get_callback)); +#endif // BUILDFLAG(IS_ANDROID) + // TODO(crbug.com/40255884): Set `file_operations_factory` to support + // sandboxed network service on Android. + shared_dictionary_manager_ = SharedDictionaryManager::CreateOnDisk( + params_->file_paths->shared_dictionary_directory->path().Append( + FILE_PATH_LITERAL("db")), + params_->file_paths->shared_dictionary_directory->path().Append( + FILE_PATH_LITERAL("cache")), + params_->shared_dictionary_cache_max_size, + shared_dictionary::kDictionaryMaxCountPerNetworkContext, +#if BUILDFLAG(IS_ANDROID) + std::move(get_callback), +#endif // BUILDFLAG(IS_ANDROID) + /*file_operations_factory=*/nullptr); + } else { + shared_dictionary_manager_ = SharedDictionaryManager::CreateInMemory( + params_->shared_dictionary_cache_max_size, + shared_dictionary::kDictionaryMaxCountPerNetworkContext); + } + } + + mojo::PendingRemote + url_loader_factory_for_cert_net_fetcher; + mojo::PendingReceiver + url_loader_factory_for_cert_net_fetcher_receiver = + url_loader_factory_for_cert_net_fetcher + .InitWithNewPipeAndPassReceiver(); + + scoped_refptr session_cleanup_cookie_store = + MakeSessionCleanupCookieStore(); + + url_request_context_owner_ = MakeURLRequestContext( + std::move(url_loader_factory_for_cert_net_fetcher), + session_cleanup_cookie_store, + std::move(on_url_request_context_builder_configured), + params_->bound_network); + url_request_context_ = url_request_context_owner_.url_request_context.get(); + + cookie_manager_ = std::make_unique( + url_request_context_, &first_party_sets_access_delegate_, + std::move(session_cleanup_cookie_store), + std::move(params_->cookie_manager_params), + network_service_->tpcd_metadata_manager()); + + cookie_manager_->AddSettingsWillChangeCallback( + base::BindRepeating(&NetworkContext::OnCookieManagerSettingsChanged, + weak_factory_.GetWeakPtr())); + + network_service_->RegisterNetworkContext(this); + + // Only register for destruction if |this| will be wholly lifetime-managed + // by the NetworkService. In the other constructors, lifetime is shared with + // other consumers, and thus self-deletion is not safe and can result in + // double-frees. + receiver_.set_disconnect_handler(base::BindOnce( + &NetworkContext::OnConnectionError, base::Unretained(this))); + + socket_factory_ = std::make_unique( + url_request_context_->net_log(), url_request_context_); +#if BUILDFLAG(IS_WIN) + if (params_->socket_brokers) { + socket_factory_->BindSocketBroker( + std::move(params_->socket_brokers->server)); + } +#endif + resource_scheduler_ = std::make_unique(); + + if (params_->http_auth_static_network_context_params) { + http_auth_merged_preferences_.SetAllowDefaultCredentials( + params_->http_auth_static_network_context_params + ->allow_default_credentials); + } + + InitializeCorsParams(); + + SetSplitAuthCacheByNetworkAnonymizationKey( + params_->split_auth_cache_by_network_anonymization_key); + +#if BUILDFLAG(IS_CT_SUPPORTED) + if (params_->ct_policy) + SetCTPolicy(std::move(params_->ct_policy)); + + base::FilePath sct_auditing_path; + GetFullDataFilePath(params_->file_paths, + &network::mojom::NetworkContextFilePaths:: + sct_auditing_pending_reports_file_name, + sct_auditing_path); + sct_auditing_handler_ = + std::make_unique(this, sct_auditing_path); + sct_auditing_handler()->SetMode(params_->sct_auditing_mode); +#endif // BUILDFLAG(IS_CT_SUPPORTED) + +#if BUILDFLAG(IS_ANDROID) + if (params_->cookie_manager) + GetCookieManager(std::move(params_->cookie_manager)); +#endif // BUILDFLAG(IS_ANDROID) + + CreateURLLoaderFactoryForCertNetFetcher( + std::move(url_loader_factory_for_cert_net_fetcher_receiver)); + + SetBlockTrustTokens(params_->block_trust_tokens); + + if (params_ && params_->http_cache_file_operations_factory) { + http_cache_file_operations_factory_ = + base::MakeRefCounted( + std::move(params_->http_cache_file_operations_factory)); + } + + if (prefetch_enabled_) { + InitializePrefetchURLLoaderFactory(); + } +} + +NetworkContext::NetworkContext( + NetworkService* network_service, + mojo::PendingReceiver receiver, + net::URLRequestContext* url_request_context, + const std::vector& cors_exempt_header_list) + : network_service_(network_service), + url_request_context_(url_request_context), +#if BUILDFLAG(ENABLE_REPORTING) + is_observing_reporting_service_(false), +#endif // BUILDFLAG(ENABLE_REPORTING) + receiver_(this, std::move(receiver)), + first_party_sets_access_delegate_( + /*receiver=*/mojo::NullReceiver(), + /*params=*/nullptr, + /*manager=*/nullptr), + cookie_manager_(std::make_unique( + url_request_context, + nullptr, + /*first_party_sets_access_delegate=*/nullptr, + /*params=*/nullptr, + /*tpcd_metadata_manager=*/nullptr)), + socket_factory_( + std::make_unique(url_request_context_->net_log(), + url_request_context)), + cors_preflight_controller_(network_service), + http_auth_merged_preferences_(network_service), + ohttp_handler_(this), + prefetch_enabled_( + base::FeatureList::IsEnabled(features::kNetworkContextPrefetch)), + prefetch_cache_(prefetch_enabled_ ? std::make_unique() + : nullptr) { + // May be nullptr in tests. + if (network_service_) + network_service_->RegisterNetworkContext(this); + resource_scheduler_ = std::make_unique(); + + for (const auto& key : cors_exempt_header_list) + cors_exempt_header_list_.insert(key); + + acam_preflight_spec_conformant_ = base::FeatureList::IsEnabled( + network::features:: + kAccessControlAllowMethodsInCORSPreflightSpecConformant); + + if (prefetch_enabled_) { + InitializePrefetchURLLoaderFactory(); + } +} + +NetworkContext::~NetworkContext() { + is_destructing_ = true; + + // May be nullptr in tests. + if (network_service_) { + network_service_->DeregisterNetworkContext(this); + } + + if (domain_reliability_monitor_) + domain_reliability_monitor_->Shutdown(); + // Because of the order of declaration in the class, + // domain_reliability_monitor_ will be destroyed before + // |url_loader_factories_| which could own URLLoader's whose destructor call + // back into this class and might use domain_reliability_monitor_. So we reset + // |domain_reliability_monitor_| here explicitly, instead of changing the + // order, because any work calling into |domain_reliability_monitor_| at + // shutdown would be unnecessary as the reports would be thrown out. + domain_reliability_monitor_.reset(); + + if (url_request_context_ && + url_request_context_->transport_security_state()) { +#if BUILDFLAG(IS_CT_SUPPORTED) + if (require_ct_delegate_) { + url_request_context_->transport_security_state()->SetRequireCTDelegate( + nullptr); + } +#endif // BUILDFLAG(IS_CT_SUPPORTED) + } + +#if BUILDFLAG(ENABLE_REPORTING) + if (is_observing_reporting_service_) { + DCHECK(url_request_context()); + // May be nullptr in tests. + if (url_request_context()->reporting_service()) { + url_request_context()->reporting_service()->RemoveReportingCacheObserver( + this); + } + } +#endif // BUILDFLAG(ENABLE_REPORTING) + +#if BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED) + if (!dismount_closures_.empty()) { + // Dismount all mounted directories after a generous delay, so that + // pending asynchronous IO tasks have a chance to complete before the + // directory is unmounted. + constexpr base::TimeDelta kDismountDelay = base::Minutes(5); + + for (auto& dismount_closure : dismount_closures_) { + std::ignore = base::ThreadPool::PostDelayedTask( + FROM_HERE, std::move(dismount_closure), kDismountDelay); + } + } +#endif // BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED) + + // Clear `url_loader_factories_` before deleting the contents, as it can + // result in re-entrant calls to DestroyURLLoaderFactory(). + std::set, + base::UniquePtrComparator> + url_loader_factories = std::move(url_loader_factories_); +} + +void NetworkContext::OnCookieManagerSettingsChanged() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + for (const std::unique_ptr& rcm : + restricted_cookie_managers_) { + rcm->OnCookieSettingsChanged(); + } +} + +// static +std::unique_ptr NetworkContext::CreateForTesting( + NetworkService* network_service, + mojo::PendingReceiver receiver, + mojom::NetworkContextParamsPtr params, + OnURLRequestContextBuilderConfiguredCallback + on_url_request_context_builder_configured) { + return std::make_unique( + base::PassKey(), network_service, std::move(receiver), + std::move(params), OnConnectionCloseCallback(), + std::move(on_url_request_context_builder_configured)); +} + +// static +void NetworkContext::SetCertVerifierForTesting( + net::CertVerifier* cert_verifier) { + g_cert_verifier_for_testing = cert_verifier; +} + +void NetworkContext::CreateURLLoaderFactory( + mojo::PendingReceiver receiver, + mojom::URLLoaderFactoryParamsPtr params, + scoped_refptr resource_scheduler_client) { + url_loader_factories_.emplace( + std::make_unique( + this, std::move(params), std::move(resource_scheduler_client), + std::move(receiver), &cors_origin_access_list_, + prefetch_cache_.get())); +} + +void NetworkContext::CreateURLLoaderFactoryForCertNetFetcher( + mojo::PendingReceiver factory_receiver) { + // TODO(crbug.com/40695068): investigate changing these params. + auto url_loader_factory_params = mojom::URLLoaderFactoryParams::New(); + url_loader_factory_params->is_trusted = true; + url_loader_factory_params->process_id = mojom::kBrowserProcessId; + url_loader_factory_params->automatically_assign_isolation_info = true; + url_loader_factory_params->is_orb_enabled = false; + CreateURLLoaderFactory(std::move(factory_receiver), + std::move(url_loader_factory_params)); +} + +void NetworkContext::ActivateDohProbes() { + DCHECK(url_request_context_->host_resolver()); + + doh_probes_request_.reset(); + doh_probes_request_ = + url_request_context_->host_resolver()->CreateDohProbeRequest(); + doh_probes_request_->Start(); +} + +void NetworkContext::SetClient( + mojo::PendingRemote client) { + client_.reset(); + client_.Bind(std::move(client)); +} + +void NetworkContext::CreateURLLoaderFactory( + mojo::PendingReceiver receiver, + mojom::URLLoaderFactoryParamsPtr params) { + scoped_refptr resource_scheduler_client = + base::MakeRefCounted( + ResourceScheduler::ClientId::Create(params->top_frame_id), + IsBrowserInitiated(params->process_id == mojom::kBrowserProcessId), + resource_scheduler_.get(), + url_request_context_->network_quality_estimator()); + CreateURLLoaderFactory(std::move(receiver), std::move(params), + std::move(resource_scheduler_client)); +} + +void NetworkContext::ResetURLLoaderFactories() { + // Move all factories to a temporary vector so ClearBindings() does not + // invalidate the iterator if the factory gets deleted. + std::vector factories; + factories.reserve(url_loader_factories_.size()); + for (const auto& factory : url_loader_factories_) + factories.push_back(factory.get()); + for (auto* factory : factories) + factory->ClearBindings(); +} + +void NetworkContext::GetViaObliviousHttp( + mojom::ObliviousHttpRequestPtr request, + mojo::PendingRemote client) { + ohttp_handler_.StartRequest(std::move(request), std::move(client)); +} + +void NetworkContext::GetCookieManager( + mojo::PendingReceiver receiver) { + cookie_manager_->AddReceiver(std::move(receiver)); +} + +void NetworkContext::GetRestrictedCookieManager( + mojo::PendingReceiver receiver, + mojom::RestrictedCookieManagerRole role, + const url::Origin& origin, + const net::IsolationInfo& isolation_info, + const net::CookieSettingOverrides& cookie_setting_overrides, + mojo::PendingRemote cookie_observer) { + RestrictedCookieManager::ComputeFirstPartySetMetadata( + origin, url_request_context_->cookie_store(), isolation_info, + base::BindOnce(&NetworkContext::OnComputedFirstPartySetMetadata, + weak_factory_.GetWeakPtr(), std::move(receiver), role, + origin, isolation_info, cookie_setting_overrides, + std::move(cookie_observer))); +} + +void NetworkContext::OnRCMDisconnect( + const network::RestrictedCookieManager* rcm) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto it = restricted_cookie_managers_.find(rcm); + CHECK(it != restricted_cookie_managers_.end(), base::NotFatalUntil::M130); + restricted_cookie_managers_.erase(it); +} + +void NetworkContext::OnComputedFirstPartySetMetadata( + mojo::PendingReceiver receiver, + mojom::RestrictedCookieManagerRole role, + const url::Origin& origin, + const net::IsolationInfo& isolation_info, + const net::CookieSettingOverrides& cookie_setting_overrides, + mojo::PendingRemote cookie_observer, + net::FirstPartySetMetadata first_party_set_metadata) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + std::unique_ptr ptr = + std::make_unique( + role, url_request_context_->cookie_store(), + cookie_manager_->cookie_settings(), origin, isolation_info, + cookie_setting_overrides, std::move(cookie_observer), + std::move(first_party_set_metadata), + network_service_->metrics_updater()); + + auto callback = base::BindOnce(&NetworkContext::OnRCMDisconnect, + base::Unretained(this), ptr.get()); + ptr->InstallReceiver(std::move(receiver), std::move(callback)); + restricted_cookie_managers_.insert(std::move(ptr)); +} + +void NetworkContext::GetTrustTokenQueryAnswerer( + mojo::PendingReceiver receiver, + const url::Origin& top_frame_origin) { + // Only called when Trust Tokens is enabled, i.e. trust_token_store_ is + // non-null. + DCHECK(trust_token_store_); + DCHECK(network_service_); + + std::optional suitable_top_frame_origin = + SuitableTrustTokenOrigin::Create(top_frame_origin); + + const SynchronousTrustTokenKeyCommitmentGetter* const key_commitment_getter = + network_service_->trust_token_key_commitments(); + + // It's safe to dereference |suitable_top_frame_origin| here as, during the + // process of vending the TrustTokenQueryAnswerer, the browser ensures that + // the requesting context's top frame origin is suitable for Trust Tokens. + auto answerer = std::make_unique( + std::move(*suitable_top_frame_origin), trust_token_store_.get(), + key_commitment_getter); + + trust_token_query_answerers_.Add(std::move(answerer), std::move(receiver)); +} + +void NetworkContext::GetStoredTrustTokenCounts( + GetStoredTrustTokenCountsCallback callback) { + if (trust_token_store_) { + auto get_trust_token_counts_from_store = + [](NetworkContext::GetStoredTrustTokenCountsCallback callback, + TrustTokenStore* trust_token_store) { + std::vector result; + for (auto& issuer_count_pair : + trust_token_store->GetStoredTrustTokenCounts()) { + result.push_back(mojom::StoredTrustTokensForIssuer::New( + std::move(issuer_count_pair.first), issuer_count_pair.second)); + } + std::move(callback).Run(std::move(result)); + }; + trust_token_store_->ExecuteOrEnqueue( + base::BindOnce(get_trust_token_counts_from_store, std::move(callback))); + } else { + // The Trust Tokens feature is disabled, return immediately with an empty + // vector. + std::move(callback).Run({}); + } +} + +void NetworkContext::DeleteStoredTrustTokens( + const url::Origin& issuer, + DeleteStoredTrustTokensCallback callback) { + if (!trust_token_store_) { + std::move(callback).Run( + mojom::DeleteStoredTrustTokensStatus::kFailureFeatureDisabled); + return; + } + + std::optional suitable_issuer_origin = + SuitableTrustTokenOrigin::Create(issuer); + if (!suitable_issuer_origin) { + std::move(callback).Run( + mojom::DeleteStoredTrustTokensStatus::kFailureInvalidOrigin); + return; + } + + trust_token_store_->ExecuteOrEnqueue(base::BindOnce( + [](SuitableTrustTokenOrigin issuer, + DeleteStoredTrustTokensCallback callback, TrustTokenStore* store) { + const bool did_delete_tokens = store->DeleteStoredTrustTokens(issuer); + const auto status = + did_delete_tokens + ? mojom::DeleteStoredTrustTokensStatus::kSuccessTokensDeleted + : mojom::DeleteStoredTrustTokensStatus::kSuccessNoTokensDeleted; + std::move(callback).Run(status); + }, + std::move(*suitable_issuer_origin), std::move(callback))); +} + +void NetworkContext::SetBlockTrustTokens(bool block) { + block_trust_tokens_ = block; +} + +void NetworkContext::OnProxyLookupComplete( + ProxyLookupRequest* proxy_lookup_request) { + auto it = proxy_lookup_requests_.find(proxy_lookup_request); + CHECK(it != proxy_lookup_requests_.end(), base::NotFatalUntil::M130); + proxy_lookup_requests_.erase(it); +} + +void NetworkContext::DisableQuic() { + url_request_context_->http_transaction_factory()->GetSession()->DisableQuic(); +} + +void NetworkContext::DestroyURLLoaderFactory( + PrefetchMatchingURLLoaderFactory* url_loader_factory) { + if (is_destructing_) { + return; + } + auto it = url_loader_factories_.find(url_loader_factory); + CHECK(it != url_loader_factories_.end(), base::NotFatalUntil::M130); + url_loader_factories_.erase(it); +} + +void NetworkContext::Remove(WebTransport* transport) { + auto it = web_transports_.find(transport); + if (it != web_transports_.end()) { + web_transports_.erase(it); + } +} + +void NetworkContext::LoaderCreated(uint32_t process_id) { + loader_count_per_process_[process_id] += 1; +} + +void NetworkContext::LoaderDestroyed(uint32_t process_id) { + auto it = loader_count_per_process_.find(process_id); + CHECK(it != loader_count_per_process_.end(), base::NotFatalUntil::M130); + it->second -= 1; + if (it->second == 0) + loader_count_per_process_.erase(it); +} + +bool NetworkContext::CanCreateLoader(uint32_t process_id) { + auto it = loader_count_per_process_.find(process_id); + uint32_t count = (it == loader_count_per_process_.end() ? 0 : it->second); + return count < max_loaders_per_process_; +} + +size_t NetworkContext::GetNumOutstandingResolveHostRequestsForTesting() const { + size_t sum = 0; + if (internal_host_resolver_) + sum += internal_host_resolver_->GetNumOutstandingRequestsForTesting(); + for (const auto& host_resolver : host_resolvers_) + sum += host_resolver->GetNumOutstandingRequestsForTesting(); // IN-TEST + return sum; +} + +bool NetworkContext::SkipReportingPermissionCheck() const { +#if BUILDFLAG(ENABLE_REPORTING) + return params_ && params_->skip_reporting_send_permission_check; +#else + return false; +#endif // BUILDFLAG(ENABLE_REPORTING) +} + +void NetworkContext::ClearTrustTokenData(mojom::ClearDataFilterPtr filter, + base::OnceClosure done) { + if (!trust_token_store_) { + std::move(done).Run(); + return; + } + trust_token_store_->ExecuteOrEnqueue(base::BindOnce( + [](mojom::ClearDataFilterPtr filter, base::OnceClosure done, + TrustTokenStore* store) { + std::ignore = store->ClearDataForFilter(std::move(filter)); + std::move(done).Run(); + }, + std::move(filter), std::move(done))); +} + +void NetworkContext::ClearTrustTokenSessionOnlyData( + ClearTrustTokenSessionOnlyDataCallback callback) { + // Only called when Private State Tokens is enabled, i.e., + // `trust_token_store_` is non-null. + DCHECK(trust_token_store_); + DCHECK(cookie_manager_); + + DeleteCookiePredicate cookie_predicate = + cookie_manager_->cookie_settings().CreateDeleteCookieOnExitPredicate(); + + auto store_predicate = base::BindRepeating( + [](DeleteCookiePredicate predicate, const std::string& origin) { + return predicate.Run(origin, net::CookieSourceScheme::kSecure); + }, + std::move(cookie_predicate)); + trust_token_store_->ExecuteOrEnqueue(base::BindOnce( + [](base::RepeatingCallback pred, + ClearTrustTokenSessionOnlyDataCallback cb, TrustTokenStore* store) { + bool any_data_deleted = store->ClearDataForPredicate(std::move(pred)); + std::move(cb).Run(any_data_deleted); + }, + std::move(store_predicate), std::move(callback))); +} + +void NetworkContext::ClearNetworkingHistoryBetween( + base::Time start_time, + base::Time end_time, + base::OnceClosure completion_callback) { +#if BUILDFLAG(IS_CT_SUPPORTED) + auto barrier = base::BarrierClosure(3, std::move(completion_callback)); + sct_auditing_handler()->ClearPendingReports(barrier); +#else + auto barrier = base::BarrierClosure(2, std::move(completion_callback)); +#endif // BUIDLFLAG(IS_CT_SUPPORTED) + + url_request_context_->transport_security_state()->DeleteAllDynamicDataBetween( + start_time, end_time, barrier); + + // TODO(mmenke): Neither of these methods waits until the changes have been + // commited to disk. They probably should, as most similar methods net/ + // exposes do. + // May not be set in all tests. + if (network_qualities_pref_delegate_) + network_qualities_pref_delegate_->ClearPrefs(); + + url_request_context_->http_server_properties()->Clear(barrier); +} + +void NetworkContext::ClearHttpCache(base::Time start_time, + base::Time end_time, + mojom::ClearDataFilterPtr filter, + ClearHttpCacheCallback callback) { + // It's safe to use Unretained below as the HttpCacheDataRemover is owned by + // |this| and guarantees it won't call its callback if deleted. + http_cache_data_removers_.push_back(HttpCacheDataRemover::CreateAndStart( + url_request_context_, std::move(filter), start_time, end_time, + base::BindOnce(&NetworkContext::OnHttpCacheCleared, + base::Unretained(this), std::move(callback)))); +} + +void NetworkContext::ComputeHttpCacheSize( + base::Time start_time, + base::Time end_time, + ComputeHttpCacheSizeCallback callback) { + // It's safe to use Unretained below as the HttpCacheDataCounter is owned by + // |this| and guarantees it won't call its callback if deleted. + http_cache_data_counters_.push_back(HttpCacheDataCounter::CreateAndStart( + url_request_context_, start_time, end_time, + base::BindOnce(&NetworkContext::OnHttpCacheSizeComputed, + base::Unretained(this), std::move(callback)))); +} + +void NetworkContext::ClearCorsPreflightCache( + mojom::ClearDataFilterPtr filter, + ClearCorsPreflightCacheCallback callback) { + cors_preflight_controller_.ClearCorsPreflightCache(std::move(filter)); + std::move(callback).Run(); +} + +void NetworkContext::ClearHostCache(mojom::ClearDataFilterPtr filter, + ClearHostCacheCallback callback) { + net::HostCache* host_cache = + url_request_context_->host_resolver()->GetHostCache(); + DCHECK(host_cache); + host_cache->ClearForHosts(MakeDomainFilter(filter.get())); + std::move(callback).Run(); +} + +void NetworkContext::ClearHttpAuthCache(base::Time start_time, + base::Time end_time, + mojom::ClearDataFilterPtr filter, + ClearHttpAuthCacheCallback callback) { + net::HttpNetworkSession* http_session = + url_request_context_->http_transaction_factory()->GetSession(); + DCHECK(http_session); + + http_session->http_auth_cache()->ClearEntriesAddedBetween( + start_time, end_time, BuildUrlFilter(std::move(filter))); + // TODO(mmenke): Use another error code for this, as ERR_ABORTED has somewhat + // magical handling with respect to navigations. + http_session->CloseAllConnections(net::ERR_ABORTED, "Clearing auth cache"); + + std::move(callback).Run(); +} + +void NetworkContext::ClearReportingCacheReports( + mojom::ClearDataFilterPtr filter, + ClearReportingCacheReportsCallback callback) { +#if BUILDFLAG(ENABLE_REPORTING) + net::ReportingService* reporting_service = + url_request_context_->reporting_service(); + if (reporting_service) { + if (filter) { + reporting_service->RemoveBrowsingData( + net::ReportingBrowsingDataRemover::DATA_TYPE_REPORTS, + BuildOriginFilter(std::move(filter))); + } else { + reporting_service->RemoveAllBrowsingData( + net::ReportingBrowsingDataRemover::DATA_TYPE_REPORTS); + } + } +#endif // BUILDFLAG(ENABLE_REPORTING) + + std::move(callback).Run(); +} + +void NetworkContext::ClearReportingCacheClients( + mojom::ClearDataFilterPtr filter, + ClearReportingCacheClientsCallback callback) { +#if BUILDFLAG(ENABLE_REPORTING) + net::ReportingService* reporting_service = + url_request_context_->reporting_service(); + if (reporting_service) { + if (filter) { + reporting_service->RemoveBrowsingData( + net::ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS, + BuildOriginFilter(std::move(filter))); + } else { + reporting_service->RemoveAllBrowsingData( + net::ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS); + } + } +#endif // BUILDFLAG(ENABLE_REPORTING) + + std::move(callback).Run(); +} + +void NetworkContext::ClearNetworkErrorLogging( + mojom::ClearDataFilterPtr filter, + ClearNetworkErrorLoggingCallback callback) { +#if BUILDFLAG(ENABLE_REPORTING) + net::NetworkErrorLoggingService* logging_service = + url_request_context_->network_error_logging_service(); + if (logging_service) { + if (filter) { + logging_service->RemoveBrowsingData(BuildOriginFilter(std::move(filter))); + } else { + logging_service->RemoveAllBrowsingData(); + } + } +#endif // BUILDFLAG(ENABLE_REPORTING) + + std::move(callback).Run(); +} + +void NetworkContext::SetDocumentReportingEndpoints( + const base::UnguessableToken& reporting_source, + const url::Origin& origin, + const net::IsolationInfo& isolation_info, + const base::flat_map& endpoints) { +#if BUILDFLAG(ENABLE_REPORTING) + DCHECK(!reporting_source.is_empty()); + DCHECK_EQ(net::IsolationInfo::RequestType::kOther, + isolation_info.request_type()); + net::ReportingService* reporting_service = + url_request_context()->reporting_service(); + if (reporting_service) { + reporting_service->SetDocumentReportingEndpoints(reporting_source, origin, + isolation_info, endpoints); + } +#endif // BUILDFLAG(ENABLE_REPORTING) +} + +void NetworkContext::SendReportsAndRemoveSource( + const base::UnguessableToken& reporting_source) { +#if BUILDFLAG(ENABLE_REPORTING) + DCHECK(!reporting_source.is_empty()); + net::ReportingService* reporting_service = + url_request_context()->reporting_service(); + if (reporting_service) + reporting_service->SendReportsAndRemoveSource(reporting_source); +#endif // BUILDFLAG(ENABLE_REPORTING) +} + +void NetworkContext::QueueReport( + const std::string& type, + const std::string& group, + const GURL& url, + const std::optional& reporting_source, + const net::NetworkAnonymizationKey& network_anonymization_key, + base::Value::Dict body) { + QueueReportInternal(type, group, url, reporting_source, + network_anonymization_key, std::move(body), + net::ReportingTargetType::kDeveloper); +} + +void NetworkContext::QueueEnterpriseReport(const std::string& type, + const std::string& group, + const GURL& url, + base::Value::Dict body) { + // Enterprise reports don't use a |reporting_source| or + // |network_anonymization_key|. Enterprise endpoints are profile-bound and not + // document-bound like web developer endpoints. + QueueReportInternal(type, group, url, /*reporting_source=*/std::nullopt, + net::NetworkAnonymizationKey(), std::move(body), + net::ReportingTargetType::kEnterprise); +} + +void NetworkContext::QueueReportInternal( + const std::string& type, + const std::string& group, + const GURL& url, + const std::optional& reporting_source, + const net::NetworkAnonymizationKey& network_anonymization_key, + base::Value::Dict body, + net::ReportingTargetType target_type) { +#if BUILDFLAG(ENABLE_REPORTING) + // If |reporting_source| is provided, it must not be empty. + DCHECK(!(reporting_source.has_value() && reporting_source->is_empty())); + // Enterprise reports have an empty |network_anonymization_key|. + if (target_type == net::ReportingTargetType::kDeveloper && + require_network_anonymization_key_) { + DCHECK(!network_anonymization_key.IsEmpty()); + } + + // Get the ReportingService. + net::URLRequestContext* request_context = url_request_context(); + net::ReportingService* reporting_service = + request_context->reporting_service(); + // TODO(paulmeyer): Remove this once the network service ships everywhere. + if (!reporting_service) { + return; + } + + std::string reported_user_agent = ""; + if (request_context->http_user_agent_settings() != nullptr) { + reported_user_agent = + request_context->http_user_agent_settings()->GetUserAgent(); + } + + reporting_service->QueueReport( + url, reporting_source, network_anonymization_key, reported_user_agent, + group, type, std::move(body), 0 /* depth */, target_type); +#endif // BUILDFLAG(ENABLE_REPORTING) +} + +void NetworkContext::QueueSignedExchangeReport( + mojom::SignedExchangeReportPtr report, + const net::NetworkAnonymizationKey& network_anonymization_key) { +#if BUILDFLAG(ENABLE_REPORTING) + if (require_network_anonymization_key_) { + DCHECK(!network_anonymization_key.IsEmpty()); + } + + net::NetworkErrorLoggingService* logging_service = + url_request_context_->network_error_logging_service(); + if (!logging_service) + return; + std::string user_agent; + if (url_request_context_->http_user_agent_settings() != nullptr) { + user_agent = + url_request_context_->http_user_agent_settings()->GetUserAgent(); + } + net::NetworkErrorLoggingService::SignedExchangeReportDetails details; + details.network_anonymization_key = network_anonymization_key; + details.success = report->success; + details.type = std::move(report->type); + details.outer_url = std::move(report->outer_url); + details.inner_url = std::move(report->inner_url); + details.cert_url = std::move(report->cert_url); + details.referrer = std::move(report->referrer); + details.server_ip_address = std::move(report->server_ip_address); + details.protocol = std::move(report->protocol); + details.method = std::move(report->method); + details.status_code = report->status_code; + details.elapsed_time = report->elapsed_time; + details.user_agent = std::move(user_agent); + logging_service->QueueSignedExchangeReport(std::move(details)); +#endif // BUILDFLAG(ENABLE_REPORTING) +} + +#if BUILDFLAG(ENABLE_REPORTING) +void NetworkContext::AddReportingApiObserver( + mojo::PendingRemote observer) { + if (url_request_context() && url_request_context()->reporting_service()) { + if (!is_observing_reporting_service_) { + is_observing_reporting_service_ = true; + url_request_context()->reporting_service()->AddReportingCacheObserver( + this); + reporting_api_observers_.set_disconnect_handler( + base::BindRepeating(&NetworkContext::OnReportingObserverDisconnect, + weak_factory_.GetWeakPtr())); + } + auto id = reporting_api_observers_.Add(std::move(observer)); + + auto service_reports = + url_request_context()->reporting_service()->GetReports(); + for (const net::ReportingReport* service_report : service_reports) { + reporting_api_observers_.Get(id)->OnReportAdded(*service_report); + } + + base::flat_map> + endpoints_by_origin = url_request_context() + ->reporting_service() + ->GetV1ReportingEndpointsByOrigin(); + for (auto const& origin_and_endpoints : endpoints_by_origin) { + OnEndpointsUpdatedForOrigin(origin_and_endpoints.second); + } + } +} + +void NetworkContext::OnReportAdded(const net::ReportingReport* service_report) { + for (const auto& observer : reporting_api_observers_) { + observer->OnReportAdded(*service_report); + } +} + +void NetworkContext::OnEndpointsUpdatedForOrigin( + const std::vector& endpoints) { + for (const auto& observer : reporting_api_observers_) { + observer->OnEndpointsUpdatedForOrigin(endpoints); + } +} + +void NetworkContext::OnReportUpdated( + const net::ReportingReport* service_report) { + for (const auto& observer : reporting_api_observers_) { + observer->OnReportUpdated(*service_report); + } +} + +void NetworkContext::OnReportingObserverDisconnect( + mojo::RemoteSetElementId /*mojo_id*/) { + if (!reporting_api_observers_.size()) { + DCHECK(url_request_context()); + DCHECK(url_request_context()->reporting_service()); + url_request_context()->reporting_service()->RemoveReportingCacheObserver( + this); + is_observing_reporting_service_ = false; + } +} +#endif // BUILDFLAG(ENABLE_REPORTING) + +void NetworkContext::ClearDomainReliability( + mojom::ClearDataFilterPtr filter, + DomainReliabilityClearMode mode, + ClearDomainReliabilityCallback callback) { + if (domain_reliability_monitor_) { + domain_reliability::DomainReliabilityClearMode dr_mode; + if (mode == + mojom::NetworkContext::DomainReliabilityClearMode::CLEAR_CONTEXTS) { + dr_mode = domain_reliability::CLEAR_CONTEXTS; + } else { + dr_mode = domain_reliability::CLEAR_BEACONS; + } + + domain_reliability_monitor_->ClearBrowsingData( + dr_mode, BuildOriginFilter(std::move(filter))); + } + std::move(callback).Run(); +} + +void NetworkContext::CloseAllConnections(CloseAllConnectionsCallback callback) { + net::HttpNetworkSession* http_session = + url_request_context_->http_transaction_factory()->GetSession(); + DCHECK(http_session); + + // TODO(mmenke): Use another error code for this, as ERR_ABORTED has somewhat + // magical handling with respect to navigations. + http_session->CloseAllConnections(net::ERR_ABORTED, + "Embedder closing all connections"); + + std::move(callback).Run(); +} + +void NetworkContext::CloseIdleConnections( + CloseIdleConnectionsCallback callback) { + net::HttpNetworkSession* http_session = + url_request_context_->http_transaction_factory()->GetSession(); + DCHECK(http_session); + + http_session->CloseIdleConnections("Embedder closing idle connections"); + + std::move(callback).Run(); +} + +void NetworkContext::SetNetworkConditions( + const base::UnguessableToken& throttling_profile_id, + mojom::NetworkConditionsPtr conditions) { + std::unique_ptr network_conditions; + if (conditions) { + network_conditions = std::make_unique( + conditions->offline, conditions->latency.InMillisecondsF(), + conditions->download_throughput, conditions->upload_throughput, + conditions->packet_loss, conditions->packet_queue_length, + conditions->packet_reordering); + } + ThrottlingController::SetConditions(throttling_profile_id, + std::move(network_conditions)); +} + +void NetworkContext::SetAcceptLanguage(const std::string& new_accept_language) { + // This may only be called on NetworkContexts created with the constructor + // that calls MakeURLRequestContext(). + DCHECK(user_agent_settings_); + user_agent_settings_->set_accept_language(new_accept_language); +} + +void NetworkContext::SetEnableReferrers(bool enable_referrers) { + // This may only be called on NetworkContexts created with the constructor + // that calls MakeURLRequestContext(). + DCHECK(network_delegate_); + network_delegate_->set_enable_referrers(enable_referrers); +} + +#if BUILDFLAG(IS_CT_SUPPORTED) +void NetworkContext::SetCTPolicy(mojom::CTPolicyPtr ct_policy) { + if (!require_ct_delegate_) + return; + + require_ct_delegate_->UpdateCTPolicies(ct_policy->excluded_hosts, + ct_policy->excluded_spkis); +} + +int NetworkContext::CheckCTRequirementsForSignedExchange( + net::CertVerifyResult& cert_verify_result, + const net::HostPortPair& host_port_pair) { + net::X509Certificate* verified_cert = cert_verify_result.verified_cert.get(); + + net::TransportSecurityState::CTRequirementsStatus ct_requirement_status = + url_request_context_->transport_security_state()->CheckCTRequirements( + host_port_pair, cert_verify_result.is_issued_by_known_root, + cert_verify_result.public_key_hashes, verified_cert, + cert_verify_result.policy_compliance); + + if (url_request_context_->sct_auditing_delegate()) { + url_request_context_->sct_auditing_delegate()->MaybeEnqueueReport( + host_port_pair, verified_cert, cert_verify_result.scts); + } + + switch (ct_requirement_status) { + case net::TransportSecurityState::CT_REQUIREMENTS_NOT_MET: + return net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED; + case net::TransportSecurityState::CT_REQUIREMENTS_MET: + return net::OK; + case net::TransportSecurityState::CT_NOT_REQUIRED: + // CT is not required if the certificate does not chain to a publicly + // trusted root certificate. + if (!cert_verify_result.is_issued_by_known_root) + return net::OK; + // For old certificates (issued before 2018-05-01), + // CheckCTRequirements() may return CT_NOT_REQUIRED, so we check the + // compliance status here. + // TODO(crbug.com/40580363): Remove this condition once we require + // signing certificates to have CanSignHttpExchanges extension, because + // such certificates should be naturally after 2018-05-01. + if (cert_verify_result.policy_compliance == + net::ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS || + cert_verify_result.policy_compliance == + net::ct::CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY) { + return net::OK; + } + // Require CT compliance, by overriding CT_NOT_REQUIRED and treat it as + // ERR_CERTIFICATE_TRANSPARENCY_REQUIRED. + return net::ERR_CERTIFICATE_TRANSPARENCY_REQUIRED; + } +} + +void NetworkContext::MaybeEnqueueSCTReport( + const net::HostPortPair& host_port_pair, + const net::X509Certificate* validated_certificate_chain, + const net::SignedCertificateTimestampAndStatusList& + signed_certificate_timestamps) { + sct_auditing_handler()->MaybeEnqueueReport(host_port_pair, + validated_certificate_chain, + signed_certificate_timestamps); +} + +void NetworkContext::SetSCTAuditingMode(mojom::SCTAuditingMode mode) { + sct_auditing_handler()->SetMode(mode); +} + +void NetworkContext::CanSendSCTAuditingReport( + base::OnceCallback callback) { + // If the NetworkContextClient hasn't been set yet or has disconnected for + // some reason, just return `false`. (One case where this could occur is when + // restarting SCTAuditingReporter instances loaded form disk at startup -- see + // crbug.com/1347180 for more details on that case.) + if (!client_) { + std::move(callback).Run(false); + return; + } + client_->OnCanSendSCTAuditingReport(std::move(callback)); +} + +void NetworkContext::OnNewSCTAuditingReportSent() { + client_->OnNewSCTAuditingReportSent(); +} +#endif // BUILDFLAG(IS_CT_SUPPORTED) + +void NetworkContext::CreateUDPSocket( + mojo::PendingReceiver receiver, + mojo::PendingRemote listener) { + socket_factory_->CreateUDPSocket(std::move(receiver), std::move(listener)); +} + +void NetworkContext::CreateRestrictedUDPSocket( + const net::IPEndPoint& addr, + mojom::RestrictedUDPSocketMode mode, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojom::RestrictedUDPSocketParamsPtr params, + mojo::PendingReceiver receiver, + mojo::PendingRemote listener, + CreateRestrictedUDPSocketCallback callback) { + // SimpleHostResolver is transitively owned by |this|. + socket_factory_->CreateRestrictedUDPSocket( + addr, mode, traffic_annotation, std::move(params), std::move(receiver), + std::move(listener), SimpleHostResolver::Create(this), + std::move(callback)); +} + +void NetworkContext::CreateTCPServerSocket( + const net::IPEndPoint& local_addr, + mojom::TCPServerSocketOptionsPtr options, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojo::PendingReceiver receiver, + CreateTCPServerSocketCallback callback) { + socket_factory_->CreateTCPServerSocket( + local_addr, std::move(options), + static_cast(traffic_annotation), + std::move(receiver), std::move(callback)); +} + +void NetworkContext::CreateTCPConnectedSocket( + const std::optional& local_addr, + const net::AddressList& remote_addr_list, + mojom::TCPConnectedSocketOptionsPtr tcp_connected_socket_options, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojo::PendingReceiver receiver, + mojo::PendingRemote observer, + CreateTCPConnectedSocketCallback callback) { + socket_factory_->CreateTCPConnectedSocket( + local_addr, remote_addr_list, std::move(tcp_connected_socket_options), + static_cast(traffic_annotation), + std::move(receiver), std::move(observer), std::move(callback)); +} + +void NetworkContext::CreateTCPBoundSocket( + const net::IPEndPoint& local_addr, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojo::PendingReceiver receiver, + CreateTCPBoundSocketCallback callback) { + socket_factory_->CreateTCPBoundSocket( + local_addr, + static_cast(traffic_annotation), + std::move(receiver), std::move(callback)); +} + +void NetworkContext::CreateProxyResolvingSocketFactory( + mojo::PendingReceiver receiver) { + proxy_resolving_socket_factories_.Add( + std::make_unique(url_request_context()), + std::move(receiver)); +} + +void NetworkContext::LookUpProxyForURL( + const GURL& url, + const net::NetworkAnonymizationKey& network_anonyization_key, + mojo::PendingRemote proxy_lookup_client) { + DCHECK(proxy_lookup_client); + std::unique_ptr proxy_lookup_request( + std::make_unique(std::move(proxy_lookup_client), this, + network_anonyization_key)); + ProxyLookupRequest* proxy_lookup_request_ptr = proxy_lookup_request.get(); + proxy_lookup_requests_.insert(std::move(proxy_lookup_request)); + proxy_lookup_request_ptr->Start(url); +} + +void NetworkContext::ForceReloadProxyConfig( + ForceReloadProxyConfigCallback callback) { + net::ConfiguredProxyResolutionService* configured_proxy_resolution_service = + nullptr; + if (url_request_context() + ->proxy_resolution_service() + ->CastToConfiguredProxyResolutionService( + &configured_proxy_resolution_service)) { + configured_proxy_resolution_service->ForceReloadProxyConfig(); + } else { + LOG(WARNING) + << "NetworkContext::ForceReloadProxyConfig() had no effect, as the " + "underlying ProxyResolutionService does not support that concept."; + } + std::move(callback).Run(); +} + +void NetworkContext::ClearBadProxiesCache( + ClearBadProxiesCacheCallback callback) { + url_request_context()->proxy_resolution_service()->ClearBadProxiesCache(); + std::move(callback).Run(); +} + +void NetworkContext::CreateWebSocket( + const GURL& url, + const std::vector& requested_protocols, + const net::SiteForCookies& site_for_cookies, + net::StorageAccessApiStatus storage_access_api_status, + const net::IsolationInfo& isolation_info, + std::vector additional_headers, + int32_t process_id, + const url::Origin& origin, + uint32_t options, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation, + mojo::PendingRemote handshake_client, + mojo::PendingRemote + url_loader_network_observer, + mojo::PendingRemote auth_handler, + mojo::PendingRemote header_client, + const std::optional& throttling_profile_id) { +#if BUILDFLAG(ENABLE_WEBSOCKETS) + if (!websocket_factory_) + websocket_factory_ = std::make_unique(this); + + DCHECK_GE(process_id, 0); + + websocket_factory_->CreateWebSocket( + url, requested_protocols, site_for_cookies, storage_access_api_status, + isolation_info, std::move(additional_headers), process_id, origin, + options, + static_cast(traffic_annotation), + std::move(handshake_client), std::move(url_loader_network_observer), + std::move(auth_handler), std::move(header_client), throttling_profile_id); +#endif // BUILDFLAG(ENABLE_WEBSOCKETS) +} + +void NetworkContext::CreateWebTransport( + const GURL& url, + const url::Origin& origin, + const net::NetworkAnonymizationKey& key, + std::vector fingerprints, + mojo::PendingRemote + pending_handshake_client) { + web_transports_.insert( + std::make_unique(url, origin, key, fingerprints, this, + std::move(pending_handshake_client))); +} + +void NetworkContext::CreateNetLogExporter( + mojo::PendingReceiver receiver) { + net_log_exporter_receivers_.Add(std::make_unique(this), + std::move(receiver)); +} + +void NetworkContext::ResolveHost( + mojom::HostResolverHostPtr host, + const net::NetworkAnonymizationKey& network_anonymization_key, + mojom::ResolveHostParametersPtr optional_parameters, + mojo::PendingRemote response_client) { + if (!internal_host_resolver_) { + internal_host_resolver_ = std::make_unique( + url_request_context_->host_resolver(), url_request_context_->net_log()); + } + internal_host_resolver_->ResolveHost( + std::move(host), network_anonymization_key, + std::move(optional_parameters), std::move(response_client)); +} + +void NetworkContext::CreateHostResolver( + const std::optional& config_overrides, + mojo::PendingReceiver receiver) { + net::HostResolver* internal_resolver = url_request_context_->host_resolver(); + std::unique_ptr private_internal_resolver; + + if (config_overrides && + config_overrides.value() != net::DnsConfigOverrides()) { + // If custom configuration is needed, create a separate internal resolver + // with the specified configuration overrides. Because we are using a non- + // standard resolver, disable the cache. + // + // TODO(crbug.com/40577881): Consider allowing per-resolve overrides, so the + // same net::HostResolver with the same scheduler and cache can be used with + // different overrides. But since this is only used for special cases for + // now, much easier to create entirely separate net::HostResolver instances. + net::HostResolver::ManagerOptions options; + options.insecure_dns_client_enabled = true; + // Assume additional types are unnecessary for these special cases. + options.additional_types_via_insecure_dns_enabled = false; + options.dns_config_overrides = config_overrides.value(); + private_internal_resolver = + network_service_->host_resolver_factory()->CreateStandaloneResolver( + url_request_context_->net_log(), std::move(options), + "" /* host_mapping_rules */, false /* enable_caching */); + private_internal_resolver->SetRequestContext(url_request_context_); + internal_resolver = private_internal_resolver.get(); + } + + host_resolvers_.emplace(std::make_unique( + std::move(receiver), + base::BindOnce(&NetworkContext::OnHostResolverShutdown, + base::Unretained(this)), + internal_resolver, std::move(private_internal_resolver), + url_request_context_->net_log())); +} + +void NetworkContext::VerifyCertForSignedExchange( + const scoped_refptr& certificate, + const GURL& url, + const std::string& ocsp_result, + const std::string& sct_list, + VerifyCertForSignedExchangeCallback callback) { + uint64_t cert_verify_id = ++next_cert_verify_id_; + CHECK_NE(0u, next_cert_verify_id_); // The request ID should not wrap around. + auto pending_cert_verify = std::make_unique(); + pending_cert_verify->callback = std::move(callback); + pending_cert_verify->result = std::make_unique(); + pending_cert_verify->certificate = certificate; + pending_cert_verify->url = url; + pending_cert_verify->ocsp_result = ocsp_result; + pending_cert_verify->sct_list = sct_list; + net::CertVerifier* cert_verifier = + g_cert_verifier_for_testing ? g_cert_verifier_for_testing + : url_request_context_->cert_verifier(); + int result = cert_verifier->Verify( + net::CertVerifier::RequestParams(certificate, url.host(), + 0 /* cert_verify_flags */, ocsp_result, + sct_list), + pending_cert_verify->result.get(), + base::BindOnce(&NetworkContext::OnVerifyCertForSignedExchangeComplete, + base::Unretained(this), cert_verify_id), + &pending_cert_verify->request, + net::NetLogWithSource::Make(url_request_context_->net_log(), + net::NetLogSourceType::CERT_VERIFIER_JOB)); + cert_verifier_requests_[cert_verify_id] = std::move(pending_cert_verify); + + if (result != net::ERR_IO_PENDING) + OnVerifyCertForSignedExchangeComplete(cert_verify_id, result); +} + +void NetworkContext::NotifyExternalCacheHit(const GURL& url, + const std::string& http_method, + const net::NetworkIsolationKey& key, + bool include_credentials) { + net::HttpCache* cache = + url_request_context_->http_transaction_factory()->GetCache(); + if (!cache) + return; + cache->OnExternalCacheHit(url, http_method, key, include_credentials); +} + +void NetworkContext::SetCorsOriginAccessListsForOrigin( + const url::Origin& source_origin, + std::vector allow_patterns, + std::vector block_patterns, + SetCorsOriginAccessListsForOriginCallback callback) { + cors_origin_access_list_.SetAllowListForOrigin(source_origin, allow_patterns); + cors_origin_access_list_.SetBlockListForOrigin(source_origin, block_patterns); + std::move(callback).Run(); +} + +void NetworkContext::AddHSTS(const std::string& host, + base::Time expiry, + bool include_subdomains, + AddHSTSCallback callback) { + net::TransportSecurityState* state = + url_request_context_->transport_security_state(); + state->AddHSTS(host, expiry, include_subdomains); + std::move(callback).Run(); +} + +void NetworkContext::IsHSTSActiveForHost(const std::string& host, + IsHSTSActiveForHostCallback callback) { + net::TransportSecurityState* security_state = + url_request_context_->transport_security_state(); + + if (!security_state) { + std::move(callback).Run(false); + return; + } + + std::move(callback).Run(security_state->ShouldUpgradeToSSL(host)); +} + +void NetworkContext::GetHSTSState(const std::string& domain, + GetHSTSStateCallback callback) { + base::Value::Dict result; + + if (base::IsStringASCII(domain)) { + net::TransportSecurityState* transport_security_state = + url_request_context()->transport_security_state(); + if (transport_security_state) { + net::TransportSecurityState::STSState static_sts_state; + net::TransportSecurityState::PKPState static_pkp_state; + bool found_sts_static = transport_security_state->GetStaticSTSState( + domain, &static_sts_state); + bool found_pkp_static = transport_security_state->GetStaticPKPState( + domain, &static_pkp_state); + if (found_sts_static || found_pkp_static) { + result.Set("static_upgrade_mode", + static_cast(static_sts_state.upgrade_mode)); + result.Set("static_sts_include_subdomains", + static_sts_state.include_subdomains); + result.Set("static_sts_observed", + static_sts_state.last_observed.InSecondsFSinceUnixEpoch()); + result.Set("static_sts_expiry", + static_sts_state.expiry.InSecondsFSinceUnixEpoch()); + result.Set("static_pkp_include_subdomains", + static_pkp_state.include_subdomains); + result.Set("static_pkp_observed", + static_pkp_state.last_observed.InSecondsFSinceUnixEpoch()); + result.Set("static_pkp_expiry", + static_pkp_state.expiry.InSecondsFSinceUnixEpoch()); + result.Set("static_spki_hashes", + HashesToBase64String(static_pkp_state.spki_hashes)); + result.Set("static_sts_domain", static_sts_state.domain); + result.Set("static_pkp_domain", static_pkp_state.domain); + } + + net::TransportSecurityState::STSState dynamic_sts_state; + net::TransportSecurityState::PKPState dynamic_pkp_state; + bool found_sts_dynamic = transport_security_state->GetDynamicSTSState( + domain, &dynamic_sts_state); + + bool found_pkp_dynamic = transport_security_state->GetDynamicPKPState( + domain, &dynamic_pkp_state); + if (found_sts_dynamic) { + result.Set("dynamic_upgrade_mode", + static_cast(dynamic_sts_state.upgrade_mode)); + result.Set("dynamic_sts_include_subdomains", + dynamic_sts_state.include_subdomains); + result.Set("dynamic_sts_observed", + dynamic_sts_state.last_observed.InSecondsFSinceUnixEpoch()); + result.Set("dynamic_sts_expiry", + dynamic_sts_state.expiry.InSecondsFSinceUnixEpoch()); + result.Set("dynamic_sts_domain", dynamic_sts_state.domain); + } + + if (found_pkp_dynamic) { + result.Set("dynamic_pkp_include_subdomains", + dynamic_pkp_state.include_subdomains); + result.Set("dynamic_pkp_observed", + dynamic_pkp_state.last_observed.InSecondsFSinceUnixEpoch()); + result.Set("dynamic_pkp_expiry", + dynamic_pkp_state.expiry.InSecondsFSinceUnixEpoch()); + result.Set("dynamic_spki_hashes", + HashesToBase64String(dynamic_pkp_state.spki_hashes)); + result.Set("dynamic_pkp_domain", dynamic_pkp_state.domain); + } + + result.Set("result", found_sts_static || found_pkp_static || + found_sts_dynamic || found_pkp_dynamic); + } else { + result.Set("error", "no TransportSecurityState active"); + } + } else { + result.Set("error", "non-ASCII domain name"); + } + + std::move(callback).Run(std::move(result)); +} + +void NetworkContext::DeleteDynamicDataForHost( + const std::string& host, + DeleteDynamicDataForHostCallback callback) { + net::TransportSecurityState* transport_security_state = + url_request_context()->transport_security_state(); + if (!transport_security_state) { + std::move(callback).Run(false); + return; + } + + std::move(callback).Run( + transport_security_state->DeleteDynamicDataForHost(host)); +} + +void NetworkContext::EnableStaticKeyPinningForTesting( + EnableStaticKeyPinningForTestingCallback callback) { + net::TransportSecurityState* state = + url_request_context_->transport_security_state(); + state->EnableStaticPinsForTesting(); + state->SetPinningListAlwaysTimelyForTesting(true); + std::move(callback).Run(); +} + +void NetworkContext::VerifyCertificateForTesting( + const scoped_refptr& certificate, + const std::string& hostname, + const std::string& ocsp_response, + const std::string& sct_list, + VerifyCertificateForTestingCallback callback) { + net::CertVerifier* cert_verifier = url_request_context_->cert_verifier(); + + auto state = std::make_unique(); + auto* request = &state->request; + auto* result = &state->result; + + cert_verifier->Verify( + net::CertVerifier::RequestParams(certificate.get(), hostname, 0, + ocsp_response, sct_list), + result, + base::BindOnce(TestVerifyCertCallback, std::move(state), + std::move(callback)), + request, net::NetLogWithSource()); +} + +void NetworkContext::PreconnectSockets( + uint32_t num_streams, + const GURL& original_url, + mojom::CredentialsMode credentials_mode, + const net::NetworkAnonymizationKey& network_anonymization_key) { + DCHECK(!require_network_anonymization_key_ || + !network_anonymization_key.IsEmpty()); + + GURL url = GetHSTSRedirect(original_url); + + // |PreconnectSockets| may receive arguments from the renderer, which is not + // guaranteed to validate them. + if (num_streams == 0) + return; + + std::string user_agent; + if (url_request_context_->http_user_agent_settings()) { + user_agent = + url_request_context_->http_user_agent_settings()->GetUserAgent(); + } + net::HttpRequestInfo request_info; + request_info.url = url; + request_info.method = net::HttpRequestHeaders::kGetMethod; + request_info.extra_headers.SetHeader(net::HttpRequestHeaders::kUserAgent, + user_agent); + + switch (credentials_mode) { + case mojom::CredentialsMode::kOmit: + request_info.load_flags = net::LOAD_DO_NOT_SAVE_COOKIES; + request_info.privacy_mode = net::PRIVACY_MODE_ENABLED; + break; + + case mojom::CredentialsMode::kSameOrigin: + // Not yet implemented. If you need this credentials mode please update + // this branch to set the correct request_info fields. + NOTREACHED_NORETURN() << "kSameOrigin not yet implemented"; + + case mojom::CredentialsMode::kInclude: + request_info.load_flags = net::LOAD_NORMAL; + request_info.privacy_mode = net::PRIVACY_MODE_DISABLED; + break; + + case mojom::CredentialsMode::kOmitBug_775438_Workaround: + request_info.load_flags = net::LOAD_DO_NOT_SAVE_COOKIES; + request_info.privacy_mode = + net::PRIVACY_MODE_ENABLED_WITHOUT_CLIENT_CERTS; + break; + } + + request_info.network_anonymization_key = network_anonymization_key; + + net::HttpTransactionFactory* factory = + url_request_context_->http_transaction_factory(); + net::HttpNetworkSession* session = factory->GetSession(); + net::HttpStreamFactory* http_stream_factory = session->http_stream_factory(); + http_stream_factory->PreconnectStreams( + base::saturated_cast(num_streams), request_info); +} + +#if BUILDFLAG(IS_P2P_ENABLED) +void NetworkContext::CreateP2PSocketManager( + const net::NetworkAnonymizationKey& network_anonymization_key, + mojo::PendingRemote client, + mojo::PendingReceiver + trusted_socket_manager, + mojo::PendingReceiver socket_manager_receiver) { + std::unique_ptr socket_manager = + std::make_unique( + network_anonymization_key, std::move(client), + std::move(trusted_socket_manager), std::move(socket_manager_receiver), + base::BindRepeating(&NetworkContext::DestroySocketManager, + base::Unretained(this)), + url_request_context_); + socket_managers_[socket_manager.get()] = std::move(socket_manager); +} +#endif // BUILDFLAG(IS_P2P_ENABLED) + +void NetworkContext::CreateMdnsResponder( + mojo::PendingReceiver responder_receiver) { +#if BUILDFLAG(ENABLE_MDNS) + if (!mdns_responder_manager_) + mdns_responder_manager_ = std::make_unique(); + + mdns_responder_manager_->CreateMdnsResponder(std::move(responder_receiver)); +#else + NOTREACHED_IN_MIGRATION(); +#endif // BUILDFLAG(ENABLE_MDNS) +} + +void NetworkContext::AddDomainReliabilityContextForTesting( + const url::Origin& origin, + const GURL& upload_url, + AddDomainReliabilityContextForTestingCallback callback) { + auto config = std::make_unique(); + config->origin = origin; + config->include_subdomains = false; + config->collectors.push_back(std::make_unique(upload_url)); + config->success_sample_rate = 1.0; + config->failure_sample_rate = 1.0; + domain_reliability_monitor_->AddContextForTesting(std::move(config)); + std::move(callback).Run(); +} + +void NetworkContext::ForceDomainReliabilityUploadsForTesting( + ForceDomainReliabilityUploadsForTestingCallback callback) { + domain_reliability_monitor_->ForceUploadsForTesting(); + std::move(callback).Run(); +} + +void NetworkContext::SetSplitAuthCacheByNetworkAnonymizationKey( + bool split_auth_cache_by_network_anonymization_key) { + url_request_context_->http_transaction_factory() + ->GetSession() + ->http_auth_cache() + ->SetKeyServerEntriesByNetworkAnonymizationKey( + split_auth_cache_by_network_anonymization_key); +} + +void NetworkContext::SaveHttpAuthCacheProxyEntries( + SaveHttpAuthCacheProxyEntriesCallback callback) { + net::HttpAuthCache* http_auth_cache = + url_request_context_->http_transaction_factory() + ->GetSession() + ->http_auth_cache(); + base::UnguessableToken cache_key = + network_service_->http_auth_cache_copier()->SaveHttpAuthCache( + *http_auth_cache); + std::move(callback).Run(cache_key); +} + +void NetworkContext::LoadHttpAuthCacheProxyEntries( + const base::UnguessableToken& cache_key, + LoadHttpAuthCacheProxyEntriesCallback callback) { + net::HttpAuthCache* http_auth_cache = + url_request_context_->http_transaction_factory() + ->GetSession() + ->http_auth_cache(); + network_service_->http_auth_cache_copier()->LoadHttpAuthCache( + cache_key, http_auth_cache); + std::move(callback).Run(); +} + +void NetworkContext::AddAuthCacheEntry( + const net::AuthChallengeInfo& challenge, + const net::NetworkAnonymizationKey& network_anonymization_key, + const net::AuthCredentials& credentials, + AddAuthCacheEntryCallback callback) { + net::HttpAuthCache* http_auth_cache = + url_request_context_->http_transaction_factory() + ->GetSession() + ->http_auth_cache(); + http_auth_cache->Add(challenge.challenger, + challenge.is_proxy ? net::HttpAuth::AUTH_PROXY + : net::HttpAuth::AUTH_SERVER, + challenge.realm, + net::HttpAuth::StringToScheme(challenge.scheme), + network_anonymization_key, challenge.challenge, + credentials, challenge.path); + std::move(callback).Run(); +} + +void NetworkContext::SetCorsNonWildcardRequestHeadersSupport(bool value) { + if (!base::FeatureList::IsEnabled( + features::kCorsNonWildcardRequestHeadersSupport)) { + return; + } + cors_non_wildcard_request_headers_support_ = + cors::NonWildcardRequestHeadersSupport(value); +} + +void NetworkContext::LookupServerBasicAuthCredentials( + const GURL& url, + const net::NetworkAnonymizationKey& network_anonymization_key, + LookupServerBasicAuthCredentialsCallback callback) { + net::HttpAuthCache* http_auth_cache = + url_request_context_->http_transaction_factory() + ->GetSession() + ->http_auth_cache(); + net::HttpAuthCache::Entry* entry = http_auth_cache->LookupByPath( + url::SchemeHostPort(url), net::HttpAuth::AUTH_SERVER, + network_anonymization_key, url.path()); + if (entry && entry->scheme() == net::HttpAuth::AUTH_SCHEME_BASIC) + std::move(callback).Run(entry->credentials()); + else + std::move(callback).Run(std::nullopt); +} + +#if BUILDFLAG(IS_CHROMEOS_ASH) +void NetworkContext::LookupProxyAuthCredentials( + const net::ProxyServer& proxy_server, + const std::string& auth_scheme, + const std::string& realm, + LookupProxyAuthCredentialsCallback callback) { + net::HttpAuth::Scheme net_scheme = + net::HttpAuth::StringToScheme(base::ToLowerASCII(auth_scheme)); + if (net_scheme == net::HttpAuth::Scheme::AUTH_SCHEME_MAX) { + std::move(callback).Run(std::nullopt); + return; + } + net::HttpAuthCache* http_auth_cache = + url_request_context_->http_transaction_factory() + ->GetSession() + ->http_auth_cache(); + // TODO(crbug.com/40704785): Mapping proxy addresses to URLs is a + // lossy conversion, shouldn't do this. + const char* scheme = + proxy_server.is_secure_http_like() ? "https://" : "http://"; + url::SchemeHostPort scheme_host_port( + GURL(scheme + proxy_server.host_port_pair().ToString())); + if (!scheme_host_port.IsValid()) { + std::move(callback).Run(std::nullopt); + return; + } + + // Unlike server credentials, proxy credentials are not keyed on + // NetworkAnonymizationKey. + net::HttpAuthCache::Entry* entry = http_auth_cache->Lookup( + scheme_host_port, net::HttpAuth::AUTH_PROXY, realm, net_scheme, + net::NetworkAnonymizationKey()); + if (entry) + std::move(callback).Run(entry->credentials()); + else + std::move(callback).Run(std::nullopt); +} +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + +const net::HttpAuthPreferences* NetworkContext::GetHttpAuthPreferences() const { + return &http_auth_merged_preferences_; +} + +size_t NetworkContext::NumOpenWebTransports() const { + return base::ranges::count(web_transports_, false, &WebTransport::torn_down); +} + +bool NetworkContext::AllURLLoaderFactoriesAreBoundToNetworkForTesting( + net::handles::NetworkHandle target_network) const { + for (const auto& factory : url_loader_factories_) { + if (factory->GetBoundNetworkForTesting() != target_network) { + return false; + } + } + return true; +} + +void NetworkContext::OnHttpAuthDynamicParamsChanged( + const mojom::HttpAuthDynamicParams* + http_auth_dynamic_network_service_params) { + http_auth_merged_preferences_.SetServerAllowlist( + http_auth_dynamic_network_service_params->server_allowlist); + http_auth_merged_preferences_.SetDelegateAllowlist( + http_auth_dynamic_network_service_params->delegate_allowlist); + http_auth_merged_preferences_.set_delegate_by_kdc_policy( + http_auth_dynamic_network_service_params->delegate_by_kdc_policy); + http_auth_merged_preferences_.set_negotiate_disable_cname_lookup( + http_auth_dynamic_network_service_params->negotiate_disable_cname_lookup); + http_auth_merged_preferences_.set_negotiate_enable_port( + http_auth_dynamic_network_service_params->enable_negotiate_port); + http_auth_merged_preferences_.set_basic_over_http_enabled( + http_auth_dynamic_network_service_params->basic_over_http_enabled); +#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) + http_auth_merged_preferences_.set_ntlm_v2_enabled( + http_auth_dynamic_network_service_params->ntlm_v2_enabled); +#endif // BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA) + +#if BUILDFLAG(IS_ANDROID) + http_auth_merged_preferences_.set_auth_android_negotiate_account_type( + http_auth_dynamic_network_service_params->android_negotiate_account_type); +#endif // BUILDFLAG(IS_ANDROID) + +#if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) + http_auth_merged_preferences_.set_allow_gssapi_library_load( + http_auth_dynamic_network_service_params->allow_gssapi_library_load); +#endif // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) + if (http_auth_dynamic_network_service_params->allowed_schemes.has_value()) { + http_auth_merged_preferences_.set_allowed_schemes(std::set( + http_auth_dynamic_network_service_params->allowed_schemes->begin(), + http_auth_dynamic_network_service_params->allowed_schemes->end())); + } else { + http_auth_merged_preferences_.set_allowed_schemes(std::nullopt); + } + + url_matcher_ = std::make_unique(); + url_matcher::util::AddAllowFilters(url_matcher_.get(), + http_auth_dynamic_network_service_params + ->patterns_allowed_to_use_all_schemes); + http_auth_merged_preferences_.set_http_auth_scheme_filter( + base::BindRepeating(&NetworkContext::IsAllowedToUseAllHttpAuthSchemes, + base::Unretained(this))); +} + +URLRequestContextOwner NetworkContext::MakeURLRequestContext( + mojo::PendingRemote + url_loader_factory_for_cert_net_fetcher, + scoped_refptr session_cleanup_cookie_store, + OnURLRequestContextBuilderConfiguredCallback + on_url_request_context_builder_configured, + net::handles::NetworkHandle bound_network) { + URLRequestContextBuilderMojo builder; + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + + bool is_network_bound = bound_network != net::handles::kInvalidNetworkHandle; + if (is_network_bound) { + builder.BindToNetwork(bound_network); + } + + std::unique_ptr cert_verifier; + if (g_cert_verifier_for_testing) { + cert_verifier = std::make_unique(); + } else { + DCHECK(params_->cert_verifier_params); + // base::Unretained() is safe below because |this| will own + // |cert_verifier|. + // TODO(crbug.com/40693524): this cert verifier should deal with + // disconnections if the CertVerifierService is run outside of the browser + // process. + cert_verifier = std::make_unique( + std::move(params_->cert_verifier_params->cert_verifier_service), + std::move(params_->cert_verifier_params + ->cert_verifier_service_client_receiver), + std::move(url_loader_factory_for_cert_net_fetcher), + base::BindRepeating( + &NetworkContext::CreateURLLoaderFactoryForCertNetFetcher, + base::Unretained(this))); + + // Whether the cert verifier is remote or in-process, we should wrap it in + // caching and coalescing layers to avoid extra verifications and IPCs. + cert_verifier = std::make_unique( + std::make_unique( + std::move(cert_verifier))); + +#if BUILDFLAG(IS_CHROMEOS) + // TODO(crbug.com/40928765): The TrustAnchorUsed callback should + // work on all platforms. (Also consider whether this wrapper is the best + // way to handle this or if it should be refactored.) + auto cert_verifier_with_trust_anchors = + std::make_unique(base::BindRepeating( + &NetworkContext::TrustAnchorUsed, base::Unretained(this))); + cert_verifier_with_trust_anchors->InitializeOnIOThread( + std::move(cert_verifier)); + cert_verifier = std::move(cert_verifier_with_trust_anchors); +#endif // BUILDFLAG(IS_CHROMEOS) + } + + builder.SetCertVerifier(IgnoreErrorsCertVerifier::MaybeWrapCertVerifier( + *command_line, nullptr, std::move(cert_verifier))); + +#if BUILDFLAG(IS_CT_SUPPORTED) + builder.set_sct_auditing_delegate( + std::make_unique(weak_factory_.GetWeakPtr())); +#endif // BUILDFLAG(IS_CT_SUPPORTED) + + std::unique_ptr network_delegate = + std::make_unique( + params_->enable_referrers, + params_->validate_referrer_policy_on_initial_request, + std::move(params_->proxy_error_client), this); + network_delegate_ = network_delegate.get(); + builder.set_network_delegate(std::move(network_delegate)); + + // Decide which ProxyDelegate to create. At most one of these will be the + // case for any given NetworkContext: either PrefetchProxy, handling its + // custom proxy configs, or IpProtection, using the proxy allowlist. + // TODO(https://crbug.com/40947771): Once the WebView traffic experiment is + // done, we should only create an IpProtectionProxyDelegate when + // `params_->ip_protection_config_getter` is set (to avoid creating proxy + // delegates for network contexts that don't participate in IP Protection, or + // for any network context when the IP Protection feature is disabled). + auto* nspal = network_service_->network_service_proxy_allow_list(); + if (!params_->initial_custom_proxy_config && nspal->IsEnabled()) { + auto ipp_config_cache = std::make_unique( + std::move(params_->ip_protection_config_getter)); + std::unique_ptr proxy_delegate = + std::make_unique( + nspal, std::move(ipp_config_cache), params_->enable_ip_protection); + proxy_delegate->SetReceiver( + std::move(params_->ip_protection_proxy_delegate)); + proxy_delegate_ = proxy_delegate.get(); + builder.set_proxy_delegate(std::move(proxy_delegate)); + } else if (params_->initial_custom_proxy_config || + params_->custom_proxy_config_client_receiver) { + std::unique_ptr proxy_delegate = + std::make_unique( + std::move(params_->initial_custom_proxy_config), + std::move(params_->custom_proxy_config_client_receiver), + std::move(params_->custom_proxy_connection_observer_remote)); + proxy_delegate_ = proxy_delegate.get(); + builder.set_proxy_delegate(std::move(proxy_delegate)); + } + + net::NetLog* net_log = nullptr; + if (network_service_) { + net_log = network_service_->net_log(); + builder.set_net_log(net_log); + if (!is_network_bound) { + // Network bound URLRequestContexts build and configure their own special + // HostResolverManager and HostResolver. So, don't inject the + // NetworkService one even if NetworkService is enabled. + builder.set_host_resolver_manager( + network_service_->host_resolver_manager()); + builder.set_host_resolver_factory( + network_service_->host_resolver_factory()); + } + builder.SetHttpAuthHandlerFactory( + network_service_->CreateHttpAuthHandlerFactory(this)); + builder.set_network_quality_estimator( + network_service_->network_quality_estimator()); + } + + if (session_cleanup_cookie_store) { + std::unique_ptr cookie_store = + std::make_unique(session_cleanup_cookie_store.get(), + net_log); + if (params_->persist_session_cookies) + cookie_store->SetPersistSessionCookies(true); + + builder.SetCookieStore(std::move(cookie_store)); + } + + if (base::FeatureList::IsEnabled(features::kPrivateStateTokens) || + base::FeatureList::IsEnabled(features::kFledgePst)) { + trust_token_store_ = std::make_unique(); + + base::FilePath trust_token_path; + if (GetFullDataFilePath( + params_->file_paths, + &network::mojom::NetworkContextFilePaths::trust_token_database_name, + trust_token_path)) { + SQLiteTrustTokenPersister::CreateForFilePath( + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), kTrustTokenDatabaseTaskPriority, + base::TaskShutdownBehavior::BLOCK_SHUTDOWN}), + trust_token_path, kTrustTokenWriteBufferingWindow, + base::BindOnce(&NetworkContext::FinishConstructingTrustTokenStore, + weak_factory_.GetWeakPtr())); + } else { + trust_token_store_->OnStoreReady(std::make_unique( + std::make_unique(), + std::make_unique( + network_service()->trust_token_key_commitments()))); + } + } + + std::unique_ptr user_agent_settings = + std::make_unique( + params_->accept_language, params_->user_agent); + // Borrow an alias for future use before giving the builder ownership. + user_agent_settings_ = user_agent_settings.get(); + builder.set_http_user_agent_settings(std::move(user_agent_settings)); + + builder.set_enable_brotli(params_->enable_brotli); + builder.set_enable_zstd(params_->enable_zstd); + + if (params_->proxy_resolver_factory) { + builder.SetMojoProxyResolverFactory( + std::move(params_->proxy_resolver_factory)); + } + +#if BUILDFLAG(IS_WIN) + if (params_->windows_system_proxy_resolver) { + builder.SetMojoWindowsSystemProxyResolver( + std::move(params_->windows_system_proxy_resolver)); + } +#endif // BUILDFLAG(IS_WIN) + +#if BUILDFLAG(IS_CHROMEOS_ASH) + if (params_->dhcp_wpad_url_client) { + builder.SetDhcpWpadUrlClient(std::move(params_->dhcp_wpad_url_client)); + } +#endif // BUILDFLAG(IS_CHROMEOS_ASH) + + if (!params_->http_cache_enabled) { + builder.DisableHttpCache(); + } else { + net::URLRequestContextBuilder::HttpCacheParams cache_params; + cache_params.max_size = params_->http_cache_max_size; + // Checking both to see if there are any file paths at all, and if there is + // specifically an http_cache_directory filepath in order to avoid a + // potential nullptr dereference if we just checked that + // `params_->file_paths->http_cache_directory' existed. + if (!params_->file_paths || !params_->file_paths->http_cache_directory) { + cache_params.type = + net::URLRequestContextBuilder::HttpCacheParams::IN_MEMORY; + } else { + // Network-bound NetworkContexts should not persist state on disk. + CHECK(!is_network_bound); + cache_params.path = params_->file_paths->http_cache_directory->path(); + cache_params.type = network_session_configurator::ChooseCacheType(); + if (params_->http_cache_file_operations_factory) { + cache_params.file_operations_factory = + base::MakeRefCounted( + std::move(params_->http_cache_file_operations_factory)); + } + } + cache_params.reset_cache = params_->reset_http_cache_backend; + +#if BUILDFLAG(IS_ANDROID) + app_status_listeners_.push_back( + std::make_unique( + cache_params.app_status_listener_getter)); +#endif // BUILDFLAG(IS_ANDROID) + builder.EnableHttpCache(cache_params); + } + + std::unique_ptr ssl_config_service = + std::make_unique( + std::move(params_->initial_ssl_config), + std::move(params_->ssl_config_client_receiver)); + SSLConfigServiceMojo* ssl_config_service_raw = ssl_config_service.get(); + builder.set_ssl_config_service(std::move(ssl_config_service)); + + if (!params_->initial_proxy_config && + !params_->proxy_config_client_receiver.is_valid()) { + params_->initial_proxy_config = + net::ProxyConfigWithAnnotation::CreateDirect(); + } + builder.set_proxy_config_service(std::make_unique( + std::move(params_->proxy_config_client_receiver), + std::move(params_->initial_proxy_config), + std::move(params_->proxy_config_poller_client))); + builder.set_pac_quick_check_enabled(params_->pac_quick_check_enabled); + + std::unique_ptr pref_service; + + base::FilePath http_server_properties_file_name; + if (GetFullDataFilePath(params_->file_paths, + &network::mojom::NetworkContextFilePaths:: + http_server_properties_file_name, + http_server_properties_file_name)) { + // Network-bound NetworkContexts should not persist state on disk. + CHECK(!is_network_bound); + scoped_refptr json_pref_store(new JsonPrefStore( + http_server_properties_file_name, nullptr, + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN, + base::TaskPriority::BEST_EFFORT}))); + PrefServiceFactory pref_service_factory; + pref_service_factory.set_user_prefs(json_pref_store); + pref_service_factory.set_async(true); + scoped_refptr pref_registry(new PrefRegistrySimple()); + HttpServerPropertiesPrefDelegate::RegisterPrefs(pref_registry.get()); + NetworkQualitiesPrefDelegate::RegisterPrefs(pref_registry.get()); + pref_service = pref_service_factory.Create(pref_registry.get()); + + builder.SetHttpServerProperties(std::make_unique( + std::make_unique(pref_service.get()), + net_log)); + + network_qualities_pref_delegate_ = + std::make_unique( + pref_service.get(), network_service_->network_quality_estimator()); + } + + base::FilePath transport_security_persister_file_name; + if (GetFullDataFilePath(params_->file_paths, + &network::mojom::NetworkContextFilePaths:: + transport_security_persister_file_name, + transport_security_persister_file_name)) { + // Network-bound NetworkContexts should not persist state on disk. + CHECK(!is_network_bound); + builder.set_transport_security_persister_file_path( + transport_security_persister_file_name); + } + builder.set_hsts_policy_bypass_list(params_->hsts_policy_bypass_list); + +#if BUILDFLAG(ENABLE_REPORTING) + bool reporting_enabled = base::FeatureList::IsEnabled(features::kReporting); + if (reporting_enabled) { + auto reporting_policy = net::ReportingPolicy::Create(); + if (params_->reporting_delivery_interval) { + reporting_policy->delivery_interval = + *params_->reporting_delivery_interval; + reporting_policy->endpoint_backoff_policy.initial_delay_ms = + params_->reporting_delivery_interval->InMilliseconds(); + } + builder.set_reporting_policy(std::move(reporting_policy)); + } else { + builder.set_reporting_policy(nullptr); + } + + bool nel_enabled = + base::FeatureList::IsEnabled(features::kNetworkErrorLogging); + builder.set_network_error_logging_enabled(nel_enabled); + + base::FilePath reporting_and_nel_store_database_name; + if (GetFullDataFilePath(params_->file_paths, + &network::mojom::NetworkContextFilePaths:: + reporting_and_nel_store_database_name, + reporting_and_nel_store_database_name) && + (reporting_enabled || nel_enabled)) { + // Network-bound NetworkContexts should not persist state on disk. + CHECK(!is_network_bound); + scoped_refptr client_task_runner = + base::SingleThreadTaskRunner::GetCurrentDefault(); + scoped_refptr background_task_runner = + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), + net::GetReportingAndNelStoreBackgroundSequencePriority(), + base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); + std::unique_ptr sqlite_store( + new net::SQLitePersistentReportingAndNelStore( + reporting_and_nel_store_database_name, client_task_runner, + background_task_runner)); + builder.set_persistent_reporting_and_nel_store(std::move(sqlite_store)); + } else { + builder.set_persistent_reporting_and_nel_store(nullptr); + } + +#endif // BUILDFLAG(ENABLE_REPORTING) + + net::HttpNetworkSessionParams session_params; + bool is_quic_force_disabled = false; + if (network_service_ && network_service_->quic_disabled()) + is_quic_force_disabled = true; + + auto quic_context = std::make_unique(); + network_session_configurator::ParseCommandLineAndFieldTrials( + *base::CommandLine::ForCurrentProcess(), is_quic_force_disabled, + &session_params, quic_context->params()); + + session_params.disable_idle_sockets_close_on_memory_pressure = + params_->disable_idle_sockets_close_on_memory_pressure; + + if (network_service_) { + session_params.key_auth_cache_server_entries_by_network_anonymization_key = + network_service_->split_auth_cache_by_network_isolation_key(); + } + + session_params.key_auth_cache_server_entries_by_network_anonymization_key = + base::FeatureList::IsEnabled( + features::kSplitAuthCacheByNetworkIsolationKey); + + builder.set_http_network_session_params(session_params); + builder.set_quic_context(std::move(quic_context)); + + if (params_->shared_dictionary_enabled) { + builder.set_enable_shared_dictionary(true); + builder.set_enable_shared_zstd( + base::FeatureList::IsEnabled(network::features::kSharedZstd)); + } + + builder.SetCreateHttpTransactionFactoryCallback( + base::BindOnce([](net::HttpNetworkSession* session) + -> std::unique_ptr { + return std::make_unique(session); + })); + + builder.set_host_mapping_rules( + command_line->GetSwitchValueASCII(switches::kHostResolverRules)); + +#if BUILDFLAG(IS_WIN) + if (params_->socket_brokers) { + builder.set_client_socket_factory( + std::make_unique( + std::move(params_->socket_brokers->client))); + } +#endif + + require_network_anonymization_key_ = + params_->require_network_anonymization_key; + + // If `require_network_anonymization_key_` is true, but the features that can + // trigger another URLRequest are not set to respect NetworkAnonymizationKeys, + // the URLRequests that they create might not have a NAK, so only set the + // corresponding value in the URLRequestContext to true at the URLRequest + // layer if all those features are set to respect NAK. + if (require_network_anonymization_key_ && + net::NetworkAnonymizationKey::IsPartitioningEnabled() && + base::FeatureList::IsEnabled( + domain_reliability::features:: + kPartitionDomainReliabilityByNetworkIsolationKey)) { + builder.set_require_network_anonymization_key(true); + } + +#if BUILDFLAG(IS_ANDROID) + builder.set_check_cleartext_permitted(params_->check_clear_text_permitted); +#endif // BUILDFLAG(IS_ANDROID) + + if (params_->cookie_deprecation_label.has_value()) { + builder.set_cookie_deprecation_label(*params_->cookie_deprecation_label); + } + +#if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS) + if (params_->device_bound_sessions_enabled) { + builder.set_has_device_bound_session_service(true); + } +#endif + + if (on_url_request_context_builder_configured) { + std::move(on_url_request_context_builder_configured).Run(&builder); + } + auto result = + URLRequestContextOwner(std::move(pref_service), builder.Build()); + + // Subscribe the CertVerifier to configuration changes that are exposed via + // the mojom::SSLConfig, but which are not part of the + // net::SSLConfig[Service] interfaces. + ssl_config_service_raw->SetCertVerifierForConfiguring( + result.url_request_context->cert_verifier()); + + // Attach some things to the URLRequestContextBuilder's + // TransportSecurityState. Since no requests have been made yet, safe to do + // this even after the call to Build(). + + if (network_service_->pins_list_updated()) { + result.url_request_context->transport_security_state()->UpdatePinList( + network_service_->pinsets(), network_service_->host_pins(), + network_service_->pins_list_update_time()); + } + +#if BUILDFLAG(IS_CT_SUPPORTED) + if (params_->enforce_chrome_ct_policy) { + require_ct_delegate_ = + std::make_unique(); + result.url_request_context->transport_security_state() + ->SetRequireCTDelegate(require_ct_delegate_.get()); + } +#endif // BUILDFLAG(IS_CT_SUPPORTED) + + if (params_->enable_domain_reliability) { + domain_reliability_monitor_ = + std::make_unique( + result.url_request_context.get(), + params_->domain_reliability_upload_reporter, + base::BindRepeating(&NetworkContext::CanUploadDomainReliability, + base::Unretained(this))); + domain_reliability_monitor_->AddBakedInConfigs(); + domain_reliability_monitor_->SetDiscardUploads( + params_->discard_domain_reliablity_uploads); + } + + return result; +} + +scoped_refptr +NetworkContext::MakeSessionCleanupCookieStore() const { + base::FilePath cookie_path; + if (!GetFullDataFilePath( + params_->file_paths, + &network::mojom::NetworkContextFilePaths::cookie_database_name, + cookie_path)) { + DCHECK(!params_->restore_old_session_cookies); + DCHECK(!params_->persist_session_cookies); + return nullptr; + } + scoped_refptr client_task_runner = + base::SingleThreadTaskRunner::GetCurrentDefault(); + scoped_refptr background_task_runner = + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), net::GetCookieStoreBackgroundSequencePriority(), + base::TaskShutdownBehavior::BLOCK_SHUTDOWN}); + + std::unique_ptr crypto_delegate = nullptr; + + if (params_->enable_encrypted_cookies) { + if (params_->cookie_encryption_provider) { + crypto_delegate = std::make_unique( + std::move(params_->cookie_encryption_provider)); + } else { + crypto_delegate = cookie_config::GetCookieCryptoDelegate(); + } + } + +#if BUILDFLAG(IS_WIN) + const bool enable_exclusive_access = params_->enable_locking_cookie_database; +#else + const bool enable_exclusive_access = false; +#endif // BUILDFLAG(IS_WIN) + scoped_refptr sqlite_store( + new net::SQLitePersistentCookieStore( + cookie_path, client_task_runner, background_task_runner, + params_->restore_old_session_cookies, std::move(crypto_delegate), + enable_exclusive_access)); + + return base::MakeRefCounted(sqlite_store); +} + +void NetworkContext::OnHttpCacheCleared(ClearHttpCacheCallback callback, + HttpCacheDataRemover* remover) { + bool removed = false; + for (auto iter = http_cache_data_removers_.begin(); + iter != http_cache_data_removers_.end(); ++iter) { + if (iter->get() == remover) { + removed = true; + http_cache_data_removers_.erase(iter); + break; + } + } + DCHECK(removed); + std::move(callback).Run(); +} + +void NetworkContext::OnHostResolverShutdown(HostResolver* resolver) { + auto found_resolver = host_resolvers_.find(resolver); + CHECK(found_resolver != host_resolvers_.end(), base::NotFatalUntil::M130); + host_resolvers_.erase(found_resolver); +} + +void NetworkContext::OnHttpCacheSizeComputed( + ComputeHttpCacheSizeCallback callback, + HttpCacheDataCounter* counter, + bool is_upper_limit, + int64_t result_or_error) { + std::erase_if(http_cache_data_counters_, base::MatchesUniquePtr(counter)); + std::move(callback).Run(is_upper_limit, result_or_error); +} + +void NetworkContext::OnConnectionError() { + // If owned by the network service, this call will delete |this|. + if (on_connection_close_callback_) + std::move(on_connection_close_callback_).Run(this); +} + +GURL NetworkContext::GetHSTSRedirect(const GURL& original_url) { + // TODO(lilyhoughton) This needs to be gotten rid of once explicit + // construction with a URLRequestContext is no longer supported. + if (!url_request_context_->transport_security_state() || + !original_url.SchemeIs("http") || + !url_request_context_->transport_security_state()->ShouldUpgradeToSSL( + original_url.host())) { + return original_url; + } + + GURL::Replacements replacements; + replacements.SetSchemeStr("https"); + return original_url.ReplaceComponents(replacements); +} + +#if BUILDFLAG(IS_P2P_ENABLED) +void NetworkContext::DestroySocketManager(P2PSocketManager* socket_manager) { + auto iter = socket_managers_.find(socket_manager); + CHECK(iter != socket_managers_.end(), base::NotFatalUntil::M130); + socket_managers_.erase(iter); +} +#endif // BUILDFLAG(IS_P2P_ENABLED) + +void NetworkContext::CanUploadDomainReliability( + const url::Origin& origin, + base::OnceCallback callback) { + client_->OnCanSendDomainReliabilityUpload( + origin, + base::BindOnce([](base::OnceCallback callback, + bool allowed) { std::move(callback).Run(allowed); }, + std::move(callback))); +} + +void NetworkContext::OnVerifyCertForSignedExchangeComplete( + uint64_t cert_verify_id, + int result) { + auto iter = cert_verifier_requests_.find(cert_verify_id); + CHECK(iter != cert_verifier_requests_.end(), base::NotFatalUntil::M130); + + auto pending_cert_verify = std::move(iter->second); + cert_verifier_requests_.erase(iter); + + bool pkp_bypassed = false; + if (result == net::OK) { +#if BUILDFLAG(IS_CT_SUPPORTED) + int ct_result = CheckCTRequirementsForSignedExchange( + *pending_cert_verify->result, + net::HostPortPair::FromURL(pending_cert_verify->url)); +#endif // BUILDFLAG(IS_CT_SUPPORTED) + net::TransportSecurityState::PKPStatus pin_validity = + url_request_context_->transport_security_state()->CheckPublicKeyPins( + net::HostPortPair::FromURL(pending_cert_verify->url), + pending_cert_verify->result->is_issued_by_known_root, + pending_cert_verify->result->public_key_hashes); + switch (pin_validity) { + case net::TransportSecurityState::PKPStatus::VIOLATED: + pending_cert_verify->result->cert_status |= + net::CERT_STATUS_PINNED_KEY_MISSING; + result = net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; + break; + case net::TransportSecurityState::PKPStatus::BYPASSED: + pkp_bypassed = true; + [[fallthrough]]; + case net::TransportSecurityState::PKPStatus::OK: + // Do nothing. + break; + } +#if BUILDFLAG(IS_CT_SUPPORTED) + if (result != net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && + ct_result != net::OK) + result = ct_result; +#endif // BUILDFLAG(IS_CT_SUPPORTED) + } + + std::move(pending_cert_verify->callback) + .Run(result, *pending_cert_verify->result.get(), pkp_bypassed); +} + +#if BUILDFLAG(IS_CHROMEOS) +void NetworkContext::TrustAnchorUsed() { + client_->OnTrustAnchorUsed(); +} +#endif // BUILDFLAG(IS_CHROMEOS) + +#if BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED) +void NetworkContext::EnsureMounted(network::TransferableDirectory* directory) { + if (directory->NeedsMount()) { + dismount_closures_.push_back(directory->Mount()); + } +} +#endif // BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED) + +void NetworkContext::InitializeCorsParams() { + for (const auto& pattern : params_->cors_origin_access_list) { + cors_origin_access_list_.SetAllowListForOrigin(pattern->source_origin, + pattern->allow_patterns); + cors_origin_access_list_.SetBlockListForOrigin(pattern->source_origin, + pattern->block_patterns); + } + for (const auto& key : params_->cors_exempt_header_list) + cors_exempt_header_list_.insert(key); + + acam_preflight_spec_conformant_ = + base::FeatureList::IsEnabled( + network::features:: + kAccessControlAllowMethodsInCORSPreflightSpecConformant) && + params_->acam_preflight_spec_conformant; +} + +void NetworkContext::FinishConstructingTrustTokenStore( + std::unique_ptr persister) { + trust_token_store_->OnStoreReady(std::make_unique( + std::move(persister), + std::make_unique( + network_service()->trust_token_key_commitments()))); +} + +bool NetworkContext::IsAllowedToUseAllHttpAuthSchemes( + const url::SchemeHostPort& scheme_host_port) { + DCHECK(url_matcher_); + return !url_matcher_->MatchURL(scheme_host_port.GetURL()).empty(); +} + +void NetworkContext::CreateTrustedUrlLoaderFactoryForNetworkService( + mojo::PendingReceiver + url_loader_factory_pending_receiver) { + auto url_loader_factory_params = mojom::URLLoaderFactoryParams::New(); + url_loader_factory_params->is_trusted = true; + url_loader_factory_params->process_id = network::mojom::kBrowserProcessId; + CreateURLLoaderFactory(std::move(url_loader_factory_pending_receiver), + std::move(url_loader_factory_params)); +} + +void NetworkContext::SetSharedDictionaryCacheMaxSize(uint64_t cache_max_size) { + if (!shared_dictionary_manager_) { + return; + } + shared_dictionary_manager_->SetCacheMaxSize(cache_max_size); +} + +void NetworkContext::ClearSharedDictionaryCache( + base::Time start_time, + base::Time end_time, + mojom::ClearDataFilterPtr filter, + ClearSharedDictionaryCacheCallback callback) { + if (!shared_dictionary_manager_) { + std::move(callback).Run(); + return; + } + shared_dictionary_manager_->ClearData(start_time, end_time, + BuildUrlFilter(std::move(filter)), + std::move(callback)); +} + +void NetworkContext::ClearSharedDictionaryCacheForIsolationKey( + const net::SharedDictionaryIsolationKey& isolation_key, + ClearSharedDictionaryCacheForIsolationKeyCallback callback) { + if (!shared_dictionary_manager_) { + std::move(callback).Run(); + return; + } + shared_dictionary_manager_->ClearDataForIsolationKey(isolation_key, + std::move(callback)); +} + +void NetworkContext::GetSharedDictionaryUsageInfo( + GetSharedDictionaryUsageInfoCallback callback) { + if (!shared_dictionary_manager_) { + std::move(callback).Run({}); + return; + } + shared_dictionary_manager_->GetUsageInfo(std::move(callback)); +} + +void NetworkContext::GetSharedDictionaryInfo( + const net::SharedDictionaryIsolationKey& isolation_key, + GetSharedDictionaryInfoCallback callback) { + if (!shared_dictionary_manager_) { + std::move(callback).Run({}); + return; + } + shared_dictionary_manager_->GetSharedDictionaryInfo(isolation_key, + std::move(callback)); +} + +void NetworkContext::GetSharedDictionaryOriginsBetween( + base::Time start_time, + base::Time end_time, + GetSharedDictionaryOriginsBetweenCallback callback) { + if (!shared_dictionary_manager_) { + std::move(callback).Run({}); + return; + } + shared_dictionary_manager_->GetOriginsBetween(start_time, end_time, + std::move(callback)); +} + +void NetworkContext::PreloadSharedDictionaryInfoForDocument( + const std::vector& urls, + mojo::PendingReceiver + preload_handle) { + if (shared_dictionary_manager_) { + shared_dictionary_manager_->PreloadSharedDictionaryInfoForDocument( + urls, std::move(preload_handle)); + } +} + +void NetworkContext::HasPreloadedSharedDictionaryInfoForTesting( + HasPreloadedSharedDictionaryInfoForTestingCallback callback) { + std::move(callback).Run( + shared_dictionary_manager_ && + shared_dictionary_manager_->HasPreloadedSharedDictionaryInfo()); +} + +void NetworkContext::ResourceSchedulerClientVisibilityChanged( + const base::UnguessableToken& client_token, + bool visible) { + resource_scheduler_->OnClientVisibilityChanged(client_token, visible); +} + +void NetworkContext::FlushCachedClientCertIfNeeded( + const net::HostPortPair& host, + const scoped_refptr& certificate) { + net::HttpNetworkSession* http_session = + url_request_context_->http_transaction_factory()->GetSession(); + DCHECK(http_session); + if (http_session->ssl_client_context()) { + http_session->ssl_client_context()->ClearClientCertificateIfNeeded( + host, certificate); + } +} + +void NetworkContext::FlushMatchingCachedClientCert( + const scoped_refptr& certificate) { + net::HttpNetworkSession* http_session = + url_request_context_->http_transaction_factory()->GetSession(); + DCHECK(http_session); + if (http_session->ssl_client_context()) { + http_session->ssl_client_context()->ClearMatchingClientCertificate( + certificate); + } +} + +void NetworkContext::SetCookieDeprecationLabel( + const std::optional& label) { + CHECK(url_request_context_); + url_request_context_->set_cookie_deprecation_label(label); +} + +void NetworkContext::RevokeNetworkForNonces( + const std::vector& nonces, + RevokeNetworkForNoncesCallback callback) { + for (const auto& nonce : nonces) { + network_revocation_nonces_.insert(nonce); + const std::set& exemptions = network_revocation_exemptions_[nonce]; + for (const auto& factory : url_loader_factories_) { + factory->CancelRequestsIfNonceMatchesAndUrlNotExempted(nonce, exemptions); + } +#if BUILDFLAG(ENABLE_WEBSOCKETS) + if (websocket_factory_) { + websocket_factory_->RemoveIfNonceMatches(nonce); + } +#endif // BUILDFLAG(ENABLE_WEBSOCKETS) + } + + if (callback) { + std::move(callback).Run(); + } +} + +void NetworkContext::ExemptUrlFromNetworkRevocationForNonce( + const GURL& exempted_url, + const base::UnguessableToken& nonce, + ExemptUrlFromNetworkRevocationForNonceCallback callback) { + GURL url_without_filename = exempted_url.GetWithoutFilename(); + network_revocation_exemptions_[nonce].insert(url_without_filename); + std::move(callback).Run(); +} + +void NetworkContext::Prefetch( + int32_t request_id, + uint32_t options, + const ResourceRequest& request, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { + if (!prefetch_enabled_) { + return; + } + + PrefetchURLLoaderClient* client = prefetch_cache_->Emplace(request); + if (!client) { + // This is normal if we already have a prefetch in progress for the {NIK, + // URL} combination. + return; + } + + prefetch_url_loader_factory_remote_->CreateLoaderAndStart( + client->GetURLLoaderPendingReceiver(), request_id, options, request, + client->BindNewPipeAndPassRemote(), traffic_annotation); +} + +void NetworkContext::GetBoundNetworkForTesting( + GetBoundNetworkForTestingCallback callback) { + std::move(callback).Run(url_request_context()->bound_network()); +} + +bool NetworkContext::IsNetworkForNonceAndUrlAllowed( + const base::UnguessableToken& nonce, + const GURL& url) const { + // If network hasn't been revoked for the nonce, it's allowed. + if (!network_revocation_nonces_.contains(nonce)) { + return true; + } + // If network has been revoked for the nonce, but the url is exempted, it's + // allowed. + if (network_revocation_exemptions_.contains(nonce) && + network_revocation_exemptions_.find(nonce)->second.contains( + url.GetWithoutFilename())) { + return true; + } + // The nonce was revoked and the url isn't exempted. + return false; +} + +void NetworkContext::InitializePrefetchURLLoaderFactory() { + auto pending_receiver = + prefetch_url_loader_factory_remote_.BindNewPipeAndPassReceiver(); + CreateURLLoaderFactory(std::move(pending_receiver), + CreateURLLoaderFactoryParamsForPrefetch()); +} + +} // namespace network diff --git a/tools/under-control/src/testing/variations/fieldtrial_testing_config.json b/tools/under-control/src/testing/variations/fieldtrial_testing_config.json new file mode 100755 index 000000000..cee8f79a9 --- /dev/null +++ b/tools/under-control/src/testing/variations/fieldtrial_testing_config.json @@ -0,0 +1,26061 @@ +{ + "AAudioInputStudy": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseAAudioInput" + ] + } + ] + } + ], + "ALPSNewCodepoint": [ + { + "platforms": [ + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseNewAlpsCodepointHttp2", + "UseNewAlpsCodepointQUIC" + ] + } + ] + } + ], + "AVFoundationCaptureForwardSampleTimestamps": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "AVFoundationCaptureForwardSampleTimestamps" + ] + } + ] + } + ], + "AblateSearchProviderWarmupRequests": [ + { + "platforms": [ + "android", + "chromeos", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AblateSearchProviderWarmup" + ] + } + ] + } + ], + "AccessibilityIncludeLongClickAction": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AccessibilityIncludeLongClickAction" + ] + } + ] + } + ], + "AccessibilityManageBroadcastReceiverOnBackground": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled_20240701", + "enable_features": [ + "AccessibilityManageBroadcastReceiverOnBackground" + ] + } + ] + } + ], + "AccessibilityPageZoom": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "AdjustForOSLevel": "false" + }, + "enable_features": [ + "AccessibilityPageZoom" + ] + } + ] + } + ], + "AccessibilityPageZoomEnhancements": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AccessibilityPageZoomEnhancements" + ] + } + ] + } + ], + "AccessibilitySerializationSizeMetrics": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AccessibilitySerializationSizeMetrics" + ] + } + ] + } + ], + "AccessibilitySnapshotStressTests": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_Max3500_20231206", + "params": { + "AccessibilitySnapshotStressTestsMaxNodes": "3500" + }, + "enable_features": [ + "AccessibilitySnapshotStressTests" + ] + }, + { + "name": "Enabled_Max2000_20231206", + "params": { + "AccessibilitySnapshotStressTestsMaxNodes": "2000" + }, + "enable_features": [ + "AccessibilitySnapshotStressTests" + ] + }, + { + "name": "Enabled_Max1500_20231206", + "params": { + "AccessibilitySnapshotStressTestsMaxNodes": "1500" + }, + "enable_features": [ + "AccessibilitySnapshotStressTests" + ] + }, + { + "name": "Enabled_Max1000_20231206", + "params": { + "AccessibilitySnapshotStressTestsMaxNodes": "1000" + }, + "enable_features": [ + "AccessibilitySnapshotStressTests" + ] + }, + { + "name": "Control_NoMax_20231206", + "params": { + "AccessibilitySnapshotStressTestsMaxNodes": "100000" + }, + "enable_features": [ + "AccessibilitySnapshotStressTests" + ] + } + ] + } + ], + "AccessibilityUnifiedSnapshots": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AccessibilityUnifiedSnapshots" + ] + } + ] + } + ], + "AdaptiveChargingParamTuning": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Experimental_20231205", + "params": { + "adaptive_charging_min_probability": "0.5" + }, + "enable_features": [ + "AdaptiveCharging" + ] + } + ] + } + ], + "AddressInfobarDisplayLength": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Sixteen_Seconds", + "params": { + "duration-seconds": "16" + }, + "enable_features": [ + "AddressInfobarDisplayLength" + ] + } + ] + } + ], + "AlignWakeUps": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "AlignWakeUps" + ] + } + ] + } + ], + "AllowDatapipeDrainedAsBytesConsumerInBFCache": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AllowDatapipeDrainedAsBytesConsumerInBFCache" + ] + } + ] + } + ], + "AndroidAnimateSuggestionsListAppearance": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AnimateSuggestionsListAppearance" + ] + } + ] + } + ], + "AndroidAnimatedImageDragShadow": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AnimatedImageDragShadow" + ] + } + ] + } + ], + "AndroidAutofillDirectFormSubmission": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AndroidAutofillDirectFormSubmission" + ] + } + ] + } + ], + "AndroidAutofillPrefillRequestsForLoginForms": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled_LooseSimilarityCheckWithCancellingSession_20240604", + "enable_features": [ + "AndroidAutofillCancelSessionOnNavigation", + "AndroidAutofillPrefillRequestsForLoginForms", + "AndroidAutofillUsePwmPredictionsForOverrides" + ] + } + ] + } + ], + "AndroidBackPressRefactor": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledWithSystemBack_20230404", + "params": { + "system_back": "true" + }, + "enable_features": [ + "BackGestureRefactorAndroid" + ], + "disable_features": [ + "BackGestureActivityTabProvider" + ] + }, + { + "name": "EnabledWithoutSystemBack_20230404", + "params": { + "system_back": "false" + }, + "enable_features": [ + "BackGestureRefactorAndroid" + ], + "disable_features": [ + "BackGestureActivityTabProvider" + ] + }, + { + "name": "ControlWithActivityTabProvider_20230404", + "enable_features": [ + "BackGestureActivityTabProvider" + ], + "disable_features": [ + "BackGestureRefactorAndroid" + ] + } + ] + } + ], + "AndroidHatsNext": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledWithMessages_20210831", + "params": { + "en_site_id": "78FakAwAN0tK1KeaPYj0PoiAHrrQ", + "max-number": "100", + "probability": "0.5", + "site-id": "78FakAwAN0tK1KeaPYj0PoiAHrrQ" + }, + "enable_features": [ + "ChromeSurveyNextAndroid" + ] + } + ] + } + ], + "AndroidHubFloatingActionButton": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AndroidHubFloatingActionButton" + ] + } + ] + } + ], + "AndroidLowLatencyCanvas": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LowLatencyCanvas2dImageChromium", + "LowLatencyWebGLImageChromium" + ], + "min_os_version": "10.0.0" + } + ] + } + ], + "AndroidMediaPickerAdoption": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_Direct", + "params": { + "use_action_pick_images": "true" + }, + "enable_features": [ + "MediaPickerAdoption" + ], + "min_os_version": "13.0.0" + }, + { + "name": "Enabled_Direct_Plus", + "params": { + "use_action_pick_images_plus": "true" + }, + "enable_features": [ + "MediaPickerAdoption" + ], + "min_os_version": "13.0.0" + }, + { + "name": "Enabled_Indirect", + "params": { + "use_action_get_content": "true" + }, + "enable_features": [ + "MediaPickerAdoption" + ], + "min_os_version": "13.0.0" + } + ] + } + ], + "AndroidMessagesSaveCard": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_60000_dialogV2_2022-04-18", + "params": { + "autodismiss_duration_ms_SaveCard": "60000", + "save_card_dialog_v2_enabled": "true", + "save_card_message_use_followup_button_text": "false", + "save_card_message_use_gpay_icon": "true" + }, + "enable_features": [ + "MessagesForAndroidSaveCard" + ] + }, + { + "name": "Enabled_60000_dialogV1_2022-04-18", + "params": { + "autodismiss_duration_ms_SaveCard": "60000", + "save_card_message_use_followup_button_text": "false", + "save_card_message_use_gpay_icon": "true" + }, + "enable_features": [ + "MessagesForAndroidSaveCard" + ] + } + ] + } + ], + "AndroidSandboxRendererProcessPolicy": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RestrictRendererPoliciesInBaseline", + "UseRendererProcessPolicy" + ] + } + ] + } + ], + "AndroidSystemTracing": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "EnablePerfettoSystemTracing", + "enable_features": [ + "EnablePerfettoSystemTracing" + ] + } + ] + } + ], + "AndroidTNotifications": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "RationaleShownAtFirstRequest_20220909", + "params": { + "always_show_rationale_before_requesting_permission": "true", + "notification_permission_dialog_text_variant_2": "false", + "permission_request_interval_days": "7" + }, + "enable_features": [ + "NotificationPermissionVariant" + ] + }, + { + "name": "TextVariant2_20220909", + "params": { + "always_show_rationale_before_requesting_permission": "true", + "notification_permission_dialog_text_variant_2": "true", + "permission_request_interval_days": "7" + }, + "enable_features": [ + "NotificationPermissionVariant" + ] + } + ] + } + ], + "AndroidTabDeclutter": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AndroidTabDeclutter" + ] + } + ] + } + ], + "AnimationForDesktopCapturePermissionChecker": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AnimationForDesktopCapturePermissionChecker" + ] + } + ] + } + ], + "ApnRevamp": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ApnRevamp" + ] + } + ] + } + ], + "AppCloseRefreshClankStudy": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Open30", + "enable_features": [ + "FeedCloseRefresh" + ] + }, + { + "name": "Interact30", + "params": { + "delay_minutes": "30", + "require_interaction": "true" + }, + "enable_features": [ + "FeedCloseRefresh" + ] + } + ] + } + ], + "AppListLaunchRecorder": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "AppListLaunchRecorder", + "enable_features": [ + "EnableAppListLaunchRecording" + ] + } + ] + } + ], + "AppMallStudy": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AppInstallServiceUri", + "CrosMall" + ] + }, + { + "name": "Enabled_20240619", + "enable_features": [ + "AppInstallServiceUri", + "CrosMall", + "CrosMallSwa" + ] + } + ] + } + ], + "AppSpecificHistory": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AppSpecificHistory" + ] + } + ] + } + ], + "AppStreamingAccessibilityIntegration": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EcheSWAProcessAndroidAccessibilityTree" + ] + } + ] + } + ], + "AppsCollectionsFeature": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Counterfactual_M127", + "params": { + "is-counterfactual": "true", + "is-modified-order": "false" + }, + "enable_features": [ + "AppsCollections" + ] + }, + { + "name": "Enabled_M127", + "params": { + "is-counterfactual": "false", + "is-modified-order": "false" + }, + "enable_features": [ + "AppsCollections" + ] + }, + { + "name": "Modified_Order_M127", + "params": { + "is-counterfactual": "false", + "is-modified-order": "true" + }, + "enable_features": [ + "AppsCollections" + ] + } + ] + } + ], + "AppsCollectionsHATS": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "HATS_Survey_Needing", + "params": { + "prob": "0.075", + "survey_cycle_length": "7", + "survey_start_date_ms": "1717064595", + "trigger_id": "c568w7vW40jBnuKU19R0RZJEYkgx" + }, + "enable_features": [ + "HappinessTrackingLauncherAppsNeeding" + ] + } + ] + } + ], + "AppsCollectionsHATSFinding": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "HATS_Survey_Finding", + "params": { + "prob": "0.025", + "survey_cycle_length": "7", + "survey_start_date_ms": "1717064595", + "trigger_id": "G3Fdon7fh0jBnuKU19R0XRX1udZS" + }, + "enable_features": [ + "HappinessTrackingLauncherAppsFinding" + ] + } + ] + } + ], + "ArcBlockIoScheduler": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "data_block_io_scheduler": "true" + }, + "enable_features": [ + "ArcBlockIoScheduler" + ], + "min_os_version": "15880.0.0" + } + ] + } + ], + "ArcExtendInputAnrTimeout": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ArcExtendInputAnrTimeout" + ], + "min_os_version": "15915.0.0" + } + ] + } + ], + "ArcIgnoreHoverEventAnr": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IgnoreHoverEventAnr" + ], + "min_os_version": "15818.0.0" + } + ] + } + ], + "ArcLazyWebViewInit": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LazyWebViewInit" + ] + } + ] + } + ], + "ArcOnDemandV2": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_app_launch_20240705", + "params": { + "activate_on_app_launch": "true" + }, + "enable_features": [ + "ArcOnDemandV2" + ] + } + ] + } + ], + "ArcSkipDropPageCache": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ArcSkipDropPageCache" + ] + } + ] + } + ], + "ArcUnthrottleOnActiveAudio": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20240307", + "enable_features": [ + "ArcUnthrottleOnActiveAudio" + ], + "min_os_version": "15794.0.0" + } + ] + } + ], + "ArcVmBlkMultipleWorkers": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ArcEnableVirtioBlkMultipleWorkers" + ] + } + ] + } + ], + "ArcVmBroadcastPreAnrHandling": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ArcVmBroadcastPreAnrHandling" + ] + } + ] + } + ], + "ArcVmDalvikMemoryProfile": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ArcUseDalvikMemoryProfile" + ] + } + ] + } + ], + "ArcVmIdleManagerV2": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledAC_V2", + "params": { + "delay_ms": "420000", + "ignore_battery_for_test": "true", + "pending_idle_reactivate": "false" + }, + "enable_features": [ + "ArcIdleManager" + ], + "min_os_version": "15795.0.0" + } + ] + } + ], + "ArcVmInitThrottle3": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "throttle_to_50_percent", + "params": { + "quota": "50" + }, + "enable_features": [ + "CrOSLateBootArcVmInitialThrottle" + ] + }, + { + "name": "throttle_to_75_percent", + "params": { + "quota": "75" + }, + "enable_features": [ + "CrOSLateBootArcVmInitialThrottle" + ] + } + ] + } + ], + "ArcVmLowMemJemallocArenas": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootArcVmLowMemJemallocArenas" + ] + } + ] + } + ], + "ArcVmMemorySize": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledVmMemSize-500_20231031", + "params": { + "shift_mib": "-500" + }, + "enable_features": [ + "ArcVmMemorySize" + ] + } + ] + } + ], + "ArcVmS2Idle": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ArcS2Idle" + ], + "min_os_version": "15880.0.0" + } + ] + } + ], + "ArcVmVirtualSwap": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "VirtualSwapEnabled_25PercentVmSize_10SecondSwapInterval", + "params": { + "guest_reclaim_enabled": "true", + "size_percentage": "25", + "virtual_swap_enabled": "true", + "virtual_swap_interval_ms": "10000" + }, + "enable_features": [ + "ArcGuestZram" + ] + } + ] + } + ], + "ArcVmmSwap": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ArcVmmSwapPolicy", + "ArcVmmSwapoutGhostWindow", + "ArcvmSwapoutKeyboardShortcut" + ], + "min_os_version": "15489.0.0" + }, + { + "name": "Enabled_20230615", + "enable_features": [ + "ArcVmmSwapPolicy", + "ArcVmmSwapoutGhostWindow" + ], + "min_os_version": "15489.0.0" + } + ] + } + ], + "AshUrgentDiscardingFromPerformanceManager": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20240328", + "enable_features": [ + "AshUrgentDiscardingFromPerformanceManager" + ] + } + ] + } + ], + "AssistMultiWord": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledWithGboard_20230907", + "params": { + "block": "[]", + "group": "gboard" + }, + "enable_features": [ + "AssistMultiWord" + ] + }, + { + "name": "EnabledWithGboardD_20230907", + "params": { + "block": "[]", + "group": "gboard_d" + }, + "enable_features": [ + "AssistMultiWord" + ] + }, + { + "name": "EnabledWithGboardE_20230907", + "params": { + "block": "[]", + "group": "gboard_e" + }, + "enable_features": [ + "AssistMultiWord" + ] + } + ] + } + ], + "AsyncDnsLinux": [ + { + "platforms": [ + "linux" + ], + "experiments": [ + { + "name": "Enabled_20221111", + "enable_features": [ + "AsyncDns" + ] + } + ] + } + ], + "AsyncNotiicationmanager": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AsyncNotificationManager" + ] + } + ] + } + ], + "AsyncQuicSession": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AsyncQuicSession" + ] + } + ] + } + ], + "AttributionReportDeliveryRetryDelays": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_CurrentDelay", + "params": { + "first_retry_delay": "5m", + "second_retry_delay": "15m" + }, + "enable_features": [ + "AttributionReportDeliveryRetryDelays" + ] + }, + { + "name": "Enabled_SmallDelay", + "params": { + "first_retry_delay": "2m", + "second_retry_delay": "10m" + }, + "enable_features": [ + "AttributionReportDeliveryRetryDelays" + ] + }, + { + "name": "Enabled_MediumDelay", + "params": { + "first_retry_delay": "10m", + "second_retry_delay": "1h" + }, + "enable_features": [ + "AttributionReportDeliveryRetryDelays" + ] + }, + { + "name": "Enabled_LargeDelay", + "params": { + "first_retry_delay": "15m", + "second_retry_delay": "6h" + }, + "enable_features": [ + "AttributionReportDeliveryRetryDelays" + ] + }, + { + "name": "Enabled_XLargeDelay", + "params": { + "first_retry_delay": "20m", + "second_retry_delay": "24h" + }, + "enable_features": [ + "AttributionReportDeliveryRetryDelays" + ] + } + ] + } + ], + "AudioFocusEnforcementStudy": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "DisabledV2", + "disable_features": [ + "AudioFocusEnforcement" + ] + } + ] + } + ], + "AudioOffload": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AudioOffload" + ] + } + ] + } + ], + "AudioRendererAlgorithmStartingCapacityForEncrypted": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "StartingCapacityForEncrypted_1000ms", + "params": { + "starting_capacity_for_encrypted": "1000ms" + }, + "enable_features": [ + "AudioRendererAlgorithmParameters" + ] + } + ] + } + ], + "AuthenticateUsingUserConsentVerifierApi": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AuthenticateUsingUserConsentVerifierApi", + "AuthenticateUsingUserConsentVerifierInteropApi" + ] + } + ] + } + ], + "AutoDisableAccessibility": [ + { + "platforms": [ + "android", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutoDisableAccessibility" + ] + } + ] + } + ], + "AutoSpeculationRules": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20231201", + "params": { + "config": "{\"framework_to_speculation_rules\":{\"12\":\"{\\\"prefetch\\\":[{\\\"source\\\":\\\"document\\\",\\\"eagerness\\\":\\\"conservative\\\",\\\"where\\\":{\\\"href_matches\\\":\\\"/*\\\"}}]}\"}}", + "holdback": "false" + }, + "enable_features": [ + "AutoSpeculationRules" + ] + }, + { + "name": "Holdback_20231201", + "params": { + "config": "{\"framework_to_speculation_rules\":{\"12\":\"{\\\"prefetch\\\":[{\\\"source\\\":\\\"document\\\",\\\"eagerness\\\":\\\"conservative\\\",\\\"where\\\":{\\\"href_matches\\\":\\\"/*\\\"}}]}\"}}", + "holdback": "true" + }, + "enable_features": [ + "AutoSpeculationRules" + ] + } + ] + } + ], + "AutocorrectByDefault": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "block": "[]" + }, + "enable_features": [ + "AutocorrectByDefault" + ] + }, + { + "name": "Default", + "params": { + "block": "[]" + }, + "enable_features": [ + "AutocorrectByDefault" + ] + }, + { + "name": "Holdback", + "params": { + "block": "[]" + }, + "enable_features": [] + } + ] + } + ], + "AutofillAddressFieldSwapping": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillAddressFieldSwapping" + ] + } + ] + } + ], + "AutofillAddressUserPerceptionSurveyUS": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "en_site_id": "Q13fLRHym0ugnJ3q1cK0Tm5d8fMW", + "probability": "1" + }, + "enable_features": [ + "AutofillAddressUserPerceptionSurvey" + ] + } + ] + } + ], + "AutofillAssociateForms": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillAssociateForms" + ] + } + ] + } + ], + "AutofillChangeDisusedAddressSuggestionTreatment": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "ignored-suggestions": "3" + }, + "enable_features": [ + "AutofillChangeDisusedAddressSuggestionTreatment" + ] + } + ] + } + ], + "AutofillContentEditableChangeEvents": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillContentEditableChangeEvents" + ] + } + ] + } + ], + "AutofillCreditCardUserPerceptionSurvey": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "en_site_id": "Q13fLRHym0ugnJ3q1cK0Tm5d8fMW", + "probability": "1" + }, + "enable_features": [ + "AutofillCreditCardUserPerceptionSurvey" + ] + } + ] + } + ], + "AutofillDontPrefixMatchCreditCardNumbersOrCvcs": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillDontPrefixMatchCreditCardNumbersOrCvcs" + ] + } + ] + } + ], + "AutofillDynamicallyLoadsFieldsForAddressInput": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillDynamicallyLoadsFieldsForAddressInput" + ] + } + ] + } + ], + "AutofillEnableAccountStorageForIneligibleCountries": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableAccountStorageForIneligibleCountries" + ] + } + ] + } + ], + "AutofillEnableAndroidNKeyForFidoAuthentication": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableAndroidNKeyForFidoAuthentication" + ] + } + ] + } + ], + "AutofillEnableCardBenefits": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableCardBenefitsForAmericanExpress", + "AutofillEnableCardBenefitsForCapitalOne", + "AutofillEnableCardBenefitsSync" + ] + } + ] + } + ], + "AutofillEnableCvcStorage": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableCvcStorageAndFilling", + "SyncAutofillWalletCredentialData" + ] + } + ] + } + ], + "AutofillEnableDisablingSuggestionsOnJSFocus": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillAndroidDisableSuggestionsOnJSFocus" + ] + } + ] + } + ], + "AutofillEnableEmailHeuristicOnlyAddressForms": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_AutocompleteAll", + "params": { + "autocomplete_email": "false" + }, + "enable_features": [ + "AutofillEnableEmailHeuristicOnlyAddressForms" + ] + } + ] + } + ], + "AutofillEnableExpirationDateImprovements": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableExpirationDateImprovements" + ] + } + ] + } + ], + "AutofillEnableFillingPhoneCountryCodesByAddressCountryCodes": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableFillingPhoneCountryCodesByAddressCountryCodes" + ] + } + ] + } + ], + "AutofillEnableFpanRiskBasedAuthentication": [ + { + "platforms": [ + "android", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableFpanRiskBasedAuthentication" + ] + } + ] + } + ], + "AutofillEnableLabelPrecedenceForTurkishAddresses": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableLabelPrecedenceForTurkishAddresses" + ] + } + ] + } + ], + "AutofillEnableLoadingAndConfirmation": [ + { + "platforms": [ + "android", + "chromeos", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableSaveCardLoadingAndConfirmation", + "AutofillEnableSaveCardLocalSaveFallback", + "AutofillEnableVcnEnrollLoadingAndConfirmation" + ] + } + ] + } + ], + "AutofillEnableManualFallbackIPH": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableManualFallbackIPH" + ] + } + ] + } + ], + "AutofillEnableMerchantDomainInUnmaskCardRequest": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "AutofillEnableMerchantDomainInUnmaskCardRequest", + "enable_features": [ + "AutofillEnableMerchantDomainInUnmaskCardRequest" + ] + } + ] + } + ], + "AutofillEnableNewCardProfileRankingAlgorithm": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableRankingFormulaAddressProfiles", + "AutofillEnableRankingFormulaCreditCards" + ] + } + ] + } + ], + "AutofillEnableNewSaveCardBubbleUi": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableNewSaveCardBubbleUi" + ] + } + ] + } + ], + "AutofillEnableVerveCardSupport": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableVerveCardSupport" + ] + } + ] + } + ], + "AutofillEnableVirtualCardOnFile": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillParseVcnCardOnFileStandaloneCvcFields", + "SyncAutofillWalletUsageData" + ] + } + ] + } + ], + "AutofillEnableVirtualCards": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableVirtualCards" + ] + } + ] + } + ], + "AutofillEnableXHRSubmissionDetectionIOS": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableXHRSubmissionDetectionIOS" + ] + } + ] + } + ], + "AutofillFixCachingOnJavaScriptChanges": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AllowJavaScriptToResetAutofillState", + "AutofillFixCachingOnJavaScriptChanges" + ] + } + ] + } + ], + "AutofillForUnclassifiedFieldsAvailable": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillForUnclassifiedFieldsAvailable" + ] + } + ] + } + ], + "AutofillGranularFillingAvailable": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "autofill_granular_filling_with_expand_control_visible_on_selection_only": "false", + "autofill_granular_filling_with_fill_everything_in_the_footer": "true", + "autofill_granular_filling_with_improved_labels": "true" + }, + "enable_features": [ + "AutofillGranularFillingAvailable" + ] + }, + { + "name": "Enabled_WithoutImprovedLabels", + "params": { + "autofill_granular_filling_with_expand_control_visible_on_selection_only": "false", + "autofill_granular_filling_with_fill_everything_in_the_footer": "true", + "autofill_granular_filling_with_improved_labels": "false" + }, + "enable_features": [ + "AutofillGranularFillingAvailable" + ] + }, + { + "name": "Enabled_WithFillEverythingAtTheTop", + "params": { + "autofill_granular_filling_with_expand_control_visible_on_selection_only": "false", + "autofill_granular_filling_with_fill_everything_in_the_footer": "false", + "autofill_granular_filling_with_improved_labels": "true" + }, + "enable_features": [ + "AutofillGranularFillingAvailable" + ] + }, + { + "name": "Enabled_WithExpandControlVisibleOnSelectionOnly", + "params": { + "autofill_granular_filling_with_expand_control_visible_on_selection_only": "true", + "autofill_granular_filling_with_fill_everything_in_the_footer": "true", + "autofill_granular_filling_with_improved_labels": "true" + }, + "enable_features": [ + "AutofillGranularFillingAvailable" + ] + } + ] + } + ], + "AutofillImproveSubmissionDetection": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_UnifySubmissionAndUseDomNodeIds", + "enable_features": [ + "AutofillReplaceCachedWebElementsByRendererIds", + "AutofillUnifyAndFixFormTracking" + ] + } + ] + } + ], + "AutofillKeyboardAccessory": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_With_Cards_and_VCN_20230324", + "enable_features": [ + "AutofillKeyboardAccessory", + "AutofillManualFallbackAndroid" + ] + } + ] + } + ], + "AutofillLogDeduplicationMetrics": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillLogDeduplicationMetrics" + ] + } + ] + } + ], + "AutofillLogUKMEventsWithSampleRate": [ + { + "platforms": [ + "android", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillLogUKMEventsWithSampleRate" + ] + } + ] + } + ], + "AutofillModelPredictions": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "model_active": "false" + }, + "enable_features": [ + "AutofillModelPredictions" + ] + } + ] + } + ], + "AutofillMoreProminentPopup": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillMoreProminentPopup" + ] + } + ] + } + ], + "AutofillPasswordUserPerceptionSurvey": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "en_site_id": "cLnNGzEX59NNVVEtwumiSF", + "probability": "1" + }, + "enable_features": [ + "AutofillPasswordUserPerceptionSurvey" + ] + } + ] + } + ], + "AutofillPhoneNumberDetectionImprovements": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_All", + "enable_features": [ + "AutofillConsiderPhoneNumberSeparatorsValidLabels", + "AutofillEnableSupportForPhoneNumberTrunkTypes", + "AutofillInferCountryCallingCode", + "AutofillPreferParsedPhoneNumber" + ] + } + ] + } + ], + "AutofillPopupZOrderSecuritySurface_V2": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillPopupZOrderSecuritySurface" + ] + } + ] + } + ], + "AutofillPreFilledFieldsCorrectly": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_OverwritePlaceholdersOnly", + "enable_features": [ + "AutofillOverwritePlaceholdersOnly", + "AutofillSkipPreFilledFields" + ] + } + ] + } + ], + "AutofillRequireValidLocalCardsInSettings": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillRequireValidLocalCardsInSettings" + ] + } + ] + } + ], + "AutofillSharedStorageServerCardData": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillSharedStorageServerCardData" + ] + } + ] + } + ], + "AutofillSilentlyRemoveQuasiDuplicates": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillSilentlyRemoveQuasiDuplicates" + ] + } + ] + } + ], + "AutofillSuggestionNStrikeModel": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "strike-limit": "5" + }, + "enable_features": [ + "AutofillSuggestionNStrikeModel" + ] + } + ] + } + ], + "AutofillSurveys": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "mac", + "windows", + "linux" + ], + "experiments": [ + { + "name": "Card_20230606", + "params": { + "en_site_id": "F2fsskHvB0ugnJ3q1cK0NXLjUaK5", + "probability": "1.0" + }, + "enable_features": [ + "AutofillCardSurvey" + ], + "disable_features": [ + "AutofillAddressSurvey", + "AutofillPasswordSurvey" + ] + }, + { + "name": "Password_20230606", + "params": { + "en_site_id": "6VQ4NCCaq0ugnJ3q1cK0TR13rB8t", + "probability": "1.0" + }, + "enable_features": [ + "AutofillPasswordSurvey" + ], + "disable_features": [ + "AutofillAddressSurvey", + "AutofillCardSurvey" + ] + }, + { + "name": "Address_20230606", + "params": { + "en_site_id": "qQW9c2ho10ugnJ3q1cK0X48UQjZs", + "probability": "1.0" + }, + "enable_features": [ + "AutofillAddressSurvey" + ], + "disable_features": [ + "AutofillCardSurvey", + "AutofillPasswordSurvey" + ] + } + ] + } + ], + "AutofillTestFormWithTestAddresses": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillTestFormWithTestAddresses" + ] + } + ] + } + ], + "AutofillUKMExperimentalFields": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "autofill_experimental_regex_bucket1": "test1" + }, + "enable_features": [ + "AutofillUKMExperimentalFields" + ] + } + ] + } + ], + "AutofillUploadCardRequestTimeout": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillUploadCardRequestTimeout" + ] + } + ] + } + ], + "AutofillUploadVotesForFieldsWithEmail": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillUploadVotesForFieldsWithEmail" + ] + } + ] + } + ], + "AutofillUpstream": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20220124", + "enable_features": [ + "AutofillUpstream" + ] + } + ] + } + ], + "AutofillUpstreamUpdatedUi": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_Security", + "params": { + "autofill_upstream_updated_ui_treatment": "1" + }, + "enable_features": [ + "AutofillUpstreamUpdatedUi" + ] + } + ] + } + ], + "AutofillVcnEnrollRequestTimeout": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillVcnEnrollRequestTimeout" + ] + } + ] + } + ], + "AutomaticLazyFrameLoading": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_LazyEmbeds0_20220809", + "params": { + "allowed_websites": "https://www.youtube.com|/embed,https://www.google.com|/maps/embed", + "strategy": "allow_list", + "timeout": "0" + }, + "enable_features": [ + "AutomaticLazyFrameLoadingToEmbedUrls", + "AutomaticLazyFrameLoadingToEmbeds" + ], + "disable_features": [ + "AutomaticLazyFrameLoadingToAds" + ] + }, + { + "name": "Enabled_LazyEmbeds3000_20220809", + "params": { + "allowed_websites": "https://www.youtube.com|/embed,https://www.google.com|/maps/embed", + "strategy": "allow_list", + "timeout": "3000" + }, + "enable_features": [ + "AutomaticLazyFrameLoadingToEmbedUrls", + "AutomaticLazyFrameLoadingToEmbeds" + ], + "disable_features": [ + "AutomaticLazyFrameLoadingToAds" + ] + }, + { + "name": "Enabled_LazyEmbeds5000_20220809", + "params": { + "allowed_websites": "https://www.youtube.com|/embed,https://www.google.com|/maps/embed", + "strategy": "allow_list", + "timeout": "5000" + }, + "enable_features": [ + "AutomaticLazyFrameLoadingToEmbedUrls", + "AutomaticLazyFrameLoadingToEmbeds" + ], + "disable_features": [ + "AutomaticLazyFrameLoadingToAds" + ] + }, + { + "name": "Enabled_LazyEmbedUrls_20220809", + "params": { + "allowed_websites": "https://www.youtube.com|/embed,https://www.google.com|/maps/embed", + "strategy": "allow_list" + }, + "enable_features": [ + "AutomaticLazyFrameLoadingToEmbedUrls" + ], + "disable_features": [ + "AutomaticLazyFrameLoadingToAds", + "AutomaticLazyFrameLoadingToEmbeds" + ] + } + ] + } + ], + "AvatarsCloudMigration": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AvatarsCloudMigration" + ] + } + ] + } + ], + "AvoidEntryCreationForNoStore": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "AvoidEntryCreationForNoStoreCacheSize": "10000" + }, + "enable_features": [ + "AvoidEntryCreationForNoStore" + ] + } + ] + } + ], + "AvoidLoadingPredictorPrefetchDuringBrowserStartup": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AvoidLoadingPredictorPrefetchDuringBrowserStartup" + ] + } + ] + } + ], + "AvoidResourceRequestCopies": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AvoidResourceRequestCopies" + ] + } + ] + } + ], + "AvoidScheduleWorkDuringNativeEventProcessing": [ + { + "platforms": [ + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AvoidScheduleWorkDuringNativeEventProcessing" + ] + } + ] + } + ], + "BFCachePerformanceManagerPolicy": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledPolicy_CacheSize6_20230525", + "params": { + "cache_size": "6", + "foreground_cache_size": "0" + }, + "enable_features": [ + "BFCachePerformanceManagerPolicy", + "BackForwardCacheSize" + ] + } + ] + } + ], + "BackForwardCacheCaptureBlockingDetails": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RegisterJSSourceLocationBlockingBFCache" + ] + } + ] + } + ], + "BackForwardCacheForPageWithCacheControlNotStoredHeader": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240129", + "params": { + "level": "restore-unless-cookie-change", + "ttl": "3m" + }, + "enable_features": [ + "CacheControlNoStoreEnterBackForwardCache" + ] + } + ] + } + ], + "BackForwardCacheMediaSessionService": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BackForwardCacheMediaSessionService" + ] + } + ] + } + ], + "BackForwardCacheMemoryControls": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + }, + { + "name": "Enabled_1000", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1000" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + }, + { + "name": "Enabled_1000", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1001" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + }, + { + "name": "Enabled_1000", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1100" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + }, + { + "name": "Enabled_1000", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1200" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + }, + { + "name": "Enabled_1300", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1300" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + }, + { + "name": "Enabled_1000", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1400" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + }, + { + "name": "Enabled_1500", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1500" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + }, + { + "name": "Enabled_1000", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1600" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + }, + { + "name": "Enabled_1700", + "params": { + "memory_threshold_for_back_forward_cache_in_mb": "1700" + }, + "enable_features": [ + "BackForwardCacheMemoryControls" + ] + } + ] + } + ], + "BackForwardCacheNotRestoredReasons": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BackForwardCacheSendNotRestoredReasons" + ] + } + ] + } + ], + "BackForwardCache_NoMemoryLimit_Trial": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BackForwardCache_NoMemoryLimit_Trial" + ] + } + ] + } + ], + "BackNavigationMenuIPH": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledIPHWhenUserPerformsChainedBackNavigation_20230510", + "params": { + "availability": ">0", + "event_trigger": "name:back_navigation_menu_iph_is_triggered;comparator:<=4;window:365;storage:365", + "event_used": "name:back_navigation_menu_is_opened;comparator:==0;window:7;storage:365", + "session_rate": "<1", + "snooze_params": "max_limit:4,snooze_interval:7", + "x_experiment": "1" + }, + "enable_features": [ + "IPH_BackNavigationMenu" + ] + } + ] + } + ], + "BackToHomeAnimation": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20240423", + "enable_features": [ + "BackToHomeAnimation" + ] + } + ] + } + ], + "BackgroundCrxDownloaderMac": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "enable_features": [ + "BackgroundCrxDownloaderMac" + ] + } + ] + } + ], + "BackgroundResourceFetch": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BackgroundResourceFetch", + "ReduceTransferSizeUpdatedIPC" + ] + } + ] + } + ], + "BackgroundThreadNormalMemoryPriorityWin": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BackgroundThreadNormalMemoryPriorityWin" + ] + } + ] + } + ], + "BatchNativeEventsInMessagePumpEpoll": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "android_webview", + "android_weblayer" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BatchNativeEventsInMessagePumpEpoll" + ] + } + ] + } + ], + "BatchNativeEventsInMessagePumpKqueue": [ + { + "platforms": [ + "mac", + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BatchNativeEventsInMessagePumpKqueue" + ] + } + ] + } + ], + "BatterySaverModeRenderTuning": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BatterySaverModeRenderTuning" + ] + } + ] + } + ], + "BeforeunloadEventCancelByPreventDefault": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BeforeunloadEventCancelByPreventDefault" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "BeforeunloadEventCancelByPreventDefault" + ] + } + ] + } + ], + "BiometricAuthPwdFillAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20210616", + "enable_features": [ + "BiometricTouchToFill" + ] + } + ] + } + ], + "BlinkSchedulerCompositorTQPolicyDuringThreadedScroll": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledWithLowPriority_20220729", + "params": { + "policy": "low-priority-with-anti-starvation" + }, + "enable_features": [ + "ThreadedScrollPreventRenderingStarvation" + ] + } + ] + } + ], + "BlockAcceptClientHints": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "BlockedSite": "https://www.google.com" + }, + "enable_features": [ + "BlockAcceptClientHints" + ] + } + ] + } + ], + "BluetoothQualityReport": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20221013", + "enable_features": [ + "BluetoothQualityReport" + ] + } + ] + } + ], + "BoardingPassDetectorMultiArms": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_US", + "params": { + "boarding_pass_detector_urls": "https://www.aa.com,https://www.delta.com,https://www.hawaiianairlines.com" + }, + "enable_features": [ + "BoardingPassDetector" + ] + } + ] + } + ], + "BoostRenderProcessForLoading": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prioritize_prerendering": "false", + "target_urls": "[]" + }, + "enable_features": [ + "BoostRenderProcessForLoading" + ] + } + ] + } + ], + "BorealisProvision": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BorealisProvision" + ] + } + ] + } + ], + "BorealisZinkGlDriver": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BorealisZinkGlDriver" + ] + } + ] + } + ], + "BottomOmniboxPhase2IOS": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_Both_Top", + "params": { + "BottomOmniboxPromoDefaultPositionParam": "Top" + }, + "enable_features": [ + "BottomOmniboxPromoAppLaunch", + "BottomOmniboxPromoDefaultPosition", + "BottomOmniboxPromoFRE", + "BottomOmniboxPromoRegionFilter" + ] + } + ] + } + ], + "BoundaryEventDispatchTracksNodeRemoval": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BoundaryEventDispatchTracksNodeRemoval" + ] + } + ] + } + ], + "BrowserControlsEarlyResize": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BrowserControlsEarlyResize" + ] + } + ] + } + ], + "BrowserSwitcherNoneIsGreylist": [ + { + "platforms": [ + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BrowserSwitcherNoneIsGreylist" + ] + } + ] + } + ], + "BrowserThreadPoolAdjustmentForAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "thread_pool_default_20230920", + "params": { + "BrowserThreadPoolCoresMultiplier": "0.6", + "BrowserThreadPoolMax": "8", + "BrowserThreadPoolMin": "6", + "BrowserThreadPoolOffset": "0" + }, + "enable_features": [ + "BrowserThreadPoolAdjustment" + ] + } + ] + } + ], + "BrowserThreadPoolAdjustmentForDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "thread_pool_default_20230920", + "params": { + "BrowserThreadPoolCoresMultiplier": "0.6", + "BrowserThreadPoolMax": "32", + "BrowserThreadPoolMin": "16", + "BrowserThreadPoolOffset": "0" + }, + "enable_features": [ + "BrowserThreadPoolAdjustment" + ] + } + ] + } + ], + "BrowsingDataModelAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BrowsingDataModel" + ] + } + ] + } + ], + "BubbleMetricsApi": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BubbleMetricsApi" + ] + } + ] + } + ], + "BufferSizeForFilterSourceStream": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "buffer_size_0032k_20230919", + "params": { + "BufferSizeForFilterSourceStream": "32768" + }, + "enable_features": [ + "BufferSizeForFilterSourceStreamFeature" + ] + } + ] + } + ], + "BuiltInHlsMP4": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BuiltInHlsMP4" + ] + } + ] + } + ], + "CCTGoogleBottomBar": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledWithSearchButton_Dev_20240718", + "params": { + "google_bottom_bar_button_list": "0,3,9,2" + }, + "enable_features": [ + "CCTGoogleBottomBar" + ] + } + ] + } + ], + "CCTPrewarmTab": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CCTPrewarmTab" + ] + } + ] + } + ], + "COMInitForUtilWin": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UtilWinProcessUsesUIPump", + "UtilityWithUIPumpInitializesCOM" + ] + } + ] + } + ], + "CPSS-V2-Android": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20240508", + "enable_features": [ + "PermissionDedicatedCpssSettingAndroid" + ] + } + ] + } + ], + "CPUInterventionEvaluationLogging": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240215", + "enable_features": [ + "CPUInterventionEvaluationLogging" + ] + } + ] + } + ], + "CSSDisplayAnimation": [ + { + "platforms": [ + "android", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CSSDisplayAnimation" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "CSSDisplayAnimation" + ] + } + ] + } + ], + "CSSLazyParsingFastPath": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CSSLazyParsingFastPath" + ] + } + ] + } + ], + "CVDisplayLinkBeginFrameSource": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CVDisplayLinkBeginFrameSource" + ] + } + ] + } + ], + "CameraMicPreview": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CameraMicPreview", + "GetUserMediaDeferredDeviceSettingsSelection" + ] + } + ] + } + ], + "Canvas2DAutoFlushParams": [ + { + "platforms": [ + "mac", + "windows", + "android" + ], + "experiments": [ + { + "name": "Candidate", + "params": { + "max_pinned_image_kb": "32768", + "max_recorded_op_kb": "2048" + }, + "enable_features": [ + "Canvas2DAutoFlushParams" + ] + } + ] + } + ], + "Canvas2DReclaimUnusedResources": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "Canvas2DReclaimUnusedResources" + ] + } + ] + } + ], + "CanvasHibernationExperiments": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "Canvas2DHibernation", + "Canvas2DHibernationReleaseTransferMemory", + "ClearCanvasResourcesInBackground", + "EvictionUnlocksResources" + ] + } + ] + } + ], + "CanvasOutOfProcessRasterization": [ + { + "platforms": [ + "chromeos", + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CanvasOopRasterization" + ] + } + ] + } + ], + "CaptureModeEducation": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "EnabledShortcutNudge_20231214", + "params": { + "CaptureModeEducationParam": "ShortcutNudge" + }, + "enable_features": [ + "CaptureModeEducation" + ] + }, + { + "name": "EnabledShortcutTutorial_20231214", + "params": { + "CaptureModeEducationParam": "ShortcutTutorial" + }, + "enable_features": [ + "CaptureModeEducation" + ] + }, + { + "name": "EnabledQuickSettingsNudge_20231214", + "params": { + "CaptureModeEducationParam": "QuickSettingsNudge" + }, + "enable_features": [ + "CaptureModeEducation" + ] + } + ] + } + ], + "CastMirroringPlayoutDelayChromeOS": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "cast_mirroring_playout_delay_ms": "200" + }, + "enable_features": [ + "CastMirroringPlayoutDelay" + ] + } + ] + } + ], + "CastStreamingVp9": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CastStreamingVp9" + ] + } + ] + } + ], + "CatanCombinedHoldback23H2": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DelayFirstPeriodicPAPurgeOrReclaim", + "DelayFirstWorkerWake", + "InhibitLoadingStateUpdate", + "MainThreadCompositingPriority", + "QuickIntensiveWakeUpThrottlingAfterLoading", + "ReduceCookieIPCs", + "UseCompositorJob" + ], + "disable_features": [ + "RecordSequenceManagerCrashKeys", + "ThreadControllerSetsProfilerMetadata" + ] + } + ] + }, + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DelayFirstPeriodicPAPurgeOrReclaim", + "DelayFirstWorkerWake", + "InhibitLoadingStateUpdate", + "QuickIntensiveWakeUpThrottlingAfterLoading", + "ReduceCookieIPCs", + "RunTasksByBatches", + "UseCompositorJob" + ], + "disable_features": [ + "RecordSequenceManagerCrashKeys", + "ThreadControllerSetsProfilerMetadata" + ] + } + ] + }, + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CacheMacSandboxProfiles", + "DelayFirstPeriodicPAPurgeOrReclaim", + "DelayFirstWorkerWake", + "InhibitLoadingStateUpdate", + "MacSetDefaultTaskRole", + "MainThreadCompositingPriority", + "QuickIntensiveWakeUpThrottlingAfterLoading", + "ReduceCookieIPCs", + "RunTasksByBatches", + "SkipConditionVariableWakeupHack", + "UseCompositorJob" + ], + "disable_features": [ + "RecordSequenceManagerCrashKeys", + "ThreadControllerSetsProfilerMetadata" + ] + } + ] + }, + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AboveNormalCompositingBrowserWin", + "DelayFirstPeriodicPAPurgeOrReclaim", + "DelayFirstWorkerWake", + "ExplicitHighResolutionTimerWin", + "InhibitLoadingStateUpdate", + "MainThreadCompositingPriority", + "QuickIntensiveWakeUpThrottlingAfterLoading", + "ReduceCookieIPCs", + "UseCompositorJob", + "UseEcoQoSForBackgroundProcess" + ], + "disable_features": [ + "RecordSequenceManagerCrashKeys", + "ThreadControllerSetsProfilerMetadata" + ] + } + ] + } + ], + "CbdTimeframeRequired": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CbdTimeframeRequired" + ] + } + ] + } + ], + "CctClientDataHeader": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "expected_version": "300000000", + "header_value": "header value" + }, + "enable_features": [ + "CCTClientDataHeader" + ] + } + ] + } + ], + "CdmStorageDatabaseDefaultTrial": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "CdmStorageDatabaseMigration" + ] + } + ] + } + ], + "CheckHTMLParserBudgetLessOften": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_Nonstable_20230320", + "enable_features": [ + "CheckHTMLParserBudgetLessOften" + ] + } + ] + } + ], + "ChromeCartDomBasedHeuristics": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "enabled_chrome_cart_dom_based_heuristics_20230214", + "enable_features": [ + "ChromeCartDomBasedHeuristics" + ] + } + ] + } + ], + "ChromeCompose": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "Compose" + ] + } + ] + } + ], + "ChromeHomeFrequency": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_4H", + "params": { + "start_surface_return_time_on_tablet_seconds": "14400" + }, + "enable_features": [ + "StartSurfaceReturnTime" + ] + } + ] + } + ], + "ChromeLabs": [ + { + "platforms": [ + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20210128", + "enable_features": [ + "ChromeLabs" + ] + } + ] + } + ], + "ChromeLabsChromeOS": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled_20210617", + "enable_features": [ + "ChromeLabs" + ] + } + ] + } + ], + "ChromeOSARCVMAppRescue": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledGroupMedium_20221212", + "params": { + "interval": "30000", + "swappiness": "0" + }, + "enable_features": [ + "ArcMglruReclaim" + ] + } + ] + } + ], + "ChromeOSARCVMLmkPerceptibleMinState": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ArcLmkPerceptibleMinStateUpdate" + ] + } + ] + } + ], + "ChromeOSARCVMReclaimThrottle": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledGroupMedium_20220808", + "params": { + "ArcVmInactivityTimeMs": "600s", + "ArcVmTrimBackoffTimeMs": "900s", + "MaxPageLimit": "250000", + "OnlyDropCachesOnFirstMemoryPressureAfterArcVmBoot": "true", + "PagesPerMinute": "15000", + "TrimArcVmOnFirstMemoryPressureAfterArcVmBoot": "true" + }, + "enable_features": [ + "TrimArcVmOnMemoryPressure" + ] + } + ] + } + ], + "ChromeOSAmbientModeManagedScreensaver": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "enable_features": [ + "ChromeOSAmbientModeManagedScreensaver" + ] + }, + { + "name": "Enabled", + "enable_features": [ + "ChromeOSAmbientModeManagedScreensaver" + ] + } + ] + } + ], + "ChromeOSBoostUrgentVariables": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledGroup60_20230307", + "params": { + "BoostUrgent": "60" + }, + "enable_features": [ + "CrOSLateBootSchedUtilHints60", + "SchedUtilHints" + ], + "disable_features": [ + "CrOSLateBootSchedUtilHints40", + "CrOSLateBootSchedUtilHints80" + ] + } + ] + } + ], + "ChromeOSContainerAppPreinstall": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ContainerAppPreinstall" + ] + } + ] + } + ], + "ChromeOSGlanceablesTimeManagementClassroomStudentView": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "GlanceablesTimeManagementClassroomStudentView" + ] + } + ] + } + ], + "ChromeOSGlanceablesTimeManagementTasksView": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "GlanceablesTimeManagementTasksView" + ] + } + ] + } + ], + "ChromeOSGrowthFramework": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledInDemoMode", + "enable_features": [ + "GrowthCampaignsInDemoMode", + "GrowthFramework" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkFileAppGamgee": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "file_app_gamgee_exp" + }, + "enable_features": [ + "GrowthCampaignsExperimentFileAppGamgee" + ], + "disable_features": [ + "GoogleOneOfferFilesBanner" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkG1Nudge": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Photos", + "params": { + "exp_tag": "g1_photos" + }, + "enable_features": [ + "DisableGoogleOneOfferFilesBanner", + "GrowthCampaignsExperimentG1Nudge" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy1": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_1_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment1" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy10": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_10_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment10" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy11": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_11_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment11" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy12": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_12_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment12" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy13": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_13_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment13" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy14": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_14_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment14" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy15": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_15_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment15" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy16": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_16_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment16" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy17": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_17_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment17" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy18": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_18_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment18" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy19": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_19_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment19" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy2": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_2_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment2" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy20": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_20_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment20" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy3": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_3_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment3" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy4": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_4_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment4" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy5": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_5_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment5" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy6": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_6_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment6" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy7": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_7_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment7" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy8": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_8_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment8" + ] + } + ] + } + ], + "ChromeOSGrowthFrameworkStudy9": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "exp_tag": "exp_tag_9_1" + }, + "enable_features": [ + "GrowthCampaignsExperiment9" + ] + } + ] + } + ], + "ChromeOSHoldingSpaceSuggestions": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "enable_features": [ + "HoldingSpaceSuggestions" + ] + }, + { + "name": "Enabled_Teamfood", + "enable_features": [ + "HoldingSpaceSuggestions" + ] + } + ] + } + ], + "ChromeOSIgnoreUiGainsOnAGC": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20230905", + "enable_features": [ + "IgnoreUiGains" + ] + } + ] + } + ], + "ChromeOSMaterialNextWaveOneWithTimeOfDayM117AndBeyond": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "TimeOfDayEnabledM117AndBeyond", + "enable_features": [ + "FeatureManagementTimeOfDayScreenSaver", + "FeatureManagementTimeOfDayWallpaper", + "Jelly", + "TimeOfDayScreenSaver", + "TimeOfDayWallpaper" + ] + } + ] + } + ], + "ChromeOSMemoryPressureSignalStudyArc": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled5MinutesKillDelay", + "params": { + "critical_threshold_percentage": "800", + "priority_app_lmk_delay_list": "com.mojang.minecraftpe,com.cisco.anyconnect.vpn.android.avf,com.cisco.anyconnect.vpn.android.avf:nchs,com.cisco.anyconnect.vpn.android.avf:umbrella,zscaler.com.zschromeosapp,net.openvpn.openvpn,net.openvpn.openvpn:openvpn_service,com.checkpoint.VPN,com.fortinet.forticlient_vpn,com.fast.free.unblock.secure.vpn,com.zscaler.doeprod4522", + "priority_app_lmk_delay_sec": "300" + }, + "enable_features": [ + "ArcPriorityAppLmkDelay", + "ChromeOSMemoryPressureSignalStudyArc" + ] + } + ] + } + ], + "ChromeOSMemoryPressureSignalStudyNonArc": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "ChromeOSMemoryPressureSignalStudyNonArc" + ] + } + ] + } + ], + "ChromeOSOobeGaiaInfoScreen": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "OobeGaiaInfoScreen" + ] + } + ] + } + ], + "ChromeOSOobePersonalizedOnboarding": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OobePersonalizedOnboarding" + ] + } + ] + } + ], + "ChromeOSOobeQuickStart": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "OobeQuickStart" + ] + } + ] + } + ], + "ChromeOSPrintingIppUsb": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IppFirstSetupForUsbPrinters" + ] + } + ] + } + ], + "ChromeOSRawPSIMetrics": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledGroup10s_20220107", + "params": { + "period": "10" + }, + "enable_features": [ + "ArcVmMemoryPSIReports", + "MemoryPressureMetricsDetail" + ] + } + ] + } + ], + "ChromeOSWelcomeTourV2": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WelcomeTourV2" + ] + }, + { + "name": "Counterfactual", + "enable_features": [ + "WelcomeTourCounterfactualArm" + ] + }, + { + "name": "Holdback", + "enable_features": [ + "WelcomeTourHoldbackArm" + ] + } + ] + } + ], + "ChromeStartAccessibility": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "StartSurfaceWithAccessibility" + ] + } + ] + } + ], + "ChromeWallpaperSearchEntrypoints": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "BothEntrypointsAndAnimation", + "enable_features": [ + "CustomizeChromeWallpaperSearchButton", + "NtpWallpaperSearchButton", + "NtpWallpaperSearchButtonAnimation" + ] + }, + { + "name": "BothEntrypointsNoAnimation", + "enable_features": [ + "CustomizeChromeWallpaperSearchButton", + "NtpWallpaperSearchButton" + ], + "disable_features": [ + "NtpWallpaperSearchButtonAnimation" + ] + }, + { + "name": "PanoramaButtonOnlyNoAnimation", + "enable_features": [ + "CustomizeChromeWallpaperSearchButton" + ], + "disable_features": [ + "NtpWallpaperSearchButton", + "NtpWallpaperSearchButtonAnimation" + ] + } + ] + } + ], + "ChromeWallpaperSearchGlobal": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "WallpaperSearchGlobal", + "enable_features": [ + "CustomizeChromeWallpaperSearch", + "CustomizeChromeWallpaperSearchInspirationCard", + "WallpaperSearchGraduated" + ], + "disable_features": [ + "WallpaperSearchSettingsVisibility" + ] + } + ] + } + ], + "ChromeWallpaperSearchHaTS": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "WallpaperSearchHatsDelayParam": "18s", + "en_site_id": "foo", + "probability": "1.0" + }, + "enable_features": [ + "HappinessTrackingSurveysForWallpaperSearch" + ] + } + ] + } + ], + "ChromeWideEchoCancellation": [ + { + "platforms": [ + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20220412", + "params": { + "processing_fifo_size": "110" + }, + "enable_features": [ + "ChromeWideEchoCancellation" + ] + } + ] + } + ], + "Chromnient": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_Responsive_Omnibox_Entry_Point", + "params": { + "endpoint-url": "https://lensfrontend-pa.googleapis.com/v1/crupload", + "omnibox-entry-point": "true", + "omnibox-entry-point-always-visible": "false", + "select-text-over-region-trigger-threshold": "0.1", + "text-vertical-margin": "12", + "use-oauth-for-requests": "true" + }, + "enable_features": [ + "LensOverlay" + ], + "disable_features": [ + "ContextMenuSearchForVideoFrame" + ] + } + ] + } + ], + "ClankFeedSyntheticCapabilities": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FeedSyntheticCapabilities" + ] + } + ] + } + ], + "ClankFollowUIUpdate": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FeedFollowUiUpdate" + ] + } + ] + } + ], + "ClankTabResumpton": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "max_tiles_number": "1", + "show_see_more": "true", + "show_tabs_in_one_module": "true", + "use_default_app_filter": "true", + "use_salient_image": "true" + }, + "enable_features": [ + "TabResumptionModuleAndroid" + ] + }, + { + "name": "EnabledV2", + "params": { + "disable_blend": "true", + "enable_v2": "true", + "max_tiles_number": "1", + "show_see_more": "true", + "show_tabs_in_one_module": "true", + "use_default_app_filter": "true", + "use_salient_image": "true" + }, + "enable_features": [ + "TabResumptionModuleAndroid" + ] + }, + { + "name": "EnabledML", + "params": { + "enable_v2": "true", + "fetch_history_backend": "true", + "fetch_local_tabs_backend": "true", + "show_see_more": "true", + "show_tabs_in_one_module": "true", + "use_default_app_filter": "true", + "use_salient_image": "true" + }, + "enable_features": [ + "TabResumptionModuleAndroid" + ] + } + ] + } + ], + "ClearDeviceDataOnSignOutForManagedUsers": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ClearDeviceDataOnSignOutForManagedUsers" + ] + } + ] + } + ], + "ClearGrShaderDiskCacheOnInvalidPrefix": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ClearGrShaderDiskCacheOnInvalidPrefix" + ] + } + ] + } + ], + "ClearUndecryptablePasswords": [ + { + "platforms": [ + "mac", + "windows", + "linux", + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ClearUndecryptablePasswords" + ] + } + ] + } + ], + "ClientSideDetectionKeyboardPointerLockRequest": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ClientSideDetectionKeyboardPointerLockRequest" + ] + } + ] + } + ], + "ClientSideDetectionNotificationPrompt": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ClientSideDetectionNotificationPrompt" + ] + } + ] + } + ], + "ClientSideDetectionRetryLimit": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "RetryTimeMax": "15" + }, + "enable_features": [ + "ClientSideDetectionRetryLimit" + ] + } + ] + } + ], + "ClientSideDetectionSamplePing": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ClientSideDetectionSamplePing" + ] + } + ] + } + ], + "ClientSideDetectionVibrationApi": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ClientSideDetectionVibrationApi" + ] + } + ] + } + ], + "ClipboardDeemphasisAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "MaxAge180", + "params": { + "UIClipboardMaximumAge": "180" + }, + "enable_features": [ + "ClipboardMaximumAge" + ] + } + ] + } + ], + "CoalesceSelectionchangeEvent": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CoalesceSelectionchangeEvent" + ] + } + ] + } + ], + "CodeBasedRBD": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20230420", + "params": { + "code-based-rbd": "true" + }, + "enable_features": [ + "CodeBasedRBD" + ] + } + ] + } + ], + "CollectAndroidFrameTimelineMetricsStudy": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20230926", + "enable_features": [ + "CollectAndroidFrameTimelineMetrics" + ] + } + ] + } + ], + "CollectAndroidFrameTimelineMetricsWebviewStudy": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled_20240320", + "enable_features": [ + "CollectAndroidFrameTimelineMetrics" + ] + } + ] + } + ], + "Collections": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Dogfood", + "params": { + "allow_bookmark_type_swapping": "true", + "autodismiss_enabled": "true", + "enable_persisted_tab_data_maintenance": "true", + "enable_price_notification": "true", + "enable_price_tracking": "true", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "CommercePriceTracking", + "OptimizationGuidePushNotifications", + "ReadLater", + "ShoppingList" + ] + }, + { + "name": "Default_1__M100_C_v5", + "params": { + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "ReadLater" + ] + }, + { + "name": "ReadLater_CCT_non_US__NoCustomTab_M100_C_v5", + "params": { + "use_cct": "false", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "ReadLater" + ] + }, + { + "name": "ReadLater_SaveFlow_non_US__SemiIntegratedRedux_M100_C_v5", + "params": { + "allow_bookmark_type_swapping": "true", + "autodismiss_enabled": "true", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "ReadLater" + ] + }, + { + "name": "Default_1__M100_A_v5", + "params": { + "enable_persisted_tab_data_maintenance": "true", + "enable_price_tracking": "true", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "CommercePriceTracking", + "ReadLater" + ] + }, + { + "name": "ReadLater_CCT_US__NoCustomTab_M100_A_v5", + "params": { + "enable_persisted_tab_data_maintenance": "true", + "enable_price_tracking": "true", + "use_cct": "false", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "CommercePriceTracking", + "ReadLater" + ] + }, + { + "name": "ReadLater_SaveFlow_US__SemiIntegratedRedux_M100_A_v5", + "params": { + "allow_bookmark_type_swapping": "true", + "autodismiss_enabled": "true", + "enable_persisted_tab_data_maintenance": "true", + "enable_price_tracking": "true", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "CommercePriceTracking", + "ReadLater" + ] + }, + { + "name": "WallE_US__ShoppingCompact_M100_A_v5", + "params": { + "autodismiss_enabled": "true", + "bookmark_compact_visuals_enabled": "true", + "enable_persisted_tab_data_maintenance": "true", + "enable_price_notification": "true", + "enable_price_tracking": "true", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "CommercePriceTracking", + "OptimizationGuidePushNotifications", + "ReadLater", + "ShoppingList" + ] + }, + { + "name": "ReadLater_SaveFlow_non_US__SemiIntegrated_NoCCT_M100_C_v7", + "params": { + "allow_bookmark_type_swapping": "true", + "autodismiss_enabled": "true", + "use_cct": "false", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "ReadLater" + ] + }, + { + "name": "WallE_US__ShoppingCompact_WithRL_M100_A_v7", + "params": { + "allow_bookmark_type_swapping": "true", + "autodismiss_enabled": "true", + "bookmark_compact_visuals_enabled": "true", + "enable_persisted_tab_data_maintenance": "true", + "enable_price_notification": "true", + "enable_price_tracking": "true", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "CommercePriceTracking", + "OptimizationGuidePushNotifications", + "ReadLater", + "ShoppingList" + ] + }, + { + "name": "WallE_US__ShoppingCompact_WithRL_NoCCT_M100_A_v7", + "params": { + "allow_bookmark_type_swapping": "true", + "autodismiss_enabled": "true", + "bookmark_compact_visuals_enabled": "true", + "enable_persisted_tab_data_maintenance": "true", + "enable_price_notification": "true", + "enable_price_tracking": "true", + "use_cct": "false", + "use_root_bookmark_as_default": "true" + }, + "enable_features": [ + "CommercePriceTracking", + "OptimizationGuidePushNotifications", + "ReadLater", + "ShoppingList" + ] + } + ] + } + ], + "CombinedWebViewOptimizations": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AvoidResourceRequestCopies", + "CreateSpareRendererOnBrowserContextCreation", + "EnsureExistingRendererAlive", + "LazyBindJsInjection", + "SkipUnnecessaryThreadHopsForParseHeaders", + "WebViewOptimizeXrwNavigationFlow" + ] + } + ] + } + ], + "CommerceHintAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "enabled_commerce_hint_20220623", + "enable_features": [ + "CommerceHintAndroid" + ] + } + ] + } + ], + "CommerceLocalPDPDetection": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CommerceLocalPDPDetection" + ] + } + ] + } + ], + "CommercePriceInsights": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_1": "name:price_insights_page_action_icon_label_in_trigger;comparator:any;window:0;storage:360", + "event_trigger": "name:price_insights_page_action_icon_label_in_trigger;comparator:any;window:0;storage:360", + "event_used": "name:price_insights_page_action_icon_label_used;comparator:any;window:0;storage:360", + "price-insights-show-feedback": "true", + "session_rate": "any" + }, + "enable_features": [ + "IPH_PriceInsightsPageActionIconLabelFeature", + "PriceInsights" + ] + } + ] + } + ], + "ComposeEnableNudgeForUnspecifiedHint": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "ComposeEnableNudgeForUnspecifiedHint" + ] + } + ] + } + ], + "ComposeModelQualityLogging": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "ComposeLoggingEnabled_Dogfood", + "params": { + "model_execution_feature_compose": "true" + }, + "enable_features": [ + "ModelQualityLogging" + ] + } + ] + } + ], + "ComposeOnDeviceModel": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "on_device_retract_unsafe_content": "false", + "on_device_text_safety_token_interval": "10" + }, + "enable_features": [ + "OptimizationGuideComposeOnDeviceEval", + "OptimizationGuideOnDeviceModel", + "TextSafetyClassifier" + ] + } + ] + } + ], + "ComposeProactiveNudgePosition": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_CursorNudge", + "params": { + "proactive_nudge_compact_ui": "true", + "proactive_nudge_delay_milliseconds": "1000", + "proactive_nudge_force_show_probability": "0.02", + "proactive_nudge_show_probability": "0.0" + }, + "enable_features": [ + "AutofillCaretExtraction", + "ComposeProactiveNudge", + "EnableComposeNudgeAtCursor" + ] + }, + { + "name": "Enabled_FieldNudge", + "params": { + "proactive_nudge_delay_milliseconds": "1000", + "proactive_nudge_force_show_probability": "0.02", + "proactive_nudge_show_probability": "0.0" + }, + "enable_features": [ + "ComposeProactiveNudge" + ], + "disable_features": [ + "AutofillCaretExtraction", + "EnableComposeNudgeAtCursor" + ] + } + ] + } + ], + "ComposeUiRefinement": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ComposeUiRefinement" + ] + } + ] + } + ], + "CompressionDictionaryTransport": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CompressionDictionaryTransport" + ] + } + ] + } + ], + "CompressionDictionaryTransportOverHttp1": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CompressionDictionaryTransportOverHttp1" + ] + } + ] + } + ], + "ConcurrentViewTransitionsSPA": [ + { + "platforms": [ + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ConcurrentViewTransitionsSPA" + ] + } + ] + } + ], + "ConditionalImageResize": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ConditionalImageResize" + ] + } + ] + } + ], + "ConditionallySkipGpuChannelFlush": [ + { + "platforms": [ + "android", + "android_webview", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ConditionallySkipGpuChannelFlush" + ] + } + ] + } + ], + "ConfigurableV8CodeCacheHotHours": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "cache_72h_20230904", + "params": { + "V8CodeCacheHotHours": "72" + }, + "enable_features": [ + "ConfigurableV8CodeCacheHotHours" + ] + } + ] + } + ], + "ContentCaptureExperiment": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "EnableExperiment", + "enable_features": [ + "ContentCaptureTriggeringForExperiment" + ] + } + ] + } + ], + "ContinueEventTimingRecordingWhenBufferIsFull": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows", + "android_webview", + "android_weblayer" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ContinueEventTimingRecordingWhenBufferIsFull" + ] + } + ] + } + ], + "CookieAccessDetailsNotificationDeDuping": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240621", + "enable_features": [ + "CookieAccessDetailsNotificationDeDuping" + ] + } + ] + } + ], + "CookieDeprecationFacilitatedTestingCookieDeprecation": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "windows", + "mac", + "linux", + "android" + ], + "experiments": [ + { + "name": "Treatment_PreStable_20231002", + "params": { + "SkipTpcdMitigationsForAdsHeuristics": "true", + "SkipTpcdMitigationsForAdsMetadata": "true", + "SkipTpcdMitigationsForAdsSupport": "true", + "decision_delay_time": "1s", + "disable_3p_cookies": "true", + "disable_ads_apis": "false", + "enable_otr_profiles": "false", + "enable_silent_onboarding": "false", + "label": "prestable_treatment_1", + "need_onboarding_for_label": "true", + "need_onboarding_for_synthetic_trial": "true", + "use_profile_filtering": "false", + "version": "2" + }, + "enable_features": [ + "AttributionDebugReportingCookieDeprecationTesting", + "CookieDeprecationFacilitatedTesting", + "SkipTpcdMitigationsForAds", + "TPCDAdHeuristicSubframeRequestTagging" + ] + } + ] + } + ], + "CookieDeprecationFacilitatedTestingFledgeTrustedSignalsHeaders": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "windows", + "mac", + "linux", + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FledgeFacilitatedTestingSignalsHeaders" + ] + } + ] + } + ], + "CookieSameSiteConsidersRedirectChainDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CookieSameSiteConsidersRedirectChain" + ] + } + ] + } + ], + "CopyClientKeysCertsToChaps": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CopyClientKeysCertsToChaps" + ] + } + ] + } + ], + "CpssStringChange": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "NewStringWithHats_20240221", + "params": { + "probability": "1.0", + "probability_vector": "0.3,0.7", + "prompt_disposition_filter": "LocationBarLeftQuietChip", + "prompt_disposition_reason_filter": "OnDevicePredictionModel,PredictionService", + "request_type_filter": "Notifications,Geolocation", + "survey_display_time": "OnPromptAppearing", + "trigger_id": "TfmwCkztT0ugnJ3q1cK0URBBSdir,FohGLzZdE0ugnJ3q1cK0QyypEaVo" + }, + "enable_features": [ + "CpssQuietChipTextUpdate", + "PermissionsPromptSurvey" + ] + } + ] + } + ], + "CrOSAudioHfpMicSrToggle": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20240625", + "enable_features": [ + "AudioHFPMicSRToggle" + ] + } + ] + } + ], + "CrOSBluetoothA2dpAacCodec": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootAudioA2DPAdvancedCodecs" + ] + } + ] + } + ], + "CrOSBluetoothCoredump": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_Coredump", + "enable_features": [ + "BluetoothCoredump" + ] + } + ] + } + ], + "CrOSBluetoothFlossCoredump": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BluetoothFlossCoredump" + ] + } + ] + } + ], + "CrOSBluetoothFlossTelephony": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BluetoothFlossTelephony" + ] + } + ] + } + ], + "CrOSBluetoothHfpSuperWideband": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootAudioHFPSwb" + ] + } + ] + } + ], + "CrOSEnforceSystemAec": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSEnforceSystemAec" + ], + "disable_features": [ + "AudioServiceOutOfProcess", + "ChromeWideEchoCancellation" + ] + } + ] + } + ], + "CrOSEnforceSystemAecNsAgc": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSEnforceSystemAecNsAgc" + ] + } + ] + } + ], + "CrOSEventSequenceLogging": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableEventSequenceLogging" + ] + }, + { + "name": "AppDiscoveryLogging", + "enable_features": [ + "AppDiscoveryLogging", + "EnableEventSequenceLogging" + ] + } + ] + } + ], + "CrOSFederatedAutocorrectPhh": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "launch_stage": "prod" + }, + "enable_features": [ + "AutocorrectFederatedPhh" + ] + } + ] + } + ], + "CrOSFederatedLauncherQueryPhhVersion2": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "launch_stage": "prod" + }, + "enable_features": [ + "FederatedLauncherQueryAnalyticsVersion2Task" + ] + } + ] + } + ], + "CrOSLateBootAllowFirmwareDumps": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootAllowFirmwareDumps" + ] + } + ] + } + ], + "CrOSLateBootArcVmVcpuBoost": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootArcVmVcpuBoost" + ], + "hardware_classes": [ + "brya", + "dedede", + "myst", + "octopus", + "rex" + ] + } + ] + } + ], + "CrOSLateBootAudioHFPOffload": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20220520", + "enable_features": [ + "CrOSLateBootAudioHFPOffload" + ] + } + ] + } + ], + "CrOSLateBootAudioOffloadCrasDSPToSOF": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20240421", + "enable_features": [ + "CrOSLateBootAudioOffloadCrasDSPToSOF" + ] + } + ] + } + ], + "CrOSLateBootAudioStyleTransferStudy": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootAudioStyleTransfer" + ] + } + ] + } + ], + "CrOSLateBootDynamicEPP": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootDynamicEPP" + ] + } + ] + } + ], + "CrOSLateBootEEVDF": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootEEVDF" + ] + } + ] + } + ], + "CrOSLateBootHighResOffVariables": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootHighResOff" + ], + "hardware_classes": [ + "octopus" + ] + } + ] + } + ], + "CrOSLateBootLongBluetoothAutosuspend": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootLongBluetoothAutosuspend" + ] + } + ] + } + ], + "CrOSLateBootLowMemorySignaling": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledEarlyDiscard_20240605", + "params": { + "CompleteStallMs": "700", + "PartialStallMs": "20" + }, + "enable_features": [ + "CrOSLateBootDiscardStaleAtModeratePressure", + "CrOSLateBootOverrideLmkdPsiDefaults" + ], + "disable_features": [ + "CrOSLateBootPsiAdjustAvailable", + "CrOSLockMainProgramText" + ] + }, + { + "name": "EnabledAvailableAdjustmentPsi_20240605", + "enable_features": [ + "CrOSLateBootPsiAdjustAvailable" + ], + "disable_features": [ + "CrOSLateBootDiscardStaleAtModeratePressure", + "CrOSLateBootOverrideLmkdPsiDefaults", + "CrOSLockMainProgramText" + ] + }, + { + "name": "EnabledAvailableAdjustmentPsiFull_20240605", + "params": { + "PsiTopThreshold": "20.0", + "PsiUseFull": "true" + }, + "enable_features": [ + "CrOSLateBootPsiAdjustAvailable" + ], + "disable_features": [ + "CrOSLateBootDiscardStaleAtModeratePressure", + "CrOSLateBootOverrideLmkdPsiDefaults", + "CrOSLockMainProgramText" + ] + }, + { + "name": "EnabledAvailableAdjustmentPsiWithEarlyDiscard_20240605", + "params": { + "CompleteStallMs": "700", + "PartialStallMs": "20" + }, + "enable_features": [ + "CrOSLateBootDiscardStaleAtModeratePressure", + "CrOSLateBootOverrideLmkdPsiDefaults", + "CrOSLateBootPsiAdjustAvailable" + ], + "disable_features": [ + "CrOSLockMainProgramText" + ] + }, + { + "name": "EnabledMlockChrome_20240605", + "enable_features": [ + "CrOSLockMainProgramText" + ], + "disable_features": [ + "CrOSLateBootDiscardStaleAtModeratePressure", + "CrOSLateBootOverrideLmkdPsiDefaults", + "CrOSLateBootPsiAdjustAvailable" + ] + }, + { + "name": "EnabledMlockChromeWithAvailableAdjustmentPsi_20240605", + "enable_features": [ + "CrOSLateBootPsiAdjustAvailable", + "CrOSLockMainProgramText" + ], + "disable_features": [ + "CrOSLateBootDiscardStaleAtModeratePressure", + "CrOSLateBootOverrideLmkdPsiDefaults" + ] + } + ] + } + ], + "CrOSLateBootMediaDynamicCgroup": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootMediaDynamicCgroup" + ] + } + ] + } + ], + "CrOSLateBootResourcedVariableTimeMemorySignal": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootResourcedVariableTimeMemorySignal" + ] + } + ] + } + ], + "CrOSLateBootSchedTrace": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootSchedTrace" + ] + } + ] + } + ], + "CrOSLateBootSlowAdaptiveCharging": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootSlowAdaptiveCharging" + ] + } + ] + } + ], + "CrOSLateBootSwapZramCompAlgorithm": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledZstd_20231003", + "params": { + "comp_algorithm": "zstd" + }, + "enable_features": [ + "CrOSLateBootSwapZramCompAlgorithm" + ] + } + ] + } + ], + "CrOSLateBootSwapZramTuning": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledGroupA", + "params": { + "multiplier": "1.5" + }, + "enable_features": [ + "CrOSLateBootSwapZramDisksize" + ] + } + ] + } + ], + "CrOSLocalImageSearch": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LauncherImageSearch", + "LauncherImageSearchIndexingLimit", + "LauncherImageSearchOcr", + "LauncherSearchControl", + "ProductivityLauncherImageSearch" + ] + }, + { + "name": "Enabled_20240516", + "enable_features": [ + "LauncherImageSearch", + "LauncherImageSearchIndexingLimit", + "LauncherImageSearchOcr", + "LauncherSearchControl", + "ProductivityLauncherImageSearch" + ] + }, + { + "name": "Disabled_20240516", + "disable_features": [ + "LauncherImageSearch", + "LauncherImageSearchIndexingLimit", + "LauncherImageSearchOcr", + "LauncherSearchControl", + "ProductivityLauncherImageSearch" + ] + }, + { + "name": "EnabledOnCore", + "enable_features": [ + "LauncherImageSearch", + "LauncherImageSearchIndexingLimit", + "LauncherImageSearchOcr", + "LauncherSearchControl", + "LocalImageSearchOnCore", + "ProductivityLauncherImageSearch" + ] + } + ] + } + ], + "CrOSMglruNoKVMOpt": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "NoKVMOptBehavior_20230613", + "params": { + "MGLRUEnableValue": "7" + }, + "enable_features": [ + "MGLRUEnable" + ] + } + ] + } + ], + "CrabbyAvif": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_CrabbyAvif", + "enable_features": [ + "CrabbyAvif" + ] + } + ] + } + ], + "CreditCardInfobarDisplayLength": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Sixteen_Seconds", + "params": { + "duration-seconds": "16" + }, + "enable_features": [ + "CreditCardInfobarDisplayLength" + ] + } + ] + } + ], + "CrosBatterySaver": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "BatterySaverActivationChargePercent": "20", + "BatterySaverNotificationBehavior": "kBSMAutoEnable" + }, + "enable_features": [ + "CrosBatterySaver" + ] + } + ] + } + ], + "CrosLazyLoginWebUI": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableLazyLoginWebUILoading" + ] + } + ] + } + ], + "CrostiniTerminaDlcForceOta": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrostiniTerminaDlcForceOta" + ], + "min_os_version": "15771.0.0" + } + ] + } + ], + "CssRubyAlign": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CssRubyAlign" + ] + } + ] + } + ], + "CursiveManagedStylusPreinstall": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CursiveManagedStylusPreinstall" + ] + } + ] + } + ], + "CursorAnchorInfoMojoPipe": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CursorAnchorInfoMojoPipe" + ] + } + ] + } + ], + "CustomizeChromeSidePanelExtensionsCard": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CustomizeChromeSidePanelExtensionsCard" + ] + } + ] + } + ], + "D3D11Vp9kSVCHWDecoding": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "D3D11Vp9kSVCHWDecoding" + ] + } + ] + } + ], + "DIPSStatefulBounceEnforcement": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_v0", + "params": { + "delete": "true", + "triggering_action": "stateful_bounce" + }, + "enable_features": [ + "DIPS" + ] + } + ] + } + ], + "DOMParserIncludeShadowRoots": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "DOMParserIncludeShadowRoots" + ] + } + ] + } + ], + "DOMStorageReliabilityEnhancements": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "ios", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "BothEnabled", + "enable_features": [ + "CoalesceStorageAreaCommits", + "DomStorageSmartFlushing" + ] + }, + { + "name": "CoalescingEnabled", + "enable_features": [ + "CoalesceStorageAreaCommits" + ], + "disable_features": [ + "DomStorageSmartFlushing" + ] + }, + { + "name": "CheckpointingEnabled", + "enable_features": [ + "DomStorageSmartFlushing" + ], + "disable_features": [ + "CoalesceStorageAreaCommits" + ] + } + ] + } + ], + "DTCKeyUploadedBySharedAPIEnabled": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DTCKeyUploadedBySharedAPIEnabled" + ] + } + ] + } + ], + "DXGIWaitableSwapChain": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled_MaxQueuedFrames2_20230203", + "params": { + "DXGIWaitableSwapChainMaxQueuedFrames": "2" + }, + "enable_features": [ + "DXGIWaitableSwapChain" + ] + } + ] + } + ], + "DangerousDownloadInterstitial": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DangerousDownloadInterstitial" + ] + } + ] + } + ], + "DataControlsDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableDesktopDataControls" + ] + } + ] + } + ], + "DataControlsScreenshotProtection": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableScreenshotProtection" + ] + } + ] + } + ], + "DbscPhase1aStudy": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "dice-support": "enabled" + }, + "enable_features": [ + "EnableBoundSessionCredentials" + ] + } + ] + } + ], + "DecodedImageWorkingSetBudget": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "budget_default_128M_256M_20230921", + "params": { + "DecodedImageWorkingSetBudgetBytesForAboveThreshold": "268435456", + "DefaultDecodedImageWorkingSetBudgetBytes": "134217728" + }, + "enable_features": [ + "ImageDecodeConfigurableFeature" + ] + } + ] + } + ], + "DecommitPooledPages": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DecommitPooledPages" + ] + } + ] + } + ], + "DecreaseProcessingAudioFifoSize": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled1_20230425", + "params": { + "fifo_size": "10" + }, + "enable_features": [ + "DecreaseProcessingAudioFifoSize" + ] + } + ] + } + ], + "DefaultANGLEMetal": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DefaultANGLEMetal" + ] + } + ] + } + ], + "DefaultBrowserPromoIPadStudy": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DefaultBrowserPromoIPadExperimentalString" + ] + } + ] + } + ], + "DefaultBrowserPromptRefreshLaunch": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "V2Enabled3V2_20240625", + "params": { + "group_name": "enabled-v2-arm-3", + "max_prompt_count": "5", + "reprompt_duration": "21d", + "reprompt_duration_multiplier": "1", + "show_app_menu_chip": "false", + "show_app_menu_item": "true", + "show_info_bar": "true", + "updated_info_bar_copy": "false" + }, + "enable_features": [ + "DefaultBrowserPromptRefresh", + "DefaultBrowserPromptRefreshTrial" + ] + } + ] + } + ], + "DefaultGpuDiskCacheSize": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "max_cache_6M_20230913", + "params": { + "GpuDefaultMaxProgramCacheMemoryBytes": "6291456" + }, + "enable_features": [ + "DefaultGpuDiskCacheSize" + ] + } + ] + } + ], + "DefaultOpenSSLBufferSizeFeature": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "ssl_buffer_size_17K_20230920", + "params": { + "DefaultOpenSSLBufferSize": "17408" + }, + "enable_features": [ + "DefaultOpenSSLBufferSizeFeature" + ] + } + ] + } + ], + "DefaultPassthroughCommandDecoder": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "BlockListByDevice": "", + "BlockListByModel": "" + }, + "enable_features": [ + "DefaultPassthroughCommandDecoder" + ] + } + ] + } + ], + "DeferSpeculativeRFHCreation": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DeferSpeculativeRFHCreation" + ] + } + ] + } + ], + "DeferredSparerRendererForTopChromeWebUI": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DeferredSpareRendererForTopChromeWebUI" + ] + } + ] + } + ], + "DelayMediaSinkDiscovery": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DelayMediaSinkDiscovery" + ] + } + ] + } + ], + "DelayablePriorityThreshold": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Medium_20230906", + "params": { + "DelayablePriorityThreshold": "medium" + }, + "enable_features": [ + "DelayablePriorityThresholdFeature" + ] + } + ] + } + ], + "DeprecateUnload": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240124", + "params": { + "allowlist": "a.com,b.com,c.com,d.com,e.com,f.com,web-platform.test,www1.web-platform.test,127.0.0.1,example.test,www.google.com,www.youtube.com,www.facebook.com,www.pornhub.com,www.xvideos.com,twitter.com,www.wikipedia.org,www.instagram.com,www.reddit.com,www.amazon.com,duckduckgo.com,www.yahoo.com,www.xnxx.com,www.tiktok.com,www.bing.com,www.yahoo.co.jp,weather.com,www.whatsapp.com,dzen.ru,xhamster.com,openai.com,outlook.live.com,www.microsoft.com,microsoftonline.com,www.microsoftonline.com,www.linkedin.com,www.quora.com,www.twitch.tv,www.naver.com,netflix.com,www.netflix.com,www.office.com,vk.com,www.vk.com,www.globo.com,www.aliexpress.com,www.cnn.com,zoom.us,www.zoom.us,www.imdb.com,x.com,www.nytimes.com,onlyfans.com,www.espn.com,www.amazon.co.jp,www.pinterest.com,www.uol.com.br,www.ebay.com,www.marca.com,www.canva.com,www.spotify.com,www.bbc.com,www.paypal.com,www.apple.com", + "rollout_bucket": "10", + "rollout_percent": "100" + }, + "enable_features": [ + "DeprecateUnload", + "DeprecateUnloadByAllowList" + ] + } + ] + } + ], + "DeskBarWindowOcclusionOptimization": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DeskBarWindowOcclusionOptimization" + ] + } + ] + } + ], + "DeskButton": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20231025", + "enable_features": [ + "DeskButton" + ] + } + ] + } + ], + "DeskProfiles": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled_20240313", + "enable_features": [ + "DeskProfiles" + ] + } + ] + } + ], + "DesktopCapturePermissionChecker": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled_SckPicker_20240522", + "enable_features": [ + "DesktopCapturePermissionChecker", + "ScreenCaptureKitPickerScreen", + "ScreenCaptureKitStreamPickerSonoma" + ] + } + ] + } + ], + "DesktopLinkCapturingPWAExperiment": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_DefaultOn", + "params": { + "link_capturing_guardrail_storage_duration": "60", + "link_capturing_state": "on_by_default" + }, + "enable_features": [ + "DesktopPWAsLinkCapturing" + ] + }, + { + "name": "Enabled_DefaultOff", + "params": { + "link_capturing_guardrail_storage_duration": "60", + "link_capturing_state": "off_by_default" + }, + "enable_features": [ + "DesktopPWAsLinkCapturing" + ] + } + ] + } + ], + "DesktopNtpDriveCache": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Cache_1m", + "params": { + "NtpDriveModuleCacheMaxAgeSParam": "60", + "NtpDriveModuleExperimentGroupParam": "experiment_1234" + }, + "enable_features": [ + "NtpDriveModule" + ] + } + ] + } + ], + "DesktopNtpImageErrorDetection": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "ImageErrorDetection", + "enable_features": [ + "NtpBackgroundImageErrorDetection" + ] + } + ] + } + ], + "DesktopNtpMiddleSlotPromoDismissal": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "MiddleSlotPromoDismissal", + "enable_features": [ + "NtpMiddleSlotPromoDismissal" + ] + } + ] + } + ], + "DesktopNtpModules": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "RecipeTasksRuleBasedDiscountDriveManagedUsersCartOptimizeRecipeTasksSAPIV2Fre_Enabled", + "params": { + "NtpModulesLoadTimeoutMillisecondsParam": "3000", + "use_sapi_v2": "true" + }, + "enable_features": [ + "NtpModulesLoadTimeoutMilliseconds", + "NtpPhotosModule" + ], + "disable_features": [ + "NtpShoppingTasksModule" + ] + } + ] + } + ], + "DesktopNtpTabResumption": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "TabResumption_Random", + "params": { + "use_random_score": "true" + }, + "enable_features": [ + "NtpMostRelevantTabResumptionModule", + "SegmentationPlatformURLVisitResumptionRanker" + ] + } + ] + } + ], + "DesktopOmniboxCalculatorProvider": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OmniboxCalcProvider" + ] + } + ] + } + ], + "DesktopOmniboxKeywordProvider": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "enabled", + "params": { + "VitalizeAutocompletedKeywordsScore": "900" + }, + "enable_features": [ + "OmniboxVitalizeAutocompletedKeywords" + ] + } + ] + } + ], + "DesktopOmniboxShortcutBoost": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "ShortcutBoostGroupWithSearches": "true", + "ShortcutBoostNonTopHitSearchThreshold": "2", + "ShortcutBoostNonTopHitThreshold": "2", + "ShortcutBoostSearchScore": "1414", + "ShortcutBoostUrlScore": "1414", + "omnibox_history_cluster_provider_inherit_search_match_score": "true", + "omnibox_history_cluster_provider_score": "1414" + }, + "enable_features": [ + "JourneysOmniboxHistoryClusterProvider", + "OmniboxShortcutBoost" + ] + } + ] + } + ], + "DesktopOmniboxStarterPackExpansion": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "StarterPackExpansion" + ] + } + ] + } + ], + "DesktopOmnibox_HistoryQuickProviderSpecificity": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "DomainSuggestionsAlternativeScoring": "true", + "DomainSuggestionsMaxMatchesPerDomain": "2", + "DomainSuggestionsMinInputLength": "4", + "DomainSuggestionsScoreFactor": "1", + "DomainSuggestionsTypedUrlsOffset": "1", + "DomainSuggestionsTypedUrlsThreshold": "7", + "DomainSuggestionsTypedVisitCapPerVisit": "2", + "DomainSuggestionsTypedVisitOffset": "1", + "DomainSuggestionsTypedVisitThreshold": "4" + }, + "enable_features": [ + "OmniboxDomainSuggestions" + ] + } + ] + } + ], + "DesktopPWAInstallPromotionML": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "guardrail_report_prob": "0.5", + "max_days_to_store_guardrails": "180", + "model_and_user_decline_report_prob": "0.5" + }, + "enable_features": [ + "WebAppsEnableMLModelForPromotion" + ] + } + ] + } + ], + "DesktopReEngagement": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "max_active_days": "0", + "max_active_weeks": "0", + "max_monthly_active_days": "2" + }, + "enable_features": [ + "AllowRecentSessionTracking", + "IPH_DesktopReEngagement" + ] + } + ] + } + ], + "DesktopWebAppUniversalInstallExperiment": [ + { + "platforms": [ + "linux", + "mac", + "windows", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "WebAppUniversalInstallExperiment", + "enable_features": [ + "WebAppUniversalInstall" + ] + } + ] + } + ], + "DestroyProfileOnBrowserClose": [ + { + "platforms": [ + "chromeos_lacros" + ], + "experiments": [ + { + "name": "DestroyProfileOnBrowserClose", + "enable_features": [ + "DestroyProfileOnBrowserClose" + ] + } + ] + } + ], + "DestroySystemProfiles": [ + { + "platforms": [ + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "DestroySystemProfiles", + "enable_features": [ + "DestroySystemProfiles" + ] + } + ] + } + ], + "DetailsStyling": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DetailsStyling" + ] + } + ] + } + ], + "DevToolsTabTarget": [ + { + "platforms": [ + "linux", + "mac", + "windows", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DevToolsTabTarget" + ] + }, + { + "name": "Control", + "disable_features": [ + "DevToolsTabTarget" + ] + } + ] + } + ], + "DeviceAuthenticatorAndroidx": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DeviceAuthenticatorAndroidx" + ] + } + ] + } + ], + "DexFixer": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DexFixer" + ] + } + ] + } + ], + "DiacriticsOnPhysicalKeyboardLongpressOnByDefault": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DiacriticsOnPhysicalKeyboardLongpress", + "DiacriticsOnPhysicalKeyboardLongpressDefaultOn" + ] + } + ] + } + ], + "DipsOnForegroundSequence": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DipsOnForegroundSequence" + ] + } + ] + } + ], + "DisableBlackHoleOnNoNewNetwork": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DisableBlackHoleOnNoNewNetwork" + ] + } + ] + } + ], + "DisableGles2ForOopR": [ + { + "platforms": [ + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "disable_features": [ + "UseGles2ForOopR" + ] + } + ] + } + ], + "DisableMemoryReclaimerInBackground": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DisableMemoryReclaimerInBackground" + ] + } + ] + } + ], + "DisableUrgentPageDiscarding": [ + { + "platforms": [ + "mac", + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "UrgentPageDiscarding" + ] + } + ] + } + ], + "DisallowManagedProfileSignout": [ + { + "platforms": [ + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DisallowManagedProfileSignout" + ] + } + ] + } + ], + "DiscardInputEventsToRecentlyMovedFrames": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "DoNotDiscard", + "params": { + "distance_factor": "100000.", + "time_ms": "0" + }, + "enable_features": [ + "DiscardInputEventsToRecentlyMovedFrames" + ] + }, + { + "name": "50_250_ms", + "params": { + "distance_factor": ".5", + "time_ms": "250" + }, + "enable_features": [ + "DiscardInputEventsToRecentlyMovedFrames" + ] + } + ] + } + ], + "DiscoFeedEndpoint": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DiscoFeedEndpoint" + ] + } + ] + } + ], + "DiscountConsentV2": [ + { + "platforms": [ + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "enabled_ntp_native_dialog_with_approved_strings_M104_20220809", + "params": { + "discount-consent-ntp-variation": "4", + "step-one-static-content": "Let Google help you find discounts for your carts", + "step-one-use-static-content": "true" + }, + "enable_features": [ + "DiscountConsentV2" + ] + } + ] + } + ], + "DiscountsAutoPopup": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "history-cluster-behavior": "1", + "merchant-wide-behavior": "0", + "non-merchant-wide-behavior": "0" + }, + "enable_features": [ + "DiscountDialogAutoPopupBehaviorSetting" + ] + } + ] + } + ], + "DlpRegionalizedEndpoints": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DlpRegionalizedEndpoints" + ] + } + ] + } + ], + "DnsHttpsSvcbTimeout": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "UseDnsHttpsSvcbInsecureExtraTimeMax": "500ms", + "UseDnsHttpsSvcbInsecureExtraTimeMin": "300ms", + "UseDnsHttpsSvcbInsecureExtraTimePercent": "50", + "UseDnsHttpsSvcbSecureExtraTimeMax": "500ms", + "UseDnsHttpsSvcbSecureExtraTimeMin": "300ms", + "UseDnsHttpsSvcbSecureExtraTimePercent": "50" + }, + "enable_features": [ + "UseDnsHttpsSvcb" + ] + } + ] + } + ], + "DoNotEvictOnAXLocationChange": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DoNotEvictOnAXLocationChange" + ] + } + ] + } + ], + "DontAlwaysPushPictureLayerImpls": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DontAlwaysPushPictureLayerImpls" + ] + } + ] + } + ], + "DontFallbackToDefaultImplementationInAccountManagerFacade": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DontFallbackToDefaultImplementationInAccountManagerFacade" + ] + } + ] + } + ], + "DownloadLater": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledWithDateTimePicker", + "params": { + "show_date_time_picker": "true" + }, + "enable_features": [ + "DownloadLater" + ] + }, + { + "name": "EnabledWithoutDateTimePicker", + "params": { + "show_date_time_picker": "false" + }, + "enable_features": [ + "DownloadLater" + ] + } + ] + } + ], + "DownloadWarningSurvey": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "DownloadBubbleBypass_20240513", + "params": { + "en_site_id": "ikozJtokP0ugnJ3q1cK0SbwHjMKE", + "probability": "1.0", + "survey_type": "0" + }, + "enable_features": [ + "DownloadWarningSurvey" + ] + }, + { + "name": "DownloadBubbleHeed_20240513", + "params": { + "en_site_id": "jhF4CtEp50ugnJ3q1cK0UZhzeE9d", + "probability": "1.0", + "survey_type": "1" + }, + "enable_features": [ + "DownloadWarningSurvey" + ] + }, + { + "name": "DownloadBubbleIgnore_20240513", + "params": { + "en_site_id": "QGZEf3nUW0ugnJ3q1cK0PoGTrYqX", + "ignore_delay_seconds": "300", + "probability": "0.5", + "survey_type": "2" + }, + "enable_features": [ + "DownloadWarningSurvey" + ] + }, + { + "name": "DownloadsPageBypass_20240513", + "params": { + "en_site_id": "B4TxfW2d50ugnJ3q1cK0SrBjxPp9", + "probability": "1.0", + "survey_type": "3" + }, + "enable_features": [ + "DownloadWarningSurvey" + ] + }, + { + "name": "DownloadsPageHeed_20240513", + "params": { + "en_site_id": "P1UCDjb5L0ugnJ3q1cK0S1YhAs9h", + "probability": "1.0", + "survey_type": "4" + }, + "enable_features": [ + "DownloadWarningSurvey" + ] + }, + { + "name": "DownloadsPageIgnore_20240513", + "params": { + "en_site_id": "ToBgFcctL0ugnJ3q1cK0UoPbrdFt", + "probability": "0.5", + "survey_type": "5" + }, + "enable_features": [ + "DownloadWarningSurvey" + ] + } + ] + } + ], + "DownloadsMigrateToJobsAPI": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DownloadsMigrateToJobsAPI" + ] + } + ] + } + ], + "DropUnrecognizedTemplateUrlParameters": [ + { + "platforms": [ + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DropUnrecognizedTemplateUrlParameters" + ] + } + ] + } + ], + "DynamicCrxDownloaderPriority": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DynamicCrxDownloaderPriority" + ] + } + ] + } + ], + "DynamicScrollCullRectExpansion": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DynamicScrollCullRectExpansion" + ] + } + ] + } + ], + "ESBDownloadRowPromo": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "blocked_by": "none", + "blocking": "none", + "event_1": "name:esb_download_promo_row_viewed;comparator:<7;window:90;storage:90", + "event_2": "name:esb_download_promo_row_clicked;comparator:<3;window:90;storage:90", + "event_trigger": "name:dangerous_download_esb_promo_row_trigger;comparator:any;window:360;storage:360", + "event_used": "name:enable_enhanced_protection;comparator:==0;window:21;storage:90", + "session_rate": "any", + "session_rate_impact": "none" + }, + "enable_features": [ + "EsbDownloadRowPromo" + ] + } + ] + } + ], + "ESBInfobarPromo": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnhancedSafeBrowsingPromo" + ] + } + ] + } + ], + "ESBInlineSettingsPromo": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IPH_iOSInlineEnhancedSafeBrowsingPromo" + ] + } + ] + } + ], + "EagerPrefetchBlockUntilHeadDifferentTimeoutsRetrospective": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "block_until_head_timeout_eager_prefetch": "500" + }, + "enable_features": [ + "PrefetchUseContentRefactor" + ] + } + ] + } + ], + "EdgeToEdgeAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DynamicSafeAreaInsets", + "DynamicSafeAreaInsetsOnScroll" + ] + } + ] + } + ], + "En840AndFstDecoderParamsUpdate": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enable_Model_And_Params_20230602", + "enable_features": [ + "ImeFstDecoderParamsUpdate", + "ImeUsEnglishModelUpdate" + ] + } + ] + } + ], + "EnableADPFGpuCompositorThread": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableADPFGpuCompositorThread" + ] + } + ] + } + ], + "EnableADPFRendererMain": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableADPFRendererMain" + ] + } + ] + } + ], + "EnableADPFScrollBoost": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20230530", + "enable_features": [ + "EnableADPFScrollBoost" + ] + } + ] + } + ], + "EnableBackForwardCacheForOngoingSubframeNavigation": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240305", + "enable_features": [ + "EnableBackForwardCacheForOngoingSubframeNavigation" + ] + } + ] + } + ], + "EnableConfigurableThreadCacheMultiplier": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "multiplier_2.0_20230904", + "params": { + "ThreadCacheMultiplier": "2", + "ThreadCacheMultiplierForAndroid": "1" + }, + "enable_features": [ + "EnableConfigurableThreadCacheMultiplier" + ] + } + ] + } + ], + "EnableCustomInputStreamBufferSize": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "EnabledWith64KiBMay2024", + "params": { + "BufferSize": "65536" + }, + "enable_features": [ + "EnableCustomInputStreamBufferSize" + ] + }, + { + "name": "EnabledWith32KiBMay2024", + "params": { + "BufferSize": "32768" + }, + "enable_features": [ + "EnableCustomInputStreamBufferSize" + ] + }, + { + "name": "EnabledWith16KiBMay2024", + "params": { + "BufferSize": "16384" + }, + "enable_features": [ + "EnableCustomInputStreamBufferSize" + ] + }, + { + "name": "EnabledWith8KiBMay2024", + "params": { + "BufferSize": "8192" + }, + "enable_features": [ + "EnableCustomInputStreamBufferSize" + ] + } + ] + } + ], + "EnableDevToolsJsErrorReporting": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableDevToolsJsErrorReporting" + ] + } + ] + } + ], + "EnableFallbackFontsCrashReporting": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled_20230404", + "enable_features": [ + "EnableFallbackFontsCrashReporting" + ] + } + ] + } + ], + "EnableFuzzyMatchAcrossLauncher": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LauncherFuzzyMatchAcrossProviders" + ] + } + ] + } + ], + "EnableImmediateDrawDuringScrollInteraction": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DrawImmediatelyWhenInteractive" + ] + }, + { + "name": "EnabledV2", + "enable_features": [ + "DrawImmediatelyWhenInteractive" + ] + }, + { + "name": "EnabledV3", + "enable_features": [ + "DrawImmediatelyWhenInteractive" + ] + } + ] + } + ], + "EnableOneTapForMaps": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_20240709", + "params": { + "OneTapForMapsConsentModeParam": "iph", + "TCAddressOneTap": "true", + "confidence_score_threshold": "0.9963" + }, + "enable_features": [ + "EnableExpKitTextClassifier", + "EnableExpKitTextClassifierAddress", + "EnableOneTapForMaps" + ], + "min_os_version": "16.4.0" + } + ] + } + ], + "EnableOverwritingPlaceholderUsernames": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableOverwritingPlaceholderUsernames" + ] + } + ] + } + ], + "EnablePDPMetricsUSDesktopIOS": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ShoppingPDPMetrics" + ] + } + ] + } + ], + "EnablePixPayflow": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillEnableSyncingOfPixBankAccounts", + "EnablePixDetection", + "EnablePixDetectionOnCopyEvent", + "EnablePixDetectionOnDomContentLoaded", + "EnablePixPayments" + ] + } + ] + } + ], + "EnablePkcs12ToChapsDualWrite": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnablePkcs12ToChapsDualWrite" + ] + } + ] + } + ], + "EnablePreferencesAccountStorage": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnablePreferencesAccountStorage" + ] + } + ] + } + ], + "EnableSessionSerializationOptimizations": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableSessionSerializationOptimizations" + ] + } + ] + } + ], + "EnableShoppingListIOSM119": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_20231112", + "enable_features": [ + "ShoppingList" + ] + } + ] + } + ], + "EnableTcpPortRandomization": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableTcpPortRandomization" + ] + } + ] + } + ], + "EnableVkPipelineCache": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableVkPipelineCache" + ] + } + ] + } + ], + "EnableWatchdogReportOnlyModeOnGpuInit": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableWatchdogReportOnlyModeOnGpuInit" + ] + } + ] + } + ], + "EnableWifiQos": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableWifiQos" + ] + } + ] + } + ], + "EndOfLifeIncentive": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledOffer_20230324", + "params": { + "incentive_type": "offer" + }, + "enable_features": [ + "EolIncentive" + ] + } + ] + } + ], + "EnsureExistingRendererAlive": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnsureExistingRendererAlive" + ] + } + ] + } + ], + "EnterprisePolicyOnSignin": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnterprisePolicyOnSignin" + ] + } + ] + } + ], + "EstablishGpuChannelChanges": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EstablishGpuChannelChanges", + "enable_features": [ + "EarlyEstablishGpuChannel", + "EstablishGpuChannelAsync" + ] + } + ] + } + ], + "EventTimingFallbackToModalDialogStart": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EventTimingFallbackToModalDialogStart" + ] + } + ] + } + ], + "EventTimingHandleOrphanPointerup": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows", + "android_webview", + "android_weblayer" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EventTimingHandleOrphanPointerup" + ] + } + ] + } + ], + "EventTimingKeypressAndCompositionInteractionId": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EventTimingKeypressAndCompositionInteractionId" + ] + } + ] + } + ], + "EvictionThrottlesDraw": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EvictionThrottlesDraw" + ] + } + ] + } + ], + "ExcludeTransparentTextsFromBeingLcpEligible": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows", + "android_webview", + "android_weblayer" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ExcludeTransparentTextsFromBeingLcpEligible" + ] + } + ] + } + ], + "ExpandCompositedCullRect": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "ExpandCompositedCullRect" + } + ] + } + ], + "ExperimentalFeaturesVisibilityDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabOrganizationSettingsVisibility" + ] + } + ] + } + ], + "ExploreSitesDense": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "WithDenseBottom", + "params": { + "denseVariation": "titleBottom", + "mostLikelyVariation": "groupedIcon", + "variation": "mostLikelyTile" + }, + "enable_features": [ + "ExploreSites" + ] + } + ] + } + ], + "ExtensionPageHats": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "PanelNotSeen", + "params": { + "extension-page-trigger-id": "42JiNWbpq0ugnJ3q1cK0Q7uYnB1P", + "extension-survey-arm": "ExtensionsSafetyHubHaTSArms::kReviewPanelNotShown", + "prob": "1", + "settings-time": "10s" + }, + "enable_features": [ + "HappinessTrackingSurveysExtensionsSafetyHub" + ] + }, + { + "name": "PanelSeen", + "params": { + "extension-page-trigger-id": "Zxq6GQvXC0ugnJ3q1cK0Q3gXah4x", + "extension-survey-arm": "ExtensionsSafetyHubHaTSArms::kReviewPanelShown", + "prob": "1", + "settings-time": "10s" + }, + "enable_features": [ + "HappinessTrackingSurveysExtensionsSafetyHub" + ] + }, + { + "name": "PanelInteraction", + "params": { + "extension-page-trigger-id": "evSXEigVW0ugnJ3q1cK0UapaYUbK", + "extension-survey-arm": "ExtensionsSafetyHubHaTSArms::kReviewPanelInteraction", + "prob": "1", + "settings-time": "10s" + }, + "enable_features": [ + "HappinessTrackingSurveysExtensionsSafetyHub" + ] + } + ] + } + ], + "ExtensionParentalControlsOnLinuxMacWindows": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableExtensionsPermissionsForSupervisedUsersOnDesktop", + "EnableSupervisedUserSkipParentApprovalToInstallExtensions" + ] + } + ] + } + ], + "ExtensionSafetyHubNoPrivacyPracticesTrigger": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafetyHubExtensionsNoPrivacyPracticesTrigger" + ] + } + ] + } + ], + "ExtensionTelemetryDeclarativeNetRequestActionSignal": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafeBrowsingExtensionTelemetryDeclarativeNetRequestActionSignal" + ] + } + ] + } + ], + "ExtensionsServiceWorkerOptimizedEventDispatch": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ExtensionsServiceWorkerOptimizedEventDispatch" + ] + } + ] + } + ], + "ExternalBeginFrameSourceWinUsesRunOrPostTask": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ExternalBeginFrameSourceWinUsesRunOrPostTask" + ] + } + ] + } + ], + "ExternalHDR10": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableExternalDisplayHDR10Mode" + ] + } + ] + } + ], + "ExtremeLightweightUAFDetector": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "BrowserProcessOnly", + "params": { + "quarantine_capacity_in_bytes": "1048576", + "sampling_frequency": "100", + "target_processes": "browser_only" + }, + "enable_features": [ + "ExtremeLightweightUAFDetector" + ] + } + ] + } + ], + "FLEDGEBiddingAndAuctionServer": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows", + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "FledgeBiddingAndAuctionKeyConfig": "{\"https://publickeyservice.gcp.privacysandboxservices.com\": \"https://publickeyservice.pa.gcp.privacysandboxservices.com/.well-known/protected-auction/v1/public-keys\", \"https://publickeyservice.pa.gcp.privacysandboxservices.com\": \"https://publickeyservice.pa.gcp.privacysandboxservices.com/.well-known/protected-auction/v1/public-keys\", \"https://publickeyservice.pa.aws.privacysandboxservices.com\": \"https://publickeyservice.pa.aws.privacysandboxservices.com/.well-known/protected-auction/v1/public-keys\"}", + "FledgeBiddingAndAuctionKeyURL": "https://publickeyservice.pa.gcp.privacysandboxservices.com/.well-known/protected-auction/v1/public-keys" + }, + "enable_features": [ + "FledgeBiddingAndAuctionServer" + ] + } + ] + } + ], + "FamilyMemberRoleFeedback": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240722", + "enable_features": [ + "FetchListFamilyMembersWithCapability", + "UseFamilyMemberRolePrefsForFeedback" + ] + } + ] + } + ], + "FastPairHandshakeLongTermRefactor": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FastPairHandshakeLongTermRefactor" + ] + } + ] + } + ], + "FastPairPWACompanion": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20240711", + "params": { + "pwa-companion-app-id": "ckdjfcfapbgminighllemapmpdlpihia", + "pwa-companion-device-ids": "08A97F,5A36A5,6EDAF7,9ADB11,A7D7A0,C8E228,D87A3E,F2020E,F58DE7,30346C,7862CE,C193F7,05D40E,02FC97,AB442D,FB19ED,C55C79,2EE57B", + "pwa-companion-install-uri": "https://mypixelbuds.google.com/", + "pwa-companion-play-store-uri": "https://play.google.com/store/apps/details?id=com.google.android.apps.wearables.maestro.companion" + }, + "enable_features": [ + "FastPairPwaCompanion" + ] + }, + { + "name": "Enabled_20240711_Dogfood", + "params": { + "pwa-companion-app-id": "ckdjfcfapbgminighllemapmpdlpihia", + "pwa-companion-device-ids": "08A97F,5A36A5,6EDAF7,9ADB11,A7D7A0,C8E228,D87A3E,F2020E,F58DE7,30346C,7862CE,C193F7,05D40E,02FC97,AB442D,FB19ED,C55C79,2EE57B", + "pwa-companion-install-uri": "https://mypixelbuds.google.com/", + "pwa-companion-play-store-uri": "https://play.google.com/store/apps/details?id=com.google.android.apps.wearables.maestro.companion" + }, + "enable_features": [ + "FastPairPwaCompanion" + ] + }, + { + "name": "EnabledWithStagingLinks_Dogfood", + "params": { + "pwa-companion-app-id": "kncedjianpafagdchkiinagaaokkhpaa", + "pwa-companion-device-ids": "08A97F,5A36A5,6EDAF7,9ADB11,A7D7A0,C8E228,D87A3E,F2020E,F58DE7,30346C,7862CE,C193F7,05D40E,02FC97,AB442D,FB19ED,C55C79,2EE57B", + "pwa-companion-install-uri": "https://mypixelbuds-preprod.corp.google.com/", + "pwa-companion-play-store-uri": "https://play.google.com/store/apps/details?id=com.google.android.apps.wearables.maestro.companion" + }, + "enable_features": [ + "FastPairPwaCompanion" + ] + } + ] + } + ], + "FasterSplitScreenSetup": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled_Dogfood_20231030", + "enable_features": [ + "FasterSplitScreenSetup" + ] + } + ] + } + ], + "FeedContainment": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FeedContainment" + ] + } + ] + } + ], + "FeedLoadingPlaceholder": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FeedLoadingPlaceholder" + ] + } + ] + } + ], + "FeedPositionAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_Feed_Position_Push_Down_Small_1", + "params": { + "push_down_feed_small": "true" + }, + "enable_features": [ + "FeedPositionAndroid" + ] + }, + { + "name": "Enabled_Feed_Position_Push_Down_Large_1", + "params": { + "push_down_feed_large": "true" + }, + "enable_features": [ + "FeedPositionAndroid" + ] + }, + { + "name": "Enabled_Feed_Position_Pull_Up_1", + "params": { + "pull_up_feed": "true" + }, + "enable_features": [ + "FeedPositionAndroid" + ] + } + ] + } + ], + "FeedPullToRefreshIph": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_trigger": "name:pulltorefresh_triggered;comparator:==0;window:360;storage:360", + "event_used": "name:feed_swipe_refresh_shown;comparator:==0;window:7;storage:360", + "session_rate": "==0" + }, + "enable_features": [ + "IPH_FeedSwipeRefresh" + ] + } + ] + } + ], + "FeedSignedOutViewDemotion": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FeedSignedOutViewDemotion" + ] + } + ] + } + ], + "FencedFramesEnableCredentialsForAutomaticBeacons": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FencedFramesAutomaticBeaconCredentials" + ] + } + ] + } + ], + "FencedFramesEnableCrossOriginAutomaticBeacons": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FencedFramesCrossOriginAutomaticBeacons" + ] + } + ] + } + ], + "FencedFramesEnableCrossOriginEventReporting": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FencedFramesCrossOriginEventReportingUnlabeledTraffic" + ] + } + ] + } + ], + "FencedFramesEnableM120Features": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FencedFramesM120FeaturesPart2" + ] + } + ] + } + ], + "FencedFramesEnableReportEventHeaderChanges": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FencedFramesReportEventHeaderChanges" + ] + } + ] + } + ], + "FenderAutoPreconnectLcpOrigins": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledWithOne_20240214", + "params": { + "lcpp_preconnect_frequency_threshold": "0.5", + "lcpp_preconnect_max_origins": "1" + }, + "enable_features": [ + "LCPPAutoPreconnectLcpOrigin" + ] + } + ] + } + ], + "FetchGaiaHashOnSignIn": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FetchGaiaHashOnSignIn" + ] + } + ] + } + ], + "FetchLaterAPI": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240112", + "params": { + "send_on_enter_bfcache": "true" + }, + "enable_features": [ + "FetchLaterAPI" + ] + } + ] + } + ], + "FindRegistrationImprovements": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnableAll_20231004", + "enable_features": [ + "ServiceWorkerFetchResponseCallbackUseHighPriority", + "ServiceWorkerMergeFindRegistrationForClientUrl", + "ServiceWorkerRegistrationCache", + "ServiceWorkerScopeCache", + "ServiceWorkerStorageControlOnThreadPool", + "ServiceWorkerStorageControlResponseUseHighPriority" + ] + } + ] + } + ], + "Floss": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "Floss" + ] + } + ] + } + ], + "FlossIsAvailabilityCheckNeeded": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "disable_features": [ + "FlossIsAvailabilityCheckNeeded" + ] + } + ] + } + ], + "FlushPersistentSystemProfileOnWrite": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FlushPersistentSystemProfileOnWrite" + ] + } + ] + } + ], + "FocusMode": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "FocusModeEnabled", + "enable_features": [ + "FocusMode" + ] + } + ] + } + ], + "FollowOnboarding": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20221116", + "params": { + "awareness_style": "IPH" + }, + "enable_features": [ + "WebFeedAwareness", + "WebFeedOnboarding" + ] + } + ] + } + ], + "ForestFeature": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ForestFeature" + ] + }, + { + "name": "EnabledWithoutWeather", + "enable_features": [ + "ForestFeature" + ], + "disable_features": [ + "BirchWeather" + ] + }, + { + "name": "EnabledWithWeatherProdEndpoint", + "params": { + "prod_weather_endpoint": "true" + }, + "enable_features": [ + "BirchWeather", + "ForestFeature" + ] + } + ] + } + ], + "FormControlsVerticalWritingModeDirectionSupport": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FormControlsVerticalWritingModeDirectionSupport" + ] + } + ] + } + ], + "FrameRoutingCache": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FrameRoutingCache" + ] + } + ] + } + ], + "GMSCoreEmoji": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "GMSCoreEmoji" + ] + } + ] + } + ], + "GalleryAppPdfEditNotification": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledEditOrSign_20230127", + "params": { + "text": "Edit or sign" + }, + "enable_features": [ + "GalleryAppPdfEditNotification" + ] + }, + { + "name": "EnabledOpenAndEdit_20230127", + "params": { + "text": "Open and edit" + }, + "enable_features": [ + "GalleryAppPdfEditNotification" + ] + } + ] + } + ], + "GamingPerksStudy": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "CounterfactualControl_20240710", + "params": { + "IPH_ScalableIphGaming_availability": ">=0", + "IPH_ScalableIphGaming_event_1": "name:ScalableIphGameWindowOpened;comparator:>0;window:365;storage:365", + "IPH_ScalableIphGaming_event_trigger": "name:IphScalableIphGamingEventTrigger;comparator:==0;window:365;storage:365", + "IPH_ScalableIphGaming_event_used": "name:IphScalableIphGamingEventUsed;comparator:any;window:365;storage:365", + "IPH_ScalableIphGaming_session_rate": "any", + "IPH_ScalableIphGaming_tracking_only": "true", + "IPH_ScalableIphGaming_x_CustomConditionTriggerEvent": "ScalableIphUnlocked", + "IPH_ScalableIphGaming_x_CustomUiType": "None", + "IPH_ScalableIphGaming_x_CustomVersionNumber": "1" + }, + "enable_features": [ + "IPH_ScalableIphGaming" + ] + }, + { + "name": "Notification_20240710", + "params": { + "IPH_ScalableIphGaming_availability": ">=0", + "IPH_ScalableIphGaming_event_1": "name:ScalableIphGameWindowOpened;comparator:>0;window:365;storage:365", + "IPH_ScalableIphGaming_event_trigger": "name:IphScalableIphGamingEventTrigger;comparator:==0;window:365;storage:365", + "IPH_ScalableIphGaming_event_used": "name:IphScalableIphGamingEventUsed;comparator:any;window:365;storage:365", + "IPH_ScalableIphGaming_session_rate": "any", + "IPH_ScalableIphGaming_x_CustomButtonActionType": "PerksMinecraftRealms2023", + "IPH_ScalableIphGaming_x_CustomConditionTriggerEvent": "ScalableIphUnlocked", + "IPH_ScalableIphGaming_x_CustomNotificationBodyText": "", + "IPH_ScalableIphGaming_x_CustomNotificationButtonText": "Get perk", + "IPH_ScalableIphGaming_x_CustomNotificationId": "scalable_iph_gaming", + "IPH_ScalableIphGaming_x_CustomNotificationImageType": "Minecraft", + "IPH_ScalableIphGaming_x_CustomNotificationTitle": "Get 3 months of Minecraft Realms Plus at no cost on your Chromebook", + "IPH_ScalableIphGaming_x_CustomUiType": "Notification", + "IPH_ScalableIphGaming_x_CustomVersionNumber": "1" + }, + "enable_features": [ + "IPH_ScalableIphGaming" + ] + } + ] + } + ], + "GcmNativeBackgroundTask": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "GcmNativeBackgroundTask" + ] + } + ] + } + ], + "GenGpuDiskCacheKeyPrefixInGpuService": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "GenGpuDiskCacheKeyPrefixInGpuService" + ] + } + ] + } + ], + "GenericFontSettingCache": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "GenericFontSettingCache" + ] + } + ] + } + ], + "GetMostChromeHats": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "en_site_id": "GLvAVoj3X0ugnJ3q1cK0SRghzrsT", + "get-most-chrome-time": "15s", + "probability": "1" + }, + "enable_features": [ + "HappinessTrackingSurveysGetMostChrome" + ] + } + ] + } + ], + "GetTheMostOutOfChrome": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "GetTheMostOutOfChrome" + ] + } + ] + } + ], + "GifRecording": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "GifRecording", + "NotificationImageDrag" + ] + } + ] + } + ], + "GlobalMediaControlsUpdatedUI": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "GlobalMediaControlsUpdatedUI" + ] + } + ] + } + ], + "GlobalVaapiLock": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "GlobalVaapiLock" + ] + } + ] + } + ], + "GoogleLensDesktopContentMenuTranslate": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LensEnableImageTranslate" + ] + } + ] + } + ], + "GoogleLensDesktopImageFormatOptimizations": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "WebpQualityBackendV6", + "params": { + "dismiss-loading-state-on-document-on-load-completed-in-primary-main-frame": "false", + "dismiss-loading-state-on-navigation-entry-committed": "true", + "encoding-quality-image-search": "45", + "encoding-quality-region-search": "45", + "lens-homepage-url": "https://lens.google.com/v3/", + "lens-html-redirect-fix": "false", + "use-jpeg-for-image-search": "false", + "use-webp-for-image-search": "true" + }, + "enable_features": [ + "LensImageFormatOptimizations", + "LensStandalone" + ] + }, + { + "name": "WebpBackendOnlyV6", + "params": { + "encoding-quality-image-search": "90", + "encoding-quality-region-search": "90", + "lens-homepage-url": "https://lens.google.com/v3/", + "lens-html-redirect-fix": "false", + "use-jpeg-for-image-search": "false", + "use-webp-for-image-search": "true" + }, + "enable_features": [ + "LensImageFormatOptimizations", + "LensStandalone" + ] + }, + { + "name": "JpegQualityBackendV6", + "params": { + "dismiss-loading-state-on-document-on-load-completed-in-primary-main-frame": "false", + "dismiss-loading-state-on-navigation-entry-committed": "true", + "encoding-quality-image-search": "40", + "encoding-quality-region-search": "40", + "lens-homepage-url": "https://lens.google.com/v3/", + "lens-html-redirect-fix": "false", + "use-jpeg-for-image-search": "true", + "use-webp-for-image-search": "false" + }, + "enable_features": [ + "LensImageFormatOptimizations", + "LensStandalone" + ] + }, + { + "name": "JpegBackendOnlyV6", + "params": { + "encoding-quality-image-search": "90", + "encoding-quality-region-search": "90", + "lens-homepage-url": "https://lens.google.com/v3/", + "lens-html-redirect-fix": "false", + "use-jpeg-for-image-search": "true", + "use-webp-for-image-search": "false" + }, + "enable_features": [ + "LensImageFormatOptimizations", + "LensStandalone" + ] + }, + { + "name": "JpegQualityOnlyV6", + "params": { + "encoding-quality-image-search": "40", + "encoding-quality-region-search": "40", + "use-jpeg-for-image-search": "true", + "use-webp-for-image-search": "false" + }, + "enable_features": [ + "LensImageFormatOptimizations" + ] + } + ] + } + ], + "GoogleLensTabletIntegration": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_110422", + "params": { + "enableCameraAssistedSearchOnTablet": "true", + "enableCameraAssistedSearchOnTabletWidget": "true", + "enableContextMenuSearchOnTablet": "true" + }, + "enable_features": [ + "LensCameraAssistedSearch", + "LensOnQuickActionSearchWidget" + ] + } + ] + } + ], + "GoogleTtsWithLanguagePacks": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ExperimentalAccessibilityGoogleTtsLanguagePacks" + ] + } + ] + } + ], + "GrCacheLimits": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "cache_96_256_8_default_20230911", + "params": { + "MaxDefaultGlyphCacheTextureBytes": "8388608", + "MaxGaneshResourceCacheBytes": "100663296", + "MaxHighEndGaneshResourceCacheBytes": "268435456" + }, + "enable_features": [ + "GrCacheLimitsFeature" + ] + } + ] + } + ], + "GwpAsanAndroid2024": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "TripleBrowserReservation", + "params": { + "BrowserMaxAllocations": "210", + "BrowserMaxMetadata": "765", + "BrowserTotalPages": "1536" + }, + "enable_features": [ + "GwpAsanMalloc", + "GwpAsanPartitionAlloc" + ] + } + ] + } + ], + "GwpAsanDesktop2024": [ + { + "platforms": [ + "chromeos", + "linux", + "mac" + ], + "experiments": [ + { + "name": "TripleBrowserReservation", + "params": { + "BrowserMaxAllocations": "210", + "BrowserMaxMetadata": "765", + "BrowserTotalPages": "6144" + }, + "enable_features": [ + "GwpAsanMalloc", + "GwpAsanPartitionAlloc" + ] + } + ] + } + ], + "GwpAsanLinux": [ + { + "platforms": [ + "chromeos_lacros", + "fuchsia" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "AllocationSamplingMultiplier": "1500", + "AllocationSamplingRange": "16", + "MaxAllocations": "50", + "MaxMetadata": "210", + "ProcessSamplingBoost2": "10", + "ProcessSamplingProbability": "0.01" + }, + "enable_features": [ + "GwpAsanMalloc", + "GwpAsanPartitionAlloc" + ] + } + ] + } + ], + "H2InitialMaxConcurrentStreamsOverride": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "initial_max_concurrent_streams": "10" + }, + "enable_features": [ + "H2InitialMaxConcurrentStreamsOverride" + ] + } + ] + } + ], + "HTTP2": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled6", + "params": { + "http2_grease_settings": "true" + }, + "enable_features": [ + "Http2Grease" + ] + } + ] + } + ], + "HangoutsExtensionV3": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HangoutsExtensionV3" + ] + } + ] + } + ], + "HappinessTrackingBorealisGames": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.10", + "survey_cycle_length": "7", + "survey_start_date_ms": "1684386279365", + "trigger_id": "KiAbogQzG0jBnuKU19R0RhWzttj4" + }, + "enable_features": [ + "HappinessTrackingBorealisGames" + ] + } + ] + } + ], + "HappinessTrackingMediaAppPdf": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.0174", + "survey_cycle_length": "90", + "survey_start_date_ms": "1662336000000", + "trigger_id": "s5EmUqzvY0jBnuKU19R0Tdf9ticy" + }, + "enable_features": [ + "HappinessTrackingMediaAppPdf" + ] + } + ] + } + ], + "HappinessTrackingOffice": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.01", + "survey_cycle_length": "90", + "survey_start_date_ms": "1721606400000", + "trigger_id": "ZMEQmwKYE0jBnuKU19R0Uk7d5aG4" + }, + "enable_features": [ + "HappinessTrackingOffice" + ] + } + ] + } + ], + "HappinessTrackingOsSettingsSearch": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.01", + "survey_cycle_length": "7", + "survey_start_date_ms": "1678393016", + "trigger_id": "Fa3H4WsCf0jBnuKU19R0Sq6aUpgf" + }, + "enable_features": [ + "HappinessTrackingOsSettingsSearch" + ] + } + ] + } + ], + "HappinessTrackingPersonalizationAvatar": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.01", + "survey_cycle_length": "90", + "survey_start_date_ms": "1653548400", + "trigger_id": "JUanXwTKV0jBnuKU19R0V3H9stME" + }, + "enable_features": [ + "HappinessTrackingPersonalizationAvatar" + ] + } + ] + } + ], + "HappinessTrackingPersonalizationScreensaver": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.01", + "survey_cycle_length": "90", + "survey_start_date_ms": "1653548400", + "trigger_id": "1dEvSx6iU0jBnuKU19R0P6uwwNZ4" + }, + "enable_features": [ + "HappinessTrackingPersonalizationScreensaver" + ] + } + ] + } + ], + "HappinessTrackingPersonalizationWallpaper": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.05", + "survey_cycle_length": "90", + "survey_start_date_ms": "1653548400", + "trigger_id": "PaBNFUU6d0jBnuKU19R0RAjzNxg5" + }, + "enable_features": [ + "HappinessTrackingPersonalizationWallpaper" + ] + } + ] + } + ], + "HappinessTrackingPhotosExperience": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.0174", + "survey_cycle_length": "90", + "survey_start_date_ms": "1662336000000", + "trigger_id": "TGGtMoxqP0jBnuKU19R0Vwye2rn4" + }, + "enable_features": [ + "HappinessTrackingPhotosExperience" + ] + } + ] + } + ], + "HappinessTrackingSystemBatteryLife": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "histogram_name": "ChromeOS.HaTS.BatteryLife", + "prob": "0.02", + "survey_cycle_length": "7", + "survey_start_date_ms": "1681974000000", + "trigger_id": "1xncr1Dp20jBnuKU19R0XpozVULu" + }, + "enable_features": [ + "HappinessTrackingSystemBatteryLife" + ] + } + ] + } + ], + "HappinessTrackingSystemEnt": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "histogram_name": "ChromeOS.HaTS.GeneralWithLocaleForTest", + "prob": "0.02", + "survey_cycle_length": "7", + "survey_start_date_ms": "1478592000000", + "trigger_id": "h48muKREX0jBnuKU19R0UkKwC3pM" + }, + "enable_features": [ + "HappinessTrackingSystemEnt" + ] + } + ] + } + ], + "HappinessTrackingSystemPerformance": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "histogram_name": "ChromeOS.HaTS.Performance", + "prob": "0.02", + "survey_cycle_length": "7", + "survey_start_date_ms": "1641024000000", + "trigger_id": "d9usFbUBd0jBnuKU19R0YEKpVBkq" + }, + "enable_features": [ + "HappinessTrackingSystemPerformance" + ] + } + ] + } + ], + "HappinessTrackingSystemPeripherals": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "histogram_name": "ChromeOS.HaTS.Peripherals", + "prob": "0.02", + "survey_cycle_length": "7", + "survey_start_date_ms": "1686747998371", + "trigger_id": "f4LxbstpP0jBnuKU19R0P4FWKuAs" + }, + "enable_features": [ + "HappinessTrackingSystemPeripherals" + ] + } + ] + } + ], + "HappinessTrackingSystemStability": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_M100_2022_05_04", + "params": { + "histogram_name": "ChromeOS.HaTS.Stability", + "prob": "0.02", + "survey_cycle_length": "7", + "survey_start_date_ms": "1641024000000", + "trigger_id": "d6XgkEBLK0jBnuKU19R0VEK7mCc9" + }, + "enable_features": [ + "HappinessTrackingSystemStability" + ] + } + ] + } + ], + "HatsArcGames": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "custom_client_data": "{\"package_names\":[\"com.roblox.client\",\"com.dts.freefireth\",\"air.com.lunime.gachaclub\",\"com.devsisters.ck\",\"com.tocaboca.tocalifeworld\",\"com.innersloth.spacemafia\",\"com.microsoft.microsoftsolitairecollection\",\"com.king.candycrushsaga\",\"com.king.candycrushsodasaga\",\"air.com.lunime.gachalife\",\"com.playrix.township\",\"com.dts.freefiremax\",\"com.mobilityware.spider\",\"net.wooga.junes_journey_hidden_object_mystery_game\",\"com.mobile.legends\",\"com.ninjakiwi.bloonstd6\",\"com.lockwoodpublishing.avakinlife\",\"com.pixel.art.coloring.color.number\",\"com.playrix.homescapes\",\"com.miHoYo.GenshinImpact\",\"com.mojang.minecraftpe\"]}", + "prob": "0.005", + "survey_cycle_length": "7", + "survey_start_date_ms": "1638316800000", + "trigger_id": "rJ6AqzkxG0jBnuKU19R0UJFsCCjz" + }, + "enable_features": [ + "HappinessTrackingArcGames" + ] + } + ] + } + ], + "HatsBluetoothRevamp": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.01", + "survey_cycle_length": "7", + "survey_start_date_ms": "1642608000000", + "trigger_id": "FvkCS2uJU0jBnuKU19R0UrXtnAdP" + }, + "enable_features": [ + "HappinessTrackingSystemBluetoothRevamp" + ] + } + ] + } + ], + "HatsGeneralCamera": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledWithHistogram_20230704", + "params": { + "enabled_for_googlers": "true", + "histogram_name": "ChromeOS.HaTS.GeneralCamera", + "prob": "0.01", + "survey_cycle_length": "7", + "survey_start_date_ms": "1688472000000", + "trigger_id": "7V7wMHHeK0jBnuKU19R0YYaGnV7M" + }, + "enable_features": [ + "HappinessTrackingGeneralCamera" + ] + } + ] + } + ], + "HatsOnboardingExperience": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.05", + "survey_cycle_length": "2147483647", + "survey_start_date_ms": "1617260400000", + "trigger_id": "NAgJpJZhz0jBnuKU19R0UuVK5EA7" + }, + "enable_features": [ + "HappinessTrackingOnboardingExperience" + ] + } + ] + } + ], + "HatsPrivacyHubPostLaunch": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled_20231027", + "params": { + "prob": "0.05", + "survey_cycle_length": "7", + "survey_start_date_ms": "1693296065000", + "trigger_id": "pmx19g6jw0jBnuKU19R0PK8xn3Ge" + }, + "enable_features": [ + "HappinessTrackingPrivacyHubPostLaunch" + ] + } + ] + } + ], + "HatsSmartUnlock": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.05", + "survey_cycle_length": "7", + "survey_start_date_ms": "1627801200000", + "trigger_id": "4oPHNnPJy0jBnuKU19R0T1NSmNes" + }, + "enable_features": [ + "HappinessTrackingSmartLock" + ] + } + ] + } + ], + "HatsUnlock": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "prob": "0.001", + "survey_cycle_length": "7", + "survey_start_date_ms": "1627801200000", + "trigger_id": "qqZi3hpfx0jBnuKU19R0UA7zE7e4" + }, + "enable_features": [ + "HappinessTrackingUnlock" + ] + } + ] + } + ], + "HeapProfilingCentralControl": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240627", + "params": { + "utility-prob-pct": "50", + "utility-process-params": "{\"is-supported\":true,\"sampling-rate-bytes\":1000000}" + }, + "enable_features": [ + "HeapProfilerCentralControl", + "HeapProfilerReporting" + ] + } + ] + } + ], + "HeatmapPalmDetectionStudy": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableHeatmapPalmDetection" + ] + } + ] + } + ], + "HelpAppLauncherSearch": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HelpAppLauncherSearch" + ] + } + ] + } + ], + "HideDelegatedFrameHostMac": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HideDelegatedFrameHostMac" + ] + } + ] + } + ], + "HistoryEmbeddings": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HistoryEmbeddings" + ] + } + ] + } + ], + "HitTestOpaqueness": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HitTestOpaqueness" + ] + } + ] + } + ], + "HlsBuiltinPlayer": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BuiltInHlsPlayer" + ] + } + ] + } + ], + "HoldbackRemoveMobileViewportDoubleTap": [ + { + "platforms": [ + "android", + "android_weblayer" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "RemoveMobileViewportDoubleTap" + ] + } + ] + } + ], + "Hotspot": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "enable_features": [ + "Hotspot" + ] + }, + { + "name": "Enabled", + "enable_features": [ + "Hotspot" + ] + } + ] + } + ], + "HttpDiskCachePrewarming": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "WithReadAndDiscardBody_20240328", + "params": { + "http_disk_cache_prewarming_use_read_and_discard_body_option": "true" + }, + "enable_features": [ + "HttpDiskCachePrewarming", + "SimpleURLLoaderUseReadAndDiscardBodyOption" + ] + } + ] + } + ], + "HttpsFirstModeIncognitoPhase1": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HttpsFirstModeIncognito" + ] + } + ] + } + ], + "HttpsFirstModeV2ForTypicallySecureUsers": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HttpsFirstModeV2ForTypicallySecureUsers" + ] + } + ] + } + ], + "HttpsUpgrades": [ + { + "platforms": [ + "android", + "windows", + "chromeos", + "chromeos_lacros", + "mac", + "linux" + ], + "experiments": [ + { + "name": "EnabledWithHttpsFirstModeForEngagedSites_20231003", + "enable_features": [ + "HttpsFirstModeV2ForEngagedSites" + ] + } + ] + } + ], + "IOSBackgroundPasteboardAccess": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_CanaryDev", + "enable_features": [ + "OnlyAccessClipboardAsync" + ] + } + ] + } + ], + "IOSBackgroundRefresh": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_20220908", + "enable_features": [ + "EnableFeedBackgroundRefresh" + ] + } + ] + } + ], + "IOSBrowserEditMenuMetrics": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IOSBrowserEditMenuMetrics" + ] + } + ] + } + ], + "IOSChooseFromDrive": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IOSChooseFromDrive" + ] + } + ] + } + ], + "IOSContentNotification": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_Promo", + "params": { + "ContentPushNotificationsExperimentType": "1" + }, + "enable_features": [ + "ContentPushNotifications" + ] + }, + { + "name": "Registered_Promo", + "params": { + "ContentPushNotificationsExperimentType": "5" + }, + "enable_features": [ + "ContentPushNotifications" + ] + }, + { + "name": "Enabled_Provisional", + "params": { + "ContentPushNotificationsExperimentType": "3" + }, + "enable_features": [ + "ContentPushNotifications" + ] + }, + { + "name": "Registered_Provisional", + "params": { + "ContentPushNotificationsExperimentType": "6" + }, + "enable_features": [ + "ContentPushNotifications" + ] + }, + { + "name": "Enabled_Setuplist", + "params": { + "ContentPushNotificationsExperimentType": "2" + }, + "enable_features": [ + "ContentPushNotifications" + ] + }, + { + "name": "Registered_Setuplist", + "params": { + "ContentPushNotificationsExperimentType": "7" + }, + "enable_features": [ + "ContentPushNotifications" + ] + } + ] + } + ], + "IOSDisableFullscreenStudy": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "DisableFullscreenScrolling" + ] + } + ] + } + ], + "IOSDockingPromo": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_FFR_20240419", + "params": { + "IOSDockingPromoExperimentType": "1", + "IOSDockingPromoNewUserInactiveThreshold": "24h", + "IOSDockingPromoNewUserInactiveThresholdHours": "24", + "IOSDockingPromoOldUserInactiveThreshold": "72h", + "IOSDockingPromoOldUserInactiveThresholdHours": "72" + }, + "enable_features": [ + "IOSDockingPromo" + ] + }, + { + "name": "Enabled_FRE_20240419", + "params": { + "IOSDockingPromoExperimentType": "2" + }, + "enable_features": [ + "IOSDockingPromo" + ] + }, + { + "name": "Enabled_Beta_FFR_20240419", + "params": { + "IOSDockingPromoExperimentType": "1", + "IOSDockingPromoNewUserInactiveThreshold": "12h", + "IOSDockingPromoNewUserInactiveThresholdHours": "12", + "IOSDockingPromoOldUserInactiveThreshold": "24h", + "IOSDockingPromoOldUserInactiveThresholdHours": "24" + }, + "enable_features": [ + "IOSDockingPromo" + ] + }, + { + "name": "Enabled_Beta_FRE_20240419", + "params": { + "IOSDockingPromoExperimentType": "2" + }, + "enable_features": [ + "IOSDockingPromo" + ] + }, + { + "name": "Enabled_Canary_Dev_FFR_20240419", + "params": { + "IOSDockingPromoExperimentType": "1", + "IOSDockingPromoNewUserInactiveThreshold": "6h", + "IOSDockingPromoNewUserInactiveThresholdHours": "6", + "IOSDockingPromoOldUserInactiveThreshold": "12h", + "IOSDockingPromoOldUserInactiveThresholdHours": "12" + }, + "enable_features": [ + "IOSDockingPromo" + ] + }, + { + "name": "Enabled_Canary_Dev_FRE_20240419", + "params": { + "IOSDockingPromoExperimentType": "2" + }, + "enable_features": [ + "IOSDockingPromo" + ] + } + ] + } + ], + "IOSEnableColorLensAndVoiceIconsInHomeScreenWidget": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "kEnableColorLensAndVoiceIconsInHomeScreenWidget" + ] + } + ] + } + ], + "IOSFastApplicationWillTerminate": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FastApplicationWillTerminate" + ] + } + ] + } + ], + "IOSFeatureEngagementSessionReset": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FeatureEngagementSessionReset" + ] + } + ] + } + ], + "IOSFeedCUI1Refinements": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableCUI1Refinements" + ] + } + ] + } + ], + "IOSFeedCUI3NextPageAppFlow": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableCUI3NextPageAppFlow" + ] + } + ] + } + ], + "IOSFeedSyncPromo": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Launched_Vertical_6Impressions", + "params": { + "DiscoverFeedTopSyncPromoStyle": "2", + "autodismissImpressions": "6" + }, + "enable_features": [ + "EnableDiscoverFeedTopSyncPromo" + ] + } + ] + } + ], + "IOSFollowUIUpdate": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableFollowUIUpdate" + ] + } + ] + } + ], + "IOSFullscreenImprovement": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FullscreenImprovement" + ] + } + ] + } + ], + "IOSHomeMemoryImprovements": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HomeMemoryImprovements" + ] + } + ] + } + ], + "IOSInactiveTabButtonRefactoring": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "InactiveTabButtonRefactoring" + ] + } + ] + } + ], + "IOSKeepsRenderProcessAlive": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "KeepsRenderProcessAlive" + ] + } + ] + } + ], + "IOSLensWebPageEarlyTransitionEnabled": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LensWebPageEarlyTransitionEnabled" + ] + } + ] + } + ], + "IOSLogApplicationStorageSizeMetrics": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LogApplicationStorageSizeMetrics" + ] + } + ] + } + ], + "IOSMeasurementExperience": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_20240419", + "enable_features": [ + "EnableMeasurementsExperience" + ] + }, + { + "name": "MeasurementsOnly_20240419", + "enable_features": [ + "EnableMeasurementsExperience" + ] + }, + { + "name": "ViewportOnly_20240419", + "enable_features": [ + "EnableViewportIntents" + ] + }, + { + "name": "MeasurementsAndViewport_20240419", + "enable_features": [ + "EnableMeasurementsExperience", + "EnableViewportIntents" + ] + } + ] + } + ], + "IOSModernTabStrip": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "modern-tab-strip-new-tab-button": "dynamic" + }, + "enable_features": [ + "ModernTabStrip" + ] + } + ] + } + ], + "IOSOverflowMenuCustomization": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_CanaryDev", + "enable_features": [ + "OverflowMenuCustomization" + ] + } + ] + } + ], + "IOSParcelTrackingCarrierNumberDetection": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableNewParcelTrackingNumberDetection" + ] + } + ] + } + ], + "IOSPartitionAllocBackupRefPtr": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PartitionAllocBackupRefPtr" + ] + } + ] + } + ], + "IOSSaveToDrive": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_20240523", + "enable_features": [ + "IOSDownloadNoUIUpdateInBackground", + "IOSSaveToDrive" + ] + } + ] + } + ], + "IOSSaveToPhotosImprovements": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SaveToPhotosImprovements" + ] + } + ] + } + ], + "IOSSaveUsernameInUff": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IosSaveUsernameInUff" + ] + } + ] + } + ], + "IOSSharedHighlightingColorChange": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IOSSharedHighlightingColorChange" + ] + } + ] + } + ], + "IOSSignInUff": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IOSPasswordSignInUff" + ] + } + ] + } + ], + "IOSStart4Hour": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled4Hour", + "params": { + "ReturnToStartSurfaceInactiveDurationInSeconds": "14400" + }, + "enable_features": [ + "StartSurface" + ] + } + ] + } + ], + "IOSStickyAutofillAndPasswordInfobars": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AutofillStickyInfobarIos" + ] + } + ] + } + ], + "IOSTFLiteLanguageDetection": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_20220429", + "enable_features": [ + "DownloadServiceForegroundSessionIOSFeature", + "TFLiteLanguageDetectionEnabled" + ] + } + ] + } + ], + "IOSTabGroupInGridiPad": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabGroupsIPad" + ] + } + ] + } + ], + "IOSTabGroupInGridiPhone": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabGroupsInGrid" + ] + } + ] + } + ], + "IOSTabGroupSync": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabGroupSync" + ] + } + ] + } + ], + "IOSTabResumption15": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Tab_Resumption_15_And_2_20240610", + "params": { + "tr15-salient-image": "true", + "tr15-see-more-button": "true" + }, + "enable_features": [ + "PageContentAnnotations", + "SegmentationPlatformURLVisitResumptionRanker", + "TabResumption1_5", + "TabResumption2" + ] + } + ] + } + ], + "IOSTipsNotifications": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IOSTipsNotifications" + ] + } + ] + } + ], + "IOSUseUserDefaultsForExitedCleanlyBeacon": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "UseUserDefaultsForExitedCleanlyBeaconEnabler" + ] + } + ] + } + ], + "IOSWebChannels": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "EnabledWebChannels", + "enable_features": [ + "EnableWebChannels" + ] + } + ] + } + ], + "IOSiPadGhostCards": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableiPadFeedGhostCards" + ] + } + ] + } + ], + "IPProtectionPhase0": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "enabled_proxy_a_ip_protection_phase_04_19_2024", + "params": { + "IpPrivacyBsaEnablePrivacyPass": "true", + "IpPrivacyDirectOnly": "false", + "IpPrivacyIncludeOAuthTokenInGetProxyConfig": "true", + "IpPrivacyTokenServer": "https://phosphor-pa.googleapis.com", + "IpPrivacyTokenServerGetInitialDataPath": "/v1/ipblinding/getInitialData", + "IpPrivacyTokenServerGetProxyConfigPath": "/v1/ipblinding/getProxyConfig", + "IpPrivacyTokenServerGetTokensPath": "/v1/ipblinding/auth", + "IpPrivacyUseProxyChains": "true", + "MaskedDomainListExperimentalVersion": "rc0" + }, + "enable_features": [ + "EnableIpPrivacyProxy", + "MaskedDomainList" + ] + } + ] + } + ], + "ImageDescriptionsAlternativeRouting": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ImageDescriptionsAlternativeRouting" + ] + } + ] + } + ], + "ImprovedSemanticsActivityIndicators": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ImprovedSemanticsActivityIndicators" + ] + } + ] + } + ], + "IncludeJSCallStackInExtensionApiRequestStudy": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IncludeJSCallStackInExtensionApiRequest" + ] + } + ] + } + ], + "IncognitoReauthenticationForAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IncognitoReauthenticationForAndroid" + ] + } + ] + } + ], + "IncognitoScreenshot": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IncognitoScreenshot" + ] + } + ] + } + ], + "IncreaseCoookieAccesCacheSize": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IncreaseCoookieAccesCacheSize" + ] + } + ] + } + ], + "IncreasedCmdBufferParseSlice": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IncreasedCmdBufferParseSlice" + ] + } + ] + } + ], + "IncrementLocalSurfaceIdForMainframeSameDocNavigation": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "linux", + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IncrementLocalSurfaceIdForMainframeSameDocNavigation" + ] + } + ] + } + ], + "IndexedDBCompressValuesWithSnappy": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "ios", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IndexedDBCompressValuesWithSnappy" + ] + } + ] + } + ], + "IndexedDBShardBackingStores": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "ios", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IndexedDBShardBackingStores" + ] + } + ] + } + ], + "InfoBarIconMonochrome": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "InfoBarIconMonochrome" + ] + } + ] + } + ], + "InputDeviceSettingsSplit": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Disabled_InputDeviceSettingsSplit", + "disable_features": [ + "InputDeviceSettingsSplit" + ] + } + ] + } + ], + "InputStreamOptimizations": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "InputStreamOptimizations" + ] + } + ] + } + ], + "InsecureFormSubmissionInterstitial": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "InsecureFormSubmissionInterstitial" + ] + } + ] + } + ], + "InstallAmbientBadgeEngagement": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_Message_Visit", + "enable_features": [ + "AmbientBadgeSuppressFirstVisit", + "InstallableAmbientBadgeMessage" + ] + } + ] + } + ], + "InstallAndroidUnwindDfm": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "InstallAndroidUnwindDfm" + ] + } + ] + } + ], + "IntersectionOptimization": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IntersectionOptimization" + ] + } + ] + } + ], + "IsolatedWebApps": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IsolatedWebAppAutomaticUpdates", + "IsolatedWebApps" + ] + } + ] + } + ], + "JourneysOnDeviceClusteringContentClustering": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "AllVisitsContentClusteringPairwiseMerge_20230714", + "params": { + "collections_blocklist": "/collection/it_glossary,/collection/periodicals,/collection/software,/collection/tv_networks,/collection/websites", + "search_visits_only": "false", + "use_pairwise_merge": "true" + }, + "enable_features": [ + "JourneysOnDeviceClusteringContentClustering" + ] + } + ] + } + ], + "KeepAliveInBrowserMigration": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240117", + "enable_features": [ + "KeepAliveInBrowserMigration" + ] + }, + { + "name": "AttributionReportingInBrowserMigration", + "enable_features": [ + "AttributionReportingInBrowserMigration", + "KeepAliveInBrowserMigration" + ] + } + ] + } + ], + "KeyboardAccessoryAddressIPH": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Address_IPH_Enabled", + "params": { + "availability": "any", + "event_trigger": "name:keyboard_accessory_address_filling_iph_trigger;comparator:<10;window:90;storage:360", + "event_used": "name:keyboard_accessory_address_suggestion_accepted;comparator:<2;window:90;storage:360", + "session_rate": "<1" + }, + "enable_features": [ + "IPH_KeyboardAccessoryAddressFilling" + ], + "disable_features": [] + } + ] + } + ], + "KeyboardAccessoryPasswordIPH": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Password_IPH_Enabled", + "params": { + "availability": "any", + "event_trigger": "name:keyboard_accessory_password_filling_iph_trigger;comparator:<10;window:90;storage:360", + "event_used": "name:keyboard_accessory_password_suggestion_accepted;comparator:<2;window:90;storage:360", + "session_rate": "<1" + }, + "enable_features": [ + "IPH_KeyboardAccessoryPasswordFilling" + ], + "disable_features": [] + } + ] + } + ], + "KeyboardAccessoryPaymentIPH": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Payment_IPH_Enabled", + "params": { + "availability": "any", + "event_trigger": "name:keyboard_accessory_payment_filling_iph_trigger;comparator:<10;window:90;storage:360", + "event_used": "name:keyboard_accessory_payment_suggestion_accepted;comparator:<2;window:90;storage:360", + "session_rate": "<1" + }, + "enable_features": [ + "IPH_KeyboardAccessoryPaymentFilling" + ], + "disable_features": [] + } + ] + } + ], + "KeyboardAccessoryPaymentOffer": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_trigger": "name:keyboard_accessory_payment_offer_iph_trigger;comparator:<3;window:90;storage:360", + "event_used": "name:keyboard_accessory_payment_suggestion_accepted;comparator:<2;window:90;storage:360", + "session_rate": "any", + "session_rate_impact": "IPH_KeyboardAccessoryBarSwiping" + }, + "enable_features": [ + "AutofillEnableOffersInClankKeyboardAccessory", + "IPH_KeyboardAccessoryPaymentOffer" + ] + } + ] + } + ], + "KeyboardAccessorySwipingIPH": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Swiping_IPH_Enabled", + "params": { + "availability": "any", + "event_trigger": "name:keyboard_accessory_bar_swiping_iph_trigger;comparator:<10;window:90;storage:360", + "event_used": "name:keyboard_accessory_bar_swiped;comparator:<2;window:90;storage:360", + "session_rate": "<1" + }, + "enable_features": [ + "IPH_KeyboardAccessoryBarSwiping" + ], + "disable_features": [] + } + ] + } + ], + "KeyboardAndPointerLockPrompt": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "KeyboardAndPointerLockPrompt" + ] + } + ] + } + ], + "KeyboardFocusableScrollers": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "KeyboardFocusableScrollers" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "KeyboardFocusableScrollers" + ] + } + ] + } + ], + "KidsProfile": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "AllFeatures", + "enable_features": [ + "ForceSafeSearchForUnauthenticatedSupervisedUsers", + "HideGuestModeForSupervisedUsers", + "UncredentialedFilteringFallbackForSupervisedUsers" + ] + } + ] + } + ], + "KioskHeartbeatsViaERP": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "KioskHeartbeatsViaERP" + ] + } + ] + } + ], + "LCPPDeferUnusedPreload": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnableWithPostTask_20240426", + "params": { + "load_timing": "post_task" + }, + "enable_features": [ + "LCPPDeferUnusedPreload" + ] + }, + { + "name": "EnableWithLCPTimingPredictor_20240426", + "params": { + "load_timing": "lcp_timing_predictor" + }, + "enable_features": [ + "LCPPDeferUnusedPreload" + ] + } + ] + } + ], + "LCPPDoubleKey": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "lcpp_initiator_origin_histogram_sliding_window_size": "10000", + "lcpp_initiator_origin_max_histogram_buckets": "100" + }, + "enable_features": [ + "LCPPInitiatorOrigin" + ] + } + ] + } + ], + "LCPPFontURLPredictor": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "lcpp_font_prefetch_threshold": "1.1", + "lcpp_font_url_frequency_threshold": "0.1", + "lcpp_max_font_url_count_per_origin": "5", + "lcpp_max_font_url_length": "1024", + "lcpp_max_font_url_to_preload": "5" + }, + "enable_features": [ + "LCPPFontURLPredictor" + ] + }, + { + "name": "WithPrefetch", + "params": { + "lcpp_enable_font_prefetch": "true", + "lcpp_font_prefetch_threshold": "1.1", + "lcpp_font_url_frequency_threshold": "0.1", + "lcpp_max_font_url_count_per_origin": "5", + "lcpp_max_font_url_length": "1024", + "lcpp_max_font_url_to_preload": "5" + }, + "enable_features": [ + "LCPPFontURLPredictor" + ] + } + ] + } + ], + "LCPPImageLoadingPriority": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "MediumPriority_20240418", + "params": { + "lcpp_adjust_image_load_priority": "true", + "lcpp_adjust_image_load_priority_override_first_n_boost": "true", + "lcpp_enable_image_load_priority_for_htmlimageelement": "false", + "lcpp_enable_perf_improvements": "true", + "lcpp_histogram_sliding_window_size": "1000", + "lcpp_image_load_priority": "medium", + "lcpp_max_element_locator_length": "1024", + "lcpp_max_histogram_buckets": "10", + "lcpp_max_hosts_to_track": "100", + "lcpp_recorded_lcp_element_types": "image_only" + }, + "enable_features": [ + "LCPCriticalPathPredictor" + ] + } + ] + } + ], + "LCPPLazyLoadImagePreload": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnableWithNativeLazyLoading_20231113", + "params": { + "lcpp_preload_lazy_load_image_type": "native_lazy_loading" + }, + "enable_features": [ + "LCPPLazyLoadImagePreload" + ] + } + ] + } + ], + "LCPPMultipleKey": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "lcpp_max_hosts_to_track": "100", + "lcpp_multiple_key_max_path_length": "15", + "lcpp_multiple_key_type": "default" + }, + "enable_features": [ + "LCPPMultipleKey" + ] + }, + { + "name": "WithMaxHost1000", + "params": { + "lcpp_max_hosts_to_track": "1000", + "lcpp_multiple_key_max_path_length": "15", + "lcpp_multiple_key_type": "default" + }, + "enable_features": [ + "LCPPMultipleKey" + ] + }, + { + "name": "EnabledKeyStat", + "params": { + "lcpp_max_hosts_to_track": "100", + "lcpp_multiple_key_histogram_sliding_window_size": "1000", + "lcpp_multiple_key_max_histogram_buckets": "10", + "lcpp_multiple_key_max_path_length": "15", + "lcpp_multiple_key_type": "lcpp_key_stat" + }, + "enable_features": [ + "LCPPMultipleKey" + ] + } + ] + } + ], + "LCPTimingPredictorPrerender2": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LCPTimingPredictorPrerender2" + ] + } + ] + } + ], + "LacrosGooglePolicyRollout": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "enable_features": [ + "LacrosGooglePolicyRollout" + ] + } + ] + } + ], + "LargeFakeboxWithColorIconsIOS": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "LargeFakeboxWithColorIcons", + "enable_features": [ + "IOSLargeFakebox", + "OmniboxColorIcons" + ] + } + ] + } + ], + "LauncherGameSearchStudy": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "enabled_override": "true" + }, + "enable_features": [ + "AppProvisioningStatic", + "LauncherGameSearch" + ] + } + ] + } + ], + "LayoutNGShapeCache": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LayoutNGShapeCache" + ] + } + ] + } + ], + "LazyBlinkTimezoneInit": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LazyBlinkTimezoneInit" + ] + } + ] + } + ], + "LeakSkiaEventTracerAtExit": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LeakSkiaEventTracerAtExit" + ] + } + ] + } + ], + "LeftHandSideActivityIndicators": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LeftHandSideActivityIndicators" + ] + } + ] + } + ], + "LevelDBProtoAsyncWrite": [ + { + "platforms": [ + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LevelDBProtoAsyncWrite" + ] + } + ] + } + ], + "LightweightUAFDetector": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240130", + "params": { + "AllocationSamplingMultiplier": "100", + "EvictionTaskIntervalMs": "5000", + "MaxAllocations": "1400", + "MaxMetadata": "5100", + "MaxTotalSize": "131072", + "Mode": "Random", + "TotalSizeHighWaterMark": "104857", + "TotalSizeLowWaterMark": "91750" + }, + "enable_features": [ + "LightweightUafDetector" + ], + "disable_features": [ + "GwpAsanMalloc", + "GwpAsanPartitionAlloc" + ] + } + ] + } + ], + "LinkCrossDeviceDogFoodFeedback": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LinkCrossDeviceDogFoodFeedback" + ] + } + ] + } + ], + "LinkPreview": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledAltClick", + "params": { + "trigger_type": "alt_click" + }, + "enable_features": [ + "LinkPreview" + ] + } + ] + } + ], + "LinkedServicesSetting": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "ios", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LinkedServicesSetting", + "LinkedServicesSettingIos" + ] + } + ] + } + ], + "LiveCaptionChromeOS2": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_2024_04_15", + "enable_features": [ + "CrosExpandSodaLanguages", + "LiveCaptionMultiLanguage" + ] + } + ] + } + ], + "LiveCaptionExperimentalLanguages": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "available_languages": "en-US,fr-FR,it-IT,de-DE,es-ES,ja-JP,hi-IN,pt-BR,ko-KR,pl-PL,th-TH,tr-TR,id-ID,cmn-Hans-CN,cmn-Hant-TW,vi-VN,ru-RU" + }, + "enable_features": [ + "LiveCaptionExperimentalLanguages" + ] + } + ] + } + ], + "LiveCaptionMultiLanguageRollout": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "available_languages": "en-US,fr-FR,it-IT,de-DE" + }, + "enable_features": [ + "LiveCaptionMultiLanguage" + ] + } + ] + } + ], + "LoadingPhaseBufferTimeAfterFirstMeaningfulPaint": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "buffer_500ms_20230907", + "params": { + "LoadingPhaseBufferTimeAfterFirstMeaningfulPaintMillis": "500" + }, + "enable_features": [ + "LoadingPhaseBufferTimeAfterFirstMeaningfulPaint" + ] + } + ] + } + ], + "LocalStateEnterprisePasswordHashes": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LocalStateEnterprisePasswordHashes" + ] + } + ] + } + ], + "LofnPermissiveUsbPassthrough": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootPermissiveUsbPassthrough" + ], + "min_os_version": "15575.0.0" + } + ] + } + ], + "LogOnDeviceMetricsOnStartup": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "on_device_startup_metric_delay": "3m" + }, + "enable_features": [ + "LogOnDeviceMetricsOnStartup" + ] + } + ] + } + ], + "LowPriorityAsyncScriptExecution": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "PreviousBest_20240501", + "params": { + "delay_async_exec_opt_out_auto_fetch_priority_hint": "false", + "delay_async_exec_opt_out_high_fetch_priority_hint": "false", + "delay_async_exec_opt_out_low_fetch_priority_hint": "false", + "low_pri_async_exec_cross_site_only": "true", + "low_pri_async_exec_exclude_document_write": "false", + "low_pri_async_exec_exclude_non_parser_inserted": "false", + "low_pri_async_exec_feature_limit": "3s", + "low_pri_async_exec_lower_task_priority": "best_effort", + "low_pri_async_exec_main_frame_only": "true", + "low_pri_async_exec_target": "both", + "low_pri_async_exec_timeout": "1s" + }, + "enable_features": [ + "LowPriorityAsyncScriptExecution" + ] + } + ] + } + ], + "LowerHighResolutionTimerThreshold": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LowerHighResolutionTimerThreshold" + ] + } + ] + } + ], + "MacAllowBackgroundingRenderProcesses": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MacAllowBackgroundingRenderProcesses" + ] + } + ] + } + ], + "MacAppCodeSignSafeUpdates": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MacAppCodeSignClone" + ] + } + ] + } + ], + "MacImmersiveFullscreen": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ImmersiveFullscreen" + ] + } + ] + } + ], + "MacWebContentsOcclusionV2": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "EnhancedWindowOcclusionDetection": "true" + }, + "enable_features": [ + "MacWebContentsOcclusion" + ] + } + ] + } + ], + "MagicStackGradientView": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MagicStackRemoveGradientView" + ] + } + ] + } + ], + "MahiEnabled": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "MahiEnabled", + "enable_features": [ + "Mahi", + "MediaAppPdfMahi" + ] + } + ] + } + ], + "MainThreadCompositingPriority": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled_20230817", + "enable_features": [ + "MainThreadCompositingPriority" + ] + } + ] + } + ], + "MaxNumDelayableRequestsPerHostPerClient": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "MaxRequests_6_20230906", + "params": { + "MaxNumDelayableRequestsPerHostPerClient": "6" + }, + "enable_features": [ + "MaxNumDelayableRequestsPerHostPerClientFeature" + ] + } + ] + } + ], + "MediaDeviceIdStoragePartitioning": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MediaDeviceIdPartitioning", + "MediaDeviceIdRandomSaltsPerStorageKey" + ] + } + ] + } + ], + "MediaFoundationAV1Encoding": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MediaFoundationAV1Encoding" + ] + } + ] + } + ], + "MediaFoundationBatchRead": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled_200", + "params": { + "batch_read_count": "200" + }, + "enable_features": [ + "MediaFoundationBatchRead" + ] + } + ] + } + ], + "MediaFoundationCameraUsageMonitoring": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MediaFoundationCameraUsageMonitoring" + ] + } + ] + } + ], + "MediaFoundationVP9Encoding": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MediaFoundationVP9Encoding" + ] + } + ] + } + ], + "MediaHardwareSecureDecryption": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HardwareSecureDecryptionExperiment" + ] + } + ] + } + ], + "MediaHardwareSecureDecryptionFallbackPerSite": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "per_site": "true" + }, + "enable_features": [ + "HardwareSecureDecryptionFallback" + ] + } + ] + } + ], + "MediaRecorderUseMediaVideoEncoder": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MediaRecorderUseMediaVideoEncoder" + ] + } + ] + } + ], + "MeetDevicesMojoServices": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Hotlog-Experiment", + "params": { + "CommandLoggerEnabled": "true", + "CommandLoggerFrequencySeconds": "30", + "CrosHealthdProducerFrequencySeconds": "60", + "DiagnosticsLoggerEnabled": "true", + "ProcessLoggerEnabled": "true", + "SystemLoggerEnabled": "false", + "SystemLoggerFrequencySeconds": "30" + }, + "enable_features": [ + "EncryptedReportingPipeline", + "MeetDevicesCloudLogger", + "MeetDevicesMojoServices" + ] + } + ] + } + ], + "MemoryCacheStrongReference": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "FilterImageAllPages_20240124", + "enable_features": [ + "MemoryCacheStrongReference", + "MemoryCacheStrongReferenceFilterImages" + ], + "disable_features": [ + "MemoryCacheStrongReferenceFilterScripts" + ] + } + ] + } + ], + "MemoryPurgeInBackground": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "ShortDelay", + "params": { + "memory_purge_background_max_delay": "45s", + "memory_purge_background_min_delay": "30s" + }, + "enable_features": [ + "MemoryPurgeInBackground" + ] + }, + { + "name": "LongDelay", + "params": { + "memory_purge_background_max_delay": "11m", + "memory_purge_background_min_delay": "10m" + }, + "enable_features": [ + "MemoryPurgeInBackground" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "MemoryPurgeInBackground" + ] + } + ] + } + ], + "MessagePumpEpoll": [ + { + "platforms": [ + "android", + "chromeos", + "linux" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MessagePumpEpoll" + ] + } + ] + } + ], + "MessagesPreinstall": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MessagesPreinstall" + ] + } + ] + } + ], + "MetricsLogTrimming": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MetricsLogTrimming" + ] + } + ] + } + ], + "MetricsServiceDeltaSnapshotInBg": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MetricsServiceDeltaSnapshotInBg" + ] + } + ] + } + ], + "MigrateAlwaysTranslateLanguagesFix": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MigrateAlwaysTranslateLanguagesFix" + ] + } + ] + } + ], + "MigrateDefaultChromeAppToWebAppsGSuite": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20210111", + "enable_features": [ + "MigrateDefaultChromeAppToWebAppsGSuite" + ] + } + ] + } + ], + "MigrateDefaultChromeAppToWebAppsNonGSuite": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20210111", + "enable_features": [ + "MigrateDefaultChromeAppToWebAppsNonGSuite" + ] + } + ] + } + ], + "MinorModeRestrictionsForHistorySyncOptInIosStudy": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Deadline250_WithSystem_WithPrefetch_20240604_M125+", + "params": { + "FetchImmediatelyAvailableCapabilityDeadlineMs": "100", + "MinorModeRestrictionsFetchDeadlineMs": "250" + }, + "enable_features": [ + "MinorModeRestrictionsForHistorySyncOptIn", + "PrefetchSystemCapabilitiesOnAppStartup", + "PrefetchSystemCapabilitiesOnFirstRun", + "UseSystemCapabilitiesForMinorModeRestrictions" + ] + } + ] + } + ], + "MmapSafeBrowsingDatabase": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_20240116", + "params": { + "MmapSafeBrowsingDatabaseAsync": "true" + }, + "enable_features": [ + "MmapSafeBrowsingDatabase", + "SafeBrowsingOnUIThread" + ] + } + ] + } + ], + "MojoChannelAssociatedCrashesOnSendError": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MojoChannelAssociatedCrashesOnSendError" + ] + } + ] + } + ], + "MojoChannelAssociatedSendUsesRunOrPostTask": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MojoChannelAssociatedSendUsesRunOrPostTask" + ] + } + ] + } + ], + "MojoInlineMessagePayloads": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MojoInlineMessagePayloads" + ] + } + ] + } + ], + "MojoLargerDataPipeAllocationSize": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "data_pipe_2048k_20230922", + "params": { + "LargerDataPipeAllocationSize": "2097152" + }, + "enable_features": [ + "LargerDataPipeAllocationSizeFeature" + ] + } + ] + } + ], + "MojoPredictiveAllocation": [ + { + "platforms": [ + "android", + "android_webview", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MojoPredictiveAllocation" + ] + } + ] + } + ], + "MojoUseBinder": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MojoUseBinder" + ] + } + ] + } + ], + "MouseDragOnCancelledMouseMove": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MouseDragOnCancelledMouseMove" + ] + } + ] + } + ], + "MsaaSettingsMac": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "DetectHiDpiForMsaa", + "enable_features": [ + "DetectHiDpiForMsaa" + ] + } + ] + } + ], + "MultiCalendarSupport": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MultiCalendarSupport" + ] + } + ] + } + ], + "MutationEvents": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "MutationEvents" + ] + } + ] + } + ], + "MutationEventsSpecialTrialMessage": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "MutationEventsSpecialTrialMessage" + ] + } + ] + } + ], + "NavBarColorMatchesTabBackgroundAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NavBarColorMatchesTabBackground" + ] + }, + { + "name": "Enabled_DisabledAnimation", + "params": { + "color_animation_disabled": "true" + }, + "enable_features": [ + "NavBarColorMatchesTabBackground" + ] + } + ] + } + ], + "NavigationPredictorIntersectionObserver": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20240703", + "params": { + "intersection_observer_delay": "1000ms", + "max_intersection_observations": "120", + "random_anchor_sampling_period": "1" + }, + "enable_features": [ + "NavigationPredictor" + ] + } + ] + } + ], + "NavigationPredictorNewViewportFeatures": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NavigationPredictorNewViewportFeatures" + ] + } + ] + } + ], + "NearbyBleV2": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableNearbyBleV2" + ] + } + ] + } + ], + "NearbyBleV2GattServer": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableNearbyBleV2GattServer" + ] + } + ] + } + ], + "NearbyMdns": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableNearbyMdns" + ] + } + ] + } + ], + "NearbyShareNameEnabled": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IsNameEnabled" + ] + } + ] + } + ], + "NearbySharingRemoveRestrictToContacts": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "disable_features": [ + "NearbySharingRestrictToContacts" + ] + } + ] + } + ], + "NearbySharingSelfShare": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NearbySharingSelfShare" + ] + } + ] + } + ], + "NearbySharingWifiDirect": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NearbySharingWifiDirect" + ] + } + ] + } + ], + "NetAdapterMaxBufSize": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "max_buf_size_064k_20230922", + "params": { + "NetAdapterMaxBufSize": "65536" + }, + "enable_features": [ + "NetAdapterMaxBufSizeFeature" + ] + } + ] + } + ], + "NetworkServiceSandboxLinuxAndChromeOS": [ + { + "platforms": [ + "linux", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "EnabledWithMitigation", + "enable_features": [ + "NetworkServiceFileAllowlist", + "NetworkServiceSandbox", + "NetworkServiceSyscallFilter" + ], + "disable_features": [ + "kForceDisableSpectreVariant2MitigationInNetworkService" + ] + } + ] + } + ], + "NetworkServiceSandboxWindows": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled_20231025", + "enable_features": [ + "NetworkServiceSandbox" + ] + } + ] + } + ], + "NeuralPalmRejectionModelForRedrix": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20220622", + "enable_features": [ + "EnableNeuralPalmDetectionFilter" + ] + } + ] + } + ], + "NewEvSignalsEnabled": [ + { + "platforms": [ + "windows", + "mac", + "linux" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "DisableFileSystemInfo": "true", + "DisableSettings": "true" + }, + "enable_features": [ + "NewEvSignalsEnabled" + ] + } + ] + } + ], + "NoPasswordSuggestionFiltering": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NoPasswordSuggestionFiltering" + ] + } + ] + } + ], + "NoPreReadMainDll": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NoPreReadMainDll" + ] + } + ] + } + ], + "NoThrottlingVisibleAgent": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NoThrottlingVisibleAgent" + ] + } + ] + } + ], + "NonModalPromoCooldownSeparation": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "CooldownDays14_2024_06_02", + "params": { + "cooldown-days": "14" + }, + "enable_features": [ + "NonModalDefaultBrowserPromoCooldownRefactor" + ] + } + ] + } + ], + "NonStandardAppearanceValueSliderVertical": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "NonStandardAppearanceValueSliderVertical" + ] + } + ] + } + ], + "NonStandardAppearanceValuesHighUsage": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "NonStandardAppearanceValuesHighUsage" + ] + } + ] + } + ], + "NormalMaxItemsInCacheForSoftware": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "ImageCache_1000_20230914", + "params": { + "NormalMaxItemsInCacheForSoftware": "1000" + }, + "enable_features": [ + "NormalMaxItemsInCacheForSoftwareFeature" + ] + } + ] + } + ], + "NotReachedIsFatal": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_V1", + "enable_features": [ + "NotReachedIsFatal" + ] + } + ] + } + ], + "NotificationOneTapUnsubscribe": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NotificationOneTapUnsubscribe" + ], + "min_os_version": "9.0.0" + } + ] + } + ], + "NotificationsIgnoreRequireInteraction": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "NotificationsIgnoreRequireInteraction" + ] + } + ] + } + ], + "OidcAuthProfileManagement": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OidcAuthProfileManagement" + ] + } + ] + } + ], + "OmitBlurEventOnElementRemoval": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled" + } + ] + } + ], + "OmniboxActionsInSuggestIOS": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OmniboxIOSActionsInSuggest" + ] + } + ] + } + ], + "OmniboxAsyncViewInflation": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OmniboxAsyncViewInflation" + ] + } + ] + } + ], + "OmniboxBundledExperimentV1": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "DesktopExperiments", + "enable_features": [ + "OmniboxRemoveSuggestionsFromClipboard", + "OmniboxUIExperimentMaxAutocompleteMatches" + ], + "disable_features": [] + } + ] + }, + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "AndroidExperiments", + "enable_features": [ + "OmniboxDynamicMaxAutocomplete", + "OmniboxMaxURLMatches", + "OmniboxUIExperimentMaxAutocompleteMatches" + ] + } + ] + }, + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "IOSExperiments", + "params": {}, + "enable_features": [] + } + ] + } + ], + "OmniboxCr23M113Desktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "enabled", + "enable_features": [ + "Cr2023ActionChips", + "Cr2023ActionChipsIcons", + "OmniboxExpandedLayout", + "OmniboxExpandedStateColors", + "OmniboxExpandedStateHeight", + "OmniboxExpandedStateShape", + "OmniboxExpandedStateSuggestIcons", + "OmniboxSteadyStateBackgroundColor", + "OmniboxSteadyStateHeight", + "OmniboxSteadyStateTextColor", + "OmniboxSuggestionHoverFillShape", + "kOmniboxCR23SteadyStateIcons" + ] + } + ] + } + ], + "OmniboxElegantTextHeight": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OmniboxElegantTextHeight" + ] + } + ] + } + ], + "OmniboxFeaturedEnterpriseSiteSearch": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_IPH", + "enable_features": [ + "ShowFeaturedEnterpriseSiteSearch", + "ShowFeaturedEnterpriseSiteSearchIPH" + ] + }, + { + "name": "Enabled", + "enable_features": [ + "ShowFeaturedEnterpriseSiteSearch" + ] + } + ] + } + ], + "OmniboxInspireMePhase2": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledCarouselAboveTrends", + "params": { + "QueryTilesShowAboveTrends": "true", + "QueryTilesShowAsCarousel": "false", + "experiment_tag": "{maxLevels: 1, rankTiles: true}" + }, + "enable_features": [ + "OmniboxQueryTilesInZPSOnNTP", + "QueryTiles" + ] + } + ] + } + ], + "OmniboxIpadPopout": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnablePopoutOmniboxIpad" + ] + } + ] + } + ], + "OmniboxLogURLScoringSignals": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "enable_scoring_signals_annotators": "true" + }, + "enable_features": [ + "LogUrlScoringSignals" + ] + } + ] + } + ], + "OmniboxMlUrlPiecewiseMappedScoringDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_AdjustedBy0", + "params": { + "MlUrlPiecewiseMappedSearchBlending": "true", + "MlUrlPiecewiseMappedSearchBlending_BreakPoints": "0,550;0.018,1300;0.14,1398;1,1422", + "MlUrlPiecewiseMappedSearchBlending_GroupingThreshold": "1400", + "MlUrlPiecewiseMappedSearchBlending_RelevanceBias": "0", + "MlUrlScoringShortcutDocumentSignals": "true", + "enable_scoring_signals_annotators_for_ml_scoring": "true" + }, + "enable_features": [ + "MlUrlPiecewiseMappedSearchBlending", + "MlUrlScoring", + "UrlScoringModel" + ] + }, + { + "name": "Enabled_DemotedBy50", + "params": { + "MlUrlPiecewiseMappedSearchBlending": "true", + "MlUrlPiecewiseMappedSearchBlending_BreakPoints": "0,550;0.018,1250;0.14,1348;1,1422", + "MlUrlPiecewiseMappedSearchBlending_GroupingThreshold": "1350", + "MlUrlPiecewiseMappedSearchBlending_RelevanceBias": "0", + "MlUrlScoringShortcutDocumentSignals": "true", + "enable_scoring_signals_annotators_for_ml_scoring": "true" + }, + "enable_features": [ + "MlUrlPiecewiseMappedSearchBlending", + "MlUrlScoring", + "UrlScoringModel" + ] + }, + { + "name": "Enabled_PromotedBy100", + "params": { + "MlUrlPiecewiseMappedSearchBlending": "true", + "MlUrlPiecewiseMappedSearchBlending_BreakPoints": "0,550;0.018,1400;0.14,1498;1,1522", + "MlUrlPiecewiseMappedSearchBlending_GroupingThreshold": "1500", + "MlUrlPiecewiseMappedSearchBlending_RelevanceBias": "0", + "MlUrlScoringShortcutDocumentSignals": "true", + "enable_scoring_signals_annotators_for_ml_scoring": "true" + }, + "enable_features": [ + "MlUrlPiecewiseMappedSearchBlending", + "MlUrlScoring", + "UrlScoringModel" + ] + }, + { + "name": "Enabled_PromotedBy50", + "params": { + "MlUrlPiecewiseMappedSearchBlending": "true", + "MlUrlPiecewiseMappedSearchBlending_BreakPoints": "0,550;0.018,1350;0.14,1448;1,1472", + "MlUrlPiecewiseMappedSearchBlending_GroupingThreshold": "1450", + "MlUrlPiecewiseMappedSearchBlending_RelevanceBias": "0", + "MlUrlScoringShortcutDocumentSignals": "true", + "enable_scoring_signals_annotators_for_ml_scoring": "true" + }, + "enable_features": [ + "MlUrlPiecewiseMappedSearchBlending", + "MlUrlScoring", + "UrlScoringModel" + ] + } + ] + } + ], + "OmniboxOnClobberFocusTypeOnContent": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_V2", + "enable_features": [ + "OmniboxOnClobberFocusTypeOnContent" + ] + } + ] + } + ], + "OmniboxOnDeviceHeadModelSelectionFix": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Fix", + "params": { + "SelectionFix ": "true" + }, + "enable_features": [ + "OmniboxOnDeviceHeadProviderNonIncognito" + ] + } + ] + } + ], + "OmniboxOnDeviceTailSuggest": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OmniboxOnDeviceTailModel" + ] + }, + { + "name": "Enabled_Auto_Unload", + "params": { + "UnloadExecutorOnIdle ": "true" + }, + "enable_features": [ + "OmniboxOnDeviceTailModel" + ] + } + ] + } + ], + "OmniboxPrefBasedConsentHelper": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrefBasedDataCollectionConsentHelper" + ] + } + ] + } + ], + "OmniboxPrerender": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledPrerenderDSE_20230315", + "params": { + "implementation_type": "use_prefetch" + }, + "enable_features": [ + "SupportSearchSuggestionForPrerender2" + ] + }, + { + "name": "Control_20230315", + "disable_features": [ + "SupportSearchSuggestionForPrerender2" + ] + }, + { + "name": "HoldbackPrerenderDSE_20230315", + "params": { + "implementation_type": "use_prefetch" + }, + "enable_features": [ + "Prerender2Holdback", + "SupportSearchSuggestionForPrerender2" + ] + }, + { + "name": "HoldbackDisabled_20230131", + "enable_features": [ + "Prerender2Holdback" + ], + "disable_features": [ + "OmniboxTriggerForNoStatePrefetch", + "SupportSearchSuggestionForPrerender2" + ] + }, + { + "name": "HoldbackEnabled_20230131", + "enable_features": [ + "OmniboxTriggerForPrerender2" + ], + "disable_features": [ + "OmniboxTriggerForNoStatePrefetch", + "Prerender2Holdback", + "SupportSearchSuggestionForPrerender2" + ] + } + ] + } + ], + "OmniboxRTLImprovements": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OmniboxPopupRowContentConfiguration", + "OmniboxSuggestionsRTLImprovements" + ] + } + ] + } + ], + "OmniboxRelaxedDriveRequirements": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_NoSyncRequirement_IgnoreWhenDebouncing_V2", + "params": { + "DocumentProviderBackoffOn401": "true", + "DocumentProviderIgnoreWhenDebouncing": "true" + }, + "enable_features": [ + "OmniboxDocumentProviderNoSyncRequirement" + ] + }, + { + "name": "Enabled_IgnoreWhenDebouncing_V2", + "params": { + "DocumentProviderBackoffOn401": "true", + "DocumentProviderIgnoreWhenDebouncing": "true" + }, + "disable_features": [ + "OmniboxDocumentProviderNoSyncRequirement" + ] + }, + { + "name": "Enabled_NoSyncRequirement_V2", + "params": { + "DocumentProviderBackoffOn401": "true", + "DocumentProviderIgnoreWhenDebouncing": "false" + }, + "enable_features": [ + "OmniboxDocumentProviderNoSyncRequirement" + ] + } + ] + } + ], + "OmniboxStarterPackIPH": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "StarterPackIPH" + ] + } + ] + } + ], + "OmniboxTextAndAnimationOptimizations": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20230811", + "enable_features": [ + "AvoidRelayoutDuringFocusAnimation", + "ScrollToTLDOptimization" + ] + } + ] + } + ], + "OneCopyLegacyMPVideoFrameUploadViaSI": [ + { + "platforms": [ + "mac", + "windows", + "chromeos", + "chromeos_lacros", + "linux", + "fuchsia" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OneCopyLegacyMPVideoFrameUploadViaSI" + ] + } + ] + } + ], + "OneGroupPerRenderer": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OneGroupPerRenderer" + ] + } + ] + } + ], + "OneTimePermission": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledWithNormalLanguage", + "params": { + "use_stronger_prompt_language": "false" + }, + "enable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission" + ] + }, + { + "name": "EnabledWithStrongLanguage", + "params": { + "use_stronger_prompt_language": "true" + }, + "enable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission" + ] + }, + { + "name": "HatsControl", + "params": { + "probability": "1", + "probability_vector": "1.0,1.0,1.0", + "prompt_disposition_reason_filter": "DefaultFallback", + "request_type_filter": "Geolocation,VideoCapture,AudioCapture", + "survey_display_time": "OnPromptResolved", + "trigger_id": "q1b37Zevt0ugnJ3q1cK0THbqyNJ4,zZBrVcebz0ugnJ3q1cK0Q9Uo6NFQ,m42rnDDGV0ugnJ3q1cK0RDuG9CQ4" + }, + "disable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission" + ] + }, + { + "name": "Control", + "disable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission" + ] + }, + { + "name": "EnabledWithAllowOnEveryVisitAsFirstButton", + "params": { + "show_allow_always_as_first_button": "true", + "use_stronger_prompt_language": "true" + }, + "enable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission" + ] + }, + { + "name": "EnabledWithAllowWhileVisitingAsFirstButton", + "params": { + "show_allow_always_as_first_button": "true", + "use_stronger_prompt_language": "true", + "use_while_visiting_language": "true" + }, + "enable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission" + ] + }, + { + "name": "EnabledWithAllowWhileVisitingAsSecondButton", + "params": { + "show_allow_always_as_first_button": "false", + "use_stronger_prompt_language": "true", + "use_while_visiting_language": "true" + }, + "enable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission" + ] + } + ] + } + ], + "OneTimePermissionClank": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledWithNormalLanguage", + "params": { + "experimental_custom_invitation_arm_trigger_id": "eaHr88umj0tK1KeaPYj0YkhJEi1Y,8U6CRfLYU0tK1KeaPYj0RbTHRpNZ,qrWTeaJaK0tK1KeaPYj0XjFWabba", + "probability": "1", + "probability_vector": "0.5,1.0,1.0", + "prompt_disposition_reason_filter": "DefaultFallback", + "request_type_filter": "Geolocation,VideoCapture,AudioCapture", + "survey_display_time": "OnPromptResolved", + "trigger_id": "hCatPbt6B0tK1KeaPYj0WXqMjcvX,89BwvKxbJ0tK1KeaPYj0NtK7Ybn8,3fTPt7XMF0tK1KeaPYj0TXd8QN47", + "use_stronger_prompt_language": "false" + }, + "enable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission", + "PermissionsPromptSurvey" + ] + }, + { + "name": "HatsControl", + "params": { + "experimental_custom_invitation_arm_trigger_id": "Db6NddebR0tK1KeaPYj0UzKHA4zC,sRE9DYcBN0tK1KeaPYj0PtzgM3xw,t6mgdAXqK0tK1KeaPYj0VHRxVpBT", + "probability": "1", + "probability_vector": "0.5,1.0,1.0", + "prompt_disposition_reason_filter": "DefaultFallback", + "request_type_filter": "Geolocation,VideoCapture,AudioCapture", + "survey_display_time": "OnPromptResolved", + "trigger_id": "ZhVFvGaem0tK1KeaPYj0YXx2ouZy,pwU6FSjhZ0tK1KeaPYj0U8h8dv8e,wGFymXxYr0tK1KeaPYj0SxPYLBBc" + }, + "enable_features": [ + "PermissionsPromptSurvey" + ], + "disable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission" + ] + }, + { + "name": "EnabledWithStrongLanguage", + "params": { + "experimental_custom_invitation_arm_trigger_id": "eaHr88umj0tK1KeaPYj0YkhJEi1Y,8U6CRfLYU0tK1KeaPYj0RbTHRpNZ,qrWTeaJaK0tK1KeaPYj0XjFWabba", + "probability": "1", + "probability_vector": "0.5,1.0,1.0", + "prompt_disposition_reason_filter": "DefaultFallback", + "request_type_filter": "Geolocation,VideoCapture,AudioCapture", + "survey_display_time": "OnPromptResolved", + "trigger_id": "hCatPbt6B0tK1KeaPYj0WXqMjcvX,89BwvKxbJ0tK1KeaPYj0NtK7Ybn8,3fTPt7XMF0tK1KeaPYj0TXd8QN47", + "use_stronger_prompt_language": "true" + }, + "enable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission", + "PermissionsPromptSurvey" + ] + }, + { + "name": "Control", + "disable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission", + "PermissionsPromptSurvey" + ] + }, + { + "name": "EnabledWithAllowOnEveryVisitAsFirstButton", + "params": { + "experimental_custom_invitation_arm_trigger_id": "nDDiJNFrQ0tK1KeaPYj0R9NRSBEm,NBn5wUuPR0tK1KeaPYj0XpG6yifA,LvQ3ywBFy0tK1KeaPYj0X474g3gp", + "probability": "1", + "probability_vector": "0.5,1.0,1.0", + "prompt_disposition_reason_filter": "DefaultFallback", + "request_type_filter": "Geolocation,VideoCapture,AudioCapture", + "show_allow_always_as_first_button": "true", + "survey_display_time": "OnPromptResolved", + "trigger_id": "987xHCa770tK1KeaPYj0UE9kej8g,iTZrdKPCv0tK1KeaPYj0YTA7ooTP,Z5Gbxz1BA0tK1KeaPYj0ToLe1txW", + "use_stronger_prompt_language": "true" + }, + "enable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission", + "PermissionsPromptSurvey" + ] + }, + { + "name": "EnabledWithAllowWhileVisitingAsFirstButton", + "params": { + "experimental_custom_invitation_arm_trigger_id": "7maHuvQzn0tK1KeaPYj0Q9rdJDda,KzHiqHzxP0tK1KeaPYj0XSzYX5y2,DXfHq8LEH0tK1KeaPYj0PMxrXHu1", + "probability": "1", + "probability_vector": "0.5,1.0,1.0", + "prompt_disposition_reason_filter": "DefaultFallback", + "request_type_filter": "Geolocation,VideoCapture,AudioCapture", + "show_allow_always_as_first_button": "true", + "survey_display_time": "OnPromptResolved", + "trigger_id": "bCKnj4pzu0tK1KeaPYj0UG86EvNX,anf8vbQh20tK1KeaPYj0QSBJzzY9,p9ppMFjWE0tK1KeaPYj0RB2a6d8D", + "use_stronger_prompt_language": "true", + "use_while_visiting_language": "true" + }, + "enable_features": [ + "ActiveContentSettingExpiry", + "OneTimePermission", + "PermissionsPromptSurvey" + ] + } + ] + } + ], + "OngoingProcesses": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OngoingProcesses" + ] + } + ] + } + ], + "OptGuideBatchSRPTuning": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240624", + "params": { + "max_urls_for_srp_fetch": "10" + }, + "enable_features": [ + "OptimizationHintsFetchingSRP" + ] + } + ] + } + ], + "OptGuideURLCacheSize": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240625", + "params": { + "max_url_keyed_hint_cache_size": "50" + }, + "enable_features": [ + "OptimizationHints" + ] + } + ] + } + ], + "OptimizeAssociateWindowsAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OptimizeAssociateWindowsAndroid" + ] + } + ] + } + ], + "OptimizeParsingDataUrls": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240711", + "enable_features": [ + "OptimizeParsingDataUrls" + ] + } + ] + } + ], + "OptimizeStaticAnimationProperties": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "StaticAnimationOptimization" + ] + } + ] + } + ], + "OptionalToolbarButton": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Segmentation_5_Button_ML_Model_Aggressive_20240409", + "enable_features": [ + "AdaptiveButtonInTopToolbarAddToBookmarks", + "AdaptiveButtonInTopToolbarCustomizationV2", + "AdaptiveButtonInTopToolbarTranslate", + "SegmentationPlatformAdaptiveToolbarV2Feature" + ] + }, + { + "name": "Segmentation_Fixed_Random_6_Button_Forced_Refresh_60_Days_1_20240604", + "enable_features": [ + "AdaptiveButtonInTopToolbarAddToBookmarks", + "AdaptiveButtonInTopToolbarCustomizationV2", + "AdaptiveButtonInTopToolbarTranslate", + "ReadAloudInMultiWindow", + "ReadAloudTapToSeek", + "SegmentationPlatformAdaptiveToolbarV2Feature" + ] + }, + { + "name": "Segmentation_Fixed_Random_6_Button_Forced_Refresh_60_Days_20240703", + "enable_features": [ + "AdaptiveButtonInTopToolbarAddToBookmarks", + "AdaptiveButtonInTopToolbarCustomizationV2", + "AdaptiveButtonInTopToolbarTranslate", + "IPH_ReadAloudExpandedPlayerFeature", + "ReadAloudBackgroundPlayback", + "ReadAloudInMultiWindow", + "SegmentationPlatformAdaptiveToolbarV2Feature" + ] + } + ] + } + ], + "OrcaEnabled": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_From_121_Dogfood", + "params": { + "ime_allowlist": "[\"xkb:es::spa\"]" + }, + "enable_features": [ + "MantaService", + "OrcaDogfood", + "OrcaOnWorkspace" + ] + }, + { + "name": "Enabled_Pre_121_Dogfood", + "enable_features": [ + "MantaService", + "OrcaDogfood" + ] + } + ] + } + ], + "OsFeedbackDialog": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OsFeedbackDialog" + ] + } + ] + } + ], + "OsSettingsRevampWayfindingStudy": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "OsSettingsRevampWayfinding" + ] + } + ] + } + ], + "OutOfProcessPrintDriversPrint": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20230912", + "params": { + "EarlyStart": "false", + "JobPrint": "true", + "Sandbox": "false" + }, + "enable_features": [ + "EnableOopPrintDrivers" + ] + } + ] + } + ], + "OverrideAndroidOmniboxSpareRendererDelay": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_500ms", + "params": { + "omnibox_spare_renderer_delay_ms": "500" + }, + "enable_features": [ + "OverrideAndroidOmniboxSpareRendererDelay" + ] + } + ] + } + ], + "OzonePlatformAuto": [ + { + "platforms": [ + "linux" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "enable_features": [ + "AllowWindowDragUsingSystemDragDrop", + "OverrideDefaultOzonePlatformHintToAuto" + ] + } + ] + } + ], + "PMProcessPriorityPolicy": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PMProcessPriorityPolicy" + ] + } + ] + } + ], + "PageAllocatorRetryOnCommitFailure": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PageAllocatorRetryOnCommitFailure" + ] + } + ] + } + ], + "PageInfoAboutThisSite40Langs": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_231129", + "enable_features": [ + "PageInfoAboutThisSiteMoreLangs" + ] + } + ] + } + ], + "PageInfoIPH": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": ">=0", + "event_1": "name:permission_request_shown;comparator:>=3;window:90;storage:90", + "event_trigger": "name:page_info_iph_triggered;comparator:==0;window:90;storage:90", + "event_used": "name:page_info_opened;comparator:==0;window:90;storage:90", + "session_rate": "<1" + }, + "enable_features": [ + "IPH_PageInfo" + ], + "disable_features": [] + } + ] + } + ], + "PaintCacheBudget": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "paint_cache_budget_04M_20230913", + "params": { + "NormalPaintCacheBudgetBytes": "4194304" + }, + "enable_features": [ + "PaintCacheBudgetConfigurableFeature" + ] + } + ] + } + ], + "PaintHoldingCrossOrigin": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled_20211028", + "enable_features": [ + "PaintHoldingCrossOrigin" + ] + } + ] + } + ], + "PaintHoldingOOPIF": [ + { + "platforms": [ + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PaintHoldingForIframes" + ] + } + ] + } + ], + "ParkableImages": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Both_V4", + "enable_features": [ + "DelayParkingImages", + "ParkableImagesToDisk", + "UseParkableImageSegmentReader" + ] + } + ] + } + ], + "ParkableStringExperiments": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240415", + "enable_features": [ + "LessAggressiveParkableString", + "UseZstdForParkableStrings" + ] + } + ] + } + ], + "PartitionAllocAdvancedMemorySafetyChecks": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "PartitionAllocSchedulerLoopQuarantineBranchCapacity": "262144" + }, + "enable_features": [ + "PartitionAllocSchedulerLoopQuarantine", + "PartitionAllocZappingByFreeFlags" + ] + } + ] + } + ], + "PartitionAllocBackupRefPtr": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "enabled-processes": "all-processes" + }, + "enable_features": [ + "PartitionAllocBackupRefPtr" + ] + } + ] + } + ], + "PartitionAllocLargeEmptySlotSpanRing": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PartitionAllocLargeEmptySlotSpanRing" + ] + } + ] + } + ], + "PartitionAllocLargeThreadCacheSizeAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "size_android_512_20230925", + "params": { + "PartitionAllocLargeThreadCacheSizeValueForLowRAMAndroid": "512" + }, + "enable_features": [ + "PartitionAllocLargeThreadCacheSize" + ] + } + ] + } + ], + "PartitionAllocLargeThreadCacheSizeDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "size_32768_20230925", + "params": { + "PartitionAllocLargeThreadCacheSizeValue": "32768" + }, + "enable_features": [ + "PartitionAllocLargeThreadCacheSize" + ] + } + ] + } + ], + "PartitionAllocMakeFreeNoOpOnShutdown": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledInShutdown", + "params": { + "callsite": "in-shutdown-threads" + }, + "enable_features": [ + "PartitionAllocMakeFreeNoOpOnShutdown" + ] + } + ] + } + ], + "PartitionAllocMemoryReclaimer": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Interval_8sec", + "params": { + "interval": "8s", + "mode": "only-when-unprovisioning" + }, + "enable_features": [ + "PartitionAllocMemoryReclaimer", + "PartitionAllocSortSmallerSlotSpanFreeLists", + "PartitionAllocStraightenLargerSlotSpanFreeLists" + ], + "disable_features": [ + "PartitionAllocSortActiveSlotSpans" + ] + }, + { + "name": "SortActiveSlotSpans", + "params": { + "interval": "4s", + "mode": "only-when-unprovisioning" + }, + "enable_features": [ + "PartitionAllocMemoryReclaimer", + "PartitionAllocSortActiveSlotSpans", + "PartitionAllocSortSmallerSlotSpanFreeLists", + "PartitionAllocStraightenLargerSlotSpanFreeLists" + ] + }, + { + "name": "DontSortSmallerSlotSpanFreeLists", + "params": { + "interval": "4s", + "mode": "only-when-unprovisioning" + }, + "enable_features": [ + "PartitionAllocMemoryReclaimer", + "PartitionAllocStraightenLargerSlotSpanFreeLists" + ], + "disable_features": [ + "PartitionAllocSortActiveSlotSpans", + "PartitionAllocSortSmallerSlotSpanFreeLists" + ] + }, + { + "name": "AlwaysStraightenLargerSlotSpanFreeLists", + "params": { + "interval": "4s", + "mode": "always" + }, + "enable_features": [ + "PartitionAllocMemoryReclaimer", + "PartitionAllocSortSmallerSlotSpanFreeLists", + "PartitionAllocStraightenLargerSlotSpanFreeLists" + ], + "disable_features": [ + "PartitionAllocSortActiveSlotSpans" + ] + }, + { + "name": "DontStraightenLargerSlotSpanFreeLists_v2", + "params": { + "interval": "4s" + }, + "enable_features": [ + "PartitionAllocMemoryReclaimer", + "PartitionAllocSortSmallerSlotSpanFreeLists" + ], + "disable_features": [ + "PartitionAllocSortActiveSlotSpans", + "PartitionAllocStraightenLargerSlotSpanFreeLists" + ] + } + ] + } + ], + "PartitionAllocShortMemoryReclaim": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PartitionAllocShortMemoryReclaim" + ] + } + ] + } + ], + "PartitionAllocUnretainedDanglingPtr": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "mode": "dump_without_crashing" + }, + "enable_features": [ + "PartitionAllocUnretainedDanglingPtr" + ] + } + ] + } + ], + "PartitionAllocUsePoolOffsetFreelists": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PartitionAllocUsePoolOffsetFreelists" + ] + } + ] + } + ], + "PartitionAllocUseSmallSingleSlotSpans": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PartitionAllocUseSmallSingleSlotSpans" + ] + } + ] + } + ], + "PartitionNetworkStateByNetworkAnonymizationKey": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "//0": "This feature has shipped for Chrome but not for ", + "//1": "Chromium embedders, so the corresponding feature ", + "//2": "flag value is false but we rely on this entry to ", + "//3": "enable the feature for most types of tests", + "name": "EnableFeatureForTests", + "enable_features": [ + "PartitionConnectionsByNetworkIsolationKey" + ], + "disable_features": [] + } + ] + } + ], + "PartitionVisitedLinkDatabase": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "PartitionVisitedLinkDatabase", + "enable_features": [ + "PartitionVisitedLinkDatabase" + ] + } + ] + } + ], + "PassHistogramSharedMemoryOnLaunch": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PassHistogramSharedMemoryOnLaunch" + ] + } + ] + } + ], + "PasswordGenerationExperiment": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledWithStrongLabel", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "p4WLf1M6c0ugnJ3q1cK0YsmLdpng", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment", + "PasswordStrongLabel" + ] + }, + { + "name": "EnabledWithTrustedAdvice", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "Vm6DB1ki50ugnJ3q1cK0SpkrheAJ", + "password_generation_variation": "trusted_advice", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment" + ], + "disable_features": [ + "PasswordStrongLabel" + ] + }, + { + "name": "EnabledWithSafetyFirst", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "sD7hmDAoo0ugnJ3q1cK0VQ2Y8p6e", + "password_generation_variation": "safety_first", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment" + ], + "disable_features": [ + "PasswordStrongLabel" + ] + }, + { + "name": "EnabledWithTrySomethingNew", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "6QssdASS10ugnJ3q1cK0RUK4HnYU", + "password_generation_variation": "try_something_new", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment" + ], + "disable_features": [ + "PasswordStrongLabel" + ] + }, + { + "name": "EnabledWithConvenience", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "W23VEAHCT0ugnJ3q1cK0SaPHa9J4", + "password_generation_variation": "convenience", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment" + ], + "disable_features": [ + "PasswordStrongLabel" + ] + }, + { + "name": "EnabledWithCrossDevice", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "fRjzkFjzZ0ugnJ3q1cK0RWYBnkGK", + "password_generation_variation": "cross_device", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment" + ], + "disable_features": [ + "PasswordStrongLabel" + ] + }, + { + "name": "EnabledWithChunkPassword", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "gnz68PSiB0ugnJ3q1cK0Y7PcR8ix", + "password_generation_variation": "chunk_password", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment" + ], + "disable_features": [ + "PasswordStrongLabel" + ] + }, + { + "name": "EnabledWithNudgePassword", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "B8yvCYL9f0ugnJ3q1cK0NXtJvPAJ", + "password_generation_variation": "nudge_password", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment" + ], + "disable_features": [ + "PasswordStrongLabel" + ] + }, + { + "name": "EnabledWithEditPassword", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "4yPTnSKPN0ugnJ3q1cK0YJ18dkNR", + "password_generation_variation": "edit_password", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment" + ], + "disable_features": [ + "PasswordStrongLabel" + ] + }, + { + "name": "Baseline", + "params": { + "PasswordGenerationExperimentSurveyTriggedId": "DX4MWyX4R0ugnJ3q1cK0YjEiaErj", + "probability": "0.25" + }, + "enable_features": [ + "PasswordGenerationExperiment" + ], + "disable_features": [ + "PasswordStrongLabel" + ] + } + ] + } + ], + "PasswordInfobarDisplayLength": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Sixteen_Seconds", + "params": { + "duration-seconds": "16" + }, + "enable_features": [ + "PasswordInfobarDisplayLength" + ] + } + ] + } + ], + "PasswordSuggestionBottomSheetV2": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PasswordSuggestionBottomSheetV2" + ] + } + ] + } + ], + "Path2DPaintCache": [ + { + "platforms": [ + "android", + "android_webview", + "windows", + "mac", + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "Path2DPaintCache" + ] + } + ] + } + ], + "PdfOcrChromeOS": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PdfOcr" + ] + } + ] + } + ], + "PdfOcrDesktop": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PdfOcr" + ] + } + ] + } + ], + "PdfOutOfProcessIframe": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PdfOopif" + ] + } + ] + } + ], + "PdfUseSkiaRenderer": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PdfUseSkiaRenderer" + ] + } + ] + } + ], + "PerProcessReclaim": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "EnabledGroupA_08222019", + "params": { + "GraphWalkBackoffTimeSec": "60", + "NodeInvisibleTimeSec": "360", + "NodeTrimBackoffTimeSec": "1200" + }, + "enable_features": [ + "TrimOnMemoryPressure" + ] + }, + { + "name": "EnabledGroupB_08222019", + "params": { + "GraphWalkBackoffTimeSec": "180", + "NodeInvisibleTimeSec": "900", + "NodeTrimBackoffTimeSec": "1800" + }, + "enable_features": [ + "TrimOnMemoryPressure" + ] + }, + { + "name": "EnabledGroupC_08222019", + "params": { + "GraphWalkBackoffTimeSec": "180", + "NodeInvisibleTimeSec": "3600", + "NodeTrimBackoffTimeSec": "7200" + }, + "enable_features": [ + "TrimOnMemoryPressure" + ] + } + ] + } + ], + "PerfCombined2024": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ExpandedPrefetchRange", + "FledgeEnableWALForInterestGroupStorage", + "GpuInfoCollectionSeparatePrefetch", + "MojoBindingsInlineSLS", + "RunTasksByBatches", + "SharedStorageAPIEnableWALForDatabase", + "SqlWALModeOnDipsDatabase", + "SqlWALModeOnSegmentationDatabase" + ] + } + ] + }, + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "MacEfficientFileFlushUseBarrier": "true" + }, + "enable_features": [ + "FledgeEnableWALForInterestGroupStorage", + "MacEfficientFileFlush", + "MojoBindingsInlineSLS", + "NumberOfCoresWithCpuSecurityMitigation", + "SharedStorageAPIEnableWALForDatabase", + "SqlWALModeOnDipsDatabase", + "SqlWALModeOnSegmentationDatabase" + ] + } + ] + }, + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "fuchsia", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FledgeEnableWALForInterestGroupStorage", + "MojoBindingsInlineSLS", + "SharedStorageAPIEnableWALForDatabase", + "SqlWALModeOnDipsDatabase", + "SqlWALModeOnSegmentationDatabase" + ] + } + ] + }, + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FledgeEnableWALForInterestGroupStorage", + "MojoBindingsInlineSLS", + "SharedStorageAPIEnableWALForDatabase", + "SqlWALModeOnDipsDatabase", + "SqlWALModeOnSegmentationDatabase" + ], + "disable_features": [ + "EnableHangWatcher" + ] + } + ] + } + ], + "PerformanceControlsHatsStudy": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledHighEfficiencyOptOut_20230223", + "params": { + "en_site_id": "hEedoxCS30ugnJ3q1cK0YKKzXjSm", + "probability": "1.0" + }, + "enable_features": [ + "PerformanceControlsHighEfficiencyOptOutSurvey" + ], + "disable_features": [ + "PerformanceControlsBatteryPerformanceSurvey", + "PerformanceControlsBatterySaverOptOutSurvey", + "PerformanceControlsPerformanceSurvey" + ] + }, + { + "name": "EnabledBatterySaverOptOut_20230223", + "params": { + "en_site_id": "gyuzHnE940ugnJ3q1cK0RyY65eG8", + "probability": "1.0" + }, + "enable_features": [ + "PerformanceControlsBatterySaverOptOutSurvey" + ], + "disable_features": [ + "PerformanceControlsBatteryPerformanceSurvey", + "PerformanceControlsHighEfficiencyOptOutSurvey", + "PerformanceControlsPerformanceSurvey" + ] + } + ] + } + ], + "PerformanceControlsRound2Improvements": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240516", + "enable_features": [ + "DiscardRingImprovements", + "IPH_DiscardRing", + "MemorySaverModeAggressiveness" + ] + } + ] + } + ], + "PerformanceInterventionMetricsStudy": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240626", + "enable_features": [ + "IPH_PerformanceInterventionDialogFeature", + "PerformanceIntervention" + ] + } + ] + } + ], + "PeripheralCustomization": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PeripheralCustomization", + "SearchCustomizableShortcutsInLauncher", + "ShortcutCustomization" + ] + } + ] + } + ], + "PermissionElementPromptPositioning": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "NearElement", + "params": { + "PermissionElementPromptPositioningParam": "near_element" + }, + "enable_features": [ + "PermissionElementPromptPositioning" + ] + }, + { + "name": "WindowMiddle", + "params": { + "PermissionElementPromptPositioningParam": "window_middle" + }, + "enable_features": [ + "PermissionElementPromptPositioning" + ] + }, + { + "name": "LegacyPrompt", + "params": { + "PermissionElementPromptPositioningParam": "legacy_prompt" + }, + "enable_features": [ + "PermissionElementPromptPositioning" + ] + } + ] + } + ], + "PickerUI": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ModifierSplit", + "ModifierSplitDogfood", + "Picker", + "PickerDogfood" + ] + } + ] + } + ], + "PlusAddressCreateSuggestion": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "PlusAddress_IPH_Enabled", + "params": { + "availability": "any", + "event_trigger": "name:plus_address_create_suggestion_iph_trigger;comparator:<10;window:90;storage:360", + "event_used": "name:plus_address_create_suggestion_accepted;comparator:<2;window:90;storage:360", + "session_rate": "<1" + }, + "enable_features": [ + "IPH_PlusAddressCreateSuggestion" + ] + } + ] + } + ], + "PlusAddressesExperiment": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PlusAddressAffiliations", + "PlusAddressFallbackFromContextMenu", + "PlusAddressRefresh", + "PlusAddressesEnabled", + "SyncPlusAddress" + ] + } + ] + } + ], + "PlzDedicatedWorker": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DedicatedWorkerAblationStudyEnabled", + "PlzDedicatedWorker", + "ServiceWorkerClientIdAlignedWithSpec" + ] + } + ] + } + ], + "PostQuantumKyber": [ + { + "platforms": [ + "android", + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PostQuantumKyber" + ] + } + ] + } + ], + "PowerBookmarkBackend": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PowerBookmarkBackend" + ] + } + ] + } + ], + "PreFreeze": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Both_2024_05_29", + "enable_features": [ + "IsTrimMemoryBackgroundCritical", + "OnPreFreezeMemoryTrim" + ] + } + ] + } + ], + "PreInitializePageAndFrameForSVGImage": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "max_pre_initialize_count": "3" + }, + "enable_features": [ + "PreInitializePageAndFrameForSVGImage" + ] + } + ] + } + ], + "PreReadDllBrowserProcess": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrefetchVirtualMemoryPolicy" + ] + } + ] + } + ], + "PreconnectCreateNewTab": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_Nonstable_20230531", + "enable_features": [ + "PreconnectOnTabCreation" + ] + } + ] + } + ], + "PreconnectToSearchDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledWithStartupDelayForegroundOnly", + "params": { + "skip_in_background": "true", + "startup_delay_ms": "5000" + }, + "enable_features": [ + "PreconnectToSearch" + ] + } + ] + } + ], + "PreconnectToSearchWithPrivacyModeEnabled": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PreconnectToSearchWithPrivacyModeEnabled" + ] + } + ] + } + ], + "PrefetchDocumentManagerEarlyCookieCopySkipped": [ + { + "platforms": [ + "android", + "android_webview", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrefetchDocumentManagerEarlyCookieCopySkipped" + ] + } + ] + } + ], + "PrefetchProxyDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrefetchProxy" + ] + } + ] + } + ], + "PrefetchReusable": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240312", + "enable_features": [ + "PrefetchReusable" + ] + } + ] + } + ], + "PreinstalledWebAppsCoreOnly": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AppPreloadServiceAllUserTypes", + "PreinstalledWebAppsCoreOnly" + ] + } + ] + } + ], + "PreloadSystemFonts": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "preload_system_fonts_from_page": "false", + "preload_system_fonts_required_memory_gb": "4", + "preload_system_fonts_targets": "[{\"family\":\"arial\",\"weight\":400,\"size\":14,\"csize\":14,\"text\":\"ab\"}]" + }, + "enable_features": [ + "PreloadSystemFonts" + ] + } + ] + } + ], + "PreloadTopChromeWebUI": [ + { + "platforms": [ + "linux", + "mac", + "windows", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "preload-on-make-contents", + "params": { + "preload-mode": "preload-on-make-contents", + "smart-preload": "true" + }, + "enable_features": [ + "PreloadTopChromeWebUI" + ] + }, + { + "name": "preload-on-warmup", + "params": { + "preload-mode": "preload-on-warmup", + "smart-preload": "true" + }, + "enable_features": [ + "PreloadTopChromeWebUI" + ] + } + ] + } + ], + "PreloadingHeuristicsMLModel": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240501_NoEnact", + "params": { + "enact_candidates": "false" + }, + "enable_features": [ + "PreloadingHeuristicsMLModel" + ] + } + ] + } + ], + "Prerender2BookmarkBarTrigger": [ + { + "platforms": [ + "linux", + "mac", + "windows", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "OnlyMouseDown_20240718", + "params": { + "prerender_bookmarkbar_on_mouse_hover_trigger": "false", + "prerender_bookmarkbar_on_mouse_pressed_trigger": "true" + }, + "enable_features": [ + "BookmarkTriggerForPrerender2" + ] + } + ] + } + ], + "Prerender2EarlyDocumentLifecycleUpdate": [ + { + "platforms": [ + "android", + "linux", + "mac", + "windows", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "Prerender2EarlyDocumentLifecycleUpdate" + ] + } + ] + } + ], + "Prerender2EmbedderBlockedHosts": [ + { + "platforms": [ + "linux", + "mac", + "windows", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "embedder_blocked_hosts": "" + }, + "enable_features": [ + "Prerender2EmbedderBlockedHosts" + ] + } + ] + } + ], + "Prerender2NewTabPageAndroidTrigger": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20240628", + "params": { + "prerender_new_tab_page_on_touch_trigger": "47" + }, + "enable_features": [ + "NewTabPageAndroidTriggerForPrerender2" + ] + } + ] + } + ], + "Prerender2NewTabPageTrigger": [ + { + "platforms": [ + "linux", + "mac", + "windows", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "BothMouseDownAndMouseHover_20240617", + "params": { + "prerender_new_tab_page_on_mouse_hover_trigger": "true", + "prerender_new_tab_page_on_mouse_pressed_trigger": "true", + "prerender_start_delay_on_mouse_hover_ms": "300" + }, + "enable_features": [ + "NewTabPageTriggerForPrerender2" + ] + }, + { + "name": "OnlyMouseHover300ms_20240617", + "params": { + "prerender_new_tab_page_on_mouse_hover_trigger": "true", + "prerender_new_tab_page_on_mouse_pressed_trigger": "false", + "prerender_start_delay_on_mouse_hover_ms": "300" + }, + "enable_features": [ + "NewTabPageTriggerForPrerender2" + ] + }, + { + "name": "OnlyMouseHover200ms_20240617", + "params": { + "prerender_new_tab_page_on_mouse_hover_trigger": "true", + "prerender_new_tab_page_on_mouse_pressed_trigger": "false", + "prerender_start_delay_on_mouse_hover_ms": "200" + }, + "enable_features": [ + "NewTabPageTriggerForPrerender2" + ] + }, + { + "name": "OnlyMouseDown_20240617", + "params": { + "prerender_new_tab_page_on_mouse_hover_trigger": "false", + "prerender_new_tab_page_on_mouse_pressed_trigger": "true" + }, + "enable_features": [ + "NewTabPageTriggerForPrerender2" + ] + }, + { + "name": "Control_20240617", + "disable_features": [ + "NewTabPageTriggerForPrerender2" + ] + } + ] + } + ], + "Prerender2WarmUpCompositor": [ + { + "platforms": [ + "android", + "linux", + "mac", + "windows", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "DidCommitLoad_20240626", + "params": { + "trigger_point": "did_commit_load" + }, + "enable_features": [ + "Prerender2WarmUpCompositor", + "WarmUpCompositor" + ] + }, + { + "name": "DidDispatchDOMContentLoadedEvent_20240626", + "params": { + "trigger_point": "did_dispatch_dom_content_loaded_event" + }, + "enable_features": [ + "Prerender2WarmUpCompositor", + "WarmUpCompositor" + ] + }, + { + "name": "DidFinishLoad_20240626", + "params": { + "trigger_point": "did_finish_load" + }, + "enable_features": [ + "Prerender2WarmUpCompositor", + "WarmUpCompositor" + ] + }, + { + "name": "Control_20240626", + "disable_features": [ + "Prerender2WarmUpCompositor", + "WarmUpCompositor" + ] + } + ] + } + ], + "PressAndHoldEscToExitBrowserFullscreen0612": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PressAndHoldEscToExitBrowserFullscreen" + ] + } + ] + } + ], + "PriceDropNtpIPH": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": ">=0", + "event_trigger": "name:price_drop_ntp_iph_triggered;comparator:==0;window:365;storage:365", + "event_used": "name:tab_switcher_button_clicked;comparator:any;window:365;storage:365", + "session_rate": "<1" + }, + "enable_features": [ + "IPH_PriceDropNTP" + ], + "disable_features": [] + } + ] + } + ], + "PriceTrackingDesktopExpansionStudy": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ShoppingList" + ] + } + ] + } + ], + "PriceTrackingIconColors": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PriceTrackingIconColors" + ] + } + ] + } + ], + "PriceTrackingPageActionIconLabelFeatureIPH": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_trigger": "name:price_tracking_page_action_icon_label_in_trigger;comparator:==0;window:1;storage:365", + "event_used": "name:used;comparator:any;window:365;storage:365", + "session_rate": "any" + }, + "enable_features": [ + "IPH_PriceTrackingPageActionIconLabelFeature" + ], + "disable_features": [] + } + ] + } + ], + "PrintWithPostScriptType42Fonts": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrintWithPostScriptType42Fonts" + ] + } + ] + } + ], + "PrintWithReducedRasterization": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrintWithReducedRasterization" + ] + } + ] + } + ], + "PrioritizeCompositingAfterDelay": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "PrioritizeCompositingAfter50ms2", + "params": { + "PostFCP": "50", + "PreFCP": "100" + }, + "enable_features": [ + "PrioritizeCompositingAfterDelayTrials" + ] + } + ] + } + ], + "PriorityHeader": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PriorityHeader" + ] + } + ] + } + ], + "PrivacyGuideAndroid3": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20230926", + "enable_features": [ + "PrivacyGuideAndroid3" + ] + } + ] + } + ], + "PrivacyGuideHats": [ + { + "platforms": [ + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "PrivacyGuide", + "params": { + "en_site_id": "EwTBYAUeU0ugnJ3q1cK0VNYBFfQr", + "probability": "1.0", + "settings-time": "5s", + "survey": "privacy-guide" + }, + "enable_features": [ + "HappinessTrackingSurveysForDesktopPrivacyGuide" + ], + "disable_features": [ + "HappinessTrackingSurveysForDesktopSettingsPrivacy" + ] + }, + { + "name": "PrivacySettings", + "params": { + "en_site_id": "JcjxgSDnh0ugnJ3q1cK0UVkwDj1o", + "no-guide": "true", + "probability": "1.0", + "survey": "settings-privacy" + }, + "enable_features": [ + "HappinessTrackingSurveysForDesktopSettingsPrivacy" + ], + "disable_features": [ + "HappinessTrackingSurveysForDesktopPrivacyGuide" + ] + } + ] + } + ], + "PrivacyHubAppPermissions": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrosPrivacyHubAppPermissions" + ] + } + ] + } + ], + "PrivacyHubAppPermissionsV2": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrosPrivacyHubAppPermissionsV2" + ] + } + ] + } + ], + "PrivacyHubGeolocation": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrosPrivacyHub" + ] + } + ] + } + ], + "PrivacyHubMVP": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled_20230616_Dogfood", + "enable_features": [ + "CrosPrivacyHubV0" + ] + }, + { + "name": "Control_20230616_Dogfood", + "enable_features": [] + }, + { + "name": "Enabled_20230616", + "enable_features": [ + "CrosPrivacyHubV0" + ] + }, + { + "name": "Control_20230616", + "enable_features": [] + } + ] + } + ], + "PrivacyIndicators": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrivacyIndicators" + ] + } + ] + } + ], + "PrivacySandboxActivityTypeStorage": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledWithSkipPreFirstTab", + "params": { + "skip-pre-first-tab": "true" + }, + "enable_features": [ + "PrivacySandboxActivityTypeStorage" + ] + }, + { + "name": "EnabledWithoutSkipPreFirstTab", + "params": { + "skip-pre-first-tab": "false" + }, + "enable_features": [ + "PrivacySandboxActivityTypeStorage" + ] + } + ] + } + ], + "PrivacySandboxAdsAPIs": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_Notice_M1_AllAPIs_Expanded_NoOT_Stable", + "params": { + "implementation_type": "mparch" + }, + "enable_features": [ + "AllowURNsInIframes", + "AttributionReportingCrossAppWeb", + "BiddingAndScoringDebugReportingAPI", + "BrowsingTopics", + "FencedFrames", + "FencedFramesAPIChanges", + "InterestGroupStorage", + "KAnonymityService", + "PrivacySandboxAdsAPIs", + "PrivacySandboxAdsAPIsM1Override", + "PrivateAggregationApi", + "SharedStorageAPI" + ] + } + ] + } + ], + "PrivacySandboxAdsNoticeCCT": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_AGSA", + "params": { + "app-id": "com.google.android.googlequicksearchbox" + }, + "enable_features": [ + "PrivacySandboxAdsNoticeCCT" + ] + } + ] + } + ], + "PrivacySandboxAttestationsLoadPreInstalledComponent": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_PrivacySandboxAttestationsLoadPreInstalledComponent", + "enable_features": [ + "PrivacySandboxAttestationsLoadPreInstalledComponent" + ] + } + ] + } + ], + "PrivacySandboxHatsForDesktopM1": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_PrivacyPage", + "params": { + "en_site_id": "gyxt1wCrg0ugnJ3q1cK0TeuAxb15", + "probability": "1.0", + "settings-time": "20s" + }, + "enable_features": [ + "HappinessTrackingSurveysForDesktopM1AdPrivacyPage" + ], + "disable_features": [ + "HappinessTrackingSurveysForDesktopM1AdMeasurementSubpage", + "HappinessTrackingSurveysForDesktopM1FledgeSubpage", + "HappinessTrackingSurveysForDesktopM1TopicsSubpage" + ] + }, + { + "name": "Enabled_TopicsSubpage", + "params": { + "en_site_id": "HkMzAEAUa0ugnJ3q1cK0UCYW2Hyw", + "probability": "1.0", + "settings-time": "20s" + }, + "enable_features": [ + "HappinessTrackingSurveysForDesktopM1TopicsSubpage" + ], + "disable_features": [ + "HappinessTrackingSurveysForDesktopM1AdMeasurementSubpage", + "HappinessTrackingSurveysForDesktopM1AdPrivacyPage", + "HappinessTrackingSurveysForDesktopM1FledgeSubpage" + ] + }, + { + "name": "Enabled_FledgeSubpage", + "params": { + "en_site_id": "YhMPu6WWx0ugnJ3q1cK0PfKSV3YR", + "probability": "1.0", + "settings-time": "20s" + }, + "enable_features": [ + "HappinessTrackingSurveysForDesktopM1FledgeSubpage" + ], + "disable_features": [ + "HappinessTrackingSurveysForDesktopM1AdMeasurementSubpage", + "HappinessTrackingSurveysForDesktopM1AdPrivacyPage", + "HappinessTrackingSurveysForDesktopM1TopicsSubpage" + ] + }, + { + "name": "Enabled_AdMeasurementSubpage", + "params": { + "en_site_id": "vzxsxSxGk0ugnJ3q1cK0PHvFhzka", + "probability": "1.0", + "settings-time": "20s" + }, + "enable_features": [ + "HappinessTrackingSurveysForDesktopM1AdMeasurementSubpage" + ], + "disable_features": [ + "HappinessTrackingSurveysForDesktopM1AdPrivacyPage", + "HappinessTrackingSurveysForDesktopM1FledgeSubpage", + "HappinessTrackingSurveysForDesktopM1TopicsSubpage" + ] + } + ] + } + ], + "PrivacySandboxInternalsDevUI": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "enable_features": [ + "PrivacySandboxInternalsDevUI" + ] + } + ] + } + ], + "PrivacySandboxProactiveTopicsBlocking": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrivacySandboxProactiveTopicsBlocking" + ] + } + ] + } + ], + "PrivacySandboxV4": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_Notice_GA_Stable", + "params": { + "notice-required": "true", + "restricted-notice": "true" + }, + "enable_features": [ + "PrivacySandboxSettings4" + ] + }, + { + "name": "Enabled_Consent_GA_Stable", + "params": { + "consent-required": "true", + "restricted-notice": "true" + }, + "enable_features": [ + "PrivacySandboxSettings4" + ] + } + ] + } + ], + "PrivateAggregationApiFilteringIds": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrivateAggregationApiFilteringIds" + ] + } + ] + } + ], + "PrivateStateTokens": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PrivateStateTokens" + ] + } + ] + } + ], + "ProcessHtmlDataImmediately": [ + { + "platforms": [ + "android", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "AllChunks", + "params": { + "first": "true", + "main": "true", + "rest": "true" + }, + "enable_features": [ + "ProcessHtmlDataImmediately" + ] + } + ] + } + ], + "ProcessIsolationForFencedFrames": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IsolateFencedFrames" + ] + } + ] + } + ], + "ProcessReuseOnPrerenderCOOPSwap": [ + { + "platforms": [ + "windows", + "mac", + "linux", + "chromeos", + "chromeos_lacros", + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ProcessReuseOnPrerenderCOOPSwap" + ] + } + ] + } + ], + "ProductivityLauncherStudy": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "DriveRecentsWithDefaultRecency", + "enable_features": [ + "LauncherContinueSectionWithRecentsRollout125" + ] + }, + { + "name": "DriveRecentsWithMixedLocalAndDriveFiles", + "params": { + "mix_local_and_drive": "true" + }, + "enable_features": [ + "LauncherContinueSectionWithRecentsRollout125" + ] + }, + { + "name": "DriveRecentsWith14DayRecency", + "params": { + "max_recency_in_days": "14" + }, + "enable_features": [ + "LauncherContinueSectionWithRecentsRollout125" + ] + }, + { + "name": "DriveRecentsWith30DayRecency", + "params": { + "max_recency_in_days": "30" + }, + "enable_features": [ + "LauncherContinueSectionWithRecentsRollout125" + ] + }, + { + "name": "EnabledWithContinueAndMultipleQueries_20220621", + "params": { + "enable_continue": "true", + "multiple_queries_per_session": "true" + }, + "enable_features": [ + "LauncherItemSuggest", + "ProductivityLauncher" + ] + }, + { + "name": "EnabledWithContinueSection_20220621", + "params": { + "enable_continue": "true" + }, + "enable_features": [ + "ProductivityLauncher" + ], + "disable_features": [ + "LauncherItemSuggest" + ] + }, + { + "name": "EnabledWithoutContinueSection_20220621", + "params": { + "enable_continue": "false" + }, + "enable_features": [ + "ProductivityLauncher" + ], + "disable_features": [ + "LauncherItemSuggest" + ] + } + ] + } + ], + "ProfilesReordering": [ + { + "platforms": [ + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ProfilesReordering" + ] + } + ] + } + ], + "PropagateWebViewNetworkingSignals": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "SignalAndConnecMigration_20230706", + "enable_features": [ + "MigrateSessionsOnNetworkChangeV2", + "webViewPropagateNetworkSignals" + ] + }, + { + "name": "Control_20230706", + "disable_features": [ + "MigrateSessionsOnNetworkChangeV2", + "webViewPropagateNetworkSignals" + ] + }, + { + "name": "SignalNoConnecMigration_20230706", + "enable_features": [ + "webViewPropagateNetworkSignals" + ], + "disable_features": [ + "MigrateSessionsOnNetworkChangeV2" + ] + } + ] + } + ], + "ProtectedAudienceMoreGroupByOriginContextsStudy": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_2_Contexts", + "params": { + "GroupByOriginContextLimit": "2", + "IncludeFacilitatedTestingGroups": "true" + }, + "enable_features": [ + "FledgeBidderWorkletGroupByOriginContextsToKeep" + ] + }, + { + "name": "Enabled_5_Contexts", + "params": { + "GroupByOriginContextLimit": "5", + "IncludeFacilitatedTestingGroups": "true" + }, + "enable_features": [ + "FledgeBidderWorkletGroupByOriginContextsToKeep" + ] + } + ] + } + ], + "ProtectedAudienceMultiThreadedBidderWorklet": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "TwoThreads", + "params": { + "bidder_worklet_thread_pool_size_logarithmic_scaling_factor": "1.0" + }, + "enable_features": [ + "FledgeBidderWorkletThreadPool" + ] + } + ] + } + ], + "ProtectedAudienceMultiThreadedSellerWorklet": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "TwoThreads", + "params": { + "seller_worklet_thread_pool_size": "2" + }, + "enable_features": [ + "FledgeSellerWorkletThreadPool" + ] + } + ] + } + ], + "ProtectedAudienceScoreAdRenderSize": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RenderSizeInScoreAdBrowserSignals" + ] + } + ] + } + ], + "ProtectedAudiencesHeaderDirectFromSellerSignalsStudy": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FledgeDirectFromSellerSignalsHeaderAdSlot" + ] + } + ] + } + ], + "ProtectedAudiencesKAnonymityEnforcementStudy": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FledgeConsiderKAnonymity", + "FledgeEnforceKAnonymity" + ] + } + ] + } + ], + "ProtectedAudiencesPermitCrossOriginTrustedSignals": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FledgePermitCrossOriginTrustedSignals" + ] + } + ] + } + ], + "ProtectedAudiencesRealTimeReporting": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FledgeRealTimeReporting" + ] + } + ] + } + ], + "ProtectedAudiencesUpdateIfOlderThanMs": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "InterestGroupUpdateIfOlderThan" + ] + } + ] + } + ], + "PruneOldTransferCacheEntries": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PruneOldTransferCacheEntries" + ] + } + ] + } + ], + "PruneRedundantAXInlineTextBoxText": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AccessibilityPruneRedundantInlineText" + ] + } + ] + } + ], + "PsRedesign": [ + { + "platforms": [ + "linux", + "windows", + "mac", + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "enable-toggles": "true" + }, + "enable_features": [ + "PsRedesignAdPrivacyPage" + ] + } + ] + } + ], + "PumpFastToSleepAndroid": [ + { + "platforms": [ + "android_weblayer", + "android_webview", + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PumpFastToSleepAndroid" + ] + } + ] + } + ], + "PushMessagingDisallowSenderIDs": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PushMessagingDisallowSenderIDs" + ] + } + ] + } + ], + "PushMessagingGcmEndpointEnvironment": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "params": { + "PushMessagingGcmEndpointUrl": "https://jmt17.google.com/fcm/send/" + }, + "enable_features": [ + "PushMessagingGcmEndpointEnvironment" + ] + } + ] + } + ], + "QUIC": [ + { + "platforms": [ + "android_weblayer", + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "channel": "F", + "epoch": "30000000", + "retransmittable_on_wire_timeout_milliseconds": "200" + }, + "enable_features": [ + "QuicDoesNotUseFeatures" + ] + } + ] + } + ], + "QuickAnswersRichCard": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "QuickAnswersRichCard" + ] + } + ] + } + ], + "QuickDeleteAndroidFollowup": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "QuickDeleteAndroidFollowup" + ] + } + ] + } + ], + "QuotaDatabaseDisableFullFSync": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DisableQuotaDbFullFSync" + ] + } + ] + } + ], + "RTCAlignReceivedEncodedVideoTransforms": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RTCAlignReceivedEncodedVideoTransforms" + ] + } + ] + } + ], + "RawDrawAndDrDc": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "DrDc_vulkan", + "params": { + "BlockListByDevice": "amber|chopin|secret|a03|SO-51B|on7xelte|j7xelte|F41B|doha|HWYAL|a20s|begonia|b2q|t2s|channel|galahad|rk322x_box|a32|ellis|dandelion|tonga|RMX3231" + }, + "disable_features": [ + "RawDraw" + ] + } + ] + } + ], + "ReactivePrefetchAndroidDiscardBody": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "//0": "This experiment is only enabled on Android,", + "//1": "because only android has the", + "//2": "LoadingPredictorPrefetch feature enabled by", + "//3": "default. On other platforms it would conflict", + "//4": "with the ReactivePrefetchDesktop experiment.", + "name": "Enabled", + "enable_features": [ + "LoadingPredictorPrefetchUseReadAndDiscardBody" + ] + } + ] + } + ], + "ReactivePrefetchDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "use_predictions": "false" + }, + "enable_features": [ + "LoadingPredictorPrefetch", + "LoadingPredictorUseOptimizationGuide" + ] + } + ] + } + ], + "ReadAloudAppMenuIPH": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "ReadAloudAppMenuIPHEnabled", + "params": { + "availability": "any", + "event_trigger": "name:read_aloud_app_menu_iph_trigger;comparator:==0;window:30;storage:90", + "event_used": "name:read_aloud_app_menu_pressed;comparator:==0;window:30;storage:90", + "session_rate": "any" + }, + "enable_features": [ + "IPH_ReadAloudAppMenuFeature" + ] + } + ] + } + ], + "ReadAloudClankStudy": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20240623", + "params": { + "voices_override": "CiMKA3ZmehIQzqHOv8+FzrzPgM6vzr3OuRoCZWwiAkdSKAIwCQoXCgNpdGISBEFyaWEaAml0IgJJVCgCMAoKGAoDaXRjEgVDb3N0YRoCaXQiAklUKAEwCAoaCgNpdGQSB0NvcmFsbG8aAml0IgJJVCgBMAsKGQoDa2RhEgZPY2Vhbm8aAml0IgJJVCgCMAYKGQoDaGViEgbXoNeU16gaAml3IgJJTCgBMAwKHwoDaGVjEgzXkNeV1rnXk9a2150aAml3IgJJTCgCMAsKGQoDaGVkEgbXkNeS150aAml3IgJJTCgBMAkKHwoDaGVlEgzXkNa115bXlda515EaAml3IgJJTCgCMAcKIgoDbWxjEg/gtKHgtYbgtK/gtY3gtb0aAm1sIgJJTigCMAkKIgoDbWxlEg/gtKTgtJ/gtL7gtJXgtIIaAm1sIgJJTigBMAIKHwoDbWxmEgzgtLXgtL7gtK/gtYEaAm1sIgJJTigCMAwKHwoDbWxtEgzgtKTgtYDgtLDgtIIaAm1sIgJJTigBMAsKHwoDbXJhEgzgpJXgpYvgpLDgpLIaAm1yIgJJTigCMAoKKAoDbXJjEhXgpK7gpLngpL7gpLjgpL7gpJfgpLAaAm1yIgJJTigBMAUKHAoDbXJkEgngpKjgpKbgpYAaAm1yIgJJTigCMAsKHwoDbXJmEgzgpLDgpYHgpKzgpYAaAm1yIgJJTigCMAwKGQoDYWZiEgbFgcSFa2EaAnBsIgJQTCgCMAIKFwoDYm1nEgRNZWNoGgJwbCICUEwoATAMChkKA2ptaxIGQ2htdXJhGgJwbCICUEwoATAKChgKA29kYRIFT2NlYW4aAnBsIgJQTCgCMAgKGgoDemZnEgdKZXppb3JvGgJwbCICUEwoAjAJChYKA3ZmdhIDQWVyGgJybyICUk8oAjAHCigKA3RhYxIV4K6V4K6f4K6x4K+N4K6V4K6w4K+IGgJ0YSICSU4oAjAFCiIKA3RhZBIP4K6q4K614K6z4K6u4K+NGgJ0YSICSU4oATAMCjEKA3RhZhIe4K6q4K+G4K6w4K+B4K6Z4K+N4K6V4K6f4K6y4K+NGgJ0YSICSU4oAjALChwKA3RhZxIJ4K6o4K6k4K6/GgJ0YSICSU4oATAJCh8KA3RlZhIM4LCw4LGC4LCs4LGAGgJ0ZSICSU4oAjAKCiUKA3RlbRIS4LCr4LGA4LCy4LGN4LCh4LGNGgJ0ZSICSU4oATABCisKA21vbBIY4Lih4Lir4Liy4Liq4Lih4Li44LiX4LijGgJ0aCICVEgoAjAFChgKA2FtYRIFQnVsdXQaAnRyIgJUUigBMAwKFwoDY2ZzEgRWYWRpGgJ0ciICVFIoAjAHChcKA2VmdRIER8O2bBoCdHIiAlRSKAIwCQoXCgNtZm0SBEhhdmEaAnRyIgJUUigCMAUKGAoDdG1jEgVTYWhpbBoCdHIiAlRSKAEwBgodCgNoZmQSCtCe0LrQtdCw0L0aAnVrIgJVQSgCMAkKIAoDdmljEg1I4buTbmcgbmfhu41jGgJ2aSICVk4oAjAHCiAKA3ZpZBINQ8OhbmggxJHhu5NuZxoCdmkiAlZOKAEwBgoXCgN2aWUSBFLDqnUaAnZpIgJWTigCMAEKHQoDdmlmEgrEkMOhbSBtw6J5GgJ2aSICVk4oATAF" + }, + "enable_features": [ + "ReadAloud", + "ReadAloudInOverflowMenuInCCT", + "ReadAloudPlayback" + ] + } + ] + } + ], + "ReadAnythingDocsIntegrationRollout": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReadAnythingDocsIntegration" + ] + } + ] + } + ], + "ReadAnythingIPHRollout": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "distillable_urls": "support.google.com,docs.google.com", + "event_trigger": "name:iph_reading_mode_side_panel_trigger;comparator:<=3;window:360;storage:360", + "event_used": "name:reading_mode_side_panel_shown;comparator:==0;window:360;storage:360", + "session_rate": "==0" + }, + "enable_features": [ + "IPH_ReadingModeSidePanel" + ] + } + ] + } + ], + "ReadAnythingLocalSidePanelRollout": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReadAnythingLocalSidePanel" + ] + } + ] + } + ], + "ReadAnythingPermanentAccessibility": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReadAnythingPermanentAccessibility" + ] + } + ] + } + ], + "ReadAnythingReadAloudRollout": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReadAnythingReadAloud" + ] + }, + { + "name": "LanguageDownloads_Enabled", + "enable_features": [ + "ReadAloudLanguagePackDownloading", + "ReadAnythingReadAloud" + ] + }, + { + "name": "LanguageDownloadsAndVoiceSwitching_Enabled", + "enable_features": [ + "ReadAloudAutoVoiceSwitching", + "ReadAloudLanguagePackDownloading", + "ReadAnythingReadAloud" + ] + } + ] + } + ], + "ReadAnythingReadAloudWordHighlighting": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReadAnythingReadAloudAutomaticWordHighlighting" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "ReadAnythingReadAloudAutomaticWordHighlighting" + ] + } + ] + } + ], + "ReclaimOldPrepaintTiles": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReclaimOldPrepaintTiles" + ] + } + ] + } + ], + "ReclaimPrepaintTilesWhenIdle": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReclaimPrepaintTilesWhenIdle" + ] + } + ] + } + ], + "ReduceAcceptLanguage": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReduceAcceptLanguage" + ] + } + ] + } + ], + "ReduceCpuUtilization2": [ + { + "platforms": [ + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReduceCpuUtilization2" + ] + } + ] + } + ], + "ReduceIPAddressChangeNotification": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReduceIPAddressChangeNotification" + ] + } + ] + } + ], + "ReduceIPCCombined": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledUkmReduceAddEntryIPC", + "enable_features": [ + "UkmReduceAddEntryIPC" + ], + "disable_features": [ + "ReduceSubresourceResponseStartedIPC" + ] + }, + { + "name": "EnabledReduceSubresourceResponseStartedIPC", + "enable_features": [ + "ReduceSubresourceResponseStartedIPC" + ], + "disable_features": [ + "UkmReduceAddEntryIPC" + ] + }, + { + "name": "EnabledReduceIPCCombined", + "enable_features": [ + "ReduceSubresourceResponseStartedIPC", + "UkmReduceAddEntryIPC" + ] + } + ] + } + ], + "RelatedSearchesViaZPSPrefetchingDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ExtractRelatedSearchesFromPrefetchedZPSResponse" + ] + } + ] + } + ], + "RemotePageMetadataAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20240514", + "params": { + "supported_countries": "*", + "supported_locales": "*" + }, + "enable_features": [ + "RemotePageMetadata" + ] + } + ] + } + ], + "RemotePageMetadataBling": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_20240514", + "params": { + "supported_countries": "*", + "supported_locales": "*" + }, + "enable_features": [ + "PageContentAnnotationsPersistSalientImageMetadata", + "RemotePageMetadata" + ] + } + ] + } + ], + "RemotePageMetadataDesktopExpansion": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240514", + "params": { + "supported_countries": "*", + "supported_locales": "*" + }, + "enable_features": [ + "RemotePageMetadata" + ] + } + ] + } + ], + "RemoveDataUrlInSvgUse": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RemoveDataUrlInSvgUse" + ] + } + ] + } + ], + "RemoveDetectPortalFromChrome": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RemoveDetectPortalFromChrome" + ] + } + ] + } + ], + "RemoveFontLinkFallbacks": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled_20230210", + "enable_features": [ + "RemoveFontLinkFallbacks" + ] + } + ] + } + ], + "RemoveOldWebStateRestoration": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RemoveOldWebStateRestoration" + ] + } + ] + } + ], + "RenderArcNotificationsByChrome": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_20230913_Dogfood", + "enable_features": [ + "RenderArcNotificationsByChrome" + ] + }, + { + "name": "Enabled_20230913", + "enable_features": [ + "RenderArcNotificationsByChrome" + ] + } + ] + } + ], + "RenderDocumentWithNavigationQueueing": [ + { + "platforms": [ + "android_weblayer", + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledSubframeWithQueueing_20240108", + "params": { + "level": "subframe", + "queueing_level": "full" + }, + "enable_features": [ + "QueueNavigationsWhileWaitingForCommit", + "RenderDocument" + ], + "disable_features": [ + "RenderDocumentCompositorReuse" + ] + }, + { + "name": "EnabledCrashedFrameWithQueueing_20240108", + "params": { + "level": "crashed-frame", + "queueing_level": "full" + }, + "enable_features": [ + "QueueNavigationsWhileWaitingForCommit", + "RenderDocument" + ], + "disable_features": [ + "RenderDocumentCompositorReuse" + ] + }, + { + "name": "EnabledNLRSubframeWithQueueing_20240108", + "params": { + "level": "non-local-root-subframe", + "queueing_level": "full" + }, + "enable_features": [ + "QueueNavigationsWhileWaitingForCommit", + "RenderDocument" + ], + "disable_features": [ + "RenderDocumentCompositorReuse" + ] + }, + { + "name": "EnabledSubframeWithQueueingAndCompReuse_20240108", + "params": { + "level": "subframe", + "queueing_level": "full" + }, + "enable_features": [ + "QueueNavigationsWhileWaitingForCommit", + "RenderDocument", + "RenderDocumentCompositorReuse" + ] + }, + { + "name": "EnabledAllFramesWithQueueing_20240108", + "params": { + "level": "all-frames", + "queueing_level": "full" + }, + "enable_features": [ + "QueueNavigationsWhileWaitingForCommit", + "RenderDocument" + ], + "disable_features": [ + "RenderDocumentCompositorReuse" + ] + } + ] + } + ], + "RenderPassDrawnRect": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RenderPassDrawnRect" + ] + } + ] + } + ], + "ReportCertificateErrors": [ + { + "platforms": [ + "android", + "chromeos", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "ShowAndPossiblySend", + "params": { + "sendingThreshold": "1.0" + } + } + ] + } + ], + "ReportEventTimingAtVisibilityChange": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows", + "android_webview", + "android_weblayer" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReportEventTimingAtVisibilityChange" + ] + } + ] + } + ], + "ReportingServiceAlwaysFlush": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ReportingServiceAlwaysFlush" + ] + } + ] + } + ], + "RestartToGainAccessToKeychain": [ + { + "platforms": [ + "linux" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RestartToGainAccessToKeychain" + ] + } + ] + } + ], + "RetryGetVideoCaptureDeviceInfos": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RetryGetVideoCaptureDeviceInfos" + ] + } + ] + } + ], + "RichInlineAutocompleteAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_3Chars_AdditionalText", + "params": { + "rich_autocomplete_full_url": "true", + "rich_autocomplete_minimum_characters": "3" + }, + "enable_features": [ + "OmniboxRichAutocompletion" + ] + } + ] + } + ], + "RichInlineAutocompleteIOS": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "RichAutocompletionAutocompleteShortcutTextMinChar": "3", + "RichAutocompletionAutocompleteTitlesMinChar": "3", + "RichAutocompletionParam": "TextField" + }, + "enable_features": [ + "OmniboxRichAutocompletion" + ] + } + ] + } + ], + "RoundedDisplay": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "RoundedDisplayEnabled", + "enable_features": [ + "RoundedDisplay" + ] + } + ] + } + ], + "RubyLineBreakable": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RubyLineBreakable" + ] + } + ] + } + ], + "RubyLineEdgeAlignment": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RubyLineEdgeAlignment" + ] + } + ] + } + ], + "RubyShortHeuristics": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RubyShortHeuristics" + ] + } + ] + } + ], + "RunPerformanceManagerOnMainThreadSync": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RunPerformanceManagerOnMainThreadSync" + ] + } + ] + } + ], + "RunTasksByBatches": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RunTasksByBatches" + ] + } + ] + } + ], + "RustyJSONParser": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20230929", + "enable_features": [ + "UseRustJsonParser" + ] + } + ] + } + ], + "SafeBrowsingDeepScanningPromptRemoval": [ + { + "platforms": [ + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafeBrowsingDeepScanningPromptRemoval" + ] + } + ] + } + ], + "SafeBrowsingGooglePlayProtectPrompt": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "SafeBrowsingGooglePlayProtectPrompt", + "enable_features": [ + "SafeBrowsingGooglePlayProtectPrompt" + ] + } + ] + } + ], + "SafeBrowsingHashPrefixRealTimeLookups": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafeBrowsingHashPrefixRealTimeLookups" + ] + } + ] + }, + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafeBrowsingAsyncRealTimeCheck", + "SafeBrowsingHashPrefixRealTimeLookups" + ] + } + ] + } + ], + "SafeBrowsingNestedArchives": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafeBrowsingArchiveImprovements", + "SafeBrowsingStrictDownloadtimeout" + ] + } + ] + } + ], + "SafeBrowsingNewGmsApiForLocalDatabaseCheck": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafeBrowsingNewGmsApiForBrowseUrlDatabaseCheck" + ] + } + ] + } + ], + "SafeBrowsingSevenZipEvaluationEnabled": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafeBrowsingSevenZipEvaluationEnabled" + ] + } + ] + } + ], + "SafetyCheckMagicStackWithCaching": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "SafetyCheckMagicStackAutorunHoursThreshold": "720" + }, + "enable_features": [ + "SafetyCheckMagicStack", + "SegmentationPlatformIosModuleRankerSplitBySurface" + ] + } + ] + } + ], + "SafetyCheckUnusedSitePermissions": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafetyCheckUnusedSitePermissions" + ] + } + ] + } + ], + "SafetyHub": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "background-password-check-interval": "30d" + }, + "enable_features": [ + "SafetyHub" + ] + } + ] + } + ], + "SafetyHubAbusiveNotificationRevocation": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SafetyHubAbusiveNotificationRevocation" + ] + } + ] + } + ], + "SafetyHubAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "RecordPermissionExpirationTimestamps" + ] + } + ] + } + ], + "ScalableIphStudy": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "CounterfactualControl_BETA_20231204", + "params": { + "IPH_ScalableIphHelpAppBasedNudge_availability": "any", + "IPH_ScalableIphHelpAppBasedNudge_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedNudge_blocking": "none", + "IPH_ScalableIphHelpAppBasedNudge_event_trigger": "name:ScalableIphHelpAppBasedNudgeTrigger;comparator:==0;window:1;storage:7", + "IPH_ScalableIphHelpAppBasedNudge_event_used": "name:ScalableIphHelpAppBasedNudgeEventUsedNotUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedNudge_session_rate": "any", + "IPH_ScalableIphHelpAppBasedNudge_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedNudge_tracking_only": "true", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedEight_availability": "any", + "IPH_ScalableIphTimerBasedEight_blocked_by": "none", + "IPH_ScalableIphTimerBasedEight_blocking": "none", + "IPH_ScalableIphTimerBasedEight_event_1": "name:ScalableIphFiveMinTick;comparator:>=26;window:7;storage:8", + "IPH_ScalableIphTimerBasedEight_event_trigger": "name:ScalableIphTimerBasedEightTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedEight_event_used": "name:ScalableIphTimerBasedEightEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedEight_session_rate": "any", + "IPH_ScalableIphTimerBasedEight_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedEight_tracking_only": "true", + "IPH_ScalableIphTimerBasedEight_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedEight_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedEight_x_CustomConditionPhoneHubOnboardingEligible": "True", + "IPH_ScalableIphTimerBasedEight_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedEight_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedFive_availability": "any", + "IPH_ScalableIphTimerBasedFive_blocked_by": "none", + "IPH_ScalableIphTimerBasedFive_blocking": "none", + "IPH_ScalableIphTimerBasedFive_event_1": "name:ScalableIphFiveMinTick;comparator:>=16;window:7;storage:8", + "IPH_ScalableIphTimerBasedFive_event_trigger": "name:ScalableIphTimerBasedFiveTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedFive_event_used": "name:ScalableIphTimerBasedFiveEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedFive_session_rate": "any", + "IPH_ScalableIphTimerBasedFive_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedFive_tracking_only": "true", + "IPH_ScalableIphTimerBasedFive_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedFive_x_CustomConditionHasSavedPrinter": "False", + "IPH_ScalableIphTimerBasedFive_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedFive_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedFive_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedFour_availability": "any", + "IPH_ScalableIphTimerBasedFour_blocked_by": "none", + "IPH_ScalableIphTimerBasedFour_blocking": "none", + "IPH_ScalableIphTimerBasedFour_event_1": "name:ScalableIphFiveMinTick;comparator:>=12;window:7;storage:8", + "IPH_ScalableIphTimerBasedFour_event_precondition_personalization_app": "name:ScalableIphOpenPersonalizationApp;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedFour_event_trigger": "name:ScalableIphTimerBasedFourTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedFour_event_used": "name:ScalableIphTimerBasedFourEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedFour_session_rate": "any", + "IPH_ScalableIphTimerBasedFour_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedFour_tracking_only": "true", + "IPH_ScalableIphTimerBasedFour_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedFour_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedFour_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedFour_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedNine_availability": "any", + "IPH_ScalableIphTimerBasedNine_blocked_by": "none", + "IPH_ScalableIphTimerBasedNine_blocking": "none", + "IPH_ScalableIphTimerBasedNine_event_1": "name:ScalableIphFiveMinTick;comparator:>=30;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_event_precondition_youtube_app_list": "name:ScalableIphAppListItemActivationYouTube;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_event_precondition_youtube_shelf": "name:ScalableIphShelfItemActivationYouTube;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_event_trigger": "name:ScalableIphTimerBasedNineTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_event_used": "name:ScalableIphTimerBasedNineEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_session_rate": "any", + "IPH_ScalableIphTimerBasedNine_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedNine_tracking_only": "true", + "IPH_ScalableIphTimerBasedNine_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedNine_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedNine_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedNine_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedOne_availability": "any", + "IPH_ScalableIphTimerBasedOne_blocked_by": "none", + "IPH_ScalableIphTimerBasedOne_blocking": "none", + "IPH_ScalableIphTimerBasedOne_event_1": "name:ScalableIphFiveMinTick;comparator:>=0;window:7;storage:8", + "IPH_ScalableIphTimerBasedOne_event_trigger": "name:ScalableIphTimerBasedOneTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedOne_event_used": "name:ScalableIphTimerBasedOneEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedOne_session_rate": "any", + "IPH_ScalableIphTimerBasedOne_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedOne_tracking_only": "true", + "IPH_ScalableIphTimerBasedOne_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedOne_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedOne_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedOne_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedSeven_availability": "any", + "IPH_ScalableIphTimerBasedSeven_blocked_by": "none", + "IPH_ScalableIphTimerBasedSeven_blocking": "none", + "IPH_ScalableIphTimerBasedSeven_event_1": "name:ScalableIphFiveMinTick;comparator:>=24;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_android_app_list": "name:ScalableIphAppListItemActivationOpenGooglePhotosAndroid;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_android_shelf": "name:ScalableIphShelfItemActivationGooglePhotosAndroid;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_web_app_list": "name:ScalableIphAppListItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_web_shelf": "name:ScalableIphShelfItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_trigger": "name:ScalableIphTimerBasedSevenTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_used": "name:ScalableIphTimerBasedSevenEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_session_rate": "any", + "IPH_ScalableIphTimerBasedSeven_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedSeven_tracking_only": "true", + "IPH_ScalableIphTimerBasedSeven_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedSeven_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedSeven_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedSeven_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedSix_availability": "any", + "IPH_ScalableIphTimerBasedSix_blocked_by": "none", + "IPH_ScalableIphTimerBasedSix_blocking": "none", + "IPH_ScalableIphTimerBasedSix_event_1": "name:ScalableIphFiveMinTick;comparator:>=18;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_event_precondition_google_play_app_list": "name:ScalableIphAppListItemActivationOpenGooglePlayStore;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_event_precondition_google_play_shelf": "name:ScalableIphShelfItemActivationGooglePlay;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_event_trigger": "name:ScalableIphTimerBasedSixTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_event_used": "name:ScalableIphTimerBasedSixEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_session_rate": "any", + "IPH_ScalableIphTimerBasedSix_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedSix_tracking_only": "true", + "IPH_ScalableIphTimerBasedSix_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedSix_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedSix_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedSix_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedTen_availability": "any", + "IPH_ScalableIphTimerBasedTen_blocked_by": "none", + "IPH_ScalableIphTimerBasedTen_blocking": "none", + "IPH_ScalableIphTimerBasedTen_event_1": "name:ScalableIphFiveMinTick;comparator:>=48;window:7;storage:8", + "IPH_ScalableIphTimerBasedTen_event_precondition_print_job": "name:ScalableIphPrintJobCreated;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedTen_event_trigger": "name:ScalableIphTimerBasedTenTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedTen_event_used": "name:ScalableIphTimerBasedTenEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedTen_session_rate": "any", + "IPH_ScalableIphTimerBasedTen_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedTen_tracking_only": "true", + "IPH_ScalableIphTimerBasedTen_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedTen_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedTen_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedTen_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedThree_availability": "any", + "IPH_ScalableIphTimerBasedThree_blocked_by": "none", + "IPH_ScalableIphTimerBasedThree_blocking": "none", + "IPH_ScalableIphTimerBasedThree_event_1": "name:ScalableIphFiveMinTick;comparator:>=2;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_event_precondition_google_docs_app_list": "name:ScalableIphAppListItemActivationGoogleDocs;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_event_precondition_google_docs_shelf": "name:ScalableIphShelfItemActivationGoogleDocs;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_event_trigger": "name:ScalableIphTimerBasedThreeTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_event_used": "name:ScalableIphTimerBasedThreeEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_session_rate": "any", + "IPH_ScalableIphTimerBasedThree_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedThree_tracking_only": "true", + "IPH_ScalableIphTimerBasedThree_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedThree_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedThree_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedThree_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedTwo_availability": "any", + "IPH_ScalableIphTimerBasedTwo_blocked_by": "none", + "IPH_ScalableIphTimerBasedTwo_blocking": "none", + "IPH_ScalableIphTimerBasedTwo_event_1": "name:ScalableIphFiveMinTick;comparator:>=1;window:7;storage:8", + "IPH_ScalableIphTimerBasedTwo_event_precondition_launcher": "name:ScalableIphAppListShown;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedTwo_event_trigger": "name:ScalableIphTimerBasedTwoTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedTwo_event_used": "name:ScalableIphAppListShown;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedTwo_session_rate": "any", + "IPH_ScalableIphTimerBasedTwo_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedTwo_tracking_only": "true", + "IPH_ScalableIphTimerBasedTwo_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedTwo_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedTwo_x_CustomUiType": "None", + "IPH_ScalableIphTimerBasedTwo_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedEight_availability": "any", + "IPH_ScalableIphUnlockedBasedEight_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedEight_blocking": "none", + "IPH_ScalableIphUnlockedBasedEight_event_1": "name:ScalableIphUnlocked;comparator:>=7;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedEight_event_trigger": "name:ScalableIphUnlockedBasedEightTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedEight_event_used": "name:ScalableIphUnlockedBasedEightEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedEight_session_rate": "any", + "IPH_ScalableIphUnlockedBasedEight_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedEight_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionPhoneHubOnboardingEligible": "True", + "IPH_ScalableIphUnlockedBasedEight_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedEight_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedFive_availability": "any", + "IPH_ScalableIphUnlockedBasedFive_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedFive_blocking": "none", + "IPH_ScalableIphUnlockedBasedFive_event_1": "name:ScalableIphUnlocked;comparator:>=4;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_event_precondition_google_docs_app_list": "name:ScalableIphAppListItemActivationGoogleDocs;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_event_precondition_google_docs_shelf": "name:ScalableIphShelfItemActivationGoogleDocs;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_event_trigger": "name:ScalableIphUnlockedBasedFiveTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_event_used": "name:ScalableIphUnlockedBasedFiveEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_session_rate": "any", + "IPH_ScalableIphUnlockedBasedFive_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedFive_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedFive_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedFive_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedFive_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedFive_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedFour_availability": "any", + "IPH_ScalableIphUnlockedBasedFour_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedFour_blocking": "none", + "IPH_ScalableIphUnlockedBasedFour_event_1": "name:ScalableIphUnlocked;comparator:>=3;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_event_precondition_google_play_app_list": "name:ScalableIphAppListItemActivationOpenGooglePlayStore;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_event_precondition_google_play_shelf": "name:ScalableIphShelfItemActivationGooglePlay;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_event_trigger": "name:ScalableIphUnlockedBasedFourTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_event_used": "name:ScalableIphUnlockedBasedFourEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_session_rate": "any", + "IPH_ScalableIphUnlockedBasedFour_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedFour_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedFour_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedFour_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedFour_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedFour_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedNine_availability": "any", + "IPH_ScalableIphUnlockedBasedNine_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedNine_blocking": "none", + "IPH_ScalableIphUnlockedBasedNine_event_1": "name:ScalableIphUnlocked;comparator:>=8;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_event_precondition_youtube_app_list": "name:ScalableIphAppListItemActivationYouTube;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_event_precondition_youtube_shelf": "name:ScalableIphShelfItemActivationYouTube;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_event_trigger": "name:ScalableIphUnlockedBasedNineTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_event_used": "name:ScalableIphUnlockedBasedNineEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_session_rate": "any", + "IPH_ScalableIphUnlockedBasedNine_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedNine_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedNine_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedNine_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedNine_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedNine_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedOne_availability": "any", + "IPH_ScalableIphUnlockedBasedOne_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedOne_blocking": "none", + "IPH_ScalableIphUnlockedBasedOne_event_1": "name:ScalableIphUnlocked;comparator:>=0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedOne_event_trigger": "name:ScalableIphUnlockedBasedOneTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedOne_event_used": "name:ScalableIphUnlockedBasedOneEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedOne_session_rate": "any", + "IPH_ScalableIphUnlockedBasedOne_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedOne_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedOne_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedOne_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedOne_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedOne_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedSeven_availability": "any", + "IPH_ScalableIphUnlockedBasedSeven_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedSeven_blocking": "none", + "IPH_ScalableIphUnlockedBasedSeven_event_1": "name:ScalableIphUnlocked;comparator:>=6;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSeven_event_trigger": "name:ScalableIphUnlockedBasedSevenTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSeven_event_used": "name:ScalableIphUnlockedBasedSevenEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSeven_session_rate": "any", + "IPH_ScalableIphUnlockedBasedSeven_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedSeven_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionHasSavedPrinter": "False", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedSix_availability": "any", + "IPH_ScalableIphUnlockedBasedSix_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedSix_blocking": "none", + "IPH_ScalableIphUnlockedBasedSix_event_1": "name:ScalableIphUnlocked;comparator:>=5;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_android_app_list": "name:ScalableIphAppListItemActivationOpenGooglePhotosAndroid;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_android_shelf": "name:ScalableIphShelfItemActivationGooglePhotosAndroid;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_web_app_list": "name:ScalableIphAppListItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_web_shelf": "name:ScalableIphShelfItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_trigger": "name:ScalableIphUnlockedBasedSixTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_used": "name:ScalableIphUnlockedBasedSixEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_session_rate": "any", + "IPH_ScalableIphUnlockedBasedSix_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedSix_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedSix_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedSix_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedSix_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedSix_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedTen_availability": "any", + "IPH_ScalableIphUnlockedBasedTen_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedTen_blocking": "none", + "IPH_ScalableIphUnlockedBasedTen_event_1": "name:ScalableIphUnlocked;comparator:>=9;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTen_event_precondition_print_job": "name:ScalableIphPrintJobCreated;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTen_event_trigger": "name:ScalableIphUnlockedBasedTenTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTen_event_used": "name:ScalableIphUnlockedBasedTenEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTen_session_rate": "any", + "IPH_ScalableIphUnlockedBasedTen_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedTen_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedTen_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedTen_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedTen_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedTen_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedThree_availability": "any", + "IPH_ScalableIphUnlockedBasedThree_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedThree_blocking": "none", + "IPH_ScalableIphUnlockedBasedThree_event_1": "name:ScalableIphUnlocked;comparator:>=2;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedThree_event_precondition_personalization_app": "name:ScalableIphOpenPersonalizationApp;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedThree_event_trigger": "name:ScalableIphUnlockedBasedThreeTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedThree_event_used": "name:ScalableIphUnlockedBasedThreeEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedThree_session_rate": "any", + "IPH_ScalableIphUnlockedBasedThree_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedThree_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedThree_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedThree_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedThree_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedThree_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedTwo_availability": "any", + "IPH_ScalableIphUnlockedBasedTwo_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedTwo_blocking": "none", + "IPH_ScalableIphUnlockedBasedTwo_event_1": "name:ScalableIphUnlocked;comparator:>=1;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTwo_event_precondition_launcher": "name:ScalableIphAppListShown;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTwo_event_trigger": "name:ScalableIphUnlockedBasedTwoTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTwo_event_used": "name:ScalableIphAppListShown;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTwo_session_rate": "any", + "IPH_ScalableIphUnlockedBasedTwo_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedTwo_tracking_only": "true", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomUiType": "None", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomVersionNumber": "1" + }, + "enable_features": [ + "IPH_ScalableIphHelpAppBasedNudge", + "IPH_ScalableIphTimerBasedEight", + "IPH_ScalableIphTimerBasedFive", + "IPH_ScalableIphTimerBasedFour", + "IPH_ScalableIphTimerBasedNine", + "IPH_ScalableIphTimerBasedOne", + "IPH_ScalableIphTimerBasedSeven", + "IPH_ScalableIphTimerBasedSix", + "IPH_ScalableIphTimerBasedTen", + "IPH_ScalableIphTimerBasedThree", + "IPH_ScalableIphTimerBasedTwo", + "IPH_ScalableIphUnlockedBasedEight", + "IPH_ScalableIphUnlockedBasedFive", + "IPH_ScalableIphUnlockedBasedFour", + "IPH_ScalableIphUnlockedBasedNine", + "IPH_ScalableIphUnlockedBasedOne", + "IPH_ScalableIphUnlockedBasedSeven", + "IPH_ScalableIphUnlockedBasedSix", + "IPH_ScalableIphUnlockedBasedTen", + "IPH_ScalableIphUnlockedBasedThree", + "IPH_ScalableIphUnlockedBasedTwo", + "ScalableIph" + ], + "disable_features": [ + "ShelfLauncherNudge" + ] + }, + { + "name": "HelpAppBased_BETA_20231204", + "params": { + "IPH_ScalableIphHelpAppBasedEight_availability": "any", + "IPH_ScalableIphHelpAppBasedEight_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedEight_blocking": "none", + "IPH_ScalableIphHelpAppBasedEight_event_trigger": "name:ScalableIphHelpAppBasedEightTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedEight_event_used": "name:ScalableIphHelpAppActionOpenPhoneHub;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedEight_session_rate": "any", + "IPH_ScalableIphHelpAppBasedEight_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedEight_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedEight_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedEight_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedEight_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedFive_availability": "any", + "IPH_ScalableIphHelpAppBasedFive_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedFive_blocking": "none", + "IPH_ScalableIphHelpAppBasedFive_event_trigger": "name:ScalableIphHelpAppBasedFiveTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedFive_event_used": "name:ScalableIphHelpAppActionOpenGoogleDocs;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedFive_session_rate": "any", + "IPH_ScalableIphHelpAppBasedFive_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedFive_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedFive_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedFive_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedFive_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedFour_availability": "any", + "IPH_ScalableIphHelpAppBasedFour_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedFour_blocking": "none", + "IPH_ScalableIphHelpAppBasedFour_event_trigger": "name:ScalableIphHelpAppBasedFourTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedFour_event_used": "name:ScalableIphHelpAppActionOpenPlayStore;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedFour_session_rate": "any", + "IPH_ScalableIphHelpAppBasedFour_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedFour_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedFour_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedFour_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedFour_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedNine_availability": "any", + "IPH_ScalableIphHelpAppBasedNine_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedNine_blocking": "none", + "IPH_ScalableIphHelpAppBasedNine_event_trigger": "name:ScalableIphHelpAppBasedNineTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedNine_event_used": "name:ScalableIphHelpAppActionOpenYouTube;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedNine_session_rate": "any", + "IPH_ScalableIphHelpAppBasedNine_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedNine_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedNine_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedNine_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedNine_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedNudge_availability": "any", + "IPH_ScalableIphHelpAppBasedNudge_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedNudge_blocking": "none", + "IPH_ScalableIphHelpAppBasedNudge_event_trigger": "name:ScalableIphHelpAppBasedNudgeTrigger;comparator:==0;window:1;storage:7", + "IPH_ScalableIphHelpAppBasedNudge_event_used": "name:ScalableIphHelpAppBasedNudgeEventUsedNotUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedNudge_session_rate": "any", + "IPH_ScalableIphHelpAppBasedNudge_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomBubbleAnchorViewAppId": "nbljnnecbjbmifnoehiemkgefbnpoeak", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomBubbleId": "scalable_iph_help_app_based_open_help_app", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomBubbleText": "Continue learning about your Chromebook", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomUiType": "Bubble", + "IPH_ScalableIphHelpAppBasedNudge_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedOne_availability": "any", + "IPH_ScalableIphHelpAppBasedOne_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedOne_blocking": "none", + "IPH_ScalableIphHelpAppBasedOne_event_trigger": "name:ScalableIphHelpAppBasedOneTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedOne_event_used": "name:ScalableIphHelpAppActionOpenChrome;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedOne_session_rate": "any", + "IPH_ScalableIphHelpAppBasedOne_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedOne_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedOne_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedOne_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedOne_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedSeven_availability": "any", + "IPH_ScalableIphHelpAppBasedSeven_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedSeven_blocking": "none", + "IPH_ScalableIphHelpAppBasedSeven_event_trigger": "name:ScalableIphHelpAppBasedSevenTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedSeven_event_used": "name:ScalableIphHelpAppActionOpenSettingsPrinter;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedSeven_session_rate": "any", + "IPH_ScalableIphHelpAppBasedSeven_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedSeven_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedSeven_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedSeven_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedSeven_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedSix_availability": "any", + "IPH_ScalableIphHelpAppBasedSix_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedSix_blocking": "none", + "IPH_ScalableIphHelpAppBasedSix_event_trigger": "name:ScalableIphHelpAppBasedSixTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedSix_event_used": "name:ScalableIphHelpAppActionOpenGooglePhotos;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedSix_session_rate": "any", + "IPH_ScalableIphHelpAppBasedSix_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedSix_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedSix_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedSix_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedSix_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedTen_availability": "any", + "IPH_ScalableIphHelpAppBasedTen_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedTen_blocking": "none", + "IPH_ScalableIphHelpAppBasedTen_event_trigger": "name:ScalableIphHelpAppBasedTenTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedTen_event_used": "name:ScalableIphHelpAppActionOpenFileManager;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedTen_session_rate": "any", + "IPH_ScalableIphHelpAppBasedTen_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedTen_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedTen_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedTen_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedTen_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedThree_availability": "any", + "IPH_ScalableIphHelpAppBasedThree_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedThree_blocking": "none", + "IPH_ScalableIphHelpAppBasedThree_event_trigger": "name:ScalableIphHelpAppBasedThreeTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedThree_event_used": "name:ScalableIphHelpAppActionOpenPersonalizationApp;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedThree_session_rate": "any", + "IPH_ScalableIphHelpAppBasedThree_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedThree_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedThree_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedThree_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedThree_x_CustomVersionNumber": "1", + "IPH_ScalableIphHelpAppBasedTwo_availability": "any", + "IPH_ScalableIphHelpAppBasedTwo_blocked_by": "none", + "IPH_ScalableIphHelpAppBasedTwo_blocking": "none", + "IPH_ScalableIphHelpAppBasedTwo_event_trigger": "name:ScalableIphHelpAppBasedTwoTriggerNotUsed;comparator:==1;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedTwo_event_used": "name:ScalableIphAppListShown;comparator:any;window:7;storage:8", + "IPH_ScalableIphHelpAppBasedTwo_session_rate": "any", + "IPH_ScalableIphHelpAppBasedTwo_session_rate_impact": "none", + "IPH_ScalableIphHelpAppBasedTwo_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphHelpAppBasedTwo_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphHelpAppBasedTwo_x_CustomUiType": "None", + "IPH_ScalableIphHelpAppBasedTwo_x_CustomVersionNumber": "1" + }, + "enable_features": [ + "HelpAppWelcomeTips", + "IPH_ScalableIphHelpAppBasedEight", + "IPH_ScalableIphHelpAppBasedFive", + "IPH_ScalableIphHelpAppBasedFour", + "IPH_ScalableIphHelpAppBasedNine", + "IPH_ScalableIphHelpAppBasedNudge", + "IPH_ScalableIphHelpAppBasedOne", + "IPH_ScalableIphHelpAppBasedSeven", + "IPH_ScalableIphHelpAppBasedSix", + "IPH_ScalableIphHelpAppBasedTen", + "IPH_ScalableIphHelpAppBasedThree", + "IPH_ScalableIphHelpAppBasedTwo", + "ScalableIph" + ], + "disable_features": [ + "ShelfLauncherNudge" + ] + }, + { + "name": "TimerBased_BETA_20231204", + "params": { + "IPH_ScalableIphTimerBasedEight_availability": "any", + "IPH_ScalableIphTimerBasedEight_blocked_by": "none", + "IPH_ScalableIphTimerBasedEight_blocking": "none", + "IPH_ScalableIphTimerBasedEight_event_1": "name:ScalableIphFiveMinTick;comparator:>=26;window:7;storage:8", + "IPH_ScalableIphTimerBasedEight_event_trigger": "name:ScalableIphTimerBasedEightTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedEight_event_used": "name:ScalableIphTimerBasedEightEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedEight_session_rate": "any", + "IPH_ScalableIphTimerBasedEight_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedEight_x_CustomButtonActionType": "OpenPhoneHub", + "IPH_ScalableIphTimerBasedEight_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedEight_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedEight_x_CustomConditionPhoneHubOnboardingEligible": "True", + "IPH_ScalableIphTimerBasedEight_x_CustomNotificationBodyText": "You can quickly reply to messages from your Android phone, right from your Chromebook", + "IPH_ScalableIphTimerBasedEight_x_CustomNotificationButtonText": "Connect phone", + "IPH_ScalableIphTimerBasedEight_x_CustomNotificationId": "scalable_iph_timer_based_eight", + "IPH_ScalableIphTimerBasedEight_x_CustomNotificationSummaryText": "Welcome Tips", + "IPH_ScalableIphTimerBasedEight_x_CustomNotificationTitle": "Connect your Android phone", + "IPH_ScalableIphTimerBasedEight_x_CustomUiType": "Notification", + "IPH_ScalableIphTimerBasedEight_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedFive_availability": "any", + "IPH_ScalableIphTimerBasedFive_blocked_by": "none", + "IPH_ScalableIphTimerBasedFive_blocking": "none", + "IPH_ScalableIphTimerBasedFive_event_1": "name:ScalableIphFiveMinTick;comparator:>=16;window:7;storage:8", + "IPH_ScalableIphTimerBasedFive_event_trigger": "name:ScalableIphTimerBasedFiveTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedFive_event_used": "name:ScalableIphTimerBasedFiveEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedFive_session_rate": "any", + "IPH_ScalableIphTimerBasedFive_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedFive_x_CustomButtonActionType": "OpenSettingsPrinter", + "IPH_ScalableIphTimerBasedFive_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedFive_x_CustomConditionHasSavedPrinter": "False", + "IPH_ScalableIphTimerBasedFive_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedFive_x_CustomNotificationBodyText": "Easily add a printer to your Chromebook so it will be ready to go", + "IPH_ScalableIphTimerBasedFive_x_CustomNotificationButtonText": "Add printer", + "IPH_ScalableIphTimerBasedFive_x_CustomNotificationId": "scalable_iph_timer_based_five", + "IPH_ScalableIphTimerBasedFive_x_CustomNotificationSummaryText": "Welcome Tips", + "IPH_ScalableIphTimerBasedFive_x_CustomNotificationTitle": "Connect a printer", + "IPH_ScalableIphTimerBasedFive_x_CustomUiType": "Notification", + "IPH_ScalableIphTimerBasedFive_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedFour_availability": "any", + "IPH_ScalableIphTimerBasedFour_blocked_by": "none", + "IPH_ScalableIphTimerBasedFour_blocking": "none", + "IPH_ScalableIphTimerBasedFour_event_1": "name:ScalableIphFiveMinTick;comparator:>=12;window:7;storage:8", + "IPH_ScalableIphTimerBasedFour_event_precondition_personalization_app": "name:ScalableIphOpenPersonalizationApp;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedFour_event_trigger": "name:ScalableIphTimerBasedFourTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedFour_event_used": "name:ScalableIphTimerBasedFourEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedFour_session_rate": "any", + "IPH_ScalableIphTimerBasedFour_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedFour_x_CustomButtonActionType": "OpenPersonalizationApp", + "IPH_ScalableIphTimerBasedFour_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedFour_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedFour_x_CustomNotificationBodyText": "Make your Chromebook uniquely yours with a new wallpaper", + "IPH_ScalableIphTimerBasedFour_x_CustomNotificationButtonText": "Select wallpaper", + "IPH_ScalableIphTimerBasedFour_x_CustomNotificationId": "scalable_iph_timer_based_four", + "IPH_ScalableIphTimerBasedFour_x_CustomNotificationImageType": "Wallpaper", + "IPH_ScalableIphTimerBasedFour_x_CustomNotificationSummaryText": "Welcome Tips", + "IPH_ScalableIphTimerBasedFour_x_CustomNotificationTitle": "Customize your wallpaper", + "IPH_ScalableIphTimerBasedFour_x_CustomUiType": "Notification", + "IPH_ScalableIphTimerBasedFour_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedNine_availability": "any", + "IPH_ScalableIphTimerBasedNine_blocked_by": "none", + "IPH_ScalableIphTimerBasedNine_blocking": "none", + "IPH_ScalableIphTimerBasedNine_event_1": "name:ScalableIphFiveMinTick;comparator:>=30;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_event_precondition_youtube_app_list": "name:ScalableIphAppListItemActivationYouTube;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_event_precondition_youtube_shelf": "name:ScalableIphShelfItemActivationYouTube;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_event_trigger": "name:ScalableIphTimerBasedNineTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_event_used": "name:ScalableIphTimerBasedNineEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedNine_session_rate": "any", + "IPH_ScalableIphTimerBasedNine_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedNine_x_CustomBubbleButtonText": "Open YouTube", + "IPH_ScalableIphTimerBasedNine_x_CustomBubbleIcon": "YouTubeIcon", + "IPH_ScalableIphTimerBasedNine_x_CustomBubbleId": "scalable_iph_timer_based_nine", + "IPH_ScalableIphTimerBasedNine_x_CustomBubbleText": "Watch your favorite content on YouTube", + "IPH_ScalableIphTimerBasedNine_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphTimerBasedNine_x_CustomButtonActionType": "OpenYouTube", + "IPH_ScalableIphTimerBasedNine_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedNine_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedNine_x_CustomUiType": "Bubble", + "IPH_ScalableIphTimerBasedNine_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedOne_availability": "any", + "IPH_ScalableIphTimerBasedOne_blocked_by": "none", + "IPH_ScalableIphTimerBasedOne_blocking": "none", + "IPH_ScalableIphTimerBasedOne_event_1": "name:ScalableIphFiveMinTick;comparator:>=0;window:7;storage:8", + "IPH_ScalableIphTimerBasedOne_event_trigger": "name:ScalableIphTimerBasedOneTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedOne_event_used": "name:ScalableIphTimerBasedOneEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedOne_session_rate": "any", + "IPH_ScalableIphTimerBasedOne_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedOne_x_CustomBubbleButtonText": "Open Chrome", + "IPH_ScalableIphTimerBasedOne_x_CustomBubbleIcon": "ChromeIcon", + "IPH_ScalableIphTimerBasedOne_x_CustomBubbleId": "scalable_iph_timer_based_one", + "IPH_ScalableIphTimerBasedOne_x_CustomBubbleText": "Connect to the world on your Chromebook with Chrome browser", + "IPH_ScalableIphTimerBasedOne_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphTimerBasedOne_x_CustomButtonActionType": "OpenChrome", + "IPH_ScalableIphTimerBasedOne_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedOne_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedOne_x_CustomUiType": "Bubble", + "IPH_ScalableIphTimerBasedOne_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedSeven_availability": "any", + "IPH_ScalableIphTimerBasedSeven_blocked_by": "none", + "IPH_ScalableIphTimerBasedSeven_blocking": "none", + "IPH_ScalableIphTimerBasedSeven_event_1": "name:ScalableIphFiveMinTick;comparator:>=24;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_android_app_list": "name:ScalableIphAppListItemActivationOpenGooglePhotosAndroid;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_android_shelf": "name:ScalableIphShelfItemActivationGooglePhotosAndroid;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_web_app_list": "name:ScalableIphAppListItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_preconditions_google_photos_web_shelf": "name:ScalableIphShelfItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_trigger": "name:ScalableIphTimerBasedSevenTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_event_used": "name:ScalableIphTimerBasedSevenEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedSeven_session_rate": "any", + "IPH_ScalableIphTimerBasedSeven_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleButtonText": "Open Photos", + "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleIcon": "GooglePhotosIcon", + "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleId": "scalable_iph_timer_based_seven", + "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleText": "Explore your favorite memories in Google Photos", + "IPH_ScalableIphTimerBasedSeven_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphTimerBasedSeven_x_CustomButtonActionType": "OpenGooglePhotos", + "IPH_ScalableIphTimerBasedSeven_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedSeven_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedSeven_x_CustomUiType": "Bubble", + "IPH_ScalableIphTimerBasedSeven_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedSix_availability": "any", + "IPH_ScalableIphTimerBasedSix_blocked_by": "none", + "IPH_ScalableIphTimerBasedSix_blocking": "none", + "IPH_ScalableIphTimerBasedSix_event_1": "name:ScalableIphFiveMinTick;comparator:>=18;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_event_precondition_google_play_app_list": "name:ScalableIphAppListItemActivationOpenGooglePlayStore;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_event_precondition_google_play_shelf": "name:ScalableIphShelfItemActivationGooglePlay;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_event_trigger": "name:ScalableIphTimerBasedSixTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_event_used": "name:ScalableIphTimerBasedSixEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedSix_session_rate": "any", + "IPH_ScalableIphTimerBasedSix_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedSix_x_CustomButtonActionType": "OpenPlayStore", + "IPH_ScalableIphTimerBasedSix_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedSix_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedSix_x_CustomNotificationBodyText": "Download your favorite Android apps from the Google Play Store and use them on your Chromebook", + "IPH_ScalableIphTimerBasedSix_x_CustomNotificationButtonText": "Open Play Store", + "IPH_ScalableIphTimerBasedSix_x_CustomNotificationId": "scalable_iph_timer_based_six", + "IPH_ScalableIphTimerBasedSix_x_CustomNotificationSummaryText": "Welcome Tips", + "IPH_ScalableIphTimerBasedSix_x_CustomNotificationTitle": "Install apps from the Play Store", + "IPH_ScalableIphTimerBasedSix_x_CustomUiType": "Notification", + "IPH_ScalableIphTimerBasedSix_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedTen_availability": "any", + "IPH_ScalableIphTimerBasedTen_blocked_by": "none", + "IPH_ScalableIphTimerBasedTen_blocking": "none", + "IPH_ScalableIphTimerBasedTen_event_1": "name:ScalableIphFiveMinTick;comparator:>=48;window:7;storage:8", + "IPH_ScalableIphTimerBasedTen_event_precondition_print_job": "name:ScalableIphPrintJobCreated;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedTen_event_trigger": "name:ScalableIphTimerBasedTenTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedTen_event_used": "name:ScalableIphTimerBasedTenEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedTen_session_rate": "any", + "IPH_ScalableIphTimerBasedTen_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedTen_x_CustomBubbleButtonText": "Select file", + "IPH_ScalableIphTimerBasedTen_x_CustomBubbleIcon": "PrintJobsIcon", + "IPH_ScalableIphTimerBasedTen_x_CustomBubbleId": "scalable_iph_timer_based_ten", + "IPH_ScalableIphTimerBasedTen_x_CustomBubbleText": "Printing is easy with your Chromebook", + "IPH_ScalableIphTimerBasedTen_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphTimerBasedTen_x_CustomButtonActionType": "OpenFileManager", + "IPH_ScalableIphTimerBasedTen_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedTen_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedTen_x_CustomUiType": "Bubble", + "IPH_ScalableIphTimerBasedTen_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedThree_availability": "any", + "IPH_ScalableIphTimerBasedThree_blocked_by": "none", + "IPH_ScalableIphTimerBasedThree_blocking": "none", + "IPH_ScalableIphTimerBasedThree_event_1": "name:ScalableIphFiveMinTick;comparator:>=2;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_event_precondition_google_docs_app_list": "name:ScalableIphAppListItemActivationGoogleDocs;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_event_precondition_google_docs_shelf": "name:ScalableIphShelfItemActivationGoogleDocs;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_event_trigger": "name:ScalableIphTimerBasedThreeTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_event_used": "name:ScalableIphTimerBasedThreeEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedThree_session_rate": "any", + "IPH_ScalableIphTimerBasedThree_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedThree_x_CustomBubbleButtonText": "Open Docs", + "IPH_ScalableIphTimerBasedThree_x_CustomBubbleIcon": "GoogleDocsIcon", + "IPH_ScalableIphTimerBasedThree_x_CustomBubbleId": "scalable_iph_timer_based_three", + "IPH_ScalableIphTimerBasedThree_x_CustomBubbleText": "Create, edit, and collaborate with Google Docs", + "IPH_ScalableIphTimerBasedThree_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphTimerBasedThree_x_CustomButtonActionType": "OpenGoogleDocs", + "IPH_ScalableIphTimerBasedThree_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedThree_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedThree_x_CustomUiType": "Bubble", + "IPH_ScalableIphTimerBasedThree_x_CustomVersionNumber": "1", + "IPH_ScalableIphTimerBasedTwo_availability": "any", + "IPH_ScalableIphTimerBasedTwo_blocked_by": "none", + "IPH_ScalableIphTimerBasedTwo_blocking": "none", + "IPH_ScalableIphTimerBasedTwo_event_1": "name:ScalableIphFiveMinTick;comparator:>=1;window:7;storage:8", + "IPH_ScalableIphTimerBasedTwo_event_precondition_launcher": "name:ScalableIphAppListShown;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedTwo_event_trigger": "name:ScalableIphTimerBasedTwoTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphTimerBasedTwo_event_used": "name:ScalableIphAppListShown;comparator:any;window:7;storage:8", + "IPH_ScalableIphTimerBasedTwo_session_rate": "any", + "IPH_ScalableIphTimerBasedTwo_session_rate_impact": "none", + "IPH_ScalableIphTimerBasedTwo_x_CustomBubbleId": "scalable_iph_timer_based_two", + "IPH_ScalableIphTimerBasedTwo_x_CustomBubbleText": "Search and find your apps in the Launcher \u25c9", + "IPH_ScalableIphTimerBasedTwo_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphTimerBasedTwo_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphTimerBasedTwo_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphTimerBasedTwo_x_CustomUiType": "Bubble", + "IPH_ScalableIphTimerBasedTwo_x_CustomVersionNumber": "1" + }, + "enable_features": [ + "IPH_ScalableIphTimerBasedEight", + "IPH_ScalableIphTimerBasedFive", + "IPH_ScalableIphTimerBasedFour", + "IPH_ScalableIphTimerBasedNine", + "IPH_ScalableIphTimerBasedOne", + "IPH_ScalableIphTimerBasedSeven", + "IPH_ScalableIphTimerBasedSix", + "IPH_ScalableIphTimerBasedTen", + "IPH_ScalableIphTimerBasedThree", + "IPH_ScalableIphTimerBasedTwo", + "ScalableIph" + ], + "disable_features": [ + "ShelfLauncherNudge" + ] + }, + { + "name": "UnlockedBased_BETA_20231204", + "params": { + "IPH_ScalableIphUnlockedBasedEight_availability": "any", + "IPH_ScalableIphUnlockedBasedEight_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedEight_blocking": "none", + "IPH_ScalableIphUnlockedBasedEight_event_1": "name:ScalableIphUnlocked;comparator:>=7;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedEight_event_trigger": "name:ScalableIphUnlockedBasedEightTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedEight_event_used": "name:ScalableIphUnlockedBasedEightEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedEight_session_rate": "any", + "IPH_ScalableIphUnlockedBasedEight_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleButtonText": "Connect phone", + "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleId": "scalable_iph_unlocked_based_eight", + "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleText": "Quickly reply to your messages from your Android phone", + "IPH_ScalableIphUnlockedBasedEight_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedEight_x_CustomButtonActionType": "OpenPhoneHub", + "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedEight_x_CustomConditionPhoneHubOnboardingEligible": "True", + "IPH_ScalableIphUnlockedBasedEight_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedEight_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedFive_availability": "any", + "IPH_ScalableIphUnlockedBasedFive_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedFive_blocking": "none", + "IPH_ScalableIphUnlockedBasedFive_event_1": "name:ScalableIphUnlocked;comparator:>=4;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_event_precondition_google_docs_app_list": "name:ScalableIphAppListItemActivationGoogleDocs;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_event_precondition_google_docs_shelf": "name:ScalableIphShelfItemActivationGoogleDocs;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_event_trigger": "name:ScalableIphUnlockedBasedFiveTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_event_used": "name:ScalableIphUnlockedBasedFiveEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFive_session_rate": "any", + "IPH_ScalableIphUnlockedBasedFive_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleButtonText": "Open Docs", + "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleIcon": "GoogleDocsIcon", + "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleId": "scalable_iph_unlocked_based_five", + "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleText": "Create, edit, and collaborate with Google Docs", + "IPH_ScalableIphUnlockedBasedFive_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedFive_x_CustomButtonActionType": "OpenGoogleDocs", + "IPH_ScalableIphUnlockedBasedFive_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedFive_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedFive_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedFive_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedFour_availability": "any", + "IPH_ScalableIphUnlockedBasedFour_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedFour_blocking": "none", + "IPH_ScalableIphUnlockedBasedFour_event_1": "name:ScalableIphUnlocked;comparator:>=3;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_event_precondition_google_play_app_list": "name:ScalableIphAppListItemActivationOpenGooglePlayStore;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_event_precondition_google_play_shelf": "name:ScalableIphShelfItemActivationGooglePlay;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_event_trigger": "name:ScalableIphUnlockedBasedFourTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_event_used": "name:ScalableIphUnlockedBasedFourEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedFour_session_rate": "any", + "IPH_ScalableIphUnlockedBasedFour_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleButtonText": "Open Play Store", + "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleIcon": "PlayStoreIcon", + "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleId": "scalable_iph_unlocked_based_four", + "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleText": "Get your favorite apps from the Play Store", + "IPH_ScalableIphUnlockedBasedFour_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedFour_x_CustomButtonActionType": "OpenPlayStore", + "IPH_ScalableIphUnlockedBasedFour_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedFour_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedFour_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedFour_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedNine_availability": "any", + "IPH_ScalableIphUnlockedBasedNine_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedNine_blocking": "none", + "IPH_ScalableIphUnlockedBasedNine_event_1": "name:ScalableIphUnlocked;comparator:>=8;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_event_precondition_youtube_app_list": "name:ScalableIphAppListItemActivationYouTube;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_event_precondition_youtube_shelf": "name:ScalableIphShelfItemActivationYouTube;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_event_trigger": "name:ScalableIphUnlockedBasedNineTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_event_used": "name:ScalableIphUnlockedBasedNineEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedNine_session_rate": "any", + "IPH_ScalableIphUnlockedBasedNine_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleButtonText": "Open YouTube", + "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleIcon": "YouTubeIcon", + "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleId": "scalable_iph_unlocked_based_nine", + "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleText": "Watch your favorite content on YouTube", + "IPH_ScalableIphUnlockedBasedNine_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedNine_x_CustomButtonActionType": "OpenYouTube", + "IPH_ScalableIphUnlockedBasedNine_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedNine_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedNine_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedNine_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedOne_availability": "any", + "IPH_ScalableIphUnlockedBasedOne_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedOne_blocking": "none", + "IPH_ScalableIphUnlockedBasedOne_event_1": "name:ScalableIphUnlocked;comparator:>=0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedOne_event_trigger": "name:ScalableIphUnlockedBasedOneTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedOne_event_used": "name:ScalableIphUnlockedBasedOneEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedOne_session_rate": "any", + "IPH_ScalableIphUnlockedBasedOne_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleButtonText": "Open Chrome", + "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleIcon": "ChromeIcon", + "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleId": "scalable_iph_unlocked_based_one", + "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleText": "Connect to the world on your Chromebook with Chrome browser", + "IPH_ScalableIphUnlockedBasedOne_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedOne_x_CustomButtonActionType": "OpenChrome", + "IPH_ScalableIphUnlockedBasedOne_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedOne_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedOne_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedOne_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedSeven_availability": "any", + "IPH_ScalableIphUnlockedBasedSeven_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedSeven_blocking": "none", + "IPH_ScalableIphUnlockedBasedSeven_event_1": "name:ScalableIphUnlocked;comparator:>=6;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSeven_event_trigger": "name:ScalableIphUnlockedBasedSevenTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSeven_event_used": "name:ScalableIphUnlockedBasedSevenEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSeven_session_rate": "any", + "IPH_ScalableIphUnlockedBasedSeven_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleButtonText": "Add printer", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleIcon": "PrintJobsIcon", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleId": "scalable_iph_unlocked_based_seven", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleText": "Easily add a printer to your Chromebook", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomButtonActionType": "OpenSettingsPrinter", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionHasSavedPrinter": "False", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedSeven_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedSix_availability": "any", + "IPH_ScalableIphUnlockedBasedSix_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedSix_blocking": "none", + "IPH_ScalableIphUnlockedBasedSix_event_1": "name:ScalableIphUnlocked;comparator:>=5;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_android_app_list": "name:ScalableIphAppListItemActivationOpenGooglePhotosAndroid;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_android_shelf": "name:ScalableIphShelfItemActivationGooglePhotosAndroid;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_web_app_list": "name:ScalableIphAppListItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_preconditions_google_photos_web_shelf": "name:ScalableIphShelfItemActivationGooglePhotosWeb;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_trigger": "name:ScalableIphUnlockedBasedSixTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_event_used": "name:ScalableIphUnlockedBasedSixEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedSix_session_rate": "any", + "IPH_ScalableIphUnlockedBasedSix_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleButtonText": "Open Photos", + "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleIcon": "GooglePhotosIcon", + "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleId": "scalable_iph_unlocked_based_six", + "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleText": "Explore your favorite memories in Google Photos", + "IPH_ScalableIphUnlockedBasedSix_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedSix_x_CustomButtonActionType": "OpenGooglePhotos", + "IPH_ScalableIphUnlockedBasedSix_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedSix_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedSix_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedSix_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedTen_availability": "any", + "IPH_ScalableIphUnlockedBasedTen_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedTen_blocking": "none", + "IPH_ScalableIphUnlockedBasedTen_event_1": "name:ScalableIphUnlocked;comparator:>=9;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTen_event_precondition_print_job": "name:ScalableIphPrintJobCreated;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTen_event_trigger": "name:ScalableIphUnlockedBasedTenTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTen_event_used": "name:ScalableIphUnlockedBasedTenEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTen_session_rate": "any", + "IPH_ScalableIphUnlockedBasedTen_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleButtonText": "Select file", + "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleIcon": "PrintJobsIcon", + "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleId": "scalable_iph_unlocked_based_ten", + "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleText": "Printing is easy with your Chromebook", + "IPH_ScalableIphUnlockedBasedTen_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedTen_x_CustomButtonActionType": "OpenFileManager", + "IPH_ScalableIphUnlockedBasedTen_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedTen_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedTen_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedTen_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedThree_availability": "any", + "IPH_ScalableIphUnlockedBasedThree_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedThree_blocking": "none", + "IPH_ScalableIphUnlockedBasedThree_event_1": "name:ScalableIphUnlocked;comparator:>=2;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedThree_event_precondition_personalization_app": "name:ScalableIphOpenPersonalizationApp;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedThree_event_trigger": "name:ScalableIphUnlockedBasedThreeTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedThree_event_used": "name:ScalableIphUnlockedBasedThreeEventUsed;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedThree_session_rate": "any", + "IPH_ScalableIphUnlockedBasedThree_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleButtonText": "Select wallpaper", + "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleId": "scalable_iph_unlocked_based_three", + "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleText": "Make your Chromebook uniquely yours with a new wallpaper", + "IPH_ScalableIphUnlockedBasedThree_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedThree_x_CustomButtonActionType": "OpenPersonalizationApp", + "IPH_ScalableIphUnlockedBasedThree_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedThree_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedThree_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedThree_x_CustomVersionNumber": "1", + "IPH_ScalableIphUnlockedBasedTwo_availability": "any", + "IPH_ScalableIphUnlockedBasedTwo_blocked_by": "none", + "IPH_ScalableIphUnlockedBasedTwo_blocking": "none", + "IPH_ScalableIphUnlockedBasedTwo_event_1": "name:ScalableIphUnlocked;comparator:>=1;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTwo_event_precondition_launcher": "name:ScalableIphAppListShown;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTwo_event_trigger": "name:ScalableIphUnlockedBasedTwoTriggered;comparator:==0;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTwo_event_used": "name:ScalableIphAppListShown;comparator:any;window:7;storage:8", + "IPH_ScalableIphUnlockedBasedTwo_session_rate": "any", + "IPH_ScalableIphUnlockedBasedTwo_session_rate_impact": "none", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomBubbleId": "scalable_iph_unlocked_based_two", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomBubbleText": "Search and find your apps in the Launcher \u25c9", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomBubbleTitle": "Welcome Tips", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomConditionClientAgeInDays": "6", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomConditionNetworkConnection": "Online", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomUiType": "Bubble", + "IPH_ScalableIphUnlockedBasedTwo_x_CustomVersionNumber": "1" + }, + "enable_features": [ + "IPH_ScalableIphUnlockedBasedEight", + "IPH_ScalableIphUnlockedBasedFive", + "IPH_ScalableIphUnlockedBasedFour", + "IPH_ScalableIphUnlockedBasedNine", + "IPH_ScalableIphUnlockedBasedOne", + "IPH_ScalableIphUnlockedBasedSeven", + "IPH_ScalableIphUnlockedBasedSix", + "IPH_ScalableIphUnlockedBasedTen", + "IPH_ScalableIphUnlockedBasedThree", + "IPH_ScalableIphUnlockedBasedTwo", + "ScalableIph" + ], + "disable_features": [ + "ShelfLauncherNudge" + ] + } + ] + } + ], + "ScaleScrollbarAnimationTiming": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "fade_delay_scaling_factor": "2.0", + "fade_duration_scaling_factor": "0.5" + }, + "enable_features": [ + "ScaleScrollbarAnimationTiming" + ] + } + ] + } + ], + "SchedQoS": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SchedQoSOnResourcedForChrome" + ], + "min_os_version": "15849.0.0" + } + ] + } + ], + "ScreenCaptureKitMacScreen": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ScreenCaptureKitMacScreen" + ] + } + ] + } + ], + "ScreencastForceEnableServerSideSpeechRecognition": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "enable_features": [ + "ForceEnableServerSideSpeechRecognitionForDev" + ] + } + ] + } + ], + "ScreencastGm3": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ProjectorGm3" + ] + } + ] + } + ], + "ScreencastServerBasedUSMLocales": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled_Dogfood", + "enable_features": [ + "InternalServerSideSpeechRecognitionByFinch" + ] + } + ] + } + ], + "ScreencastServerBasedUSMRNNTLocales": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "InternalServerSideSpeechRecognitionUSMModelFinch" + ] + } + ] + } + ], + "ScreenlockReauthPromoCard": [ + { + "platforms": [ + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ScreenlockReauthPromoCard" + ] + } + ] + } + ], + "SeaPen": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "FeatureManagementSeaPen", + "SeaPen" + ] + } + ] + } + ], + "SeaPenTextInput": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SeaPenTextInput" + ] + } + ] + } + ], + "SeaPenUseExptTemplate": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SeaPenUseExptTemplate" + ] + } + ] + } + ], + "SearchEngineChoiceAttribution": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "SearchEngineChoiceAttribution" + ] + }, + { + "name": "Enabled", + "enable_features": [ + "SearchEngineChoiceAttribution" + ] + } + ] + } + ], + "SearchInCCT": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "omnibox_allowed_package_names": "org.chromium.customtabsclient" + }, + "enable_features": [ + "SearchInCCT" + ] + } + ] + } + ], + "SearchPrefetchHighPriorityPrefetches": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledHighPriorityBothTriggers_20230721", + "params": { + "mouse_down": "true", + "navigation_prefetch_param": "op", + "up_or_down": "true" + }, + "enable_features": [ + "SearchNavigationPrefetch" + ] + } + ] + } + ], + "SearchPrefetchHighPriorityPrefetchesAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnabledSearchNavigationPrefetchAndTouchDownTrigger_20231110", + "params": { + "navigation_prefetch_param": "op", + "touch_down": "true" + }, + "enable_features": [ + "OmniboxTouchDownTriggerForPrefetch", + "SearchNavigationPrefetch" + ] + } + ] + } + ], + "SearchReadyOmniboxAllowQueryEdit": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SearchReadyOmniboxAllowQueryEdit" + ] + } + ] + } + ], + "SearchWebInSidePanel": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SearchWebInSidePanel" + ] + } + ] + } + ], + "SecagentdEnableXDRNetworkEvents": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootSecagentdXDRNetworkEvents" + ] + } + ] + } + ], + "SecurityPageHats": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "probability": "0.5", + "security-page-time": "15s", + "security-page-trigger-id": "c4dvJ3Sz70ugnJ3q1cK0SkwJZodD" + }, + "enable_features": [ + "HappinessTrackingSurveysForSecurityPage" + ] + } + ] + } + ], + "SegmentationCompactionFix": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SegmentationCompactionFix" + ] + } + ] + } + ], + "SegmentationPlatformURLVisitResumptionRanker": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "use_random_score": "true" + }, + "enable_features": [ + "SegmentationPlatformURLVisitResumptionRanker" + ] + } + ] + } + ], + "SegmentationPlatformUmaFromSqlDb": [ + { + "platforms": [ + "android", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SegmentationPlatformUmaFromSqlDb" + ] + } + ] + } + ], + "SendTabToSelfV2": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SendTabToSelfV2" + ] + } + ] + } + ], + "SerializeAccessibilityPostLifecycle": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Baseline", + "enable_features": [ + "SerializeAccessibilityPostLifecycle" + ] + }, + { + "name": "HoldBack", + "disable_features": [ + "SerializeAccessibilityPostLifecycle" + ] + } + ] + } + ], + "ServerBasedTranscriptionForScreencast": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "InternalServerSideSpeechRecognition" + ] + } + ] + } + ], + "ServiceWorkerAutoPreload": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "respect_navigation_preload": "true", + "script_checksum_to_bypass": "144B3D5485B621F5896FD51D6A6FE66A07B6DBC3ACF6404748A833C2D592F900", + "use_allowlist": "true" + }, + "enable_features": [ + "ServiceWorkerAutoPreload", + "ServiceWorkerBypassFetchHandlerHashStrings" + ] + } + ] + } + ], + "ServiceWorkerAvoidMainThreadForInitialization": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ServiceWorkerAvoidMainThreadForInitialization" + ] + } + ] + } + ], + "ServiceWorkerDebugCorsExemptHeaderList": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ServiceWorkerDebugCorsExemptHeaderList" + ] + } + ] + } + ], + "ServiceWorkerStaticRouter": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ServiceWorkerStaticRouter" + ] + } + ] + } + ], + "ServiceWorkerStorageControl": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ServiceWorkerStorageControlOnIOThread", + "ServiceWorkerStorageControlResponseQueue" + ] + } + ] + } + ], + "ShareCustomActionsInCCT": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ShareCustomActionsInCCT" + ] + } + ] + } + ], + "ShareThisTabDialog": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ShareThisTabDialog" + ] + } + ] + } + ], + "SharedHighlightingAmp": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SharedHighlightingAmp" + ] + } + ] + } + ], + "SharedHighlightingIphClank": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_1": "name:iph_shared_highlighting_receiver_trigger;comparator:==0;window:7;storage:360", + "event_trigger": "name:iph_shared_highlighting_receiver_trigger;comparator:<5;window:360;storage:360", + "event_used": "name:iph_shared_highlighting_used;comparator:<2;window:360;storage:360", + "session_rate": "any" + }, + "enable_features": [ + "IPH_SharedHighlightingBuilder", + "IPH_SharedHighlightingReceiver" + ] + } + ] + } + ], + "SharedHighlightingIphDesktop": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_1": "name:iph_desktop_shared_highlighting_trigger;comparator:==0;window:7;storage:360", + "event_trigger": "name:iph_desktop_shared_highlighting_trigger;comparator:<5;window:360;storage:360", + "event_used": "name:iph_desktop_shared_highlighting_used;comparator:<2;window:360;storage:360", + "session_rate": "any" + }, + "enable_features": [ + "IPH_DesktopSharedHighlighting" + ] + } + ] + } + ], + "SharedStorageWorkletThreadImplementation": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "SharedBackingThread", + "enable_features": [ + "SharedStorageWorkletSharedBackingThreadImplementation" + ] + } + ] + } + ], + "SharedWorkerBlobURLFix": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SharedWorkerBlobURLFix" + ] + } + ] + } + ], + "SharingHubDesktopScreenshots": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DesktopScreenshots" + ] + } + ] + } + ], + "ShelfStackedHotseat": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ShelfStackedHotseat" + ] + } + ] + } + ], + "ShortCircuitUnfocusAnimation": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ShortCircuitUnfocusAnimation" + ] + } + ] + } + ], + "ShowSuggestionsOnAutofocus": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ShowSuggestionsOnAutofocus" + ] + } + ] + } + ], + "SidePanelCompanionDesktopM116Plus": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnableCompanionChromeOS_20240222", + "params": { + "open-companion-for-image-search": "false", + "open-companion-for-web-search": "false", + "open-contextual-lens-panel": "false", + "open-links-in-current-tab": "false" + }, + "enable_features": [ + "SidePanelCompanion", + "SidePanelCompanionChromeOS", + "VisualQuerySuggestions" + ], + "disable_features": [ + "SideSearch" + ] + } + ] + } + ], + "SidePanelJourneys": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "SidePanelJourneysOpensFromOmnibox": "true" + }, + "enable_features": [ + "SidePanelJourneys" + ] + } + ] + } + ], + "SidePanelPinningWithResponsiveToolbar": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledWithSidePanelPinning", + "enable_features": [ + "IPH_SidePanelGenericMenuFeature", + "IPH_SidePanelGenericPinnableFeature", + "ResponsiveToolbar", + "SidePanelPinning" + ] + }, + { + "name": "EnabledWithoutSidePanelPinning", + "enable_features": [ + "ResponsiveToolbar" + ] + } + ] + } + ], + "SideSearchInProductHelp": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_trigger": "name:side_search_iph_tgr;comparator:==0;window:90;storage:360", + "event_used": "name:side_search_opened;comparator:==0;window:90;storage:360", + "session_rate": "<3" + }, + "enable_features": [ + "IPH_SideSearch" + ] + } + ] + } + ], + "SimplifyLoadingTransparentPlaceholderImage": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240610", + "enable_features": [ + "OptimizeLoadingDataUrls", + "SimplifyLoadingTransparentPlaceholderImage" + ] + } + ] + } + ], + "SingleNTPRemoveExtraNTPs": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled_SingleNTP_RemoveExtraNTP", + "enable_features": [ + "RemoveExcessNTPs", + "SingleNTP" + ] + }, + { + "name": "Enabled_SingleNTP", + "enable_features": [ + "SingleNTP" + ] + }, + { + "name": "Enabled_RemoveExtraNTP", + "enable_features": [ + "RemoveExcessNTPs" + ] + } + ] + } + ], + "SingleVideoFrameRateThrottling": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SingleVideoFrameRateThrottling" + ] + } + ] + } + ], + "SkiaFontService": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SkiaFontService" + ] + } + ] + } + ], + "SkiaGraphite": [ + { + "platforms": [ + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SkiaGraphite" + ] + } + ] + } + ], + "SkipUnnecessaryThreadHopsForParseHeaders": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SkipUnnecessaryThreadHopsForParseHeaders" + ] + } + ] + } + ], + "SkyVaultGA": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled_SkyVaultV2", + "enable_features": [ + "SkyVaultV2" + ] + } + ] + } + ], + "SkyVaultTTBeta": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled_SkyVault", + "enable_features": [ + "SkyVault" + ] + } + ] + } + ], + "SmartZoom": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SmartZoom" + ] + } + ] + } + ], + "SnackbarUseLegacyDismissalBehavior": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SnackbarUseLegacyDismissalBehavior" + ] + } + ] + } + ], + "SnapGroup": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SnapGroup" + ] + } + ] + } + ], + "SnapshotInSwift": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SnapshotInSwift" + ] + } + ] + } + ], + "SonomaAccessibilityActivationRefinements": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SonomaAccessibilityActivationRefinements" + ] + } + ] + } + ], + "SpdyHeadersToHttpResponseUseBuilder": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SpdyHeadersToHttpResponseUseBuilder" + ] + } + ] + } + ], + "SpeculativeServiceWorkerWarmUp": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "StayPrewarmed10m_20240315", + "params": { + "sw_warm_up_batch_timer": "1ms", + "sw_warm_up_dry_run": "false", + "sw_warm_up_first_batch_timer": "1ms", + "sw_warm_up_intersection_observer": "false", + "sw_warm_up_on_idle_timeout": "true", + "sw_warm_up_on_pointerdown": "true", + "sw_warm_up_on_pointerover": "true", + "sw_warm_up_on_visible": "false", + "sw_warm_up_wait_for_load": "false" + }, + "enable_features": [ + "SpeculativeServiceWorkerWarmUp" + ], + "disable_features": [ + "SpeculativeServiceWorkerStartup" + ] + } + ] + } + ], + "SplitCacheByNetworkIsolationKey": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "//0": "This feature has shipped for Chrome but not for ", + "//1": "Chromium embedders, so the corresponding feature ", + "//2": "flag value is false but we rely on this entry to ", + "//3": "enable the feature for most types of tests", + "name": "EnableFeatureForTests", + "enable_features": [ + "SplitCacheByNetworkIsolationKey" + ] + } + ] + } + ], + "StaleStorageCleanup": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Auto_Dogfood", + "enable_features": [ + "DeleteStaleLocalStorageOnStartup", + "DeleteStaleSessionCookiesOnStartup", + "EvictStaleQuotaStorage" + ] + }, + { + "name": "Opt_In_Dogfood", + "enable_features": [ + "DeleteStaleLocalStorageOnStartup", + "DeleteStaleSessionCookiesOnStartup", + "EvictStaleQuotaStorage" + ] + } + ] + } + ], + "StandardizedBrowserZoom": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "StandardizedBrowserZoom" + ] + } + ] + } + ], + "StartupImprovements": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableStartupImprovements" + ] + } + ] + } + ], + "StorageBuckets": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "StorageBuckets" + ] + } + ] + } + ], + "StreamlineRendererInit": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "StreamlineRendererInit" + ] + } + ] + } + ], + "StructuredMetricsExternalMetrics": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "UploadCadence20ReadCadence5", + "params": { + "external_metrics_collection_interval_in_seconds": "300", + "upload_time_in_seconds": "1200" + }, + "enable_features": [ + "EnableStructuredMetrics", + "EnableStructuredMetricsService" + ] + }, + { + "name": "UploadCadence10ReadCadence3", + "params": { + "external_metrics_collection_interval_in_seconds": "180", + "upload_time_in_seconds": "600" + }, + "enable_features": [ + "EnableStructuredMetrics", + "EnableStructuredMetricsService" + ] + }, + { + "name": "UploadCadence20", + "params": { + "upload_time_in_seconds": "1200" + }, + "enable_features": [ + "EnableStructuredMetrics", + "EnableStructuredMetricsService" + ] + }, + { + "name": "StructuredMetricsExternalMetrics_100_20231027", + "params": { + "file_limit": "100" + }, + "enable_features": [ + "EnableStructuredMetrics" + ] + }, + { + "name": "StructuredMetricsExternalMetrics_70_20231027", + "params": { + "file_limit": "70" + }, + "enable_features": [ + "EnableStructuredMetrics" + ] + } + ] + } + ], + "SuppressToolbarCaptures": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "SuppressionBlockFullscreen_20231004", + "params": { + "block_for_fullscreen": "true" + }, + "enable_features": [ + "SuppressToolbarCaptures" + ] + } + ] + } + ], + "SuppressToolbarCapturesAtGestureEndStudy": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableGestureBeginEndTypes", + "SuppressToolbarCapturesAtGestureEnd" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "EnableGestureBeginEndTypes", + "SuppressToolbarCapturesAtGestureEnd" + ] + }, + { + "name": "Enabled_GestureBeginEndTypes", + "enable_features": [ + "EnableGestureBeginEndTypes" + ], + "disable_features": [ + "SuppressToolbarCapturesAtGestureEnd" + ] + } + ] + } + ], + "SuppressesLoadingPredictorOnSlowNetwork": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "slow_network_threshold": "208ms" + }, + "enable_features": [ + "SuppressesLoadingPredictorOnSlowNetwork" + ] + } + ] + } + ], + "SyncIncreaseNudgeDelayForSingleClient": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledFactor2", + "params": { + "SyncIncreaseNudgeDelayForSingleClientFactor": "2.0" + }, + "enable_features": [ + "SyncIncreaseNudgeDelayForSingleClient" + ] + } + ] + } + ], + "SyncSegmentsData": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SyncSegmentsData" + ] + } + ] + } + ], + "SysUiHoldbackStudy": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Default", + "disable_features": [ + "SysUiShouldHoldbackGifRecording", + "SysUiShouldHoldbackTaskManagement" + ] + }, + { + "name": "SysUiHoldbackStudy", + "enable_features": [ + "SysUiShouldHoldbackGifRecording", + "SysUiShouldHoldbackTaskManagement" + ] + }, + { + "name": "NoFirstPartyIntegrations", + "enable_features": [ + "SysUiShouldHoldbackTaskManagement" + ], + "disable_features": [ + "SysUiShouldHoldbackGifRecording" + ] + } + ] + } + ], + "SystemEmojiPickerGIFSupportByDefault": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SystemEmojiPickerGIFSupport" + ] + } + ] + } + ], + "SystemInfoAnswerCardsInLauncher": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LauncherSystemInfoAnswerCards" + ] + } + ] + } + ], + "TabAudioMuting": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_trigger": "name:tab_audio_muting_iph_triggered;comparator:==0;window:120;storage:365", + "event_used": "name:tab_audio_muting_toggle_viewed;comparator:==0;window:120;storage:365", + "session_rate": "==0" + }, + "enable_features": [ + "IPH_TabAudioMuting", + "TabAudioMuting" + ] + } + ] + } + ], + "TabGroupCreationDialogAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabGroupCreationDialogAndroid" + ] + } + ] + } + ], + "TabGroupParityAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "skip_tab_group_creation_dialog": "true" + }, + "enable_features": [ + "TabGroupParityAndroid", + "TabStripGroupIndicatorsAndroid" + ] + } + ] + } + ], + "TabGroupSyncAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabGroupPaneAndroid", + "TabGroupSyncAndroid", + "TabStripGroupCollapseAndroid" + ] + } + ] + } + ], + "TabGroupsCollapseFreezing": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "TabGroupsCollapseFreezing" + ] + } + ] + } + ], + "TabGroupsSaveUIUpdateAndSaveV2": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabGroupsSaveUIUpdate", + "TabGroupsSaveV2" + ] + } + ] + } + ], + "TabHoverCardImagesMacArm": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabHoverCardImages" + ] + } + ] + } + ], + "TabOrganization": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "trigger_period": "30m" + }, + "enable_features": [ + "TabOrganization" + ] + } + ] + } + ], + "TabSearchInProductHelp": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "TabSearchIPH", + "params": { + "availability": "any", + "event_trigger": "name:tab_search_iph_tgr;comparator:==0;window:90;storage:360", + "event_used": "name:tab_search_opened;comparator:==0;window:90;storage:360", + "session_rate": "<3" + }, + "enable_features": [ + "IPH_TabSearch" + ] + } + ] + } + ], + "TabStateFlatBuffer": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20240713", + "params": { + "migrate_stale_tabs": "true" + }, + "enable_features": [ + "TabStateFlatBuffer" + ] + } + ] + } + ], + "TabStripCollectionStorage": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabStripCollectionStorage" + ] + } + ] + } + ], + "TabStripStartupRefactoring": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TabStripStartupRefactoring" + ] + } + ] + } + ], + "TailoredSecurityIntegration": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "TailoredSecurityIntegration", + "enable_features": [ + "TailoredSecurityIntegration" + ] + } + ] + } + ], + "TailoredSecurityIntegrationAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20220302", + "enable_features": [ + "TailoredSecurityIntegration" + ] + } + ] + } + ], + "TextInputHostMojoCapabilityControlWorkaround": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TextInputHostMojoCapabilityControlWorkaround" + ] + } + ] + } + ], + "TextSizeAdjustImprovements": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TextSizeAdjustImprovements" + ] + } + ] + } + ], + "TheoraVideoCodec": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "TheoraVideoCodec" + ] + } + ] + } + ], + "ThirdPartyScriptDetection": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ThirdPartyScriptDetection" + ] + } + ] + } + ], + "ThreadCacheMinCachedMemoryForPurging": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "size_500kb_20230909", + "params": { + "ThreadCacheMinCachedMemoryForPurgingBytes": "512000" + }, + "enable_features": [ + "EnableConfigurableThreadCacheMinCachedMemoryForPurging" + ] + } + ] + } + ], + "ThreadCachePurgeInterval": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "interval_1_2_60_20230909", + "params": { + "ThreadCacheDefaultPurgeInterval": "2s", + "ThreadCacheMaxPurgeInterval": "60s", + "ThreadCacheMinPurgeInterval": "1s" + }, + "enable_features": [ + "EnableConfigurableThreadCachePurgeInterval" + ] + } + ] + } + ], + "ThreadGroupSemaphore": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "max_num_workers_created": "8" + }, + "enable_features": [ + "ThreadGroupSemaphore" + ] + } + ] + } + ], + "ThreadPoolCap2": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledWithRestricted3_20230907", + "params": { + "restricted_count": "3" + }, + "enable_features": [ + "ThreadPoolCap2" + ] + } + ] + } + ], + "ThreadedBodyLoader": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "PrecompileMainFrameNoWait_20240520", + "params": { + "compile-in-parallel": "false", + "compile-strategy": "lazy", + "inline-script-timeout": "0ms", + "precompile-main-frame-only": "true" + }, + "enable_features": [ + "PrecompileInlineScripts" + ], + "disable_features": [ + "ThreadedBodyLoader", + "ThreadedPreloadScanner" + ] + } + ] + } + ], + "ThrottleUnimportantFrameTimers": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ThrottleUnimportantFrameTimers" + ] + } + ] + } + ], + "TimedHTMLParserBudget": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "group_10_500_6_20230911", + "params": { + "default-parser-budget": "10ms", + "long-parser-budget": "500ms", + "num-yields-with-default-budget": "6" + }, + "enable_features": [ + "TimedHTMLParserBudget" + ] + } + ] + } + ], + "TimerSlackMac": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AlignWakeUps", + "TimerSlackMac" + ] + } + ] + } + ], + "ToolbarPinning": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ToolbarPinning" + ] + } + ] + } + ], + "TopChromeWebUIUsesSpareRenderer": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TopChromeWebUIUsesSpareRenderer" + ] + } + ] + } + ], + "TopLevelThirdPartyCookieDeprecationTrialService": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TopLevelTpcdSupportSettings" + ] + } + ] + } + ], + "TouchpadFastClickStudy": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableFastTouchpadClick" + ] + } + ] + } + ], + "TrackingProtection3pcd": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TrackingProtection3pcd" + ] + } + ] + } + ], + "TrackpadDropdownMenu": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20230829", + "enable_features": [ + "MouseAndTrackpadDropdownMenu" + ] + } + ] + } + ], + "TrackpadGestureSupport": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_20230829", + "enable_features": [ + "ConvertTrackpadEventsToMouse" + ] + } + ] + } + ], + "TransportSecurityFileWriterSchedule": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled1Minute_20240626", + "params": { + "commit_interval": "1m" + }, + "enable_features": [ + "TransportSecurityFileWriterSchedule" + ] + } + ] + } + ], + "TrustSafetySentimentSurvey": [ + { + "platforms": [ + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "max-time-to-prompt": "60m", + "min-time-to-prompt": "2m", + "ntp-visits-max-range": "4", + "ntp-visits-min-range": "2", + "privacy-sandbox-3-consent-accept-probability": "0.2", + "privacy-sandbox-3-consent-accept-trigger-id": "5t9KNsR4e0ugnJ3q1cK0RPfRpsbm", + "privacy-sandbox-3-consent-decline-probability": "0.2", + "privacy-sandbox-3-consent-decline-trigger-id": "P5svv2BbH0ugnJ3q1cK0YhTWZkiM", + "privacy-sandbox-3-notice-dismiss-probability": "0.2", + "privacy-sandbox-3-notice-dismiss-trigger-id": "2gMg6iHpn0ugnJ3q1cK0XyL2C2EX", + "privacy-sandbox-3-notice-ok-probability": "0.2", + "privacy-sandbox-3-notice-ok-trigger-id": "vBraRD9GZ0ugnJ3q1cK0T1owvGGa", + "privacy-sandbox-3-notice-settings-probability": "0.2", + "privacy-sandbox-3-notice-settings-trigger-id": "WZpnNehvi0ugnJ3q1cK0Nsdcf1Vf", + "privacy-settings-probability": "0.0", + "probability": "1.0", + "transactions-probability": "0.0", + "trusted-surface-probability": "0.0" + }, + "enable_features": [ + "TrustSafetySentimentSurvey" + ] + } + ] + } + ], + "TrustSafetySentimentSurveyV2": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20240212", + "params": { + "browsing-data-probability": "0.0", + "browsing-data-trigger-id": "1iSgej9Tq0ugnJ3q1cK0QwXZ12oo", + "control-group-probability": "0.0", + "control-group-trigger-id": "CXMbsBddw0ugnJ3q1cK0QJM1Hu8m", + "download-warning-ui-probability": "0.0", + "download-warning-ui-trigger-id": "7SS4sg4oR0ugnJ3q1cK0TNvCvd8U", + "max-time-to-prompt": "60m", + "min-session-time": "30s", + "min-time-to-prompt": "2m", + "ntp-visits-max-range": "4", + "ntp-visits-min-range": "2", + "password-check-probability": "0.0", + "password-check-trigger-id": "Xd54YDVNJ0ugnJ3q1cK0UYBRruNH", + "password-protection-ui-probability": "0.0", + "password-protection-ui-trigger-id": "bQBRghu5w0ugnJ3q1cK0RrqdqVRP", + "privacy-guide-probability": "0.0", + "privacy-guide-trigger-id": "tqR1rjeDu0ugnJ3q1cK0P9yJEq7Z", + "probability": "0.0", + "safe-browsing-interstitial-probability": "0.0", + "safe-browsing-interstitial-trigger-id": "Z9pSWP53n0ugnJ3q1cK0Y6YkGRpU", + "safety-check-probability": "0.0", + "safety-check-trigger-id": "YSDfPVMnX0ugnJ3q1cK0RxEhwkay", + "safety-hub-interaction-probability": "0.0", + "safety-hub-interaction-trigger-id": "TZq2S4frt0ugnJ3q1cK0Q5Yd4YJM", + "safety-hub-notification-probability": "0.0", + "safety-hub-notification-trigger-id": "kJV17f8Lv0ugnJ3q1cK0Nptk37ct", + "trusted-surface-probability": "0.0", + "trusted-surface-time": "5s", + "trusted-surface-trigger-id": "CMniDmzgE0ugnJ3q1cK0U6PaEn1f" + }, + "enable_features": [ + "TrustSafetySentimentSurveyV2" + ] + } + ] + } + ], + "TrustTokenOriginTrial": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "TrustTokenOperationsRequiringOriginTrial": "all-operations-require-origin-trial" + }, + "enable_features": [ + "TrustTokens" + ] + } + ] + } + ], + "TurnOffStreamingMediaCachingAlways": [ + { + "platforms": [ + "android", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TurnOffStreamingMediaCachingAlways" + ] + } + ] + } + ], + "UIEnableSharedImageCacheForGpu": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UIEnableSharedImageCacheForGpu" + ] + } + ] + } + ], + "UIPumpImprovementsWin": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UIPumpImprovementsWin" + ] + } + ] + } + ], + "UMA-NonUniformity-Trial-1-Percent": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "ios", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "group_01", + "params": { + "delta": "0.01" + }, + "enable_features": [ + "UMANonUniformityLogNormal" + ] + } + ] + } + ], + "UMA-Pseudo-Metrics-Effect-Injection-25-Percent": [ + { + "platforms": [ + "android", + "ios", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "BigEffect_01", + "params": { + "multiplicative_factor": "1.05" + }, + "enable_features": [ + "UMAPseudoMetricsEffect" + ] + } + ] + } + ], + "UPMClearMigratedDataStudy": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ClearLoginDatabaseForAllMigratedUPMUsers" + ] + } + ] + } + ], + "USSMigrationEnabled": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CrOSLateBootMigrateToUserSecretStash" + ] + } + ] + } + ], + "UiaProviderWin": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UiaProvider" + ] + } + ] + } + ], + "UnblockTouchMoveEarlier": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UnblockTouchMoveEarlier" + ] + } + ] + } + ], + "UnifiedAutoplay": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PreloadMediaEngagementData" + ] + } + ] + } + ], + "UnoDesktopM0Full": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ExplicitBrowserSigninUIOnDesktop", + "SyncEnableContactInfoDataTypeInTransportMode" + ] + } + ] + } + ], + "UnoPhase2Android": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Phase2", + "enable_features": [ + "EnablePasswordsAccountStorageForNonSyncingUsers", + "FeedBottomSyncStringRemoval", + "HideSettingsSignInPromo", + "ReadingListEnableSyncTransportModeUponSignIn", + "ReplaceSyncPromosWithSignInPromos", + "RestoreSignedInAccountAndSettingsFromBackup", + "SyncEnableContactInfoDataTypeForCustomPassphraseUsers", + "SyncEnableContactInfoDataTypeInTransportMode", + "SyncEnableWalletMetadataInTransportMode", + "SyncEnableWalletOfferInTransportMode", + "UpdateMetricsServicesStateInRestore" + ] + } + ] + } + ], + "UnthrottledTabProcessReporting": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UnthrottledTabProcessReporting" + ] + } + ] + } + ], + "UploadOfficeToCloud": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UploadOfficeToCloud" + ] + } + ] + } + ], + "UseAppBoundEncryptionProviderForEncryption": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseAppBoundEncryptionProviderForEncryption" + ] + } + ] + } + ], + "UseBoringSSLForRandBytes": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseBoringSSLForRandBytes" + ], + "disable_features": [ + "UseGetrandomForRandBytes" + ] + } + ] + } + ], + "UseBuiltInMetalShaderCache": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseBuiltInMetalShaderCache" + ] + } + ] + } + ], + "UseClientGmbInterface": [ + { + "platforms": [ + "android", + "android_webview", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseClientGmbInterface" + ] + } + ] + } + ], + "UseContextSnapshot": [ + { + "platforms": [ + "android", + "android_webview", + "android_weblayer" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseContextSnapshot" + ] + } + ] + } + ], + "UseDMSAAForTiles": [ + { + "platforms": [ + "android", + "android_webview", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "fuchsia", + "ios", + "linux", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseDMSAAForTiles" + ] + } + ] + } + ], + "UseDMSAAForTilesAndroidGL": [ + { + "platforms": [ + "android", + "android_webview", + "android_weblayer" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseDMSAAForTilesAndroidGL" + ] + } + ] + } + ], + "UseEncryptedReportingPipelineToReportArcAppInstallEvents": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseEncryptedReportingPipelineToReportArcAppInstallEvents" + ] + } + ] + } + ], + "UseFusedLocationProvider": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseFusedLocationProvider" + ] + } + ] + } + ], + "UseGMSCoreForBrandingInfo": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseGMSCoreForBrandingInfo" + ] + } + ] + } + ], + "UseGpuSchedulerDfs": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseGpuSchedulerDfs" + ] + } + ] + } + ], + "UseItemSnippetsAPI": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseItemSnippetsAPI" + ] + } + ] + }, + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "//0": "TODO(crbug.com/325314721): Enable the experiment", + "//1": "for chromeos once test migration for the new API", + "//2": "has been completed.", + "name": "Disabled", + "disable_features": [ + "UseItemSnippetsAPI" + ] + } + ] + } + ], + "UseMoveNotCopyInAXTreeCombiner": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseMoveNotCopyInAXTreeCombiner" + ] + } + ] + } + ], + "UseMoveNotCopyInMergeTreeUpdate": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseMoveNotCopyInMergeTreeUpdate" + ] + } + ] + } + ], + "UseSmartRefForGPUFenceHandle": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseSmartRefForGPUFenceHandle" + ] + } + ] + } + ], + "UseSnappyForParkableStrings": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseSnappyForParkableStrings" + ] + } + ] + } + ], + "UseThreadPriorityLowest": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UseThreadPriorityLowest" + ] + } + ] + } + ], + "UserBypassUI": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "expiration": "90d" + }, + "enable_features": [ + "UserBypassUI" + ] + } + ] + } + ], + "UserEducationV2Study": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UserEducationExperienceVersion2" + ] + } + ] + } + ], + "UserLevelMemoryPressureSignalOn4GbDevices": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled_default", + "params": { + "inert_interval_after_loading": "5m", + "memory_threshold_mb": "458" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn4GbDevices" + ] + }, + { + "name": "Enabled_99p_5m", + "params": { + "inert_interval_after_loading": "5m", + "memory_threshold_mb": "803" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn4GbDevices" + ] + }, + { + "name": "Enabled_99p_1m", + "params": { + "inert_interval_after_loading": "1m", + "memory_threshold_mb": "803" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn4GbDevices" + ] + }, + { + "name": "Enabled_95p_5m", + "params": { + "inert_interval_after_loading": "5m", + "memory_threshold_mb": "508" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn4GbDevices" + ] + }, + { + "name": "Enabled_95p_1m", + "params": { + "inert_interval_after_loading": "1m", + "memory_threshold_mb": "508" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn4GbDevices" + ] + }, + { + "name": "Enabled_90p_5m", + "params": { + "inert_interval_after_loading": "5m", + "memory_threshold_mb": "405" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn4GbDevices" + ] + }, + { + "name": "Enabled_90p_1m", + "params": { + "inert_interval_after_loading": "1m", + "memory_threshold_mb": "405" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn4GbDevices" + ] + } + ] + } + ], + "UserLevelMemoryPressureSignalOn6GbDevices": [ + { + "platforms": [ + "android", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled_default", + "params": { + "inert_interval_after_loading": "5m", + "memory_threshold_mb": "494" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn6GbDevices" + ] + }, + { + "name": "Enabled_99p_5m", + "params": { + "inert_interval_after_loading": "5m", + "memory_threshold_mb": "924" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn6GbDevices" + ] + }, + { + "name": "Enabled_99p_1m", + "params": { + "inert_interval_after_loading": "1m", + "memory_threshold_mb": "924" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn6GbDevices" + ] + }, + { + "name": "Enabled_95p_5m", + "params": { + "inert_interval_after_loading": "5m", + "memory_threshold_mb": "580" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn6GbDevices" + ] + }, + { + "name": "Enabled_95p_1m", + "params": { + "inert_interval_after_loading": "1m", + "memory_threshold_mb": "580" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn6GbDevices" + ] + }, + { + "name": "Enabled_90p_5m", + "params": { + "inert_interval_after_loading": "5m", + "memory_threshold_mb": "460" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn6GbDevices" + ] + }, + { + "name": "Enabled_90p_1m", + "params": { + "inert_interval_after_loading": "1m", + "memory_threshold_mb": "460" + }, + "enable_features": [ + "UserLevelMemoryPressureSignalOn6GbDevices" + ] + } + ] + } + ], + "UsernameFirstFlowWithIntermediateValuesPredictions": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UsernameFirstFlowWithIntermediateValuesPredictions" + ] + } + ] + } + ], + "V8CodeFlushing": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "FlushCodeBasedOnTime60", + "params": { + "V8FlushCodeOldTime": "60" + }, + "enable_features": [ + "V8FlushCodeBasedOnTime" + ], + "disable_features": [ + "V8FlushCodeBasedOnTabVisibility" + ] + }, + { + "name": "FlushCodeBasedOnTime10", + "params": { + "V8FlushCodeOldTime": "10" + }, + "enable_features": [ + "V8FlushCodeBasedOnTime" + ], + "disable_features": [ + "V8FlushCodeBasedOnTabVisibility" + ] + }, + { + "name": "FlushCodeBasedOnTime30", + "params": { + "V8FlushCodeOldTime": "30" + }, + "enable_features": [ + "V8FlushCodeBasedOnTime" + ], + "disable_features": [ + "V8FlushCodeBasedOnTabVisibility" + ] + }, + { + "name": "FlushCodeBasedOnTime45", + "params": { + "V8FlushCodeOldTime": "45" + }, + "enable_features": [ + "V8FlushCodeBasedOnTime" + ], + "disable_features": [ + "V8FlushCodeBasedOnTabVisibility" + ] + }, + { + "name": "FlushCodeBasedOnTime180", + "params": { + "V8FlushCodeOldTime": "180" + }, + "enable_features": [ + "V8FlushCodeBasedOnTime" + ], + "disable_features": [ + "V8FlushCodeBasedOnTabVisibility" + ] + }, + { + "name": "FlushCodeBasedOnTabVisibility", + "enable_features": [ + "V8FlushCodeBasedOnTabVisibility" + ], + "disable_features": [ + "V8FlushCodeBasedOnTime" + ] + } + ] + } + ], + "V8CompileHints3": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Disabled", + "disable_features": [ + "ProduceCompileHints2" + ] + }, + { + "name": "Enabled", + "enable_features": [ + "ProduceCompileHints2" + ] + } + ] + } + ], + "V8CppGCEnableLargerCage": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "V8CppGCEnableLargerCage" + ] + } + ] + } + ], + "V8EfficiencyModeTiering": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Delay10k", + "params": { + "V8EfficiencyModeTieringDelayTurbofan": "10000" + }, + "enable_features": [ + "V8EfficiencyModeTiering" + ] + }, + { + "name": "NoTurbofan", + "params": { + "V8EfficiencyModeTieringDelayTurbofan": "0" + }, + "enable_features": [ + "V8EfficiencyModeTiering" + ] + }, + { + "name": "Delay15k", + "params": { + "V8EfficiencyModeTieringDelayTurbofan": "15000" + }, + "enable_features": [ + "V8EfficiencyModeTiering" + ] + }, + { + "name": "Control", + "disable_features": [ + "V8EfficiencyModeTiering" + ] + } + ] + } + ], + "V8FlushBaselineCode": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "V8FlushBaselineCode" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "V8FlushBaselineCode" + ] + } + ] + } + ], + "V8GCOptimizeSweepForMutator": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "V8GCOptimizeSweepForMutator" + ] + } + ] + } + ], + "V8IntelJCCErratumMitigation": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "EnabledNoSlowHistogram", + "enable_features": [ + "V8IntelJCCErratumMitigation" + ] + }, + { + "name": "Enabled", + "enable_features": [ + "V8IntelJCCErratumMitigation", + "V8SlowHistogramsIntelJCCErratumMitigation" + ] + }, + { + "name": "Control", + "enable_features": [ + "V8SlowHistogramsIntelJCCErratumMitigation" + ], + "disable_features": [ + "V8IntelJCCErratumMitigation" + ] + } + ] + } + ], + "V8LocalCompileHints": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "LocalCompileHints" + ], + "disable_features": [ + "ConsumeCompileHints" + ] + }, + { + "name": "Control", + "disable_features": [ + "ConsumeCompileHints", + "LocalCompileHints" + ] + } + ] + } + ], + "V8Maglev": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "V8Maglev" + ] + } + ] + } + ], + "V8MaglevAndroid": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "MaglevAndTF", + "enable_features": [ + "V8Maglev", + "V8Turbofan" + ] + }, + { + "name": "MaglevAndNoTF", + "enable_features": [ + "V8Maglev" + ], + "disable_features": [ + "V8Turbofan" + ] + }, + { + "name": "NoMaglevAndNoTF", + "disable_features": [ + "V8Maglev", + "V8Turbofan" + ] + } + ] + } + ], + "V8ScavengerHigherCapacity": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "V8ScavengerMaxCapacity16MB", + "params": { + "V8ScavengerMaxCapacity": "16" + }, + "enable_features": [ + "V8ScavengerHigherCapacity" + ] + }, + { + "name": "V8ScavengerMaxCapacity32MB", + "params": { + "V8ScavengerMaxCapacity": "32" + }, + "enable_features": [ + "V8ScavengerHigherCapacity" + ] + }, + { + "name": "V8ScavengerMaxCapacity64MB", + "params": { + "V8ScavengerMaxCapacity": "64" + }, + "enable_features": [ + "V8ScavengerHigherCapacity" + ] + }, + { + "name": "Control", + "disable_features": [ + "V8ScavengerHigherCapacity" + ] + } + ] + } + ], + "V8SideStepTransitions": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "V8SideStepTransitions" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "V8SideStepTransitions" + ] + } + ] + } + ], + "V8SingleThreadedGCInBackgroundVariants": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "V8SingleThreadedGCInBackground" + ], + "disable_features": [ + "V8SingleThreadedGCInBackgroundNoIncrementalMarking", + "V8SingleThreadedGCInBackgroundParallelPause" + ] + }, + { + "name": "ParallelPause", + "enable_features": [ + "V8SingleThreadedGCInBackground", + "V8SingleThreadedGCInBackgroundParallelPause" + ], + "disable_features": [ + "V8SingleThreadedGCInBackgroundNoIncrementalMarking" + ] + }, + { + "name": "NoIncrementalMarking", + "enable_features": [ + "V8SingleThreadedGCInBackground", + "V8SingleThreadedGCInBackgroundNoIncrementalMarking" + ], + "disable_features": [ + "V8SingleThreadedGCInBackgroundParallelPause" + ] + } + ] + } + ], + "V8SlowHistograms": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Control", + "disable_features": [ + "V8SlowHistograms" + ] + }, + { + "name": "Enabled", + "enable_features": [ + "V8SlowHistograms" + ] + } + ] + } + ], + "V8Sparkplug-Android": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "DefaultX" + }, + { + "name": "Disabled", + "disable_features": [ + "V8SlowHistogramsSparkplugAndroid", + "V8Sparkplug" + ] + }, + { + "name": "Enabled", + "enable_features": [ + "V8SlowHistogramsSparkplugAndroid", + "V8Sparkplug" + ] + } + ] + } + ], + "V8Turboshaft": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "V8Turboshaft" + ] + } + ] + } + ], + "V8TurboshaftInstructionSelection": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "V8TurboshaftInstructionSelection" + ] + } + ] + } + ], + "V8UpdateLimitAfterLoading": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "V8UpdateLimitAfterLoading" + ] + } + ] + } + ], + "V8WasmCodeFlushing": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebAssemblyLiftoffCodeFlushing" + ] + }, + { + "name": "Control", + "disable_features": [ + "WebAssemblyLiftoffCodeFlushing" + ] + } + ] + } + ], + "V8WasmMoreAggressiveCodeCaching": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "1_ReducedThreshold", + "params": { + "WebAssemblyCodeCachingThreshold": "200" + }, + "enable_features": [ + "WebAssemblyMoreAggressiveCodeCaching" + ] + }, + { + "name": "2_IncreasedThreshold", + "params": { + "WebAssemblyCodeCachingThreshold": "10000" + }, + "enable_features": [ + "WebAssemblyMoreAggressiveCodeCaching" + ] + }, + { + "name": "3_ReducedHardThreshold", + "params": { + "WebAssemblyCodeCachingHardThreshold": "200000" + }, + "enable_features": [ + "WebAssemblyMoreAggressiveCodeCaching" + ] + }, + { + "name": "4_IncreasedHardThreshold", + "params": { + "WebAssemblyCodeCachingHardThreshold": "10000000" + }, + "enable_features": [ + "WebAssemblyMoreAggressiveCodeCaching" + ] + }, + { + "name": "5_ReducedTimeout", + "params": { + "WebAssemblyCodeCachingTimeoutMs": "500" + }, + "enable_features": [ + "WebAssemblyMoreAggressiveCodeCaching" + ] + }, + { + "name": "6_IncreasedTimeout", + "params": { + "WebAssemblyCodeCachingTimeoutMs": "10000" + }, + "enable_features": [ + "WebAssemblyMoreAggressiveCodeCaching" + ] + } + ] + } + ], + "V8WasmTurboshaft": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebAssemblyTurboshaft", + "WebAssemblyTurboshaftInstructionSelection" + ] + }, + { + "name": "EnabledNoInstructionSelection", + "enable_features": [ + "WebAssemblyTurboshaft" + ], + "disable_features": [ + "WebAssemblyTurboshaftInstructionSelection" + ] + }, + { + "name": "Control", + "disable_features": [ + "WebAssemblyTurboshaft", + "WebAssemblyTurboshaftInstructionSelection" + ] + } + ] + } + ], + "VSyncAlignedPresent": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled_2_pending_frames", + "params": { + "PendingFrames": "2" + }, + "enable_features": [ + "VSyncAlignedPresent" + ] + } + ] + } + ], + "VSyncDecoding": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "VSyncDecoding" + ] + } + ] + } + ], + "VaapiVp8TemporalLayerEncoding": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "VaapiVp8TemporalLayerEncoding" + ] + } + ] + } + ], + "VariableRefreshRateBorealis": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "ignore-availability": "false" + }, + "enable_features": [ + "EnableVariableRefreshRate" + ] + } + ] + } + ], + "VerifyDidCommitParams": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "ios", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "gesture": "true", + "http_status_code": "true", + "intended_as_new_entry": "true", + "is_overriding_user_agent": "true", + "method": "true", + "origin": "true", + "post_id": "true", + "should_replace_current_entry": "true", + "should_update_history": "true", + "url": "true", + "url_is_unreachable": "true" + }, + "enable_features": [ + "VerifyDidCommitParams" + ], + "disable_features": [] + }, + { + "name": "EnabledWithoutShouldReplace", + "params": { + "gesture": "true", + "http_status_code": "true", + "intended_as_new_entry": "true", + "is_overriding_user_agent": "true", + "method": "true", + "origin": "true", + "post_id": "true", + "should_replace_current_entry": "false", + "should_update_history": "true", + "url": "true", + "url_is_unreachable": "true" + }, + "enable_features": [ + "VerifyDidCommitParams" + ], + "disable_features": [] + }, + { + "name": "EnabledWithoutShouldReplaceAndURLIsUnreachable", + "params": { + "gesture": "true", + "http_status_code": "true", + "intended_as_new_entry": "true", + "is_overriding_user_agent": "true", + "method": "true", + "origin": "true", + "post_id": "true", + "should_replace_current_entry": "false", + "should_update_history": "true", + "url": "true", + "url_is_unreachable": "false" + }, + "enable_features": [ + "VerifyDidCommitParams" + ], + "disable_features": [] + } + ] + } + ], + "VersionedWallpaperInfo": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "VersionedWallpaperInfo" + ] + } + ] + } + ], + "VideoConferenceDLCUIRollout": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "VcDlcUi" + ] + } + ] + } + ], + "VideoConferenceRollout": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "BackgroundReplaceEnabled", + "enable_features": [ + "CrOSLateBootAudioAPNoiseCancellation", + "FeatureManagementVideoConference", + "VCBackgroundReplace" + ] + }, + { + "name": "BackgroundReplaceOnlyEnabled", + "enable_features": [ + "VCBackgroundReplace" + ] + } + ] + } + ], + "VideoDecodeBatching": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "VideoDecodeBatching" + ] + } + ] + } + ], + "ViewTransitionOnNavigation": [ + { + "platforms": [ + "android_webview", + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ViewTransitionOnNavigation" + ] + } + ] + } + ], + "VirtualKeyboardNewHeader": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "VirtualKeyboardNewHeader" + ] + } + ] + } + ], + "VisibilityAwareResourceScheduler": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_20230807", + "enable_features": [ + "VisibilityAwareResourceScheduler" + ] + } + ] + } + ], + "Vulkan": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DefaultANGLEVulkan", + "Vulkan", + "VulkanFromANGLE" + ], + "hardware_classes": [ + "brya", + "dedede", + "guybrush", + "nissa", + "rex", + "skyrim", + "volteer", + "zork" + ] + } + ] + } + ], + "VulkanV2": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "VulkanV2", + "enable_features": [ + "VulkanV2" + ] + } + ] + } + ], + "VulkanV3": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "VulkanV3", + "enable_features": [ + "VulkanV3" + ] + } + ] + } + ], + "VulkanVMALargeHeapBlockSize": [ + { + "platforms": [ + "android", + "linux" + ], + "experiments": [ + { + "name": "VulkanVMALargeHeapBlockSize", + "enable_features": [ + "VulkanVMALargeHeapBlockSize" + ] + } + ] + } + ], + "WaffleStudy": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "EnabledAllUsers", + "params": { + "for_tagged_profiles_only": "false", + "reprompt": "NO_REPROMPT" + }, + "enable_features": [ + "SearchEngineChoiceTrigger" + ] + } + ] + } + ], + "WaitForLateScrollEvents": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "DispatchImmediately", + "params": { + "mode": "DispatchScrollEventsImmediately" + }, + "enable_features": [ + "WaitForLateScrollEvents" + ] + }, + { + "name": "UseScrollPredictorForDeadline", + "params": { + "mode": "UseScrollPredictorForDeadline" + }, + "enable_features": [ + "WaitForLateScrollEvents" + ] + }, + { + "name": "UseScrollPredictorForEmptyQueue", + "params": { + "mode": "UseScrollPredictorForEmptyQueue" + }, + "enable_features": [ + "WaitForLateScrollEvents" + ] + } + ] + } + ], + "WebApkAllowIconUpdate": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_WebApkAllowIconUpdate", + "params": { + "shell_version": "166" + }, + "enable_features": [ + "WebApkAllowIconUpdate" + ] + } + ] + } + ], + "WebApkBackupAndRestore": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "PwaRestoreUi", + "WebApkBackupAndRestoreBackend" + ] + }, + { + "name": "BackendOnly", + "enable_features": [ + "WebApkBackupAndRestoreBackend" + ], + "disable_features": [ + "PwaRestoreUi" + ] + } + ] + } + ], + "WebApkShellUpdate": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_WebApkShellUpdate", + "params": { + "version": "166" + }, + "enable_features": [ + "WebApkShellUpdate" + ] + } + ] + } + ], + "WebApkUniversalInstallDefaultUrl": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "UniversalInstallDefaultUrl" + ] + } + ] + } + ], + "WebAssemblyGenericWrapper": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebAssemblyGenericWrapper" + ] + }, + { + "name": "Control", + "disable_features": [ + "WebAssemblyGenericWrapper" + ] + } + ] + } + ], + "WebAssemblyInliningCallIndirect": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebAssemblyInliningCallIndirect" + ] + }, + { + "name": "Control", + "disable_features": [ + "WebAssemblyInliningCallIndirect" + ] + } + ] + } + ], + "WebAuthenticationAndroidCredMan": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "min_gms_core_version_no_dots": "242300000" + }, + "enable_features": [ + "WebAuthenticationAndroidCredMan" + ] + } + ] + } + ], + "WebAuthenticationEnclaveAuthenticator": [ + { + "platforms": [ + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebAuthenticationEnclaveAuthenticator" + ] + } + ] + } + ], + "WebContentsCaptureHiDPI": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebContentsCaptureHiDPI" + ] + } + ] + } + ], + "WebGPU": [ + { + "platforms": [ + "chromeos", + "mac", + "windows", + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebGPUService" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "WebGPUService" + ] + } + ] + } + ], + "WebGPUSupportMetrics": [ + { + "platforms": [ + "android", + "android_webview", + "linux", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CollectWebGPUSupportMetrics" + ] + } + ] + } + ], + "WebGPUUseDXC2": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebGPUUseDXC2" + ] + } + ] + } + ], + "WebGPUUseTintIR_V2": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebGPUUseTintIR" + ] + } + ] + } + ], + "WebOtpBackendAuto": [ + { + "platforms": [ + "android", + "android_weblayer" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebOtpBackendAuto" + ] + } + ] + } + ], + "WebPermissionsApi": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebPermissionsApi" + ] + } + ] + } + ], + "WebProtectCustomRuleMessageDialog": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "DialogCustomRuleMessageEnabled", + "RealTimeUrlFilteringCustomMessage" + ] + } + ] + } + ], + "WebProtectWatermark": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "EnableWatermarkView" + ] + } + ] + } + ], + "WebRTC-Aec3BufferingMaxAllowedExcessRenderBlocksOverride": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "1" + } + ] + } + ], + "WebRTC-Aec3DelayEstimateSmoothingDelayFoundOverride": [ + { + "platforms": [ + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "0.1" + }, + { + "name": "0.3" + }, + { + "name": "0.7" + } + ] + } + ], + "WebRTC-Aec3TransparentModeHmm": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled" + } + ] + } + ], + "WebRTC-Audio-GainController2": [ + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled,switch_to_agc2:true,target_range_min_dbfs:-50,target_range_max_dbfs:-30,max_gain_db:50,initial_gain_db:15,max_gain_change_db_per_second:6,headroom_db:5,enable_clipping_predictor:true,disallow_transient_suppressor_usage:true,_20230614" + } + ] + } + ], + "WebRTC-Audio-NetEqDecisionLogicConfig": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "ios", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "enable_stable_playout_delay:true,reinit_after_expands:1000" + } + ] + } + ], + "WebRTC-Audio-OpusAvoidNoisePumpingDuringDtx": [ + { + "platforms": [ + "android", + "chromeos", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled" + } + ] + } + ], + "WebRTC-BurstyPacer": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "burst:20ms,_V1" + }, + { + "name": "burst:40ms,_V1" + } + ] + } + ], + "WebRTC-Bwe-LossBasedBweV2": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled:true,CandidateFactors:1.02|1.0|0.95,DelayBasedCandidate:true,HigherBwBiasFactor:0.0002,HigherLogBwBiasFactor:0.02,ObservationDurationLowerBound:250ms,InstantUpperBoundBwBalance:75kbps,BwRampupUpperBoundFactor:1000000.0,InstantUpperBoundTemporalWeightFactor:0.9,TemporalWeightFactor:0.9,MaxIncreaseFactor:1.3,NewtonStepSize:0.75,InherentLossUpperBoundBwBalance:75kbps,LossThresholdOfHighBandwidthPreference:0.15,_20220905" + }, + { + "name": "Enabled:true,CandidateFactors:1.02|1.0|0.95,DelayBasedCandidate:true,HigherBwBiasFactor:0.0002,HigherLogBwBiasFactor:0.02,ObservationDurationLowerBound:250ms,InstantUpperBoundBwBalance:75kbps,BwRampupUpperBoundFactor:1000000.0,InstantUpperBoundTemporalWeightFactor:0.9,TemporalWeightFactor:0.9,MaxIncreaseFactor:1.3,NewtonStepSize:0.75,InherentLossUpperBoundBwBalance:75kbps,LossThresholdOfHighBandwidthPreference:0.15,NotIncreaseIfInherentLossLessThanAverageLoss:true,_20220905" + }, + { + "name": "Enabled:true,CandidateFactors:1.02|1.0|0.95,DelayBasedCandidate:true,HigherBwBiasFactor:0.0002,HigherLogBwBiasFactor:0.02,ObservationDurationLowerBound:250ms,InstantUpperBoundBwBalance:75kbps,BwRampupUpperBoundFactor:1000000.0,InstantUpperBoundTemporalWeightFactor:0.9,TemporalWeightFactor:0.9,MaxIncreaseFactor:1.3,NewtonStepSize:0.75,InherentLossUpperBoundBwBalance:75kbps,LossThresholdOfHighBandwidthPreference:0.15,NotIncreaseIfInherentLossLessThanAverageLoss:true,TrendlineIntegrationEnabled:true,TrendlineObservationsWindowSize:2,_20220905" + } + ] + } + ], + "WebRTC-Bwe-ProbingConfiguration": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "network_state_probe_duration:200ms,network_state_interval:10s,min_probe_delta:20ms,est_lower_than_network_ratio:0.7,skip_if_est_larger_than_fraction_of_max:0.9,alr_scale:1.5,step_size:1.5" + } + ] + } + ], + "WebRTC-Bwe-ReceiverLimitCapsOnly": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "fuchsia", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled" + } + ] + } + ], + "WebRTC-Bwe-RobustThroughputEstimatorSettings": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "enabled:true,_V1" + } + ] + } + ], + "WebRTC-IPv6NetworkResolutionFixes": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled,ResolveStunHostnameForFamily:true,PreferGlobalIPv6Address:true,DiversifyIpv6Interfaces:true,_20220929" + } + ] + } + ], + "WebRTC-JitterEstimatorConfig": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "num_stddev_delay_clamp:5,num_stddev_delay_outlier:2,num_stddev_size_outlier:2,estimate_noise_when_congested:false,_20230118_BETA" + } + ] + } + ], + "WebRTC-LibvpxVp9Encoder-SvcFrameDropConfig": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled,layer_drop_mode:1,max_consec_drop:2,_20240416" + } + ] + } + ], + "WebRTC-SendBufferSizeBytes": [ + { + "platforms": [ + "android", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "262144,_V1" + } + ] + } + ], + "WebRTC-SendPacketsOnWorkerThread": [ + { + "platforms": [ + "android", + "android_weblayer", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled,_20221205" + } + ] + } + ], + "WebRTC-SlackedTaskQueuePacedSender": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled,max_queue_time:75ms,_V4" + } + ] + } + ], + "WebRTC-VP8ConferenceTemporalLayers": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "2_V1" + } + ] + } + ], + "WebRTC-Video-EnableRetransmitAllLayers": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled,_20230607_BETA" + } + ] + } + ], + "WebRTC-Video-H26xPacketBuffer": [ + { + "platforms": [ + "android", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebRTC-Video-H26xPacketBuffer" + ] + } + ] + } + ], + "WebRTC-Vp9ExternalRefCtrl": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "ios", + "android", + "android_weblayer" + ], + "experiments": [ + { + "name": "Enabled" + } + ] + } + ], + "WebRTC-ZeroPlayoutDelay": [ + { + "platforms": [ + "windows", + "mac", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "android", + "android_weblayer", + "android_webview" + ], + "experiments": [ + { + "name": "min_pacing:0ms,max_decode_queue_size:8,", + "params": { + "max_post_decode_queue_size": "10", + "reduce_steady_state_queue_size_threshold": "20" + }, + "enable_features": [ + "LowLatencyVideoRendererAlgorithm" + ] + } + ] + } + ], + "WebRTCHardwareVideoEncoderFrameDrop": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "ios", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebRTCHardwareVideoEncoderFrameDrop" + ] + } + ] + } + ], + "WebRTCPipeWireCapturer": [ + { + "platforms": [ + "linux" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebRTCPipeWireCapturer" + ] + } + ] + } + ], + "WebRtcEncodedTransformDirectCallback": [ + { + "platforms": [ + "android", + "android_webview", + "chromeos", + "chromeos_lacros", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebRtcEncodedTransformDirectCallback" + ] + } + ] + } + ], + "WebRtcHWDecodingDisabledCfM": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Disabled_webrtc-hw-decoding", + "disable_features": [ + "webrtc-hw-decoding" + ] + } + ] + } + ], + "WebRtcThreadsUseResourceEfficientType": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebRtcThreadsUseResourceEfficientType" + ] + } + ] + } + ], + "WebUIBubblePersistentRendererStudy": [ + { + "platforms": [ + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebUIBubblePerProfilePersistence" + ] + } + ] + } + ], + "WebUICodeCache": [ + { + "platforms": [ + "android", + "android_weblayer", + "android_webview", + "chromeos", + "chromeos_lacros", + "fuchsia", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebUICodeCache" + ] + }, + { + "name": "Disabled", + "disable_features": [ + "WebUICodeCache" + ] + } + ] + } + ], + "WebUITabStrip": [ + { + "platforms": [ + "linux", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_trigger": "name:webui_tab_strip_iph_triggered;comparator:<3;window:1;storage:365", + "event_used": "name:webui_tab_strip_opened;comparator:==0;window:90;storage:365", + "session_rate": "any" + }, + "enable_features": [ + "IPH_WebUITabStrip", + "WebUITabStrip" + ] + } + ] + }, + { + "platforms": [ + "chromeos_lacros" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "availability": "any", + "event_trigger": "name:webui_tab_strip_iph_triggered;comparator:<3;window:1;storage:365", + "event_used": "name:webui_tab_strip_opened;comparator:==0;window:90;storage:365", + "session_rate": "any" + }, + "enable_features": [ + "IPH_WebUITabStrip", + "TextfieldFocusOnTapUp", + "WebUITabStrip", + "WebUITabStripTabDragIntegration" + ] + } + ] + } + ], + "WebViewAsyncDns": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewAsyncDns" + ] + } + ] + } + ], + "WebViewExitReasonMetric": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewExitReasonMetric" + ] + } + ] + } + ], + "WebViewIPProtectionPhase0": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "//0": "Refers to the combined Chrome + Full Device MDL", + "name": "mdl_3_2024-02-21", + "params": { + "MaskedDomainListExperimentGroup": "3" + }, + "enable_features": [ + "MaskedDomainList" + ] + } + ] + } + ], + "WebViewPreloadClasses": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewPreloadClasses" + ] + } + ] + } + ], + "WebViewRecordAppDataDirectorySize": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewRecordAppDataDirectorySize" + ] + } + ] + } + ], + "WebViewSeparateResourceContext": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewSeparateResourceContext" + ] + } + ] + } + ], + "WebViewSupervisedUser": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewSupervisedUserSiteDetection" + ] + } + ] + } + ], + "WebViewSurfaceControl": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewNewInvalidateHeuristic", + "WebViewSurfaceControl" + ] + } + ] + } + ], + "WebViewSurfaceControlForTV": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "RelaxLimitAImageReaderMaxSizeToOneBlocklist": "*Broadcom*|*Google*", + "RelaxLimitAImageReaderMaxSizeToOneManufacturerBlocklist": "*Broadcom*|*Google*", + "RelaxLimitAImageReaderMaxSizeToOneSoCBlocklist": "*Broadcom*" + }, + "enable_features": [ + "RelaxLimitAImageReaderMaxSizeToOne", + "WebViewSurfaceControlForTV" + ] + } + ] + } + ], + "WebViewThreadReduction": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "ReduceAllThreads", + "params": { + "BrowserThreadPoolCoresMultiplierFor16GBAndAbove": "0.4", + "BrowserThreadPoolCoresMultiplierFor1GBTo2GB": "0.4", + "BrowserThreadPoolCoresMultiplierFor2GBTo4GB": "0.4", + "BrowserThreadPoolCoresMultiplierFor4GBTo8GB": "0.4", + "BrowserThreadPoolCoresMultiplierFor512MBTo1GB": "0.4", + "BrowserThreadPoolCoresMultiplierFor8GBTo16GB": "0.4", + "BrowserThreadPoolCoresMultiplierForLessThan512MB": "0.4", + "BrowserThreadPoolMinFor16GBAndAbove": "2", + "BrowserThreadPoolMinFor1GBTo2GB": "2", + "BrowserThreadPoolMinFor2GBTo4GB": "2", + "BrowserThreadPoolMinFor4GBTo8GB": "2", + "BrowserThreadPoolMinFor512MBTo1GB": "2", + "BrowserThreadPoolMinFor8GBTo16GB": "2", + "BrowserThreadPoolMinForLessThan512MB": "2" + }, + "enable_features": [ + "BrowserThreadPoolAdjustment", + "InProcessGpuUseIOThread", + "NetworkServiceDedicatedThread" + ] + } + ] + } + ], + "WebViewThreadSafeMedia": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewThreadSafeMedia" + ] + } + ] + } + ], + "WebViewTrackpadAndMouseTextSelectionImprovements": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled_20240424", + "enable_features": [ + "ConvertTrackpadEventsToMouse", + "MouseAndTrackpadDropdownMenu" + ] + } + ] + } + ], + "WebViewUseInitialNetworkStateAtStartup": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewUseInitialNetworkStateAtStartup" + ] + } + ] + } + ], + "WebViewUseMetricsUploadServiceOnlySdkRuntime": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewUseMetricsUploadServiceOnlySdkRuntime" + ] + } + ] + } + ], + "WebViewXRequestedWithHeaderControl": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewXRequestedWithHeaderControl" + ] + } + ] + } + ], + "WebViewZoomKeyboardShortcuts": [ + { + "platforms": [ + "android_webview" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WebViewZoomKeyboardShortcuts" + ] + } + ] + } + ], + "WebXrEnableCardboard": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "Cardboard" + ] + } + ] + } + ], + "WhatsNewV2Study": [ + { + "platforms": [ + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WhatsNewVersion2" + ] + } + ] + } + ], + "WinPdfUseFontProxy": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WinPdfUseFontProxy" + ] + } + ] + } + ], + "WinSboxACProfileWithoutFirewall": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WinSboxACProfileWithoutFirewall" + ] + } + ] + } + ], + "WinSboxNoFakeGdiInit": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WinSboxNoFakeGdiInit" + ] + } + ] + } + ], + "WinSboxZeroAppShim": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "WinSboxZeroAppShim" + ] + } + ] + } + ], + "YieldWithInputHint": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "YieldWithInputHint" + ] + } + ] + } + ], + "ZPSPrefetchOnSRPWithDebouncingAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled_300ms_FromLastRun", + "params": { + "ZeroSuggestPrefetchDebounceDelay": "300", + "ZeroSuggestPrefetchDebounceFromLastRun": "true" + }, + "enable_features": [ + "ZeroSuggestPrefetchDebouncing", + "ZeroSuggestPrefetchingOnSRP" + ], + "disable_features": [ + "ZeroSuggestPrefetchingOnWeb" + ] + }, + { + "name": "Enabled_300ms_FromLastRequest", + "params": { + "ZeroSuggestPrefetchDebounceDelay": "300", + "ZeroSuggestPrefetchDebounceFromLastRun": "false" + }, + "enable_features": [ + "ZeroSuggestPrefetchDebouncing", + "ZeroSuggestPrefetchingOnSRP" + ], + "disable_features": [ + "ZeroSuggestPrefetchingOnWeb" + ] + }, + { + "name": "Enabled_600ms_FromLastRun", + "params": { + "ZeroSuggestPrefetchDebounceDelay": "600", + "ZeroSuggestPrefetchDebounceFromLastRun": "true" + }, + "enable_features": [ + "ZeroSuggestPrefetchDebouncing", + "ZeroSuggestPrefetchingOnSRP" + ], + "disable_features": [ + "ZeroSuggestPrefetchingOnWeb" + ] + }, + { + "name": "Enabled_600ms_FromLastRequest", + "params": { + "ZeroSuggestPrefetchDebounceDelay": "600", + "ZeroSuggestPrefetchDebounceFromLastRun": "false" + }, + "enable_features": [ + "ZeroSuggestPrefetchDebouncing", + "ZeroSuggestPrefetchingOnSRP" + ], + "disable_features": [ + "ZeroSuggestPrefetchingOnWeb" + ] + }, + { + "name": "Enabled_900ms_FromLastRun", + "params": { + "ZeroSuggestPrefetchDebounceDelay": "900", + "ZeroSuggestPrefetchDebounceFromLastRun": "true" + }, + "enable_features": [ + "ZeroSuggestPrefetchDebouncing", + "ZeroSuggestPrefetchingOnSRP" + ], + "disable_features": [ + "ZeroSuggestPrefetchingOnWeb" + ] + }, + { + "name": "Enabled_900ms_FromLastRequest", + "params": { + "ZeroSuggestPrefetchDebounceDelay": "900", + "ZeroSuggestPrefetchDebounceFromLastRun": "false" + }, + "enable_features": [ + "ZeroSuggestPrefetchDebouncing", + "ZeroSuggestPrefetchingOnSRP" + ], + "disable_features": [ + "ZeroSuggestPrefetchingOnWeb" + ] + } + ] + } + ], + "ZeroCopyTabCaptureStudyMac": [ + { + "platforms": [ + "mac" + ], + "experiments": [ + { + "name": "Enabled_20220901", + "enable_features": [ + "ZeroCopyTabCapture" + ] + } + ] + } + ], + "ZeroCopyTabCaptureStudyWin": [ + { + "platforms": [ + "windows" + ], + "experiments": [ + { + "name": "Enabled_20230222", + "enable_features": [ + "ZeroCopyTabCapture" + ] + } + ] + } + ], + "iOSCPEPerformanceImprovements": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "CredentialProviderPerformanceImprovements" + ] + } + ] + } + ] +} diff --git a/tools/under-control/src/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/tools/under-control/src/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom new file mode 100755 index 000000000..11c5b6cb5 --- /dev/null +++ b/tools/under-control/src/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom @@ -0,0 +1,4419 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module blink.mojom; + +// ============ Definition for WebFeature used for UseCounter =============== +// +// Do not change assigned numbers of existing items: add new features +// to the end of the list. +// +// If you want to mark an item as no-longer-used, simply rename it, prefixing +// "kOBSOLETE_" before the existing name. +// E.g. kFrobulate becomes kOBSOLETE_Frobulate. +// +// A WebFeature conceptually represents some particular web-exposed API +// or code path which can be used/triggered by a web page. +enum WebFeature { + kOBSOLETE_PageDestruction = 0, + kWorkerStart = 4, + kSharedWorkerStart = 5, + kOpenWebDatabase = 10, + kUnprefixedRequestAnimationFrame = 13, + kPrefixedRequestAnimationFrame = 14, + kContentSecurityPolicy = 15, + kContentSecurityPolicyReportOnly = 16, + kPrefixedTransitionEndEvent = 18, + kUnprefixedTransitionEndEvent = 19, + kPrefixedAndUnprefixedTransitionEndEvent = 20, + kAutoFocusAttribute = 21, + kDataListElement = 23, + kFormAttribute = 24, + kIncrementalAttribute = 25, + kInputTypeColor = 26, + kInputTypeDate = 27, + kInputTypeDateTimeFallback = 29, + kInputTypeDateTimeLocal = 30, + kInputTypeEmail = 31, + kInputTypeMonth = 32, + kInputTypeNumber = 33, + kInputTypeRange = 34, + kInputTypeSearch = 35, + kInputTypeTel = 36, + kInputTypeTime = 37, + kInputTypeURL = 38, + kInputTypeWeek = 39, + kInputTypeWeekFallback = 40, + kListAttribute = 41, + kMaxAttribute = 42, + kMinAttribute = 43, + kPatternAttribute = 44, + kPlaceholderAttribute = 45, + kPrefixedDirectoryAttribute = 47, + kRequiredAttribute = 49, + kStepAttribute = 51, + kPageVisits = 52, + kHTMLMarqueeElement = 53, + kReflection = 55, + kOBSOLETE_PrefixedStorageInfo = 57, + kDeprecatedFlexboxWebContent = 61, + kDeprecatedFlexboxChrome = 62, + kDeprecatedFlexboxChromeExtension = 63, + kWindowEvent = 69, + kContentSecurityPolicyWithBaseElement = 70, + kDocumentClear = 74, + kXMLDocument = 77, + kXSLProcessingInstruction = 78, + kXSLTProcessor = 79, + kSVGSwitchElement = 80, + kDocumentAll = 83, + kFormElement = 84, + kDemotedFormElement = 85, + kSVGAnimationElement = 90, + kLineClamp = 96, + kSubFrameBeforeUnloadRegistered = 97, + kSubFrameBeforeUnloadFired = 98, + kDocumentCreateAttribute = 111, + kDocumentCreateAttributeNS = 112, + kDocumentXMLEncoding = 115, // Removed from DOM4. + kDocumentXMLStandalone = 116, // Removed from DOM4. + kDocumentXMLVersion = 117, // Removed from DOM4. + kNavigatorProductSub = 123, + kNavigatorVendor = 124, + kNavigatorVendorSub = 125, + kPrefixedAnimationEndEvent = 128, + kUnprefixedAnimationEndEvent = 129, + kPrefixedAndUnprefixedAnimationEndEvent = 130, + kPrefixedAnimationStartEvent = 131, + kUnprefixedAnimationStartEvent = 132, + kPrefixedAndUnprefixedAnimationStartEvent = 133, + kPrefixedAnimationIterationEvent = 134, + kUnprefixedAnimationIterationEvent = 135, + kPrefixedAndUnprefixedAnimationIterationEvent = 136, + kEventReturnValue = 137, // Legacy IE extension. + kSVGSVGElement = 138, + kDOMSubtreeModifiedEvent = 143, + kDOMNodeInsertedEvent = 144, + kDOMNodeRemovedEvent = 145, + kDOMNodeRemovedFromDocumentEvent = 146, + kDOMNodeInsertedIntoDocumentEvent = 147, + kDOMCharacterDataModifiedEvent = 148, + kPrefixedAudioDecodedByteCount = 164, + kPrefixedVideoDecodedByteCount = 165, + kPrefixedVideoSupportsFullscreen = 166, + kPrefixedVideoDisplayingFullscreen = 167, + kPrefixedVideoEnterFullscreen = 168, + kPrefixedVideoExitFullscreen = 169, + kPrefixedVideoEnterFullScreen = 170, + kPrefixedVideoExitFullScreen = 171, + kPrefixedVideoDecodedFrameCount = 172, + kPrefixedVideoDroppedFrameCount = 173, + kPrefixedElementRequestFullscreen = 176, + kPrefixedElementRequestFullScreen = 177, + kBarPropLocationbar = 178, + kBarPropMenubar = 179, + kBarPropPersonalbar = 180, + kBarPropScrollbars = 181, + kBarPropStatusbar = 182, + kBarPropToolbar = 183, + kInputTypeEmailMultiple = 184, + kInputTypeEmailMaxLength = 185, + kInputTypeEmailMultipleMaxLength = 186, + kInputTypeText = 190, + kInputTypeTextMaxLength = 191, + kInputTypePassword = 192, + kInputTypePasswordMaxLength = 193, + kPrefixedPageVisibility = 196, + kDocumentBeforeUnloadRegistered = 200, + kDocumentBeforeUnloadFired = 201, + kDocumentUnloadRegistered = 202, + kDocumentUnloadFired = 203, + kSVGLocatableNearestViewportElement = 204, + kSVGLocatableFarthestViewportElement = 205, + kSVGPointMatrixTransform = 209, + kDOMFocusInOutEvent = 211, + kFileGetLastModifiedDate = 212, + kHTMLElementInnerText = 213, + kHTMLElementOuterText = 214, + kReplaceDocumentViaJavaScriptURL = 215, + kElementPrefixedMatchesSelector = 217, + kCSSStyleSheetRules = 219, + kCSSStyleSheetAddRule = 220, + kCSSStyleSheetRemoveRule = 221, + // The above items are available in M33 branch. + + kInitMessageEvent = 222, + kPrefixedDevicePixelRatioMediaFeature = 233, + kPrefixedMaxDevicePixelRatioMediaFeature = 234, + kPrefixedMinDevicePixelRatioMediaFeature = 235, + kPrefixedTransform3dMediaFeature = 237, + kPrefixedStorageQuota = 240, + kResetReferrerPolicy = 243, + // Case-insensitivity dropped from specification. + kCaseInsensitiveAttrSelectorMatch = 244, + kFormNameAccessForImageElement = 246, + kFormNameAccessForPastNamesMap = 247, + kFormAssociationByParser = 248, + kSVGSVGElementInDocument = 250, + kSVGDocumentRootElement = 251, + kDeprecatedWebKitGradient = 260, + kDeprecatedWebKitLinearGradient = 261, + kDeprecatedWebKitRepeatingLinearGradient = 262, + kDeprecatedWebKitRadialGradient = 263, + kDeprecatedWebKitRepeatingRadialGradient = 264, + // The above items are available in M34 branch. + + kTextAutosizing = 274, + kHTMLAnchorElementPingAttribute = 276, + kSVGClassName = 279, + kHTMLMediaElementSeekToFragmentStart = 281, + kHTMLMediaElementPauseAtFragmentEnd = 282, + kOBSOLETE_PrefixedWindowURL = 283, + kWindowOrientation = 285, + kDocumentCaptureEvents = 287, + kDocumentReleaseEvents = 288, + kWindowCaptureEvents = 289, + kWindowReleaseEvents = 290, + kDocumentXPathCreateExpression = 295, + kDocumentXPathCreateNSResolver = 296, + kDocumentXPathEvaluate = 297, + kPrefixedCancelAnimationFrame = 304, + kNamedNodeMapGetNamedItem = 306, + kNamedNodeMapSetNamedItem = 307, + kNamedNodeMapRemoveNamedItem = 308, + kNamedNodeMapItem = 309, + kNamedNodeMapGetNamedItemNS = 310, + kNamedNodeMapSetNamedItemNS = 311, + kNamedNodeMapRemoveNamedItemNS = 312, + kPrefixedDocumentIsFullscreen = 318, + kPrefixedDocumentCurrentFullScreenElement = 320, + kPrefixedDocumentCancelFullScreen = 321, + kPrefixedDocumentFullscreenEnabled = 322, + kPrefixedDocumentFullscreenElement = 323, + kPrefixedDocumentExitFullscreen = 324, + // The above items are available in M35 branch. + + kSVGForeignObjectElement = 325, + kSelectionSetPosition = 327, + kAnimationFinishEvent = 328, + kSVGSVGElementInXMLDocument = 329, + kEventSrcElement = 343, + kEventCancelBubble = 344, + kOBSOLETE_EventPath = 345, + kNodeIteratorDetach = 347, + kEventGetReturnValueTrue = 350, + kEventGetReturnValueFalse = 351, + kEventSetReturnValueTrue = 352, + kEventSetReturnValueFalse = 353, + kWindowOffscreenBuffering = 356, + kWindowDefaultStatus = 357, + kWindowDefaultstatus = 358, + kPrefixedTransitionEventConstructor = 361, + kPrefixedMutationObserverConstructor = 362, + kNotificationPermission = 371, + kRangeDetach = 372, + kPrefixedFileRelativePath = 386, + kDocumentCaretRangeFromPoint = 387, + kElementScrollIntoViewIfNeeded = 389, + kRangeExpand = 393, + kHTMLImageElementX = 396, + kHTMLImageElementY = 397, + kSelectionBaseNode = 400, + kSelectionBaseOffset = 401, + kSelectionExtentNode = 402, + kSelectionExtentOffset = 403, + kSelectionType = 404, + kSelectionModify = 405, + kSelectionSetBaseAndExtent = 406, + kSelectionEmpty = 407, + kVTTCue = 409, + kVTTCueRender = 410, + kVTTCueRenderVertical = 411, + kVTTCueRenderSnapToLinesFalse = 412, + kVTTCueRenderLineNotAuto = 413, + kVTTCueRenderPositionNot50 = 414, + kVTTCueRenderSizeNot100 = 415, + kVTTCueRenderAlignNotCenter = 416, + // The above items are available in M36 branch. + + kElementRequestPointerLock = 417, + kVTTCueRenderRtl = 418, + kPostMessageFromSecureToInsecure = 419, + kPostMessageFromInsecureToSecure = 420, + kDocumentExitPointerLock = 421, + kDocumentPointerLockElement = 422, + kPrefixedCursorZoomIn = 424, + kPrefixedCursorZoomOut = 425, + kTextEncoderConstructor = 429, + kTextEncoderEncode = 430, + kTextDecoderConstructor = 431, + kTextDecoderDecode = 432, + kFocusInOutEvent = 433, + kMouseEventMovementX = 434, + kMouseEventMovementY = 435, + kDocumentFonts = 440, + kMixedContentFormsSubmitted = 441, + kFormsSubmitted = 442, + kOBSOLETE_HTMLImports = 455, + kOBSOLETE_ElementCreateShadowRoot = 456, + kOBSOLETE_DocumentRegisterElement = 457, + kEditingAppleInterchangeNewline = 458, + kEditingAppleConvertedSpace = 459, + kEditingApplePasteAsQuotation = 460, + kEditingAppleStyleSpanClass = 461, + kOBSOLETE_HTMLImportsAsyncAttribute = 463, + kXMLHttpRequestSynchronous = 465, + kCSSSelectorPseudoUnresolved = 466, + kOBSOLETE_CSSSelectorPseudoShadow = 467, + kOBSOLETE_CSSSelectorPseudoContent = 468, + kCSSSelectorPseudoHost = 469, + kCSSSelectorPseudoHostContext = 470, + kOBSOLETE_CSSDeepCombinator = 471, + // The above items are available in M37 branch. + + kUseAsm = 473, + kDOMWindowOpen = 475, + kDOMWindowOpenFeatures = 476, + kAspectRatioFlexItem = 479, + kDetailsElement = 480, + kDialogElement = 481, + kMapElement = 482, + kMeterElement = 483, + kProgressElement = 484, + kWheelEventWheelDeltaX = 491, + kWheelEventWheelDeltaY = 492, + kWheelEventWheelDelta = 493, + kSendBeacon = 494, + kSendBeaconQuotaExceeded = 495, + kSVGSMILElementInDocument = 501, + kMouseEventOffsetX = 502, + kMouseEventOffsetY = 503, + kMouseEventX = 504, + kMouseEventY = 505, + kMouseEventFromElement = 506, + kMouseEventToElement = 507, + kRequestFileSystem = 508, + kRequestFileSystemWorker = 509, + kRequestFileSystemSyncWorker = 510, + kSVGStyleElementTitle = 519, + kPictureSourceSrc = 520, + // The above items are available in M38 branch. + + kPicture = 521, + kSizes = 522, + kSrcsetXDescriptor = 523, + kSrcsetWDescriptor = 524, + kSelectionContainsNode = 525, + kXMLExternalResourceLoad = 529, + kMixedContentPrivateHostnameInPublicHostname = 530, + kOBSOLETE_LegacyProtocolEmbeddedAsSubresource = 531, + kRequestedSubresourceWithEmbeddedCredentials = 532, + kNotificationCreated = 533, + kNotificationClosed = 534, + kNotificationPermissionRequested = 535, + kSRIElementWithMatchingIntegrityAttribute = 540, + kSRIElementWithNonMatchingIntegrityAttribute = 541, + kSRIElementWithUnparsableIntegrityAttribute = 542, + kV8Animation_StartTime_AttributeGetter = 545, + kV8Animation_StartTime_AttributeSetter = 546, + kV8Animation_CurrentTime_AttributeGetter = 547, + kV8Animation_CurrentTime_AttributeSetter = 548, + kV8Animation_PlaybackRate_AttributeGetter = 549, + kV8Animation_PlaybackRate_AttributeSetter = 550, + kV8Animation_PlayState_AttributeGetter = 551, + kV8Animation_Finish_Method = 552, + kV8Animation_Play_Method = 553, + kV8Animation_Pause_Method = 554, + kV8Animation_Reverse_Method = 555, + // The above items are available in M39 branch. + + kBreakIterator = 556, + kScreenOrientationAngle = 557, + kScreenOrientationType = 558, + kScreenOrientationLock = 559, + kScreenOrientationUnlock = 560, + kGeolocationSecureOrigin = 561, + kGeolocationInsecureOrigin = 562, + kNotificationSecureOrigin = 563, + kNotificationInsecureOrigin = 564, + kNotificationShowEvent = 565, + kSVGTransformListConsolidate = 569, + kSVGAnimatedTransformListBaseVal = 570, + kQuotedAnimationName = 571, + kQuotedKeyframesRule = 572, + kSrcsetDroppedCandidate = 573, + kWindowPostMessage = 574, + kRenderRuby = 576, + kScriptElementWithInvalidTypeHasSrc = 578, + kXMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload = 581, + kCSSSelectorPseudoScrollbar = 582, + kCSSSelectorPseudoScrollbarButton = 583, + kCSSSelectorPseudoScrollbarThumb = 584, + kCSSSelectorPseudoScrollbarTrack = 585, + kCSSSelectorPseudoScrollbarTrackPiece = 586, + kLangAttribute = 587, + kLangAttributeOnHTML = 588, + kLangAttributeOnBody = 589, + kLangAttributeDoesNotMatchToUILocale = 590, + kInputTypeSubmit = 591, + kInputTypeSubmitWithValue = 592, + // The above items are available in M40 branch. + + kSetReferrerPolicy = 593, + kTextWholeText = 599, + kNotificationCloseEvent = 603, + kStyleMedia = 606, + kStyleMediaType = 607, + kStyleMediaMatchMedium = 608, + kMixedContentPresent = 609, + kMixedContentBlockable = 610, + kMixedContentAudio = 611, + kMixedContentDownload = 612, + kMixedContentFavicon = 613, + kMixedContentImage = 614, + kMixedContentInternal = 615, + kMixedContentPlugin = 616, + kMixedContentPrefetch = 617, + kMixedContentVideo = 618, + kCSSSelectorPseudoFullScreenAncestor = 628, + kCSSSelectorPseudoFullScreen = 629, + kWebKitCSSMatrix = 630, + kAudioContextCreateAnalyser = 631, + kAudioContextCreateBiquadFilter = 632, + kAudioContextCreateBufferSource = 633, + kAudioContextCreateChannelMerger = 634, + kAudioContextCreateChannelSplitter = 635, + kAudioContextCreateConvolver = 636, + kAudioContextCreateDelay = 637, + kAudioContextCreateDynamicsCompressor = 638, + kAudioContextCreateGain = 639, + kAudioContextCreateMediaElementSource = 640, + kAudioContextCreateMediaStreamDestination = 641, + kAudioContextCreateMediaStreamSource = 642, + kAudioContextCreateOscillator = 643, + kAudioContextCreatePeriodicWave = 645, + kAudioContextCreateScriptProcessor = 646, + kAudioContextCreateStereoPanner = 647, + kAudioContextCreateWaveShaper = 648, + kAudioContextDecodeAudioData = 649, + kAudioContextResume = 650, + kAudioContextSuspend = 651, + kMixedContentInNonHTTPSFrameThatRestrictsMixedContent = 661, + kMixedContentInSecureFrameThatDoesNotRestrictMixedContent = 662, + kMixedContentWebSocket = 663, + kSyntheticKeyframesInCompositedCSSAnimation = 664, + kMixedContentFormPresent = 665, + kGetUserMediaInsecureOrigin = 666, + kGetUserMediaSecureOrigin = 667, + // The above items are available in M41 branch. + + kOBSOLETE_DeviceMotionInsecureOrigin = 668, + kDeviceMotionSecureOrigin = 669, + kOBSOLETE_DeviceOrientationInsecureOrigin = 670, + kDeviceOrientationSecureOrigin = 671, + kSandboxViaIFrame = 672, + kSandboxViaCSP = 673, + kBlockedSniffingImageToScript = 674, + kFetch = 675, + kFetchBodyStream = 676, + kXMLHttpRequestAsynchronous = 677, + kWhiteSpacePreFromXMLSpace = 679, + kWhiteSpaceNowrapFromXMLSpace = 680, + kSVGSVGElementForceRedraw = 685, + kSVGSVGElementSuspendRedraw = 686, + kSVGSVGElementUnsuspendRedraw = 687, + kSVGSVGElementUnsuspendRedrawAll = 688, + kAudioContextClose = 689, + kCSSZoomNotEqualToOne = 691, + // The above items are available in M42 branch. + + kClientRectListItem = 694, + kWindowClientInformation = 695, + kWindowFind = 696, + kWindowScreenLeft = 697, + kWindowScreenTop = 698, + kV8Animation_Cancel_Method = 699, + kV8Animation_Onfinish_AttributeGetter = 700, + kV8Animation_Onfinish_AttributeSetter = 701, + kV8Window_WebKitAnimationEvent_ConstructorGetter = 707, + kCryptoGetRandomValues = 710, + kSubtleCryptoEncrypt = 711, + kSubtleCryptoDecrypt = 712, + kSubtleCryptoSign = 713, + kSubtleCryptoVerify = 714, + kSubtleCryptoDigest = 715, + kSubtleCryptoGenerateKey = 716, + kSubtleCryptoImportKey = 717, + kSubtleCryptoExportKey = 718, + kSubtleCryptoDeriveBits = 719, + kSubtleCryptoDeriveKey = 720, + kSubtleCryptoWrapKey = 721, + kSubtleCryptoUnwrapKey = 722, + kCryptoAlgorithmAesCbc = 723, + kCryptoAlgorithmHmac = 724, + kCryptoAlgorithmRsaSsaPkcs1v1_5 = 725, + kCryptoAlgorithmSha1 = 726, + kCryptoAlgorithmSha256 = 727, + kCryptoAlgorithmSha384 = 728, + kCryptoAlgorithmSha512 = 729, + kCryptoAlgorithmAesGcm = 730, + kCryptoAlgorithmRsaOaep = 731, + kCryptoAlgorithmAesCtr = 732, + kCryptoAlgorithmAesKw = 733, + kCryptoAlgorithmRsaPss = 734, + kCryptoAlgorithmEcdsa = 735, + kCryptoAlgorithmEcdh = 736, + kCryptoAlgorithmHkdf = 737, + kCryptoAlgorithmPbkdf2 = 738, + kDocumentSetDomain = 739, + kUpgradeInsecureRequestsEnabled = 740, + kOBSOLETE_UpgradeInsecureRequestsUpgradedRequest = 741, + kDocumentDesignMode = 742, + kGlobalCacheStorage = 743, + kNetInfo = 744, + kBackgroundSync = 745, + kOBSOLETE_LegacyConst = 748, + kV8Permissions_Query_Method = 750, + // The above items are available in M43 branch. + + kSVGHrefBaseVal = 758, + kSVGHrefAnimVal = 759, + kV8CSSRuleList_Item_Method = 760, + kV8MediaList_Item_Method = 761, + kV8StyleSheetList_Item_Method = 762, + kStyleSheetListAnonymousNamedGetter = 763, + kAutocapitalizeAttribute = 764, + kFullscreenSecureOrigin = 765, + kFullscreenInsecureOrigin = 766, + kDialogInSandboxedContext = 767, + kSVGSMILAnimationInImageRegardlessOfCache = 768, + kEncryptedMediaSecureOrigin = 770, + kPerformanceFrameTiming = 772, + kV8Element_Animate_Method = 773, + // The above items are available in M44 branch. + + kV8SVGSVGElement_GetElementById_Method = 778, + kV8MessageChannel_Constructor = 780, + kV8MessagePort_PostMessage_Method = 781, + kV8MessagePort_Start_Method = 782, + kV8MessagePort_Close_Method = 783, + kMessagePortsTransferred = 784, + kCSSKeyframesRuleAnonymousIndexedGetter = 785, + kV8Screen_AvailLeft_AttributeGetter = 786, + kV8Screen_AvailTop_AttributeGetter = 787, + kV8SVGFEConvolveMatrixElement_PreserveAlpha_AttributeGetter = 791, + kV8SVGStyleElement_Disabled_AttributeGetter = 798, + kV8SVGStyleElement_Disabled_AttributeSetter = 799, + kInputTypeFileSecureOrigin = 801, + kInputTypeFileInsecureOrigin = 802, + kElementAttachShadow = 804, + kV8SecurityPolicyViolationEvent_DocumentURI_AttributeGetter = 806, + kV8SecurityPolicyViolationEvent_BlockedURI_AttributeGetter = 807, + kV8SecurityPolicyViolationEvent_StatusCode_AttributeGetter = 808, + kHTMLLinkElementDisabled = 809, + kV8HTMLLinkElement_Disabled_AttributeGetter = 810, + kV8HTMLLinkElement_Disabled_AttributeSetter = 811, + kV8HTMLStyleElement_Disabled_AttributeGetter = 812, + kV8HTMLStyleElement_Disabled_AttributeSetter = 813, + kV8DOMError_Constructor = 816, + kV8DOMError_Name_AttributeGetter = 817, + kV8DOMError_Message_AttributeGetter = 818, + kTextInputFired = 830, + kV8TextEvent_Data_AttributeGetter = 831, + kV8TextEvent_InitTextEvent_Method = 832, + kClientHintsDPR_DEPRECATED = 835, + kClientHintsResourceWidth_DEPRECATED = 836, + kClientHintsViewportWidth_DEPRECATED = 837, + kSRIElementIntegrityAttributeButIneligible = 838, + kFormDataAppendNull = 843, + kNonHTMLElementSetAttributeNodeFromHTMLDocumentNameNotLowercase = 845, + kNavigatorVibrate = 850, + kNavigatorVibrateSubFrame = 851, + kV8XPathEvaluator_Constructor = 853, + kV8XPathEvaluator_CreateExpression_Method = 854, + kV8XPathEvaluator_CreateNSResolver_Method = 855, + kV8XPathEvaluator_Evaluate_Method = 856, + kRequestMIDIAccess_ObscuredByFootprinting = 857, + kV8MouseEvent_LayerX_AttributeGetter = 858, + kV8MouseEvent_LayerY_AttributeGetter = 859, + kInnerTextWithShadowTree = 860, + kSelectionToStringWithShadowTree = 861, + kWindowFindWithShadowTree = 862, + kV8CompositionEvent_InitCompositionEvent_Method = 863, + kV8CustomEvent_InitCustomEvent_Method = 864, + kV8DeviceMotionEvent_InitDeviceMotionEvent_Method = 865, + kV8DeviceOrientationEvent_InitDeviceOrientationEvent_Method = 866, + kV8Event_InitEvent_Method = 867, + kV8KeyboardEvent_InitKeyboardEvent_Method = 868, + kV8MouseEvent_InitMouseEvent_Method = 869, + kV8MutationEvent_InitMutationEvent_Method = 870, + kV8StorageEvent_InitStorageEvent_Method = 871, + kV8UIEvent_InitUIEvent_Method = 873, + kRequestFileSystemNonWebbyOrigin = 876, + kV8MemoryInfo_TotalJSHeapSize_AttributeGetter = 879, + kV8MemoryInfo_UsedJSHeapSize_AttributeGetter = 880, + kV8MemoryInfo_JSHeapSizeLimit_AttributeGetter = 881, + kV8Performance_Timing_AttributeGetter = 882, + kV8Performance_Navigation_AttributeGetter = 883, + kV8Performance_Memory_AttributeGetter = 884, + kV8SharedWorker_WorkerStart_AttributeGetter = 885, + // The above items are available in M45 branch. + + kHTMLMediaElementPreloadNone = 892, + kHTMLMediaElementPreloadMetadata = 893, + kHTMLMediaElementPreloadAuto = 894, + kHTMLMediaElementPreloadDefault = 895, + kMixedContentBlockableAllowed = 896, + kPseudoBeforeAfterForInputElement = 897, + kV8Permissions_Revoke_Method = 898, + kLinkRelDnsPrefetch = 899, + kLinkRelPreconnect = 900, + kLinkRelPreload = 901, + kLinkHeaderDnsPrefetch = 902, + kLinkHeaderPreconnect = 903, + kClientHintsMetaHTTPEquivAcceptCH = 904, + kHTMLElementDeprecatedWidth = 905, + kClientHintsContentDPR = 906, + kElementAttachShadowOpen = 907, + kElementAttachShadowClosed = 908, + kAudioParamSetValueAtTime = 909, + kAudioParamLinearRampToValueAtTime = 910, + kAudioParamExponentialRampToValueAtTime = 911, + kAudioParamSetTargetAtTime = 912, + kAudioParamSetValueCurveAtTime = 913, + kAudioParamCancelScheduledValues = 914, + kV8Permissions_Request_Method = 915, + kLinkRelPrefetch = 917, + kLinkRelPrerender = 918, + kLinkRelNext = 919, + kCSSValuePrefixedMinContent = 921, + kCSSValuePrefixedMaxContent = 922, + kCSSValuePrefixedFitContent = 923, + kCSSValuePrefixedFillAvailable = 924, + kPresentationDefaultRequest = 926, + kPresentationAvailabilityChangeEventListener = 927, + kPresentationRequestConstructor = 928, + kPresentationRequestStart = 929, + kPresentationRequestReconnect = 930, + kPresentationRequestGetAvailability = 931, + kPresentationRequestConnectionAvailableEventListener = 932, + kPresentationConnectionTerminate = 933, + kPresentationConnectionSend = 934, + kPresentationConnectionMessageEventListener = 936, + kCSSAnimationsStackedNeutralKeyframe = 937, + kReadingCheckedInClickHandler = 938, + kFlexboxIntrinsicSizeAlgorithmIsDifferent = 939, + // The above items are available in M46 branch. + + kOBSOLETE_HTMLImportsHasStyleSheets = 940, + kNetInfoType = 946, + kNetInfoDownlinkMax = 947, + kNetInfoOnChange = 948, + kNetInfoOnTypeChange = 949, + kV8Window_Alert_Method = 950, + kV8Window_Confirm_Method = 951, + kV8Window_Prompt_Method = 952, + kV8Window_Print_Method = 953, + kV8Window_RequestIdleCallback_Method = 954, + kFlexboxPercentagePaddingVertical = 955, + kFlexboxPercentageMarginVertical = 956, + kCredentialManagerGet = 960, + kCredentialManagerGetMediationOptional = 961, + kCredentialManagerGetMediationSilent = 962, + kCredentialManagerStore = 963, + // The above items are available in M47 branch. + + kBlockableMixedContentInSubframeBlocked = 966, + kCSSAtRuleCharset = 969, + kCSSAtRuleFontFace = 970, + kCSSAtRuleImport = 971, + kCSSAtRuleKeyframes = 972, + kCSSAtRuleMedia = 973, + kCSSAtRuleNamespace = 974, + kCSSAtRulePage = 975, + kCSSAtRuleSupports = 976, + kCSSAtRuleViewport = 977, + kCSSAtRuleWebkitKeyframes = 978, + kV8HTMLFieldSetElement_Elements_AttributeGetter = 979, + kOBSOLETE_ExternalAddSearchProvider = 981, + kOBSOLETE_ExternalIsSearchProviderInstalled = 982, + kV8Permissions_RequestAll_Method = 983, + kOBSOLETE_DeviceOrientationAbsoluteInsecureOrigin = 987, + kDeviceOrientationAbsoluteSecureOrigin = 988, + kFontFaceConstructor = 989, + kServiceWorkerControlledPage = 990, + kMeterElementWithMeterAppearance = 993, + kMeterElementWithNoneAppearance = 994, + kSelectionAnchorNode = 997, + kSelectionAnchorOffset = 998, + kSelectionFocusNode = 999, + kSelectionFocusOffset = 1000, + kSelectionIsCollapsed = 1001, + kSelectionRangeCount = 1002, + kSelectionGetRangeAt = 1003, + kSelectionAddRange = 1004, + kSelectionRemoveAllRanges = 1005, + kSelectionCollapse = 1006, + kSelectionCollapseToStart = 1007, + kSelectionCollapseToEnd = 1008, + kSelectionExtend = 1009, + kSelectionSelectAllChildren = 1010, + kSelectionDeleteDromDocument = 1011, + kSelectionDOMString = 1012, + kInputTypeRangeVerticalAppearance = 1013, + // The above items are available in M48 branch. + + kCSSFilterReference = 1014, + kCSSFilterGrayscale = 1015, + kCSSFilterSepia = 1016, + kCSSFilterSaturate = 1017, + kCSSFilterHueRotate = 1018, + kCSSFilterInvert = 1019, + kCSSFilterOpacity = 1020, + kCSSFilterBrightness = 1021, + kCSSFilterContrast = 1022, + kCSSFilterBlur = 1023, + kCSSFilterDropShadow = 1024, + kBackgroundSyncRegister = 1025, + kExecCommandOnInputOrTextarea = 1027, + kV8History_ScrollRestoration_AttributeGetter = 1028, + kV8History_ScrollRestoration_AttributeSetter = 1029, + kSVG1DOMFilter = 1030, + kOfflineAudioContextStartRendering = 1031, + kOfflineAudioContextSuspend = 1032, + kOfflineAudioContextResume = 1033, + kSVG1DOMPaintServer = 1035, + kSVGSVGElementFragmentSVGView = 1036, + kSVGSVGElementFragmentSVGViewElement = 1037, + kPresentationConnectionClose = 1038, + kSVG1DOMShape = 1039, + kSVG1DOMText = 1040, + kRTCPeerConnectionConstructorConstraints = 1041, + kRTCPeerConnectionConstructorCompliant = 1042, + kRTCPeerConnectionCreateOfferLegacyFailureCallback = 1044, + kRTCPeerConnectionCreateOfferLegacyConstraints = 1045, + kOBSOLETE_RTCPeerConnectionCreateOfferLegacyOfferOptions = 1046, + kRTCPeerConnectionCreateOfferLegacyCompliant = 1047, + kRTCPeerConnectionCreateAnswerLegacyFailureCallback = 1049, + kOBSOLETE_RTCPeerConnectionCreateAnswerLegacyConstraints = 1050, + kRTCPeerConnectionCreateAnswerLegacyCompliant = 1051, + kRTCPeerConnectionSetLocalDescriptionLegacyNoSuccessCallback = 1052, + kRTCPeerConnectionSetLocalDescriptionLegacyNoFailureCallback = 1053, + kRTCPeerConnectionSetLocalDescriptionLegacyCompliant = 1054, + kRTCPeerConnectionSetRemoteDescriptionLegacyNoSuccessCallback = 1055, + kRTCPeerConnectionSetRemoteDescriptionLegacyNoFailureCallback = 1056, + kRTCPeerConnectionSetRemoteDescriptionLegacyCompliant = 1057, + kRTCPeerConnectionGetStatsLegacyNonCompliant = 1058, + kNodeFilterIsFunction = 1059, + kNodeFilterIsObject = 1060, + kCSSSelectorInternalPseudoListBox = 1062, + kCSSSelectorInternalMediaControlsOverlayCastButton = 1064, + kCSSSelectorInternalPseudoSpatialNavigationFocus = 1065, + kSameOriginTextScript = 1066, + kSameOriginApplicationScript = 1067, + kSameOriginOtherScript = 1068, + kCrossOriginTextScript = 1069, + kCrossOriginApplicationScript = 1070, + kCrossOriginOtherScript = 1071, + kSVG1DOMSVGTests = 1072, + kDisableRemotePlaybackAttribute = 1074, + kV8SloppyMode = 1075, + kV8StrictMode = 1076, + kOBSOLETE_V8StrongMode = 1077, + kAudioNodeConnectToAudioNode = 1078, + kAudioNodeConnectToAudioParam = 1079, + kAudioNodeDisconnectFromAudioNode = 1080, + kAudioNodeDisconnectFromAudioParam = 1081, + kV8CSSFontFaceRule_Style_AttributeGetter = 1082, + kSelectionCollapseNull = 1083, + kSelectionSetBaseAndExtentNull = 1084, + kV8SVGSVGElement_CreateSVGNumber_Method = 1085, + kV8SVGSVGElement_CreateSVGLength_Method = 1086, + kV8SVGSVGElement_CreateSVGAngle_Method = 1087, + kV8SVGSVGElement_CreateSVGPoint_Method = 1088, + kV8SVGSVGElement_CreateSVGMatrix_Method = 1089, + kV8SVGSVGElement_CreateSVGRect_Method = 1090, + kV8SVGSVGElement_CreateSVGTransform_Method = 1091, + kV8SVGSVGElement_CreateSVGTransformFromMatrix_Method = 1092, + kFormNameAccessForNonDescendantImageElement = 1093, + kV8RegExpPrototypeStickyGetter = 1096, + kV8RegExpPrototypeToString = 1097, + kV8InputDeviceCapabilities_FiresTouchEvents_AttributeGetter = 1098, + kDataElement = 1099, + kTimeElement = 1100, + kSVG1DOMUriReference = 1101, + kSVG1DOMZoomAndPan = 1102, + kV8SVGGraphicsElement_Transform_AttributeGetter = 1103, + kMenuItemElement = 1104, + kMenuItemCloseTag = 1105, + kSVG1DOMMarkerElement = 1106, + kSVG1DOMUseElement = 1107, + kSVG1DOMMaskElement = 1108, + kV8SVGAElement_Target_AttributeGetter = 1109, + kV8SVGClipPathElement_ClipPathUnits_AttributeGetter = 1110, + kSVG1DOMFitToViewBox = 1111, + kSVG1DOMSVGElement = 1114, + kSVG1DOMImageElement = 1115, + kSVG1DOMForeignObjectElement = 1116, + kAudioContextCreateIIRFilter = 1117, + // The above items are available in M49 branch + + kCSSSelectorPseudoSlotted = 1118, + kMediaDevicesEnumerateDevices = 1119, + kEventComposedPath = 1123, + kLinkHeaderPreload = 1124, + kMouseWheelEvent = 1125, + kWheelEvent = 1126, + kMouseWheelAndWheelEvent = 1127, + kBodyScrollsInAdditionToViewport = 1128, + kDocumentDesignModeEnabeld = 1129, + kContentEditableTrue = 1130, + kContentEditableTrueOnHTML = 1131, + kContentEditablePlainTextOnly = 1132, + kV8RegExpPrototypeUnicodeGetter = 1133, + kOBSOLETE_V8IntlV8Parse = 1134, + kOBSOLETE_V8IntlPattern = 1135, + kOBSOLETE_V8IntlResolved = 1136, + kOBSOLETE_V8PromiseChain = 1137, + kOBSOLETE_V8PromiseAccept = 1138, + kOBSOLETE_V8PromiseDefer = 1139, + kEventComposed = 1140, + kGeolocationInsecureOriginIframe = 1141, + kGeolocationSecureOriginIframe = 1142, + kRequestMIDIAccessIframe_ObscuredByFootprinting = 1143, + kGetUserMediaInsecureOriginIframe = 1144, + kGetUserMediaSecureOriginIframe = 1145, + kElementRequestPointerLockIframe = 1146, + kNotificationAPIInsecureOriginIframe = 1147, + kNotificationAPISecureOriginIframe = 1148, + kWebSocket = 1149, + kMediaStreamConstraintsNameValue = 1150, + kOBSOLETE_MediaStreamConstraintsFromDictionary = 1151, + kMediaStreamConstraintsConformant = 1152, + kCSSSelectorIndirectAdjacent = 1153, + kCreateImageBitmap = 1156, + kPresentationConnectionConnectEventListener = 1157, + kPresentationConnectionCloseEventListener = 1158, + kPresentationConnectionTerminateEventListener = 1159, + kDocumentCreateEventAnimationEvent = 1162, + kDocumentCreateEventBeforeUnloadEvent = 1166, + kDocumentCreateEventCompositionEvent = 1168, + kDocumentCreateEventDragEvent = 1169, + kDocumentCreateEventErrorEvent = 1170, + kDocumentCreateEventFocusEvent = 1171, + kDocumentCreateEventHashChangeEvent = 1172, + kDocumentCreateEventMutationEvent = 1173, + kDocumentCreateEventPageTransitionEvent = 1174, + kDocumentCreateEventPopStateEvent = 1176, + kDocumentCreateEventTextEvent = 1182, + kDocumentCreateEventTransitionEvent = 1183, + kDocumentCreateEventWheelEvent = 1184, + kDocumentCreateEventTrackEvent = 1186, + kDocumentCreateEventMutationEvents = 1188, + kDocumentCreateEventSVGEvents = 1190, + kDocumentCreateEventDeviceMotionEvent = 1195, + kDocumentCreateEventDeviceOrientationEvent = 1196, + kDocumentCreateEventIDBVersionChangeEvent = 1201, + kDocumentCreateEventStorageEvent = 1221, + kDocumentCreateEventWebGLContextEvent = 1224, + kDocumentCreateEventCloseEvent = 1227, + kDocumentCreateEventKeyboardEvents = 1228, + kHTMLMediaElement = 1229, + kHTMLMediaElementInDocument = 1230, + kHTMLMediaElementControlsAttribute = 1231, + kV8Animation_Oncancel_AttributeGetter = 1233, + kV8Animation_Oncancel_AttributeSetter = 1234, + kV8HTMLCommentInExternalScript = 1235, + kV8HTMLComment = 1236, + kV8SloppyModeBlockScopedFunctionRedefinition = 1237, + kV8ForInInitializer = 1238, + kV8Animation_Id_AttributeGetter = 1239, + kV8Animation_Id_AttributeSetter = 1240, + kOBSOLETE_ApplicationCacheManifestSelectInsecureOrigin = 1245, + kOBSOLETE_ApplicationCacheManifestSelectSecureOrigin = 1246, + kOBSOLETE_ApplicationCacheAPIInsecureOrigin = 1247, + kOBSOLETE_ApplicationCacheAPISecureOrigin = 1248, + // The above items are available in M50 branch + + kCSSAtRuleApply = 1249, // Removed + kCSSSelectorPseudoAny = 1250, + kHTMLLabelElementControlForNonFormAssociatedElement = 1263, + kHTMLMediaElementLoadNetworkEmptyNotPaused = 1265, + kV8Window_WebkitSpeechGrammar_ConstructorGetter = 1267, + kV8Window_WebkitSpeechGrammarList_ConstructorGetter = 1268, + kV8Window_WebkitSpeechRecognition_ConstructorGetter = 1269, + kV8Window_WebkitSpeechRecognitionError_ConstructorGetter = 1270, + kV8Window_WebkitSpeechRecognitionEvent_ConstructorGetter = 1271, + kV8Window_SpeechSynthesis_AttributeGetter = 1272, + kV8IDBFactory_WebkitGetDatabaseNames_Method = 1273, + kScriptPassesCSPDynamic = 1275, + kCSPWithStrictDynamic = 1277, + kScrollAnchored = 1278, + kSVGCalcModeDiscrete = 1287, + kSVGCalcModeLinear = 1288, + kSVGCalcModePaced = 1289, + kSVGCalcModeSpline = 1290, + kFormSubmissionStarted = 1291, + kFormValidationStarted = 1292, + kFormValidationAbortedSubmission = 1293, + kFormValidationShowedMessage = 1294, + // The above items are available in M51 branch + + kV8Document_Images_AttributeGetter = 1297, + kV8Document_Embeds_AttributeGetter = 1298, + kV8Document_Plugins_AttributeGetter = 1299, + kV8Document_Links_AttributeGetter = 1300, + kV8Document_Forms_AttributeGetter = 1301, + kV8Document_Scripts_AttributeGetter = 1302, + kV8Document_Anchors_AttributeGetter = 1303, + kV8Document_Applets_AttributeGetter = 1304, + kMediaStreamTrackRemote = 1306, + kV8Node_IsConnected_AttributeGetter = 1307, + kShadowRootDelegatesFocus = 1308, + kOBSOLETE_MixedShadowRootV0AndV1 = 1309, + kFileAPINativeLineEndings = 1320, + kPointerEventAttributeCount = 1321, + kCompositedReplication = 1322, + kV8DataTransferItem_WebkitGetAsEntry_Method = 1325, + kV8HTMLInputElement_WebkitEntries_AttributeGetter = 1326, + kEntry_Filesystem_AttributeGetter_IsolatedFileSystem = 1327, + kEntry_GetMetadata_Method_IsolatedFileSystem = 1328, + kEntry_MoveTo_Method_IsolatedFileSystem = 1329, + kEntry_CopyTo_Method_IsolatedFileSystem = 1330, + kEntry_Remove_Method_IsolatedFileSystem = 1331, + kEntry_GetParent_Method_IsolatedFileSystem = 1332, + kEntry_ToURL_Method_IsolatedFileSystem = 1333, + kDuring_Microtask_Alert = 1334, + kDuring_Microtask_Confirm = 1335, + kDuring_Microtask_Print = 1336, + kDuring_Microtask_Prompt = 1337, + kDuring_Microtask_SyncXHR = 1338, + kCredentialManagerGetReturnedCredential = 1342, + kGeolocationInsecureOriginDeprecatedNotRemoved = 1343, + kGeolocationInsecureOriginIframeDeprecatedNotRemoved = 1344, + kProgressElementWithNoneAppearance = 1345, + kProgressElementWithProgressBarAppearance = 1346, + kPointerEventAddListenerCount = 1347, + kCSSValueAppearanceNone = 1351, + kCSSValueAppearanceNotNone = 1352, + kCSSValueAppearanceOthers = 1353, + kCSSValueAppearanceButton = 1354, + kCSSValueAppearanceCheckbox = 1356, + kCSSValueAppearanceMenulist = 1357, + kCSSValueAppearanceMenulistButton = 1358, + kCSSValueAppearanceListbox = 1359, + kCSSValueAppearanceRadio = 1360, + kCSSValueAppearanceSearchField = 1361, + kCSSValueAppearanceTextField = 1362, + kAudioContextCreatePannerAutomated = 1363, + kPannerNodeSetPosition = 1364, + kPannerNodeSetOrientation = 1365, + kAudioListenerSetPosition = 1366, + kAudioListenerSetOrientation = 1367, + kIntersectionObserver_Constructor = 1368, + kDurableStoragePersist = 1369, + kDurableStoragePersisted = 1370, + kDurableStorageEstimate = 1371, + kOBSOLETE_CSSDeepCombinatorAndShadow = 1375, + kOpacityWithPreserve3DQuirk = 1376, + kCSSSelectorPseudoReadOnly = 1377, + kCSSSelectorPseudoReadWrite = 1378, + // The above items are available in M52 branch + + kCSSSelectorPseudoDefined = 1383, + kRTCPeerConnectionAddIceCandidatePromise = 1384, + kRTCPeerConnectionAddIceCandidateLegacy = 1385, + kRTCIceCandidateDefaultSdpMLineIndex = 1386, + kMediaStreamConstraintsOldAndNew = 1389, + kOBSOLETE_V8ArrayProtectorDirtied = 1390, + kV8ArraySpeciesModified = 1391, + kV8ArrayPrototypeConstructorModified = 1392, + kOBSOLETE_V8ArrayInstanceProtoModified = 1393, + kV8ArrayInstanceConstructorModified = 1394, + kOBSOLETE_V8LegacyFunctionDeclaration = 1395, + kOBSOLETE_V8RegExpPrototypeSourceGetter = 1396, + kOBSOLETE_V8RegExpPrototypeOldFlagGetter = 1397, + kV8DecimalWithLeadingZeroInStrictMode = 1398, + kGetUserMediaPrefixed = 1400, + kGetUserMediaLegacy = 1401, + kGetUserMediaPromise = 1402, + kCSSFilterFunctionNoArguments = 1403, + kV8LegacyDateParser = 1404, + kOpenSearchInsecureOriginInsecureTarget = 1405, + kOpenSearchInsecureOriginSecureTarget = 1406, + kOpenSearchSecureOriginInsecureTarget = 1407, + kOpenSearchSecureOriginSecureTarget = 1408, + kRegisterProtocolHandlerSecureOrigin = 1409, + kRegisterProtocolHandlerInsecureOrigin = 1410, + kCrossOriginWindowAlert = 1411, + kCrossOriginWindowConfirm = 1412, + kOBSOLETE_CrossOriginWindowPrompt = 1413, + kCrossOriginWindowPrint = 1414, + kMediaStreamOnActive = 1415, + kMediaStreamOnInactive = 1416, + kAddEventListenerPassiveTrue = 1417, + kAddEventListenerPassiveFalse = 1418, + kCSPReferrerDirective = 1419, + kElementRequestPointerLockInShadow = 1421, + kShadowRootPointerLockElement = 1422, + kOBSOLETE_DocumentPointerLockElementInV0Shadow = 1423, + kTextAreaMaxLength = 1424, + kTextAreaMinLength = 1425, + kTopNavigationFromSubFrame = 1426, + kPrefixedElementRequestFullscreenInShadow = 1427, + kMediaSourceAbortRemove = 1428, + kMediaSourceDurationTruncatingBuffered = 1429, + kAudioContextCrossOriginIframe = 1430, + // The above items are available in M53 branch + + kPointerEventSetCapture = 1431, + kPointerEventDispatch = 1432, + kMIDIMessageEventReceivedTime = 1433, + kV8MediaStream_Active_AttributeGetter = 1435, + kBeforeInstallPromptEvent = 1436, + kBeforeInstallPromptEventUserChoice = 1437, + kBeforeInstallPromptEventPreventDefault = 1438, + kBeforeInstallPromptEventPrompt = 1439, + kExecCommandAltersHTMLStructure = 1440, + kSecureContextCheckPassed = 1441, + kSecureContextCheckFailed = 1442, + kSecureContextCheckForSandboxedOriginPassed = 1443, + kSecureContextCheckForSandboxedOriginFailed = 1444, + kV8DefineGetterOrSetterWouldThrow = 1445, + kV8FunctionConstructorReturnedUndefined = 1446, + kV8BroadcastChannel_Constructor = 1447, + kV8BroadcastChannel_PostMessage_Method = 1448, + kV8BroadcastChannel_Close_Method = 1449, + kTouchStartFired = 1450, + kMouseDownFired = 1451, + kPointerDownFired = 1452, + kPointerDownFiredForTouch = 1453, + kPointerEventDispatchPointerDown = 1454, + kSVGSMILBeginOrEndEventValue = 1455, + kSVGSMILBeginOrEndSyncbaseValue = 1456, + kSVGSMILElementInsertedAfterLoad = 1457, + kV8VisualViewport_OffsetLeft_AttributeGetter = 1458, + kV8VisualViewport_OffsetTop_AttributeGetter = 1459, + kV8VisualViewport_PageLeft_AttributeGetter = 1460, + kV8VisualViewport_PageTop_AttributeGetter = 1461, + kV8VisualViewport_Width_AttributeGetter = 1462, + kV8VisualViewport_Height_AttributeGetter = 1463, + kV8VisualViewport_Scale_AttributeGetter = 1464, + kVisualViewportScrollFired = 1465, + kVisualViewportResizeFired = 1466, + kNodeGetRootNode = 1467, + kSlotChangeEventAddListener = 1468, + kCSSValueAppearanceButtonForButton = 1471, + kCSSValueAppearanceButtonForOtherButtons = 1472, + kCSSValueAppearanceTextFieldForSearch = 1474, + kCSSValueAppearanceTextFieldForTextField = 1475, + kRTCPeerConnectionGetStats = 1476, + kSVGSMILAnimationAppliedEffect = 1477, + kPerformanceResourceTimingSizes = 1478, + kEventSourceDocument = 1479, + kEventSourceWorker = 1480, + kSingleOriginInTimingAllowOrigin = 1481, + kMultipleOriginsInTimingAllowOrigin = 1482, + kStarInTimingAllowOrigin = 1483, + kSVGSMILAdditiveAnimation = 1484, + kOBSOLETE_SendBeaconWithNonSimpleContentType = 1485, + kChromeLoadTimesRequestTime = 1486, + kChromeLoadTimesStartLoadTime = 1487, + kChromeLoadTimesCommitLoadTime = 1488, + kChromeLoadTimesFinishDocumentLoadTime = 1489, + kChromeLoadTimesFinishLoadTime = 1490, + kChromeLoadTimesFirstPaintTime = 1491, + kChromeLoadTimesFirstPaintAfterLoadTime = 1492, + kChromeLoadTimesNavigationType = 1493, + kChromeLoadTimesWasFetchedViaSpdy = 1494, + kChromeLoadTimesWasNpnNegotiated = 1495, + kChromeLoadTimesNpnNegotiatedProtocol = 1496, + kChromeLoadTimesWasAlternateProtocolAvailable = 1497, + kChromeLoadTimesConnectionInfo = 1498, + kChromeLoadTimesUnknown = 1499, + kSVGViewElement = 1500, + kWebShareShare = 1501, + kAuxclickAddListenerCount = 1502, + kHTMLCanvasElement = 1503, + kSVGSMILAnimationElementTiming = 1504, + kSVGSMILBeginEndAnimationElement = 1505, + kSVGSMILPausing = 1506, + kSVGSMILCurrentTime = 1507, + kHTMLBodyElementOnSelectionChangeAttribute = 1508, + kUsbGetDevices = 1519, + kUsbRequestDevice = 1520, + kUsbDeviceOpen = 1521, + kUsbDeviceClose = 1522, + kUsbDeviceSelectConfiguration = 1523, + kUsbDeviceClaimInterface = 1524, + kUsbDeviceReleaseInterface = 1525, + kUsbDeviceSelectAlternateInterface = 1526, + kUsbDeviceControlTransferIn = 1527, + kUsbDeviceControlTransferOut = 1528, + kUsbDeviceClearHalt = 1529, + kUsbDeviceTransferIn = 1530, + kUsbDeviceTransferOut = 1531, + kUsbDeviceIsochronousTransferIn = 1532, + kUsbDeviceIsochronousTransferOut = 1533, + kUsbDeviceReset = 1534, + // The above items are available in M54 branch + + kPointerEnterLeaveFired = 1535, + kPointerOverOutFired = 1536, + kDraggableAttribute = 1539, + kCleanScriptElementWithNonce = 1540, + kPotentiallyInjectedScriptElementWithNonce = 1541, + kPendingStylesheetAddedAfterBodyStarted = 1542, + kUntrustedMouseDownEventDispatchedToSelect = 1543, + kBlockedSniffingAudioToScript = 1544, + kBlockedSniffingVideoToScript = 1545, + kBlockedSniffingCSVToScript = 1546, + kMetaRefresh = 1548, + kMetaRefreshWhenCSPBlocksInlineScript = 1550, + kMiddleClickAutoscrollStart = 1551, + kRTCPeerConnectionCreateOfferOptionsOfferToReceive = 1553, + kDragAndDropScrollStart = 1554, + kPresentationConnectionListConnectionAvailableEventListener = 1555, + kWebAudioAutoplayCrossOriginIframe = 1556, + kVRGetDisplays = 1558, + kXSSAuditorBlockedScript = 1581, + kXSSAuditorBlockedEntirePage = 1582, + kXSSAuditorDisabled = 1583, + kXSSAuditorEnabledFilter = 1584, + kXSSAuditorEnabledBlock = 1585, + kXSSAuditorInvalid = 1586, + kTextInputEventOnInput = 1589, + kTextInputEventOnTextArea = 1590, + kTextInputEventOnContentEditable = 1591, + kTextInputEventOnNotNode = 1592, + kWebkitBeforeTextInsertedOnInput = 1593, + kWebkitBeforeTextInsertedOnTextArea = 1594, + kWebkitBeforeTextInsertedOnContentEditable = 1595, + kWebkitBeforeTextInsertedOnNotNode = 1596, + kWebkitEditableContentChangedOnInput = 1597, + kWebkitEditableContentChangedOnTextArea = 1598, + kWebkitEditableContentChangedOnContentEditable = 1599, + kWebkitEditableContentChangedOnNotNode = 1600, + kV8NavigatorUserMediaError_ConstraintName_AttributeGetter = 1601, + kV8HTMLMediaElement_SrcObject_AttributeGetter = 1602, + kV8HTMLMediaElement_SrcObject_AttributeSetter = 1603, + kCreateObjectURLBlob = 1604, + kCreateObjectURLMediaSource = 1605, + kCreateObjectURLMediaStream = 1606, + kLongTaskObserver = 1615, + kCSSOffsetInEffect = 1617, + // The above items are available in M55 branch + + kVRGetDisplaysInsecureOrigin = 1618, + kVRRequestPresent = 1619, + kVRRequestPresentInsecureOrigin = 1620, + kVRDeprecatedFieldOfView = 1621, + kVideoInCanvas = 1622, + kHiddenAutoplayedVideoInCanvas = 1623, + kOffscreenCanvas = 1624, + kGamepadPose = 1625, + kGamepadHand = 1626, + kGamepadDisplayId = 1627, + kGamepadButtonTouched = 1628, + kGamepadPoseHasOrientation = 1629, + kGamepadPoseHasPosition = 1630, + kGamepadPosePosition = 1631, + kGamepadPoseLinearVelocity = 1632, + kGamepadPoseLinearAcceleration = 1633, + kGamepadPoseOrientation = 1634, + kGamepadPoseAngularVelocity = 1635, + kGamepadPoseAngularAcceleration = 1636, + kV8RTCDataChannel_MaxRetransmitTime_AttributeGetter = 1638, + kV8RTCDataChannel_MaxRetransmits_AttributeGetter = 1639, + kV8RTCDataChannel_Reliable_AttributeGetter = 1640, + kV8RTCPeerConnection_AddStream_Method = 1641, + kV8RTCPeerConnection_CreateDTMFSender_Method = 1642, + kV8RTCPeerConnection_GetLocalStreams_Method = 1643, + kV8RTCPeerConnection_GetRemoteStreams_Method = 1644, + kV8RTCPeerConnection_RemoveStream_Method = 1646, + kRTCPeerConnectionCreateDataChannelMaxRetransmitTime = 1648, + kRTCPeerConnectionCreateDataChannelMaxRetransmits = 1649, + kAudioContextCreateConstantSource = 1650, + kWebAudioConstantSourceNode = 1651, + kBlinkMacSystemFont = 1654, + kRTCIceServerURL = 1656, + kRTCIceServerURLs = 1657, + kOffscreenCanvasTransferToImageBitmap2D = 1658, + kOffscreenCanvasTransferToImageBitmapWebGL = 1659, + kOBSOLETE_OffscreenCanvasCommit2D = 1660, + kOffscreenCanvasCommitWebGL = 1661, + kRTCConfigurationIceTransportPolicy = 1662, + kRTCConfigurationIceTransports = 1664, + kOBSOLETE_DocumentFullscreenElementInV0Shadow = 1665, + kScriptWithCSPBypassingSchemeParserInserted = 1666, + kScriptWithCSPBypassingSchemeNotParserInserted = 1667, + kDocumentCreateElement2ndArgStringHandling = 1668, + kV8MediaRecorder_Start_Method = 1669, + kWebBluetoothRequestDevice = 1670, + kUnitlessPerspectiveInPerspectiveProperty = 1671, + kUnitlessPerspectiveInTransformProperty = 1672, + kV8RTCSessionDescription_Type_AttributeGetter = 1673, + kV8RTCSessionDescription_Type_AttributeSetter = 1674, + kV8RTCSessionDescription_Sdp_AttributeGetter = 1675, + kV8RTCSessionDescription_Sdp_AttributeSetter = 1676, + kRTCSessionDescriptionInitNoType = 1677, + kRTCSessionDescriptionInitNoSdp = 1678, + kHTMLMediaElementPreloadForcedMetadata = 1679, + kGenericSensorStart = 1680, + kGenericSensorStop = 1681, + kTouchEventPreventedNoTouchAction = 1682, + kTouchEventPreventedForcedDocumentPassiveNoTouchAction = 1683, + kV8Event_StopPropagation_Method = 1684, + kV8Event_StopImmediatePropagation_Method = 1685, + kImageCaptureConstructor = 1686, + kV8Document_RootScroller_AttributeGetter = 1687, + kV8Document_RootScroller_AttributeSetter = 1688, + kCustomElementRegistryDefine = 1689, + kLinkHeaderServiceWorker = 1690, + // The above items are available in M56 branch. + + kCSSFlexibleBox = 1692, + kCSSGridLayout = 1693, + kFullscreenAllowedByOrientationChange = 1696, + kServiceWorkerRespondToNavigationRequestWithRedirectedResponse = 1697, + kV8AudioContext_Constructor = 1698, + kV8OfflineAudioContext_Constructor = 1699, + kAppInstalledEventAddListener = 1700, + kAudioContextGetOutputTimestamp = 1701, + kV8MediaStreamAudioDestinationNode_Constructor = 1702, + kV8AnalyserNode_Constructor = 1703, + kV8AudioBuffer_Constructor = 1704, + kV8AudioBufferSourceNode_Constructor = 1705, + kV8AudioProcessingEvent_Constructor = 1706, + kV8BiquadFilterNode_Constructor = 1707, + kV8ChannelMergerNode_Constructor = 1708, + kV8ChannelSplitterNode_Constructor = 1709, + kV8ConstantSourceNode_Constructor = 1710, + kV8ConvolverNode_Constructor = 1711, + kV8DelayNode_Constructor = 1712, + kV8DynamicsCompressorNode_Constructor = 1713, + kV8GainNode_Constructor = 1714, + kV8IIRFilterNode_Constructor = 1715, + kV8MediaElementAudioSourceNode_Constructor = 1716, + kV8MediaStreamAudioSourceNode_Constructor = 1717, + kV8OfflineAudioCompletionEvent_Constructor = 1718, + kV8OscillatorNode_Constructor = 1719, + kV8PannerNode_Constructor = 1720, + kV8PeriodicWave_Constructor = 1721, + kV8StereoPannerNode_Constructor = 1722, + kV8WaveShaperNode_Constructor = 1723, + kV8Headers_GetAll_Method = 1724, + kNavigatorVibrateEngagementNone = 1725, + kNavigatorVibrateEngagementMinimal = 1726, + kNavigatorVibrateEngagementLow = 1727, + kNavigatorVibrateEngagementMedium = 1728, + kNavigatorVibrateEngagementHigh = 1729, + kNavigatorVibrateEngagementMax = 1730, + kAlertEngagementNone = 1731, + kAlertEngagementMinimal = 1732, + kAlertEngagementLow = 1733, + kAlertEngagementMedium = 1734, + kAlertEngagementHigh = 1735, + kAlertEngagementMax = 1736, + kConfirmEngagementNone = 1737, + kConfirmEngagementMinimal = 1738, + kConfirmEngagementLow = 1739, + kConfirmEngagementMedium = 1740, + kConfirmEngagementHigh = 1741, + kConfirmEngagementMax = 1742, + kPromptEngagementNone = 1743, + kPromptEngagementMinimal = 1744, + kPromptEngagementLow = 1745, + kPromptEngagementMedium = 1746, + kPromptEngagementHigh = 1747, + kPromptEngagementMax = 1748, + kTopNavInSandbox = 1749, + kTopNavInSandboxWithoutGesture = 1750, + kTopNavInSandboxWithPerm = 1751, + kTopNavInSandboxWithPermButNoGesture = 1752, + kReferrerPolicyHeader = 1753, + kHTMLAnchorElementReferrerPolicyAttribute = 1754, + kHTMLIFrameElementReferrerPolicyAttribute = 1755, + kHTMLImageElementReferrerPolicyAttribute = 1756, + kHTMLLinkElementReferrerPolicyAttribute = 1757, + kBaseElement = 1758, + kBaseWithCrossOriginHref = 1759, + kBaseWithDataHref = 1760, + kBaseWithNewlinesInTarget = 1761, + kBaseWithOpenBracketInTarget = 1762, + kOBSOLETE_BaseWouldBeBlockedByDefaultSrc = 1763, + kV8AssigmentExpressionLHSIsCallInSloppy = 1764, + kV8AssigmentExpressionLHSIsCallInStrict = 1765, + kV8PromiseConstructorReturnedUndefined = 1766, + kFormSubmittedWithUnclosedFormControl = 1767, + kScrollbarUseVerticalScrollbarButton = 1777, + kScrollbarUseVerticalScrollbarTrack = 1779, + kScrollbarUseHorizontalScrollbarButton = 1780, + kScrollbarUseHorizontalScrollbarTrack = 1782, + kHTMLTableCellElementColspan = 1783, + kOBSOLETE_HTMLTableCellElementColspanGreaterThan1000 = 1784, + kOBSOLETE_HTMLTableCellElementColspanGreaterThan8190 = 1785, + kOBSOLETE_SelectionAddRangeIntersect = 1786, + kPostMessageFromInsecureToSecureToplevel = 1787, + // The above items are available in M57 branch. + + kV8MediaSession_Metadata_AttributeGetter = 1788, + kV8MediaSession_Metadata_AttributeSetter = 1789, + kV8MediaSession_PlaybackState_AttributeGetter = 1790, + kV8MediaSession_PlaybackState_AttributeSetter = 1791, + kV8MediaSession_SetActionHandler_Method = 1792, + kAudioParamCancelAndHoldAtTime = 1797, + kCSSValueUserModifyReadOnly = 1798, + kCSSValueUserModifyReadWrite = 1799, + kCSSValueUserModifyReadWritePlaintextOnly = 1800, + kCSSValueOnDemand = 1802, + kServiceWorkerNavigationPreload = 1803, + kFullscreenRequestWithPendingElement = 1804, + kHTMLIFrameElementAllowfullscreenAttributeSetAfterContentLoad = 1805, + kPointerEventSetCaptureOutsideDispatch = 1806, + kNotificationPermissionRequestedInsecureOrigin = 1807, + kV8DeprecatedStorageInfo_QueryUsageAndQuota_Method = 1808, + kV8DeprecatedStorageInfo_RequestQuota_Method = 1809, + kV8DeprecatedStorageQuota_QueryUsageAndQuota_Method = 1810, + kV8DeprecatedStorageQuota_RequestQuota_Method = 1811, + kV8FileReaderSync_Constructor = 1812, + kV8HTMLVideoElement_Poster_AttributeGetter = 1815, + kV8HTMLVideoElement_Poster_AttributeSetter = 1816, + kNotificationPermissionRequestedIframe = 1817, + kRtcpMuxPolicyNegotiate = 1823, + kDOMClobberedWindowPropertyAccessed = 1824, + kHTMLDocumentCreateProcessingInstruction = 1825, + kFetchResponseConstructionWithStream = 1826, + kLocationOrigin = 1827, + kCanvas2DFilter = 1830, + kCanvas2DImageSmoothingQuality = 1831, + kCanvasToBlob = 1832, + kCanvasToDataURL = 1833, + kOffscreenCanvasConvertToBlob = 1834, + kSVGInCanvas2D = 1835, + kSVGInWebGL = 1836, + kSelectionFuncionsChangeFocus = 1837, + kHTMLObjectElementGetter = 1838, + kHTMLObjectElementSetter = 1839, + kHTMLEmbedElementGetter = 1840, + kHTMLEmbedElementSetter = 1841, + kTransformUsesBoxSizeOnSVG = 1842, + // The above items are available in M58 branch. + + kScrollByKeyboardArrowKeys = 1843, + kScrollByKeyboardPageUpDownKeys = 1844, + kScrollByKeyboardHomeEndKeys = 1845, + kScrollByKeyboardSpacebarKey = 1846, + kScrollByTouch = 1847, + kScrollByWheel = 1848, + kScheduledActionIgnored = 1849, + kGetCanvas2DContextAttributes = 1850, + kV8HTMLInputElement_Capture_AttributeGetter = 1851, + kV8HTMLInputElement_Capture_AttributeSetter = 1852, + kHTMLMediaElementControlsListAttribute = 1853, + kHTMLMediaElementControlsListNoDownload = 1854, + kHTMLMediaElementControlsListNoFullscreen = 1855, + kHTMLMediaElementControlsListNoRemotePlayback = 1856, + kPointerEventClickRetargetCausedByCapture = 1857, + kVRDisplayDisplayName = 1861, + kVREyeParametersOffset = 1862, + kVRPoseLinearVelocity = 1863, + kVRPoseLinearAcceleration = 1864, + kVRPoseAngularVelocity = 1865, + kVRPoseAngularAcceleration = 1866, + kCSSOverflowPaged = 1867, + kOBSOLETE_HTMLTableElementPresentationAttributeBackground = 1869, + kV8Navigator_GetInstalledRelatedApps_Method = 1870, + kNamedAccessOnWindow_ChildBrowsingContext = 1871, + kNamedAccessOnWindow_ChildBrowsingContext_CrossOriginNameMismatch = 1872, + kV0CustomElementsRegisterHTMLCustomTag = 1873, + kV0CustomElementsRegisterHTMLTypeExtension = 1874, + kV0CustomElementsRegisterSVGElement = 1875, + kV0CustomElementsCreateCustomTagElement = 1877, + kV0CustomElementsCreateTypeExtensionElement = 1878, + kV0CustomElementsConstruct = 1879, + kWebBluetoothRemoteCharacteristicGetDescriptor = 1882, + kWebBluetoothRemoteCharacteristicGetDescriptors = 1883, + kWebBluetoothRemoteCharacteristicReadValue = 1884, + kWebBluetoothRemoteCharacteristicWriteValue = 1885, + kWebBluetoothRemoteCharacteristicStartNotifications = 1886, + kWebBluetoothRemoteCharacteristicStopNotifications = 1887, + kWebBluetoothRemoteDescriptorReadValue = 1888, + kWebBluetoothRemoteDescriptorWriteValue = 1889, + kWebBluetoothRemoteServerConnect = 1890, + kWebBluetoothRemoteServerDisconnect = 1891, + kWebBluetoothRemoteServerGetPrimaryService = 1892, + kWebBluetoothRemoteServerGetPrimaryServices = 1893, + kWebBluetoothRemoteServiceGetCharacteristic = 1894, + kWebBluetoothRemoteServiceGetCharacteristics = 1895, + kOBSOLETE_HTMLContentElement = 1896, + kOBSOLETE_HTMLShadowElement = 1897, + kHTMLSlotElement = 1898, + kAccelerometerConstructor = 1899, + kAbsoluteOrientationSensorConstructor = 1900, + kAmbientLightSensorConstructor = 1901, + kGenericSensorOnActivate = 1902, + kGenericSensorOnChange = 1903, + kGenericSensorOnError = 1904, + kGenericSensorActivated = 1905, + kGyroscopeConstructor = 1906, + kMagnetometerConstructor = 1907, + kOrientationSensorPopulateMatrix = 1908, + kWindowOpenWithInvalidURL = 1909, + kCrossOriginMainFrameNulledNameAccessed = 1910, + kMenuItemElementIconAttribute = 1911, + kWebkitCSSMatrixSetMatrixValue = 1912, + kWebkitCSSMatrixConstructFromString = 1913, + kCanRequestURLHTTPContainingNewline = 1914, + kGetGamepads = 1916, + kMediaStreamConstraintsAudio = 1918, + kMediaStreamConstraintsAudioUnconstrained = 1919, + kMediaStreamConstraintsVideo = 1920, + kMediaStreamConstraintsVideoUnconstrained = 1921, + kMediaStreamConstraintsWidth = 1922, + kMediaStreamConstraintsHeight = 1923, + kMediaStreamConstraintsAspectRatio = 1924, + kMediaStreamConstraintsFrameRate = 1925, + kMediaStreamConstraintsFacingMode = 1926, + kMediaStreamConstraintsVolume = 1927, + kMediaStreamConstraintsSampleRate = 1928, + kMediaStreamConstraintsSampleSize = 1929, + kMediaStreamConstraintsEchoCancellation = 1930, + kMediaStreamConstraintsLatency = 1931, + kMediaStreamConstraintsChannelCount = 1932, + kMediaStreamConstraintsDeviceIdAudio = 1933, + kMediaStreamConstraintsDeviceIdVideo = 1934, + kMediaStreamConstraintsDisableLocalEcho = 1935, + kMediaStreamConstraintsGroupIdAudio = 1936, + kMediaStreamConstraintsGroupIdVideo = 1937, + kOBSOLETE_MediaStreamConstraintsVideoKind = 1938, + kMediaStreamConstraintsMediaStreamSourceAudio = 1943, + kMediaStreamConstraintsMediaStreamSourceVideo = 1944, + kMediaStreamConstraintsRenderToAssociatedSink = 1945, + kMediaStreamConstraintsHotwordEnabled = 1946, + kMediaStreamConstraintsGoogEchoCancellation = 1947, + kMediaStreamConstraintsGoogExperimentalEchoCancellation = 1948, + kMediaStreamConstraintsGoogAutoGainControl = 1949, + kMediaStreamConstraintsGoogExperimentalAutoGainControl = 1950, + kMediaStreamConstraintsGoogNoiseSuppression = 1951, + kMediaStreamConstraintsGoogHighpassFilter = 1952, + kMediaStreamConstraintsGoogTypingNoiseDetection = 1953, + kMediaStreamConstraintsGoogExperimentalNoiseSuppression = 1954, + kMediaStreamConstraintsGoogBeamforming = 1955, + kMediaStreamConstraintsGoogArrayGeometry = 1956, + kMediaStreamConstraintsGoogAudioMirroring = 1957, + kMediaStreamConstraintsGoogDAEchoCancellation = 1958, + kMediaStreamConstraintsGoogNoiseReduction = 1959, + // The above items are available in M59 branch. + + kViewportFixedPositionUnderFilter = 1961, + kRequestMIDIAccessWithSysExOption_ObscuredByFootprinting = 1962, + kRequestMIDIAccessIframeWithSysExOption_ObscuredByFootprinting = 1963, + kGamepadAxes = 1964, + kGamepadButtons = 1965, + kOBSOLETE_DispatchMouseEventOnDisabledFormControl = 1967, + kElementNameDOMInvalidHTMLParserValid = 1968, + kElementNameDOMValidHTMLParserInvalid = 1969, + kGATTServerDisconnectedEvent = 1970, + kAnchorClickDispatchForNonConnectedNode = 1971, + kHTMLParseErrorNestedForm = 1972, + kFontShapingNotDefGlyphObserved = 1973, + kPostMessageOutgoingWouldBeBlockedByConnectSrc = 1974, + kPostMessageIncomingWouldBeBlockedByConnectSrc = 1975, + kCrossOriginPropertyAccess = 1977, + kCrossOriginPropertyAccessFromOpener = 1978, + kCredentialManagerCreate = 1979, + kFieldEditInSecureContext = 1981, + kFieldEditInNonSecureContext = 1982, + kCredentialManagerGetMediationRequired = 1984, + kNetInfoRtt = 1989, + kNetInfoDownlink = 1990, + kOBSOLETE_ShapeDetection_BarcodeDetectorConstructor = 1991, + kOBSOLETE_ShapeDetection_FaceDetectorConstructor = 1992, + kOBSOLETE_ShapeDetection_TextDetectorConstructor = 1993, + kOBSOLETE_InertAttribute = 1995, + kPluginInstanceAccessFromIsolatedWorld = 1996, + kPluginInstanceAccessFromMainWorld = 1997, + kShowModalForElementInFullscreenStack = 2000, + kThreeValuedPositionBackground = 2001, + kUnitlessZeroAngleFilter = 2007, + kUnitlessZeroAngleGradient = 2008, + kUnitlessZeroAngleTransform = 2010, + kCredentialManagerPreventSilentAccess = 2012, + kNetInfoEffectiveType = 2013, + kV8SpeechRecognition_Start_Method = 2014, + kTableRowDirectionDifferentFromTable = 2015, + kTableSectionDirectionDifferentFromTable = 2016, + // The above items are available in M60 branch. + + kClientHintsDeviceMemory_DEPRECATED = 2017, + kCSSRegisterProperty = 2018, + kRelativeOrientationSensorConstructor = 2019, + kOBSOLETE_kSmoothScrollJSInterventionActivated = 2020, + kBudgetAPIGetCost = 2021, + kBudgetAPIGetBudget = 2022, + kCrossOriginMainFrameNulledNonEmptyNameAccessed = 2023, + kDocumentDomainSetWithNonDefaultPort = 2025, + kDocumentDomainSetWithDefaultPort = 2026, + kFeaturePolicyHeader = 2027, + kFeaturePolicyAllowAttribute = 2028, + kMIDIPortOpen = 2029, + kMIDIOutputSend = 2030, + kMIDIMessageEvent = 2031, + kFetchEventIsReload = 2032, + kServiceWorkerClientFrameType = 2033, + kQuirksModeDocument = 2034, + kLimitedQuirksModeDocument = 2035, + kEncryptedMediaCrossOriginIframe = 2036, + kCSSSelectorWebkitMediaControls = 2037, + kCSSSelectorWebkitMediaControlsOverlayEnclosure = 2038, + kCSSSelectorWebkitMediaControlsOverlayPlayButton = 2039, + kCSSSelectorWebkitMediaControlsEnclosure = 2040, + kCSSSelectorWebkitMediaControlsPanel = 2041, + kCSSSelectorWebkitMediaControlsPlayButton = 2042, + kCSSSelectorWebkitMediaControlsCurrentTimeDisplay = 2043, + kCSSSelectorWebkitMediaControlsTimeRemainingDisplay = 2044, + kCSSSelectorWebkitMediaControlsTimeline = 2045, + kCSSSelectorWebkitMediaControlsTimelineContainer = 2046, + kCSSSelectorWebkitMediaControlsMuteButton = 2047, + kCSSSelectorWebkitMediaControlsVolumeSlider = 2048, + kCSSSelectorWebkitMediaControlsFullscreenButton = 2049, + kCSSSelectorWebkitMediaControlsToggleClosedCaptionsButton = 2050, + kLinearAccelerationSensorConstructor = 2051, + kReportUriMultipleEndpoints = 2052, + kReportUriSingleEndpoint = 2053, + kOBSOLETE_V8ConstructorNonUndefinedPrimitiveReturn = 2054, + kMediaSourceKeyframeTimeGreaterThanDependant = 2060, + kMediaSourceMuxedSequenceMode = 2061, + kPrepareModuleScript = 2062, + // The above items are available as of the M61 branch. + + kPresentationRequestStartSecureOrigin = 2063, + kPresentationRequestStartInsecureOrigin = 2064, + kPersistentClientHintHeader = 2065, + kStyleSheetListNonNullAnonymousNamedGetter = 2066, + kARIAActiveDescendantAttribute = 2069, + kARIAAtomicAttribute = 2070, + kARIAAutocompleteAttribute = 2071, + kARIABusyAttribute = 2072, + kARIACheckedAttribute = 2073, + kARIAColCountAttribute = 2074, + kARIAColIndexAttribute = 2075, + kARIAColSpanAttribute = 2076, + kARIAControlsAttribute = 2077, + kARIACurrentAttribute = 2078, + kARIADescribedByAttribute = 2079, + kARIADetailsAttribute = 2080, + kARIADisabledAttribute = 2081, + kARIADropEffectAttribute = 2082, + kARIAErrorMessageAttribute = 2083, + kARIAExpandedAttribute = 2084, + kARIAFlowToAttribute = 2085, + kARIAGrabbedAttribute = 2086, + kARIAHasPopupAttribute = 2087, + kARIAHiddenAttribute = 2089, + kARIAInvalidAttribute = 2090, + kARIAKeyShortcutsAttribute = 2091, + kARIALabelAttribute = 2092, + kARIALabeledByAttribute = 2093, + kARIALabelledByAttribute = 2094, + kARIALevelAttribute = 2095, + kARIALiveAttribute = 2096, + kARIAModalAttribute = 2097, + kARIAMultilineAttribute = 2098, + kARIAMultiselectableAttribute = 2099, + kARIAOrientationAttribute = 2100, + kARIAOwnsAttribute = 2101, + kARIAPlaceholderAttribute = 2102, + kARIAPosInSetAttribute = 2103, + kARIAPressedAttribute = 2104, + kARIAReadOnlyAttribute = 2105, + kARIARelevantAttribute = 2106, + kARIARequiredAttribute = 2107, + kARIARoleDescriptionAttribute = 2108, + kARIARowCountAttribute = 2109, + kARIARowIndexAttribute = 2110, + kARIARowSpanAttribute = 2111, + kARIASelectedAttribute = 2112, + kARIASetSizeAttribute = 2113, + kARIASortAttribute = 2114, + kARIAValueMaxAttribute = 2115, + kARIAValueMinAttribute = 2116, + kARIAValueNowAttribute = 2117, + kARIAValueTextAttribute = 2118, + kOBSOLETE_V8LabeledExpressionStatement = 2119, + kNavigatorDeviceMemory = 2121, + kFixedWidthTableDistributionChanged = 2122, + kWebkitBoxLayout = 2123, + kWebkitBoxLayoutHorizontal = 2124, + kWebkitBoxLayoutVertical = 2125, + kWebkitBoxAlignNotInitial = 2126, + kWebkitBoxDirectionNotInitial = 2127, + kWebkitBoxLinesNotInitial = 2128, + kWebkitBoxPackNotInitial = 2129, + kWebkitBoxChildFlexNotInitial = 2130, + kWebkitBoxChildFlexGroupNotInitial = 2131, + kWebkitBoxChildOrdinalGroupNotInitial = 2132, + kWebkitBoxNotDefaultOrder = 2133, + kWebkitBoxNoChildren = 2134, + kWebkitBoxOneChild = 2135, + kWebkitBoxOneChildIsLayoutBlockFlowInline = 2136, + kWebkitBoxManyChildren = 2137, + kWebkitBoxLineClamp = 2138, + kWebkitBoxLineClampPercentage = 2139, + kWebkitBoxLineClampNoChildren = 2140, + kWebkitBoxLineClampOneChild = 2141, + kWebkitBoxLineClampOneChildIsLayoutBlockFlowInline = 2142, + kWebkitBoxLineClampManyChildren = 2143, + kWebkitBoxLineClampDoesSomething = 2144, + // The above items are available as of the M62 branch. + + kFeaturePolicyAllowAttributeDeprecatedSyntax = 2145, + kSuppressHistoryEntryWithoutUserGesture = 2146, + kPerformanceServerTiming = 2157, + kAnimationSetPlaybackRateCompensatorySeek = 2162, + kOBSOLETE_DeepCombinatorInStaticProfile = 2163, + kOBSOLETE_PseudoShadowInStaticProfile = 2164, + kSchemeBypassesCSP = 2165, + kInnerSchemeBypassesCSP = 2166, + kSameOriginApplicationOctetStream = 2167, + kSameOriginApplicationXml = 2168, + kSameOriginTextHtml = 2169, + kSameOriginTextPlain = 2170, + kSameOriginTextXml = 2171, + kCrossOriginApplicationOctetStream = 2172, + kCrossOriginApplicationXml = 2173, + kCrossOriginTextHtml = 2174, + kCrossOriginTextPlain = 2175, + kCrossOriginTextXml = 2176, + // The above items are available as of the M63 branch. + + kPerformanceObserverForWindow = 2188, + kPerformanceObserverForWorker = 2189, + kPaintTimingObserved = 2190, + kPaintTimingRequested = 2191, + kHTMLMediaElementMediaPlaybackRateOutOfRange = 2192, + kCookieSet = 2194, + kCookieGet = 2195, + kGeolocationDisabledByFeaturePolicy = 2196, + kEncryptedMediaDisabledByFeaturePolicy = 2197, + kBatteryStatusGetBattery = 2198, + kOBSOLETE_BatteryStatusInsecureOrigin = 2199, + kBatteryStatusCrossOrigin = 2200, + kBatteryStatusSameOriginABA = 2201, + kHasIDClassTagAttribute = 2203, + kHasBeforeOrAfterPseudoElement = 2204, + kShapeOutsideMaybeAffectedInlineSize = 2205, + kShapeOutsideMaybeAffectedInlinePosition = 2206, + kGamepadVibrationActuator = 2207, + kMicrophoneDisabledByFeaturePolicyEstimate = 2208, + kCameraDisabledByFeaturePolicyEstimate = 2209, + kMidiDisabledByFeaturePolicy = 2210, + kGeolocationGetCurrentPosition = 2214, + kGeolocationWatchPosition = 2215, + kNetInfoSaveData = 2217, + kV8Element_GetClientRects_Method = 2218, + kV8Element_GetBoundingClientRect_Method = 2219, + kV8Range_GetClientRects_Method = 2220, + kV8Range_GetBoundingClientRect_Method = 2221, + kV8ErrorCaptureStackTrace = 2222, + kV8ErrorPrepareStackTrace = 2223, + kV8ErrorStackTraceLimit = 2224, + kPaintWorklet = 2225, + kDocumentPageHideRegistered = 2226, + kDocumentPageHideFired = 2227, + kDocumentPageShowRegistered = 2228, + kDocumentPageShowFired = 2229, + kReplaceCharsetInXHR = 2230, + kLinkRelModulePreload = 2232, + kCSPWithUnsafeEval = 2236, + kWebAssemblyInstantiation = 2237, + kV8IndexAccessor = 2238, + kV8MediaCapabilities_DecodingInfo_Method = 2239, + kV8MediaCapabilities_EncodingInfo_Method = 2240, + kV8MediaCapabilitiesInfo_Supported_AttributeGetter = 2241, + kV8MediaCapabilitiesInfo_Smooth_AttributeGetter = 2242, + kV8MediaCapabilitiesInfo_PowerEfficient_AttributeGetter = 2243, + kOBSOLETE_WindowEventInV0ShadowTree = 2244, + kWindowOpenRealmMismatch = 2247, + kGridRowTrackPercentIndefiniteHeight = 2248, + kVRGetDisplaysSupportsPresent = 2249, + kDuplicatedAttribute = 2250, + kDuplicatedAttributeForExecutedScript = 2251, + kV8RTCPeerConnection_GetSenders_Method = 2252, + kV8RTCPeerConnection_GetReceivers_Method = 2253, + kV8RTCPeerConnection_AddTrack_Method = 2254, + kV8RTCPeerConnection_RemoveTrack_Method = 2255, + kLocalCSSFile = 2256, + kLocalCSSFileExtensionRejected = 2257, + kUserMediaDisableHardwareNoiseSuppression = 2258, + // The above items are available as of the M64 branch. + + kCertificateTransparencyRequiredErrorOnResourceLoad = 2259, + kCSSSelectorPseudoWebkitAnyLink = 2260, + kAudioWorkletAddModule = 2261, + kAudioWorkletGlobalScopeRegisterProcessor = 2262, + kAudioWorkletNodeConstructor = 2263, + kHTMLMediaElementEmptyLoadWithFutureData = 2264, + kCSSValueDisplayContents = 2265, + kCSSSelectorPseudoAnyLink = 2266, + kFileAccessedCache = 2267, + kFileAccessedCookies = 2268, + kFileAccessedDatabase = 2269, + kFileAccessedFileSystem = 2270, + kFileAccessedLocalStorage = 2271, + kFileAccessedLocks = 2272, + kFileAccessedServiceWorker = 2273, + kFileAccessedSessionStorage = 2274, + kFileAccessedSharedWorker = 2275, + kV8MediaKeys_GetStatusForPolicy_Method = 2276, + kV8DeoptimizerDisableSpeculation = 2277, + kCSSSelectorCue = 2278, + kCSSSelectorWebkitCalendarPickerIndicator = 2279, + kCSSSelectorWebkitClearButton = 2280, + kCSSSelectorWebkitColorSwatch = 2281, + kCSSSelectorWebkitColorSwatchWrapper = 2282, + kCSSSelectorWebkitDateAndTimeValue = 2283, + kCSSSelectorWebkitDatetimeEdit = 2284, + kCSSSelectorWebkitDatetimeEditAmpmField = 2285, + kCSSSelectorWebkitDatetimeEditDayField = 2286, + kCSSSelectorWebkitDatetimeEditFieldsWrapper = 2287, + kCSSSelectorWebkitDatetimeEditHourField = 2288, + kCSSSelectorWebkitDatetimeEditMillisecondField = 2289, + kCSSSelectorWebkitDatetimeEditMinuteField = 2290, + kCSSSelectorWebkitDatetimeEditMonthField = 2291, + kCSSSelectorWebkitDatetimeEditSecondField = 2292, + kCSSSelectorWebkitDatetimeEditText = 2293, + kCSSSelectorWebkitDatetimeEditWeekField = 2294, + kCSSSelectorWebkitDatetimeEditYearField = 2295, + kCSSSelectorWebkitFileUploadButton = 2297, + kCSSSelectorWebkitInnerSpinButton = 2298, + kCSSSelectorWebkitInputPlaceholder = 2299, + kCSSSelectorWebkitMediaSliderContainer = 2300, + kCSSSelectorWebkitMediaSliderThumb = 2301, + kCSSSelectorWebkitMediaTextTrackContainer = 2302, + kCSSSelectorWebkitMediaTextTrackDisplay = 2303, + kCSSSelectorWebkitMediaTextTrackRegion = 2304, + kCSSSelectorWebkitMediaTextTrackRegionContainer = 2305, + kCSSSelectorWebkitMeterBar = 2306, + kCSSSelectorWebkitMeterEvenLessGoodValue = 2307, + kCSSSelectorWebkitMeterInnerElement = 2308, + kCSSSelectorWebkitMeterOptimumValue = 2309, + kCSSSelectorWebkitMeterSuboptimumValue = 2310, + kCSSSelectorWebkitProgressBar = 2311, + kCSSSelectorWebkitProgressInnerElement = 2312, + kCSSSelectorWebkitProgressValue = 2313, + kCSSSelectorWebkitSearchCancelButton = 2314, + kCSSSelectorWebkitSliderContainer = 2315, + kCSSSelectorWebkitSliderRunnableTrack = 2316, + kCSSSelectorWebkitSliderThumb = 2317, + kCSSSelectorWebkitTextfieldDecorationContainer = 2318, + kCSSSelectorWebkitUnknownPseudo = 2319, + kFilterAsContainingBlockMayChangeOutput = 2320, + kOBSOLETE_DispatchMouseUpDownEventOnDisabledFormControl = 2321, + kCSSSelectorPseudoIs = 2322, + kV8RTCRtpSender_ReplaceTrack_Method = 2323, + kInputTypeFileSecureOriginOpenChooser = 2324, + kInputTypeFileInsecureOriginOpenChooser = 2325, + kBasicShapeEllipseNoRadius = 2326, + kBasicShapeEllipseTwoRadius = 2328, + kTemporalInputTypeChooserByTrustedClick = 2329, + kTemporalInputTypeChooserByUntrustedClick = 2330, + kTemporalInputTypeIgnoreUntrustedClick = 2331, + kColorInputTypeChooserByTrustedClick = 2332, + kColorInputTypeChooserByUntrustedClick = 2333, + kCSSTypedOMStylePropertyMap = 2334, + kRTCPeerConnectionWithActiveCsp = 2346, + // The above items are available as of the M65 branch. + + kImageDecodingAttribute = 2347, + kImageDecodeAPI = 2348, + kV8HTMLElement_Autocapitalize_AttributeGetter = 2349, + kV8HTMLElement_Autocapitalize_AttributeSetter = 2350, + kCSSLegacyAlignment = 2351, + kSRISignatureCheck = 2352, + kSRISignatureSuccess = 2353, + kCSSBasicShape = 2354, + kCSSGradient = 2355, + kCSSPaintFunction = 2356, + kWebkitCrossFade = 2357, + kDisablePictureInPictureAttribute = 2358, + kOBSOLETE_CertificateTransparencyNonCompliantSubresourceInMainFrame = 2359, + kOBSOLETE_CertificateTransparencyNonCompliantResourceInSubframe = 2360, + kV8AbortController_Constructor = 2361, + kReplaceCharsetInXHRIgnoringCase = 2362, + kHTMLIFrameElementGestureMedia = 2363, + kWorkletAddModule = 2364, + kAnimationWorkletRegisterAnimator = 2365, + kWorkletAnimationConstructor = 2366, + kScrollTimelineConstructor = 2367, + kAsyncClipboardAPIRead = 2369, + kAsyncClipboardAPIWrite = 2370, + kAsyncClipboardAPIReadText = 2371, + kAsyncClipboardAPIWriteText = 2372, + kOpenerNavigationWithoutGesture = 2373, + kV8LockManager_Request_Method = 2375, + kV8LockManager_Query_Method = 2376, + kV8RTCDTMFSender_Track_AttributeGetter = 2378, + kV8RTCDTMFSender_Duration_AttributeGetter = 2379, + kV8RTCDTMFSender_InterToneGap_AttributeGetter = 2380, + kV8RTCRtpSender_Dtmf_AttributeGetter = 2381, + kRTCConstraintEnableDtlsSrtpTrue = 2382, + kRTCConstraintEnableDtlsSrtpFalse = 2383, + kDeprecatedRtcPeerConnectionId = 2384, + kV8PaintWorkletGlobalScope_RegisterPaint_Method = 2385, + kV8PaintWorkletGlobalScope_DevicePixelRatio_AttributeGetter = 2386, + kCSSSelectorPseudoFocus = 2387, + kCSSSelectorPseudoFocusVisible = 2388, + kDistrustedLegacySymantecSubresource = 2389, + kVRDisplayGetFrameData = 2390, + kXMLHttpRequestResponseXML = 2391, + kMessagePortTransferClosedPort = 2392, + kRTCLocalSdpModification = 2393, + kKeyboardApiLock = 2394, + kKeyboardApiUnlock = 2395, + kPPAPIURLRequestStreamToFile = 2396, + kPaymentHandler = 2397, + kPaymentRequestShowWithoutGesture = 2398, + kReadableStreamConstructor = 2399, + kWritableStreamConstructor = 2400, + kTransformStreamConstructor = 2401, + kNegativeBackgroundSize = 2402, + kNegativeMaskSize = 2403, + kClientHintsRtt_DEPRECATED = 2404, + kClientHintsDownlink_DEPRECATED = 2405, + kClientHintsEct_DEPRECATED = 2406, + kCrossOriginHTMLIFrameElementContentDocument = 2407, + kCrossOriginHTMLIFrameElementGetSVGDocument = 2408, + kCrossOriginHTMLEmbedElementGetSVGDocument = 2409, + kCrossOriginHTMLFrameElementContentDocument = 2410, + kCrossOriginHTMLObjectElementContentDocument = 2411, + kCrossOriginHTMLObjectElementGetSVGDocument = 2412, + kNavigatorXR = 2413, + kXRRequestDevice = 2414, + kXRRequestSession = 2415, + kXRSupportsSession = 2416, + kXRSessionGetInputSources = 2417, + kCSSResizeAuto = 2418, + kPrefixedCursorGrab = 2419, + kPrefixedCursorGrabbing = 2420, + kCredentialManagerCreatePublicKeyCredential = 2421, + kCredentialManagerGetPublicKeyCredential = 2422, + kCredentialManagerMakePublicKeyCredentialSuccess = 2423, + kCredentialManagerGetPublicKeyCredentialSuccess = 2424, + kShapeOutsideContentBox = 2425, + kShapeOutsidePaddingBox = 2426, + kShapeOutsideBorderBox = 2427, + kShapeOutsideMarginBox = 2428, + kPerformanceTimeline = 2429, + kUserTiming = 2430, + kCSSSelectorPseudoWhere = 2431, + kKeyboardApiGetLayoutMap = 2432, + kPerformanceResourceTimingInitiatorType = 2434, + kV8ArraySortNoElementsProtector = 2436, + kOBSOLETE_V8ArrayPrototypeSortJSArrayModifiedPrototype = 2437, + kV8Document_PictureInPictureEnabled_AttributeGetter = 2438, + kV8Document_PictureInPictureElement_AttributeGetter = 2439, + kV8Document_ExitPictureInPicture_Method = 2440, + kV8ShadowRoot_PictureInPictureElement_AttributeGetter = 2441, + kV8HTMLVideoElement_DisablePictureInPicture_AttributeGetter = 2442, + kV8HTMLVideoElement_DisablePictureInPicture_AttributeSetter = 2443, + kV8HTMLVideoElement_RequestPictureInPicture_Method = 2444, + kEnterPictureInPictureEventListener = 2445, + kLeavePictureInPictureEventListener = 2446, + kV8PictureInPictureWindow_Height_AttributeGetter = 2447, + kV8PictureInPictureWindow_Width_AttributeGetter = 2448, + kPictureInPictureWindowResizeEventListener = 2449, + kV8CookieStore_Delete_Method = 2450, + kV8CookieStore_Get_Method = 2451, + kV8CookieStore_GetAll_Method = 2452, + kV8CookieStore_GetChangeSubscriptions_Method = 2453, + kV8CookieStore_Has_Method = 2454, + kV8CookieStore_Set_Method = 2455, + kV8CookieStore_SubscribeToChanges_Method = 2456, + kV8CookieChangeEvent_Changed_AttributeGetter = 2457, + kV8CookieChangeEvent_Deleted_AttributeGetter = 2458, + kV8ExtendableCookieChangeEvent_Changed_AttributeGetter = 2459, + kV8ExtendableCookieChangeEvent_Deleted_AttributeGetter = 2460, + kShapeOutsideContentBoxDifferentFromMarginBox = 2461, + kShapeOutsidePaddingBoxDifferentFromMarginBox = 2462, + kDeprecatedCSSContainLayoutPositionedDescendants = 2463, + kCanvasConvertToBlob = 2465, + kPolymerV1Detected = 2466, + kPolymerV2Detected = 2467, + kPerformanceEventTimingBuffer = 2468, + kPerformanceEventTimingConstructor = 2469, + kReverseIterateDOMStorage = 2470, + kTextToSpeech_Speak = 2471, + kTextToSpeech_SpeakCrossOrigin = 2472, + kTextToSpeech_SpeakDisallowedByAutoplay = 2473, + kStaleWhileRevalidateEnabled = 2474, + kMediaElementSourceOnOfflineContext = 2475, + kOBSOLETE_MediaStreamDestinationOnOfflineContext = 2476, + kOBSOLETE_MediaStreamSourceOnOfflineContext = 2477, + kRTCDataChannelInitMaxRetransmitTime = 2478, + kRTCPeerConnectionCreateDataChannelMaxPacketLifeTime = 2479, + kV8SpeechGrammarList_AddFromUri_Method = 2480, + kV8SpeechSynthesis_Speak_Method = 2483, + kLegacySymantecCertMainFrameResource = 2484, + kLegacySymantecCertInSubresource = 2485, + kLegacySymantecCertInSubframeMainResource = 2486, + kEventTimingExplicitlyRequested = 2487, + kCSSEnvironmentVariable = 2488, + kCSSEnvironmentVariable_SafeAreaInsetTop = 2489, + kCSSEnvironmentVariable_SafeAreaInsetLeft = 2490, + kCSSEnvironmentVariable_SafeAreaInsetBottom = 2491, + kCSSEnvironmentVariable_SafeAreaInsetRight = 2492, + kMediaControlsDisplayCutoutGesture = 2493, + kDocumentOpenTwoArgs = 2494, + kDocumentOpenTwoArgsWithReplace = 2495, + kDocumentOpenThreeArgs = 2496, + kV8FunctionTokenOffsetTooLongForToString = 2497, + kServiceWorkerImportScriptNotInstalled = 2498, + kNestedDedicatedWorker = 2499, + kOBSOLETE_ClientHintsMetaAcceptCHLifetime = 2500, + kCSSFillAvailableLogicalWidth = 2507, + kCSSFillAvailableLogicalHeight = 2508, + kPopupOpenWhileFileChooserOpened = 2509, + kCookieStoreAPI = 2510, + kFeaturePolicyJSAPI = 2511, + kV8RTCPeerConnection_GetTransceivers_Method = 2512, + kV8RTCPeerConnection_AddTransceiver_Method = 2513, + kV8RTCRtpTransceiver_Direction_AttributeGetter = 2514, + kV8RTCRtpTransceiver_Direction_AttributeSetter = 2515, + kHTMLLinkElementDisabledByParser = 2516, + kRequestIsHistoryNavigation = 2517, + kAddDocumentLevelPassiveTrueWheelEventListener = 2518, + kAddDocumentLevelPassiveFalseWheelEventListener = 2519, + kAddDocumentLevelPassiveDefaultWheelEventListener = 2520, + kDocumentLevelPassiveDefaultEventListenerPreventedWheel = 2521, + kOBSOLETE_ShapeDetectionAPI = 2522, + kV8SourceBuffer_ChangeType_Method = 2523, + kPPAPIWebSocket = 2524, + kV8MediaStreamTrack_ContentHint_AttributeGetter = 2525, + kV8MediaStreamTrack_ContentHint_AttributeSetter = 2526, + kV8IDBFactory_Open_Method = 2527, + kReportingObserver = 2529, + kDeprecationReport = 2530, + kInterventionReport = 2531, + kV8WasmSharedMemory = 2532, + kV8WasmThreadOpcodes = 2533, + kFeaturePolicyReport = 2536, + kV8Window_WebkitRTCPeerConnection_ConstructorGetter = 2537, + kV8Window_WebkitMediaStream_ConstructorGetter = 2538, + kTextEncoderStreamConstructor = 2539, + kTextDecoderStreamConstructor = 2540, + kSignedExchangeInnerResponse = 2541, + kPaymentAddressLanguageCode = 2542, + kDocumentDomainBlockedCrossOriginAccess = 2543, + kDocumentDomainEnabledCrossOriginAccess = 2544, + kSerialGetPorts = 2545, + kSerialRequestPort = 2546, + kSerialPortOpen = 2547, + kSerialPortClose = 2548, + kBackgroundFetchManagerFetch = 2549, + kBackgroundFetchManagerGet = 2550, + kBackgroundFetchManagerGetIds = 2551, + kBackgroundFetchRegistrationAbort = 2552, + kBackgroundFetchRegistrationMatch = 2553, + kBackgroundFetchRegistrationMatchAll = 2554, + kFormDisabledAttributePresent = 2557, + kFormDisabledAttributePresentAndSubmit = 2558, + kCSSValueAppearanceCheckboxRendered = 2559, + kCSSValueAppearanceRadioRendered = 2561, + kCSSValueAppearanceInnerSpinButtonRendered = 2563, + kCSSValueAppearanceMenuListRendered = 2565, + kCSSValueAppearanceProgressBarRendered = 2567, + kCSSValueAppearanceSliderHorizontalRendered = 2568, + kCSSValueAppearanceSliderVerticalRendered = 2570, + kCSSValueAppearanceSliderThumbHorizontalRendered = 2572, + kCSSValueAppearanceSliderThumbVerticalRendered = 2574, + kCSSValueAppearanceSearchFieldRendered = 2576, + kCSSValueAppearanceSearchCancelRendered = 2578, + kCSSValueAppearanceTextAreaRendered = 2580, + kCSSValueAppearanceMenuListButtonRendered = 2582, + kCSSValueAppearancePushButtonRendered = 2584, + kCSSValueAppearanceSquareButtonRendered = 2586, + kCursorImageLE32x32 = 2589, + kCursorImageGT32x32 = 2590, + kOBSOLETE_RTCPeerConnectionComplexPlanBSdpUsingDefaultSdpSemantics = 2591, + // The above items are available in M71 branch. + + kResizeObserver_Constructor = 2592, + kCollator = 2593, + kNumberFormat = 2594, + kDateTimeFormat = 2595, + kPluralRules = 2596, + kRelativeTimeFormat = 2597, + kLocale = 2598, + kListFormat = 2599, + kSegmenter = 2600, + kStringLocaleCompare = 2601, + kOBSOLETE_StringToLocaleUpperCase = 2602, + kStringToLocaleLowerCase = 2603, + kNumberToLocaleString = 2604, + kDateToLocaleString = 2605, + kDateToLocaleDateString = 2606, + kDateToLocaleTimeString = 2607, + kMalformedCSP = 2608, + kV8AttemptOverrideReadOnlyOnPrototypeSloppy = 2609, + kV8AttemptOverrideReadOnlyOnPrototypeStrict = 2610, + kHTMLCanvasElementLowLatency = 2611, + kOBSOLETE_V8OptimizedFunctionWithOneShotBytecode = 2612, + kSVGGeometryPropertyHasNonZeroUnitlessValue = 2613, + kCSSValueAppearanceNoImplementationSkipBorder = 2614, + kInstantiateModuleScript = 2615, + kDynamicImportModuleScript = 2616, + kHistoryPushState = 2617, + kHistoryReplaceState = 2618, + kGetDisplayMedia = 2619, + kCursorImageGT64x64 = 2620, + kAdClick = 2621, + kUpdateWithoutShippingOptionOnShippingAddressChange = 2622, + kUpdateWithoutShippingOptionOnShippingOptionChange = 2623, + kCSSSelectorEmptyWhitespaceOnlyFail = 2624, + kActivatedImplicitRootScroller = 2625, + kCSSUnknownNamespacePrefixInSelector = 2626, + kPageLifeCycleFreeze = 2627, + kOBSOLETE_DefaultInCustomIdent = 2628, + kHTMLAnchorElementHrefTranslateAttribute = 2629, + kWebKitUserModifyEffective = 2630, + kPlainTextEditingEffective = 2631, + kOBSOLETE_LegacyTLSVersionInMainFrameResource = 2634, + kOBSOLETE_LegacyTLSVersionInSubresource = 2635, + kOBSOLETE_LegacyTLSVersionInSubframeMainResource = 2636, + kRTCMaxAudioBufferSize = 2637, + kWebKitUserModifyReadWriteEffective = 2638, + kWebKitUserModifyReadOnlyEffective = 2639, + kWebKitUserModifyPlainTextEffective = 2640, + kCSSAtRuleFontFeatureValues = 2641, + kFlexboxSingleLineAlignContent = 2642, + kSignedExchangeInnerResponseInMainFrame = 2643, + kSignedExchangeInnerResponseInSubFrame = 2644, + // The above items are available in M72 branch. + + kV8IDBFactory_Databases_Method = 2648, + kOpenerNavigationDownloadCrossOrigin = 2649, + kV8RegExpMatchIsTrueishOnNonJSRegExp = 2650, + kV8RegExpMatchIsFalseishOnJSRegExp = 2651, + kDownloadInAdFrameWithoutUserGesture = 2653, + kNavigatorAppVersion = 2654, + kNavigatorDoNotTrack = 2655, + kNavigatorHardwareConcurrency = 2656, + kNavigatorLanguage = 2657, + kNavigatorLanguages = 2658, + kNavigatorMaxTouchPoints = 2659, + kNavigatorMimeTypes = 2660, + kNavigatorPlatform = 2661, + kNavigatorPlugins = 2662, + kNavigatorUserAgent = 2663, + kWebBluetoothRequestScan = 2664, + kV8SVGGeometryElement_IsPointInFill_Method = 2665, + kV8SVGGeometryElement_IsPointInStroke_Method = 2666, + kV8SVGGeometryElement_GetTotalLength_Method = 2667, + kV8SVGGeometryElement_GetPointAtLength_Method = 2668, + kOffscreenCanvasTransferToImageBitmap = 2669, + kOffscreenCanvasIsPointInPath = 2670, + kOffscreenCanvasIsPointInStroke = 2671, + kOffscreenCanvasMeasureText = 2672, + kOffscreenCanvasGetImageData = 2673, + kV8SVGTextContentElement_GetComputedTextLength_Method = 2674, + kV8SVGTextContentElement_GetEndPositionOfChar_Method = 2675, + kV8SVGTextContentElement_GetExtentOfChar_Method = 2676, + kV8SVGTextContentElement_GetStartPositionOfChar_Method = 2677, + kV8SVGTextContentElement_GetSubStringLength_Method = 2678, + kV8BatteryManager_ChargingTime_AttributeGetter = 2679, + kV8BatteryManager_Charging_AttributeGetter = 2680, + kV8BatteryManager_DischargingTime_AttributeGetter = 2681, + kV8BatteryManager_Level_AttributeGetter = 2682, + kV8PaintRenderingContext2D_IsPointInPath_Method = 2683, + kV8PaintRenderingContext2D_IsPointInStroke_Method = 2684, + kV8PaymentRequest_CanMakePayment_Method = 2685, + kV8AnalyserNode_GetByteFrequencyData_Method = 2686, + kV8AnalyserNode_GetByteTimeDomainData_Method = 2687, + kV8AnalyserNode_GetFloatFrequencyData_Method = 2688, + kV8AnalyserNode_GetFloatTimeDomainData_Method = 2689, + kV8AudioBuffer_CopyFromChannel_Method = 2690, + kV8AudioBuffer_GetChannelData_Method = 2691, + kWebGLDebugRendererInfo = 2692, + kV8WebGL2ComputeRenderingContext_GetExtension_Method = 2693, + kV8WebGL2ComputeRenderingContext_GetSupportedExtensions_Method = 2694, + kV8WebGL2RenderingContext_GetExtension_Method = 2695, + kV8WebGL2RenderingContext_GetSupportedExtensions_Method = 2696, + kV8WebGLRenderingContext_GetExtension_Method = 2697, + kV8WebGLRenderingContext_GetSupportedExtensions_Method = 2698, + kV8Screen_AvailHeight_AttributeGetter = 2699, + kV8Screen_AvailWidth_AttributeGetter = 2700, + kV8Screen_ColorDepth_AttributeGetter = 2701, + kV8Screen_Height_AttributeGetter = 2702, + kV8Screen_PixelDepth_AttributeGetter = 2703, + kV8Screen_Width_AttributeGetter = 2704, + kWindowInnerWidth = 2705, + kWindowInnerHeight = 2706, + kV8Window_MatchMedia_Method = 2707, + kWindowScrollX = 2708, + kWindowScrollY = 2709, + kWindowPageXOffset = 2710, + kWindowPageYOffset = 2711, + kWindowScreenX = 2712, + kWindowScreenY = 2713, + kWindowOuterHeight = 2714, + kWindowOuterWidth = 2715, + kWindowDevicePixelRatio = 2716, + kCanvasCaptureStream = 2717, + kV8HTMLMediaElement_CanPlayType_Method = 2718, + kHistoryLength = 2719, + kFeaturePolicyReportOnlyHeader = 2720, + kV8PaymentRequest_HasEnrolledInstrument_Method = 2721, + kTrustedTypesEnabled = 2722, + kTrustedTypesCreatePolicy = 2723, + kTrustedTypesDefaultPolicyCreated = 2724, + kTrustedTypesAssignmentError = 2725, + kBadgeSet = 2726, + kBadgeClear = 2727, + kElementTimingExplicitlyRequested = 2728, + kV8HTMLMediaElement_CaptureStream_Method = 2729, + kQuirkyLineBoxBackgroundSize = 2730, + kDirectlyCompositedImage = 2731, + kOBSOLETE_V8HTMLVideoElement_AutoPictureInPicture_AttributeGetter = 2733, + kOBSOLETE_V8HTMLVideoElement_AutoPictureInPicture_AttributeSetter = 2734, + kOBSOLETE_AutoPictureInPictureAttribute = 2735, + kOBSOLETE_RTCAudioJitterBufferRtxHandling = 2736, + kWebShareCanShare = 2737, + kPriorityHints = 2738, + kTextAutosizedCrossSiteIframe = 2739, + kOBSOLETE_V8RTCQuicTransport_Constructor = 2740, + kOBSOLETE_V8RTCQuicTransport_Transport_AttributeGetter = 2741, + kOBSOLETE_V8RTCQuicTransport_State_AttributeGetter = 2742, + kOBSOLETE_V8RTCQuicTransport_GetKey_Method = 2743, + kOBSOLETE_V8RTCQuicTransport_GetStats_Method = 2744, + kOBSOLETE_V8RTCQuicTransport_Connect_Method = 2745, + kOBSOLETE_V8RTCQuicTransport_Listen_Method = 2746, + kOBSOLETE_V8RTCQuicTransport_Stop_Method = 2747, + kOBSOLETE_V8RTCQuicTransport_CreateStream_Method = 2748, + kV8RTCIceTransport_Constructor = 2749, + kV8RTCIceTransport_Role_AttributeGetter = 2750, + kV8RTCIceTransport_State_AttributeGetter = 2751, + kV8RTCIceTransport_GatheringState_AttributeGetter = 2752, + kV8RTCIceTransport_GetLocalCandidates_Method = 2753, + kV8RTCIceTransport_GetRemoteCandidates_Method = 2754, + kV8RTCIceTransport_GetSelectedCandidatePair_Method = 2755, + kV8RTCIceTransport_GetLocalParameters_Method = 2756, + kV8RTCIceTransport_GetRemoteParameters_Method = 2757, + kOBSOLETE_V8RTCQuicStream_Transport_AttributeGetter = 2758, + kOBSOLETE_V8RTCQuicStream_State_AttributeGetter = 2759, + kOBSOLETE_V8RTCQuicStream_ReadBufferedAmount_AttributeGetter = 2760, + kOBSOLETE_V8RTCQuicStream_MaxReadBufferedAmount_AttributeGetter = 2761, + kOBSOLETE_V8RTCQuicStream_WriteBufferedAmount_AttributeGetter = 2762, + kOBSOLETE_V8RTCQuicStream_MaxWriteBufferedAmount_AttributeGetter = 2763, + kOBSOLETE_V8RTCQuicStream_ReadInto_Method = 2764, + kOBSOLETE_V8RTCQuicStream_Write_Method = 2765, + kOBSOLETE_V8RTCQuicStream_Reset_Method = 2766, + kOBSOLETE_V8RTCQuicStream_WaitForWriteBufferedAmountBelow_Method = 2767, + kOBSOLETE_V8RTCQuicStream_WaitForReadable_Method = 2768, + // The above items are available in M73 branch. + + kHTMLTemplateElement = 2769, + kNoSysexWebMIDIWithoutPermission = 2770, + kNoSysexWebMIDIOnInsecureOrigin = 2771, + kOBSOLETE_ApplicationCacheInstalledButNoManifest = 2772, + kOBSOLETE_CustomCursorIntersectsViewport = 2776, + kOBSOLETE_ClientHintsLang = 2777, + kLinkRelPreloadImageSrcset = 2778, + kV8HTMLMediaElement_Remote_AttributeGetter = 2779, + kV8RemotePlayback_WatchAvailability_Method = 2780, + kV8RemotePlayback_Prompt_Method = 2781, + kLayoutShiftExplicitlyRequested = 2782, + kMediaSessionSkipAd = 2783, + kV8UserActivation_HasBeenActive_AttributeGetter = 2785, + kV8UserActivation_IsActive_AttributeGetter = 2786, + kTextEncoderEncodeInto = 2787, + kClientHintsUA = 2789, + kClientHintsUAArch = 2790, + kClientHintsUAPlatform = 2791, + kClientHintsUAModel = 2792, + kAnimationFrameCancelledWithinFrame = 2793, + kSchedulingIsInputPending = 2794, + kV8StringNormalize = 2795, + kOBSOLETE_U2FCryptotokenRegister = 2812, + kOBSOLETE_U2FCryptotokenSign = 2813, + kCSSValueAppearanceInnerSpinButton = 2814, + kCSSValueAppearanceMeter = 2815, + kCSSValueAppearanceProgressBar = 2816, + kCSSValueAppearancePushButton = 2818, + kCSSValueAppearanceSquareButton = 2819, + kCSSValueAppearanceSearchCancel = 2820, + kCSSValueAppearanceTextarea = 2821, + kCSSValueAppearanceTextFieldForTemporalRendered = 2823, + kOBSOLETE_AdClickNavigation = 2826, + kRTCStatsRelativePacketArrivalDelay = 2827, + // The above items are available in M74 branch. + + kCSSSelectorHostContextInSnapshotProfile = 2829, + kCSSSelectorHostContextInLiveProfile = 2830, + kImportMap = 2831, + kRefreshHeader = 2832, + kSearchEventFired = 2833, + kIdleDetectionStart = 2834, + kTargetCurrent = 2835, + kSandboxBackForwardStaysWithinSubtree = 2836, + kSandboxBackForwardAffectsFramesOutsideSubtree = 2837, + kDownloadPrePolicyCheck = 2838, + kDownloadPostPolicyCheck = 2839, + kReadableStreamGetReader = 2841, + kReadableStreamPipeThrough = 2842, + kReadableStreamPipeTo = 2843, + kCSSStyleSheetReplace = 2844, + kCSSStyleSheetReplaceSync = 2845, + kAdoptedStyleSheets = 2846, + kOBSOLETE_HTMLImportsOnReverseOriginTrials = 2847, + kOBSOLETE_ElementCreateShadowRootOnReverseOriginTrials = 2848, + kOBSOLETE_DocumentRegisterElementOnReverseOriginTrials = 2849, + kInputTypeRadio = 2850, + kInputTypeCheckbox = 2851, + kInputTypeImage = 2852, + kInputTypeButton = 2853, + kInputTypeHidden = 2854, + kInputTypeReset = 2855, + kSelectElementSingle = 2856, + kSelectElementMultiple = 2857, + kV8Animation_Effect_AttributeGetter = 2858, + kV8Animation_Effect_AttributeSetter = 2859, + kHidDeviceClose = 2860, + kHidDeviceOpen = 2861, + kHidDeviceReceiveFeatureReport = 2862, + kHidDeviceSendFeatureReport = 2863, + kHidDeviceSendReport = 2864, + kHidGetDevices = 2865, + kHidRequestDevice = 2866, + kOBSOLETE_V8RTCQuicTransport_MaxDatagramLength_AttributeGetter = 2867, + kOBSOLETE_V8RTCQuicTransport_ReadyToSendDatagram_Method = 2868, + kOBSOLETE_V8RTCQuicTransport_SendDatagram_Method = 2869, + kOBSOLETE_V8RTCQuicTransport_ReceiveDatagrams_Method = 2870, + // The above items are available in M75 branch. + + kCSSValueContainStyle = 2871, + kWebShareSuccessfulContainingFiles = 2872, + kWebShareSuccessfulWithoutFiles = 2873, + kWebShareUnsuccessfulContainingFiles = 2874, + kWebShareUnsuccessfulWithoutFiles = 2875, + kVerticalScrollbarThumbScrollingWithMouse = 2876, + kVerticalScrollbarThumbScrollingWithTouch = 2877, + kHorizontalScrollbarThumbScrollingWithMouse = 2878, + kHorizontalScrollbarThumbScrollingWithTouch = 2879, + kWebOTP = 2880, + kV8Animation_Pending_AttributeGetter = 2881, + kFocusWithoutUserActivationNotSandboxedNotAdFrame = 2882, + kFocusWithoutUserActivationNotSandboxedAdFrame = 2883, + kFocusWithoutUserActivationSandboxedNotAdFrame = 2884, + kFocusWithoutUserActivationSandboxedAdFrame = 2885, + kV8RTCRtpReceiver_JitterBufferDelayHint_AttributeGetter = 2886, + kV8RTCRtpReceiver_JitterBufferDelayHint_AttributeSetter = 2887, + kMediaCapabilitiesDecodingInfoWithKeySystemConfig = 2888, + kOBSOLETE_RevertInCustomIdent = 2889, + kUnoptimizedImagePolicies = 2890, + kVTTCueParser = 2891, + kMediaElementTextTrackContainer = 2892, + kMediaElementTextTrackList = 2893, + kPaymentRequestInitialized = 2894, + kPaymentRequestShow = 2895, + kPaymentRequestShippingAddressChange = 2896, + kPaymentRequestShippingOptionChange = 2897, + kPaymentRequestPaymentMethodChange = 2898, + kV8Animation_UpdatePlaybackRate_Method = 2899, + kTwoValuedOverflow = 2900, + kTextFragmentAnchor = 2901, + kTextFragmentAnchorMatchFound = 2902, + kNonPassiveTouchEventListener = 2903, + kPassiveTouchEventListener = 2904, + kWebXrFramebufferScale = 2906, + kWebXrIgnoreDepthValues = 2907, + kWebXrSessionCreated = 2908, + kV8XRReferenceSpace_GetOffsetReferenceSpace_Method = 2909, + kV8XRInputSource_Gamepad_AttributeGetter = 2910, + kV8XRSession_End_Method = 2911, + kV8XRWebGLLayer_Constructor = 2912, + kFetchKeepalive = 2913, + kCSSTransitionCancelledByRemovingStyle = 2914, + kV8RTCRtpSender_SetStreams_Method = 2915, + kCookieNoSameSite = 2916, + kCookieInsecureAndSameSiteNone = 2917, + // The above items are available in M76 branch. + + kUnsizedMediaPolicy = 2918, + kScrollByPrecisionTouchPad = 2919, + kPinchZoom = 2920, + kFeaturePolicyCommaSeparatedDeclarations = 2922, + kFeaturePolicySemicolonSeparatedDeclarations = 2923, + kV8CallSiteAPIGetFunctionSloppyCall = 2924, + kV8CallSiteAPIGetThisSloppyCall = 2925, + kLargestContentfulPaintExplicitlyRequested = 2927, + kPageFreezeOptIn = 2928, + kPageFreezeOptOut = 2929, + kPeriodicBackgroundSync = 2930, + kPeriodicBackgroundSyncRegister = 2931, + kLazyLoadFrameLoadingAttributeEager = 2932, + kLazyLoadFrameLoadingAttributeLazy = 2933, + kLazyLoadImageLoadingAttributeEager = 2934, + kLazyLoadImageLoadingAttributeLazy = 2935, + kPeriodicBackgroundSyncGetTags = 2937, + kPeriodicBackgroundSyncUnregister = 2938, + kCreateObjectURLMediaSourceFromWorker = 2939, + kCSSAtRuleProperty = 2940, + kServiceWorkerInterceptedRequestFromOriginDirtyStyleSheet = 2941, + kWebkitMarginBeforeCollapseDiscard = 2942, + kWebkitMarginBeforeCollapseSeparate = 2943, + kWebkitMarginBeforeCollapseSeparateMaybeDoesSomething = 2944, + kWebkitMarginAfterCollapseDiscard = 2945, + kWebkitMarginAfterCollapseSeparate = 2946, + kWebkitMarginAfterCollapseSeparateMaybeDoesSomething = 2947, + kCredentialManagerGetWithUVM = 2949, + kCredentialManagerGetSuccessWithUVM = 2951, + kDiscardInputEventToMovingIframe = 2952, + kSignedExchangeSubresourcePrefetch = 2953, + kBasicCardType = 2954, + kExecutedJavaScriptURL = 2955, + kLinkPrefetchLoadEvent = 2956, + kLinkPrefetchErrorEvent = 2957, + kFontSizeWebkitXxxLarge = 2958, + kV8Database_ChangeVersion_Method = 2959, + kV8Database_Transaction_Method = 2960, + kV8Database_ReadTransaction_Method = 2961, + kV8SQLTransaction_ExecuteSql_Method = 2962, + kV8PointerEvent_GetPredictedEvents_Method = 2971, + kOBSOLETE_ScrollSnapOnViewportBreaks = 2972, + kOBSOLETE_ScrollPaddingOnViewportBreaks = 2973, + kDownloadInAdFrame = 2974, + kDownloadInSandbox = 2975, + kDownloadWithoutUserGesture = 2976, + // The above items are available in M77 branch. + + kAutoplayDynamicDelegation = 2977, + kToggleEventHandlerDuringParsing = 2978, + kFragmentDoubleHash = 2979, + kOBSOLETE_CSSValueOverflowXOverlay = 2981, + kOBSOLETE_CSSValueOverflowYOverlay = 2982, + kContentIndexAdd = 2983, + kContentIndexDelete = 2984, + kContentIndexGet = 2985, + kV8SpeechGrammar_Constructor = 2986, + kV8SpeechGrammarList_AddFromString_Method = 2987, + kV8SpeechGrammarList_Constructor = 2988, + kV8SpeechGrammarList_Item_Method = 2989, + kV8SpeechRecognition_Constructor = 2990, + kV8SpeechRecognition_Grammars_AttributeGetter = 2991, + kV8SpeechRecognition_Grammars_AttributeSetter = 2992, + kContactsManagerSelect = 2993, + kV8MediaSession_SetPositionState_Method = 2994, + kCSSValueOverflowOverlay = 2995, + kRequestedFileSystemTemporary = 2996, + kRequestedFileSystemPersistent = 2997, + kElementWithLeftwardOrUpwardOverflowDirection_ScrollLeftOrTop = 2998, + kElementWithLeftwardOrUpwardOverflowDirection_ScrollLeftOrTopSetPositive = + 2999, + kXMLHttpRequestSynchronousInMainFrame = 3000, + kXMLHttpRequestSynchronousInCrossOriginSubframe = 3001, + kXMLHttpRequestSynchronousInSameOriginSubframe = 3002, + kXMLHttpRequestSynchronousInWorker = 3003, + kPerformanceObserverBufferedFlag = 3004, + kWakeLockAcquireScreenLock = 3005, + kWakeLockAcquireSystemLock = 3006, + kThirdPartyServiceWorker = 3007, + kJSSelfProfiling = 3008, + kHTMLFrameSetElement = 3009, + kFetchRedirectError = 3012, + kFetchRedirectManual = 3013, + kFetchCacheReload = 3014, + kV8Window_ChooseFileSystemEntries_Method = 3015, + kV8FileSystemDirectoryHandle_GetSystemDirectory_Method = 3016, + kNotificationShowTrigger = 3017, + kWebSocketStreamConstructor = 3018, + kDOMStorageRead = 3019, + kDOMStorageWrite = 3020, + kCacheStorageRead = 3021, + kCacheStorageWrite = 3022, + kIndexedDBRead = 3023, + kIndexedDBWrite = 3024, + kDeprecatedFileSystemRead = 3025, + kDeprecatedFileSystemWrite = 3026, + kPointerLockUnadjustedMovement = 3027, + // The above items are available in M78 branch. + + kCreateObjectBlob = 3028, + kQuotaRead = 3029, // available in M78 branch. + kDelegateFocus = 3030, + kThirdPartySharedWorker = 3032, + kThirdPartyBroadcastChannel = 3033, + kMediaSourceGroupEndTimestampDecreaseWithinMediaSegment = 3034, + kTextFragmentAnchorTapToDismiss = 3035, // available in M78 branch. + kXRIsSessionSupported = 3036, + kScrollbarUseScrollbarButtonReversedDirection = 3037, + kCSSSelectorPseudoScrollbarButtonReversedDirection = 3038, + kOBSOLETE_FragmentHasTildeAmpersandTilde = 3039, + kOBSOLETE_FragmentHasColonTildeColon = 3040, + kOBSOLETE_FragmentHasTildeAtTilde = 3041, + kOBSOLETE_FragmentHasAmpersandDelimiterQuestion = 3042, + kInvalidFragmentDirective = 3043, + kContactsManagerGetProperties = 3044, + kPluginElementLoadedDocument = 3046, + kPluginElementLoadedImage = 3047, + kPluginElementLoadedExternal = 3048, + kRenderSubtreeAttribute = 3049, // Removed in M82 + kARIAAnnotations = 3050, + kIntersectionObserverV2 = 3051, + kHeavyAdIntervention = 3052, + kUserTimingL3 = 3053, + kGetGamepadsFromCrossOriginSubframe = 3054, + kGetGamepadsFromInsecureContext = 3055, + kOriginCleanImageBitmapSerialization = 3056, + kNonOriginCleanImageBitmapSerialization = 3057, + kOriginCleanImageBitmapTransfer = 3058, + kNonOriginCleanImageBitmapTransfer = 3059, + kCompressionStreamConstructor = 3060, + kDecompressionStreamConstructor = 3061, + kV8RTCRtpReceiver_PlayoutDelayHint_AttributeGetter = 3062, + kV8RTCRtpReceiver_PlayoutDelayHint_AttributeSetter = 3063, + // The above items are available in M79 branch. + + kV8RegExpExecCalledOnSlowRegExp = 3064, + kV8RegExpReplaceCalledOnSlowRegExp = 3065, + kHasMarkerPseudoElement = 3066, + kWindowMove = 3067, + kWindowResize = 3068, + kMovedOrResizedPopup = 3069, + kMovedOrResizedPopup2sAfterCreation = 3070, + kDOMWindowOpenPositioningFeatures = 3071, + kMouseEventScreenX = 3072, + kMouseEventScreenY = 3073, + kCredentialManagerIsUserVerifyingPlatformAuthenticatorAvailable = 3074, + kObsoleteWebrtcTlsVersion = 3075, + kUpgradeInsecureRequestsUpgradedRequestBlockable = 3076, + kUpgradeInsecureRequestsUpgradedRequestOptionallyBlockable = 3077, + kUpgradeInsecureRequestsUpgradedRequestWebsocket = 3078, + kUpgradeInsecureRequestsUpgradedRequestForm = 3079, + kUpgradeInsecureRequestsUpgradedRequestUnknown = 3080, + kHasGlyphRelativeUnits = 3081, + kCountQueuingStrategyConstructor = 3082, + kByteLengthQueuingStrategyConstructor = 3083, + kClassicDedicatedWorker = 3084, + kModuleDedicatedWorker = 3085, + kFetchBodyStreamInServiceWorker = 3086, + kFetchBodyStreamOutsideServiceWorker = 3087, + kGetComputedStyleOutsideFlatTree = 3088, + kARIADescriptionAttribute = 3089, + kStrictMimeTypeChecksWouldBlockWorker = 3090, + kResourceTimingTaintedOriginFlagFail = 3091, + kRegisterProtocolHandlerSameOriginAsTop = 3092, + kRegisterProtocolHandlerCrossOriginSubframe = 3093, + kWebNfcNdefReaderScan = 3094, + kWebNfcNdefWriterWrite = 3095, + kOBSOLETE_HTMLPortalElement = 3096, + kOBSOLETE_V8HTMLPortalElement_Activate_Method = 3097, + kOBSOLETE_V8HTMLPortalElement_PostMessage_Method = 3098, + kOBSOLETE_V8Window_PortalHost_AttributeGetter = 3099, + kOBSOLETE_V8PortalHost_PostMessage_Method = 3100, + kOBSOLETE_V8PortalActivateEvent_Data_AttributeGetter = 3101, + kOBSOLETE_V8PortalActivateEvent_AdoptPredecessor_Method = 3102, + kLinkRelPrefetchForSignedExchanges = 3103, + kMessageEventSharedArrayBufferSameOrigin = 3104, + kMessageEventSharedArrayBufferSameAgentCluster = 3105, + kMessageEventSharedArrayBufferDifferentAgentCluster = 3106, + kCacheStorageCodeCacheHint = 3107, + kV8Metadata_ModificationTime_AttributeGetter = 3108, + kV8RTCLegacyStatsReport_Timestamp_AttributeGetter = 3109, + kInputElementValueAsDateGetter = 3110, + kInputElementValueAsDateSetter = 3111, + kHTMLMetaElementReferrerPolicy = 3112, + kNonWebbyMixedContent = 3113, + kV8SharedArrayBufferConstructed = 3114, + kScrollSnapCausesScrollOnInitialLayout = 3115, + // The above items are available in M80 branch. + + kClientHintsUAMobile = 3116, + kV8VideoPlaybackQuality_CorruptedVideoFrames_AttributeGetter = 3117, + kLongTaskBufferFull = 3118, + kHTMLMetaElementMonetization = 3119, + kHTMLLinkElementMonetization = 3120, + kOBSOLETE_InputTypeCheckboxRenderedNonSquare = 3121, + kOBSOLETE_InputTypeRadioRenderedNonSquare = 3122, + kWebkitBoxPackJustifyDoesSomething = 3123, + kWebkitBoxPackCenterDoesSomething = 3124, + kWebkitBoxPackEndDoesSomething = 3125, + kV8KeyframeEffect_Constructor = 3126, + kOBSOLETE_WebNfcAPI = 3127, + kHostCandidateAttributeGetter = 3128, + kCSPWithReasonableObjectRestrictions = 3129, + kCSPWithReasonableBaseRestrictions = 3130, + kCSPWithReasonableScriptRestrictions = 3131, + kCSPWithReasonableRestrictions = 3132, + kCSPROWithReasonableObjectRestrictions = 3133, + kCSPROWithReasonableBaseRestrictions = 3134, + kCSPROWithReasonableScriptRestrictions = 3135, + kCSPROWithReasonableRestrictions = 3136, + kCSPWithBetterThanReasonableRestrictions = 3137, + kCSPROWithBetterThanReasonableRestrictions = 3138, + kMeasureMemory = 3139, + kV8Animation_ReplaceState_AttributeGetter = 3140, + kV8Animation_Persist_Method = 3141, + kTaskControllerConstructor = 3142, + kTaskControllerSetPriority = 3143, + kTaskSignalPriority = 3144, + kSchedulerPostTask = 3145, + kV8Animation_Onremove_AttributeGetter = 3146, + kV8Animation_Onremove_AttributeSetter = 3147, + kClassicSharedWorker = 3148, + kModuleSharedWorker = 3149, + kV8Animation_CommitStyles_Method = 3150, + kSameOriginIframeWindowAlert = 3151, + kSameOriginIframeWindowConfirm = 3152, + kSameOriginIframeWindowPrompt = 3153, + kSameOriginIframeWindowPrint = 3154, + // The above items are available in M81 branch. + + kLargeStickyAd = 3155, + kCSSComparisonFunctions = 3157, + kOBSOLETE_FeaturePolicyProposalWouldChangeBehaviour = 3158, + kRTCLocalSdpModificationSimulcast = 3159, + kTrustedTypesEnabledEnforcing = 3160, + kTrustedTypesEnabledReportOnly = 3161, + kTrustedTypesAllowDuplicates = 3162, + kV8ArrayPrototypeHasElements = 3163, + kV8ObjectPrototypeHasElements = 3164, + kDisallowDocumentAccess = 3165, + kXRSessionRequestHitTestSource = 3166, + kXRSessionRequestHitTestSourceForTransientInput = 3167, + kXRDOMOverlay = 3168, + kOBSOLETE_CssStyleSheetReplaceWithImport = 3169, + kCryptoAlgorithmEd25519 = 3170, + kCryptoAlgorithmX25519 = 3171, + kDisplayNames = 3172, + kNumberFormatStyleUnit = 3173, + kDateTimeFormatRange = 3174, + kDateTimeFormatDateTimeStyle = 3175, + kBreakIteratorTypeWord = 3176, + kBreakIteratorTypeLine = 3177, + kV8FileSystemDirectoryHandle_Resolve_Method = 3178, + kV8FileSystemHandle_IsSameEntry_Method = 3179, + kOBSOLETE_V8RTCRtpSender_CreateEncodedAudioStreams_Method = 3180, + kOBSOLETE_V8RTCRtpSender_CreateEncodedVideoStreams_Method = 3181, + kOBSOLETE_V8RTCRtpReceiver_CreateEncodedAudioStreams_Method = 3182, + kOBSOLETE_V8RTCRtpReceiver_CreateEncodedVideoStreams_Method = 3183, + kQuicTransport = 3184, + kQuicTransportStreamApis = 3185, + kQuicTransportDatagramApis = 3186, + kV8Document_GetAnimations_Method = 3187, + kV8ShadowRoot_GetAnimations_Method = 3188, + kClientHintsUAFullVersion = 3189, + kOBSOLETE_SchedulerCurrentTaskSignal = 3190, + kThirdPartyFileSystem = 3191, + kThirdPartyIndexedDb = 3192, + kThirdPartyCacheStorage = 3193, + kThirdPartyLocalStorage = 3194, + kThirdPartySessionStorage = 3195, + kDeclarativeShadowRoot = 3196, + kCrossOriginOpenerPolicySameOrigin = 3197, + kCrossOriginOpenerPolicySameOriginAllowPopups = 3198, + kCrossOriginEmbedderPolicyRequireCorp = 3199, + kCoopAndCoepIsolated = 3200, + // The above items are available in M83 branch. + + kV8Document_HasTrustToken_Method = 3202, + kForceLoadAtTop = 3203, + kOBSOLETE_LegacyLayoutByDetailsMarker = 3206, + kOBSOLETE_LegacyLayoutByEditing = 3207, + kOBSOLETE_LegacyLayoutByFrameSet = 3211, + kOBSOLETE_LegacyLayoutByGrid = 3212, + kOBSOLETE_LegacyLayoutByMultiCol = 3214, + kOBSOLETE_LegacyLayoutByPrinting = 3215, + kOBSOLETE_LegacyLayoutBySVG = 3217, + kOBSOLETE_LegacyLayoutByTable = 3219, + kOBSOLETE_LegacyLayoutByTextCombine = 3220, + kOBSOLETE_LegacyLayoutByTextControl = 3221, + kOBSOLETE_LegacyLayoutByVTTCue = 3222, + kOBSOLETE_LegacyLayoutByTableFlexGridBlockInNGFragmentationContext = 3224, + kDocumentPolicyHeader = 3225, + kDocumentPolicyReportOnlyHeader = 3226, + kRequireDocumentPolicyHeader = 3227, + kDocumentPolicyIframePolicyAttribute = 3228, + kDocumentPolicyCausedPageUnload = 3229, + kRequiredDocumentPolicy = 3230, + kPerformanceObserverEntryTypesAndBuffered = 3231, + kPerformanceObserverTypeError = 3232, + kImageCaptureWhiteBalanceMode = 3233, + kImageCaptureExposureMode = 3234, + kImageCaptureFocusMode = 3235, + kImageCapturePointsOfInterest = 3236, + kImageCaptureExposureCompensation = 3237, + kImageCaptureExposureTime = 3238, + kImageCaptureColorTemperature = 3239, + kImageCaptureIso = 3240, + kImageCaptureBrightness = 3241, + kImageCaptureContrast = 3242, + kImageCaptureSaturation = 3243, + kImageCaptureSharpness = 3244, + kImageCaptureFocusDistance = 3245, + kImageCapturePan = 3246, + kImageCaptureTilt = 3247, + kImageCaptureZoom = 3248, + kImageCaptureTorch = 3249, + kXRFrameCreateAnchor = 3250, + kXRHitTestResultCreateAnchor = 3251, + kCSSKeywordRevert = 3252, + kOverlayPopupAd = 3253, + kEventTimingFirstInputExplicitlyRequested = 3254, + kCustomScrollbarPercentThickness = 3255, + kCustomScrollbarPartPercentLength = 3256, + kV8InvalidatedArrayBufferDetachingProtector = 3257, + kV8InvalidatedArrayConstructorProtector = 3258, + kV8InvalidatedArrayIteratorLookupChainProtector = 3259, + kV8InvalidatedArraySpeciesLookupChainProtector = 3260, + kV8InvalidatedIsConcatSpreadableLookupChainProtector = 3261, + kV8InvalidatedMapIteratorLookupChainProtector = 3262, + kV8InvalidatedNoElementsProtector = 3263, + kV8InvalidatedPromiseHookProtector = 3264, + kV8InvalidatedPromiseResolveLookupChainProtector = 3265, + kV8InvalidatedPromiseSpeciesLookupChainProtector = 3266, + kV8InvalidatedPromiseThenLookupChainProtector = 3267, + kV8InvalidatedRegExpSpeciesLookupChainProtector = 3268, + kV8InvalidatedSetIteratorLookupChainProtector = 3269, + kV8InvalidatedStringIteratorLookupChainProtector = 3270, + kV8InvalidatedStringLengthOverflowLookupChainProtector = 3271, + kV8InvalidatedTypedArraySpeciesLookupChainProtector = 3272, + kClientHintsUAPlatformVersion = 3273, + kIFrameCSPAttribute = 3274, + kNavigatorCookieEnabled = 3275, + kTrustTokenFetch = 3276, + kTrustTokenXhr = 3277, + kTrustTokenIframe = 3278, + kTrustedTypesPolicyCreated = 3279, + kV8HTMLVideoElement_RequestVideoFrameCallback_Method = 3280, + kV8HTMLVideoElement_CancelVideoFrameCallback_Method = 3281, + kOBSOLETE_RubyElementWithDisplayBlock = 3282, + kOBSOLETE_LocationFragmentDirectiveAccessed = 3283, + kCanvasRenderingContext = 3284, + kSchemefulSameSiteContextDowngrade = 3285, + kOriginAgentClusterHeader = 3286, + kV8WasmSimdOpcodes = 3287, + kGridRowGapPercent = 3288, + kGridRowGapPercentIndefinite = 3289, + kFlexRowGapPercent = 3290, + kFlexRowGapPercentIndefinite = 3291, + kV8RTCRtpSender_CreateEncodedStreams_Method = 3292, + kV8RTCRtpReceiver_CreateEncodedStreams_Method = 3293, + kOBSOLETEForceEncodedAudioInsertableStreams = 3294, + kOBSOLETEForceEncodedVideoInsertableStreams = 3295, + kTransformStyleContainingBlockComputedUsedMismatch = 3296, + kOBSOLETE_AdditionalGroupingPropertiesForCompat = 3297, + kPopupDoesNotExceedOwnerWindowBounds = 3298, + kPopupExceedsOwnerWindowBounds = 3299, + kPopupExceedsOwnerWindowBoundsForIframe = 3300, + kPopupGestureTapExceedsOwnerWindowBounds = 3301, + kPopupMouseDownExceedsOwnerWindowBounds = 3302, + kPopupMouseWheelExceedsOwnerWindowBounds = 3303, + kV8VarRedeclaredCatchBinding = 3304, + kWebBluetoothRemoteCharacteristicWriteValueWithResponse = 3305, + kWebBluetoothRemoteCharacteristicWriteValueWithoutResponse = 3306, + kFlexGapSpecified = 3307, + kFlexGapPositive = 3308, + kPluginInstanceAccessSuccessful = 3309, + kStorageAccessAPI_HasStorageAccess_Method = 3310, + kStorageAccessAPI_requestStorageAccess_Method = 3311, + kWebBluetoothWatchAdvertisements = 3312, + kRubyTextWithNonDefaultTextAlign = 3313, + kHTMLMetaElementReferrerPolicyOutsideHead = 3314, + kHTMLMetaElementReferrerPolicyMultipleTokens = 3315, + kOBSOLETE_V8WasmBulkMemory = 3320, + kV8WasmRefTypes = 3321, + kOBSOLETE_V8WasmMultiValue = 3322, + kHiddenBackfaceWithPossible3D = 3323, + kHiddenBackfaceWithPreserve3D = 3324, + kCSSAtRuleScrollTimeline = 3325, + kFetchUploadStreaming = 3326, + kWebkitLineClampWithoutWebkitBox = 3327, + kWebBluetoothGetDevices = 3328, + kDialogWithNonZeroScrollOffset = 3329, + kDialogHeightLargerThanViewport = 3330, + kOverlayPopup = 3331, + kContentVisibilityAuto = 3332, + kContentVisibilityHidden = 3333, + kContentVisibilityHiddenMatchable = 3334, + kInlineOverflowAutoWithInlineEndPadding = 3335, + kInlineOverflowScrollWithInlineEndPadding = 3336, + kSerialPortGetInfo = 3338, + // The above items are available in M85 branch. + + kFileSystemPickerMethod = 3339, + kV8Window_ShowOpenFilePicker_Method = 3340, + kV8Window_ShowSaveFilePicker_Method = 3341, + kV8Window_ShowDirectoryPicker_Method = 3342, + kOBSOLETE_RTCConstraintEnableRtpDataChannelsTrue = 3344, + kOBSOLETE_RTCConstraintEnableRtpDataChannelsFalse = 3345, + kFileSystemAccessDragAndDrop = 3346, + kRTCAdaptivePtime = 3347, + kHTMLMetaElementReferrerPolicyMultipleTokensAffectingRequest = 3348, + kNavigationTimingL2 = 3349, + kResourceTiming = 3350, + kV8PointerEvent_AzimuthAngle_AttributeGetter = 3351, + kV8PointerEvent_AltitudeAngle_AttributeGetter = 3352, + kCrossBrowsingContextGroupMainFrameNulledNonEmptyNameAccessed = 3353, + kPositionSticky = 3354, + kOBSOLETE_CommaSeparatorInAllowAttribute = 3355, + kMainFrameCSPViaHTTP = 3359, + kMainFrameCSPViaMeta = 3360, + kOBSOLETE_MainFrameCSPViaOriginPolicy = 3361, + kHtmlClipboardApiRead = 3362, + kHtmlClipboardApiWrite = 3363, + kOBSOLETE_CSSSystemColorComputeToSelf = 3364, + kAttributionReportingAPIAll = 3365, + kOBSOLETE_ImpressionRegistration = 3366, + kOBSOLETE_ConversionRegistration = 3367, + kWebSharePolicyAllow = 3368, + kWebSharePolicyDisallow = 3369, + kFormAssociatedCustomElement = 3370, + kWindowClosed = 3371, + kWrongBaselineOfMultiLineButton = 3372, + kWrongBaselineOfEmptyLineButton = 3373, + kV8RTCRtpTransceiver_Stopped_AttributeGetter = 3374, + kV8RTCRtpTransceiver_Stop_Method = 3375, + kSecurePaymentConfirmation = 3376, + kOBSOLETE_CSSInvalidVariableUnset = 3377, + kElementInternalsShadowRoot = 3378, + kUserDataFieldFilled_PredictedTypeMatch = 3379, + kEmailFieldFilled_PredictedTypeMatch = 3380, + kPhoneFieldFilled_PredictedTypeMatch = 3381, + kEmailFieldFilled_PatternMatch = 3382, + kOBSOLETE_LastLetterSpacingAffectsRendering = 3383, + kV8FontData_GetTables_Method = 3384, + kV8FontData_Blob_Method = 3385, + kOBSOLETE_V8FontManager_Query_Method = 3386, + kAudioContextBaseLatency = 3387, + kV8Window_GetScreenDetails_Method = 3388, + kOBSOLETE_V8Window_IsMultiScreen_Method = 3389, + kOBSOLETE_V8Window_Onscreenschange_AttributeGetter = 3390, + kOBSOLETE_V8Window_Onscreenschange_AttributeSetter = 3391, + kDOMWindowOpenPositioningFeaturesCrossScreen = 3392, + kDOMWindowSetWindowRectCrossScreen = 3393, + kFullscreenCrossScreen = 3394, + kOBSOLETE_BatterySavingsMeta = 3395, + kDigitalGoodsGetDigitalGoodsService = 3396, + kDigitalGoodsGetDetails = 3397, + kDigitalGoodsAcknowledge = 3398, + kMediaRecorder_MimeType = 3399, + kMediaRecorder_VideoBitsPerSecond = 3400, + kMediaRecorder_AudioBitsPerSecond = 3401, + kOBSOLETE_BluetoothRemoteGATTCharacteristic_Uuid = 3402, + kOBSOLETE_BluetoothRemoteGATTDescriptor_Uuid = 3403, + kOBSOLETE_BluetoothRemoteGATTService_Uuid = 3404, + kGPUAdapter_Name = 3405, + kOBSOLETE_WindowScreenInternal = 3406, + kOBSOLETE_WindowScreenPrimary = 3407, + kThirdPartyCookieRead = 3408, + kThirdPartyCookieWrite = 3409, + kRTCLegacyRtpDataChannelNegotiated = 3410, + kCrossSitePostMessage = 3411, + kSchemelesslySameSitePostMessage = 3412, + kSchemefulSameSitePostMessage = 3413, + kUnspecifiedTargetOriginPostMessage = 3414, + kSchemelesslySameSitePostMessageSecureToInsecure = 3415, + kSchemelesslySameSitePostMessageInsecureToSecure = 3416, + kOBSOLETE_BCPBroadcast = 3417, + kOBSOLETE_BCPRead = 3418, + kOBSOLETE_BCPWriteWithoutResponse = 3419, + kOBSOLETE_BCPWrite = 3420, + kOBSOLETE_BCPNotify = 3421, + kOBSOLETE_BCPIndicate = 3422, + kOBSOLETE_BCPAuthenticatedSignedWrites = 3423, + kOBSOLETE_BCPReliableWrite = 3424, + kOBSOLETE_BCPWritableAuxiliaries = 3425, + kTextAlignSpecifiedToLegend = 3426, + kV8Document_FragmentDirective_AttributeGetter = 3427, + kV8StorageManager_GetDirectory_Method = 3428, + kBeforematchHandlerRegistered = 3429, + kBluetoothAdvertisingEventName = 3430, + kBluetoothAdvertisingEventAppearance = 3431, + kBluetoothAdvertisingEventTxPower = 3432, + kCrossOriginOpenerPolicyReporting = 3433, + kGamepadId = 3434, + kElementAttachInternals = 3435, + kBluetoothDeviceName = 3436, + kRTCIceCandidateAddress = 3437, + kRTCIceCandidateCandidate = 3438, + kRTCIceCandidatePort = 3439, + kRTCIceCandidateRelatedAddress = 3440, + kRTCIceCandidateRelatedPort = 3441, + kSlotAssignNode = 3442, + kPluginName = 3443, + kPluginFilename = 3444, + kPluginDescription = 3445, + kOBSOLETE_SubresourceWebBundles = 3446, + kRTCPeerConnectionSetRemoteDescriptionPromise = 3447, + kRTCPeerConnectionSetLocalDescriptionPromise = 3448, + kRTCPeerConnectionCreateOfferPromise = 3449, + kRTCPeerConnectionCreateAnswerPromise = 3450, + kRTCPeerConnectionSetRemoteDescription = 3451, + kRTCPeerConnectionSetLocalDescription = 3452, + kRTCPeerConnectionCreateOffer = 3453, + kRTCPeerConnectionCreateAnswer = 3454, + kV8AuthenticatorAttestationResponse_GetTransports_Method = 3455, + kWebCodecsAudioDecoder = 3456, + kWebCodecsVideoDecoder = 3457, + kWebCodecsVideoEncoder = 3458, + kWebCodecsVideoTrackReader = 3459, + kWebCodecsImageDecoder = 3460, + kBackForwardCacheExperimentHTTPHeader = 3461, + kV8Navigator_OpenTCPSocket_Method = 3462, + kV8Navigator_OpenUDPSocket_Method = 3463, + kWebCodecs = 3464, + kCredentialManagerCrossOriginPublicKeyGetRequest = 3465, + kCSSContainStrictWithoutContentVisibility = 3466, + kCSSContainAllWithoutContentVisibility = 3467, + kTimerInstallFromBeforeUnload = 3468, + kTimerInstallFromUnload = 3469, + kOBSOLETE_ElementAttachInternalsBeforeConstructor = 3470, + kSMILElementHasRepeatNEventListener = 3471, + // The above items are available in M86 branch. + + kWebTransport = 3472, + kIdleDetectionPermissionRequested = 3477, + kIdentifiabilityStudyReserved3478 = 3478, + kSpeechSynthesis_GetVoices_Method = 3479, + kIdentifiabilityStudyReserved3480 = 3480, + kV8Navigator_JavaEnabled_Method = 3481, + kIdentifiabilityStudyReserved3482 = 3482, + kIdentifiabilityStudyReserved3483 = 3483, + kIdentifiabilityStudyReserved3484 = 3484, + kIdentifiabilityStudyReserved3485 = 3485, + kIdentifiabilityStudyReserved3486 = 3486, + kIdentifiabilityStudyReserved3487 = 3487, + kIdentifiabilityStudyReserved3488 = 3488, + kIdentifiabilityStudyReserved3489 = 3489, + kIdentifiabilityStudyReserved3490 = 3490, + kIdentifiabilityStudyReserved3491 = 3491, + kIdentifiabilityStudyReserved3492 = 3492, + kIdentifiabilityStudyReserved3493 = 3493, + kIdentifiabilityStudyReserved3494 = 3494, + kIdentifiabilityStudyReserved3495 = 3495, + kIdentifiabilityStudyReserved3496 = 3496, + kIdentifiabilityStudyReserved3497 = 3497, + kIdentifiabilityStudyReserved3498 = 3498, + kV8BackgroundFetchRegistration_FailureReason_AttributeGetter = 3499, + kV8Document_ElementFromPoint_Method = 3500, + kV8Document_ElementsFromPoint_Method = 3501, + kV8ShadowRoot_ElementFromPoint_Method = 3502, + kV8ShadowRoot_ElementsFromPoint_Method = 3503, + kOBSOLETE_WindowScreenTouchSupport = 3504, + kIdentifiabilityStudyReserved3505 = 3505, + kIdentifiabilityStudyReserved3506 = 3506, + kV8PushManager_SupportedContentEncodings_AttributeGetter = 3507, + kIdentifiabilityStudyReserved3508 = 3508, + kV8RTCRtpReceiver_GetCapabilities_Method = 3509, + kV8RTCRtpSender_GetCapabilities_Method = 3510, + kIdentifiabilityStudyReserved3511 = 3511, + kIdentifiabilityStudyReserved3512 = 3512, + kIdentifiabilityStudyReserved3513 = 3513, + kIdentifiabilityStudyReserved3514 = 3514, + kIdentifiabilityStudyReserved3515 = 3515, + kIdentifiabilityStudyReserved3516 = 3516, + kIdentifiabilityStudyReserved3517 = 3517, + kIdentifiabilityStudyReserved3518 = 3518, + kIdentifiabilityStudyReserved3519 = 3519, + kIdentifiabilityStudyReserved3520 = 3520, + kIdentifiabilityStudyReserved3521 = 3521, + kIdentifiabilityStudyReserved3522 = 3522, + kIdentifiabilityStudyReserved3523 = 3523, + kIdentifiabilityStudyReserved3524 = 3524, + kIdentifiabilityStudyReserved3525 = 3525, + kIdentifiabilityStudyReserved3526 = 3526, + kIdentifiabilityStudyReserved3527 = 3527, + kIdentifiabilityStudyReserved3528 = 3528, + kIdentifiabilityStudyReserved3529 = 3529, + kIdentifiabilityStudyReserved3530 = 3530, + kIdentifiabilityStudyReserved3531 = 3531, + kIdentifiabilityStudyReserved3532 = 3532, + kIdentifiabilityStudyReserved3533 = 3533, + kIdentifiabilityStudyReserved3534 = 3534, + kIdentifiabilityStudyReserved3535 = 3535, + kIdentifiabilityStudyReserved3536 = 3536, + kIdentifiabilityStudyReserved3537 = 3537, + kIdentifiabilityStudyReserved3538 = 3538, + kIdentifiabilityStudyReserved3539 = 3539, + kIdentifiabilityStudyReserved3540 = 3540, + kV8WheelEvent_DeltaMode_AttributeGetter = 3541, + kV8Touch_Force_AttributeGetter = 3542, + kWebGLRenderingContextMakeXRCompatible = 3543, + kV8WebGLCompressedTextureASTC_GetSupportedProfiles_Method = 3544, + kHTMLCanvasGetContext = 3545, + kV8BeforeInstallPromptEvent_Platforms_AttributeGetter = 3546, + kIdentifiabilityStudyReserved3547 = 3547, + kIdentifiabilityStudyReserved3548 = 3548, + kIdentifiabilityStudyReserved3549 = 3549, + kIdentifiabilityStudyReserved3550 = 3550, + kIdentifiabilityStudyReserved3551 = 3551, + kIdentifiabilityStudyReserved3552 = 3552, + kIdentifiabilityStudyReserved3553 = 3553, + kIdentifiabilityStudyReserved3554 = 3554, + kIdentifiabilityStudyReserved3555 = 3555, + kIdentifiabilityStudyReserved3556 = 3556, + kIdentifiabilityStudyReserved3557 = 3557, + kIdentifiabilityStudyReserved3558 = 3558, + kIdentifiabilityStudyReserved3559 = 3559, + kIdentifiabilityStudyReserved3560 = 3560, + kIdentifiabilityStudyReserved3561 = 3561, + kIdentifiabilityStudyReserved3562 = 3562, + kIdentifiabilityStudyReserved3563 = 3563, + kIdentifiabilityStudyReserved3564 = 3564, + kIdentifiabilityStudyReserved3565 = 3565, + kV8BaseAudioContext_SampleRate_AttributeGetter = 3566, + kOBSOLETE_WindowScreenId = 3567, + kWebGLRenderingContextGetParameter = 3568, + kWebGLRenderingContextGetRenderbufferParameter = 3569, + kWebGLRenderingContextGetShaderPrecisionFormat = 3570, + kWebGL2RenderingContextGetInternalFormatParameter = 3571, + kIdentifiabilityStudyReserved3572 = 3572, + kIdentifiabilityStudyReserved3573 = 3573, + kIdentifiabilityStudyReserved3574 = 3574, + kIdentifiabilityStudyReserved3575 = 3575, + kIdentifiabilityStudyReserved3576 = 3576, + kIdentifiabilityStudyReserved3577 = 3577, + kCascadedCSSZoomNotEqualToOne = 3578, + kForcedDarkMode = 3579, + kPreferredColorSchemeDark = 3580, + kPreferredColorSchemeDarkSetting = 3581, + kIdentifiabilityMediaDevicesEnumerateDevices = 3582, + kIdentifiabilityStudyReserved3583 = 3583, + kIdentifiabilityStudyReserved3584 = 3584, + kIdentifiabilityStudyReserved3585 = 3585, + kIdentifiabilityStudyReserved3586 = 3586, + kIdentifiabilityStudyReserved3587 = 3587, + kIdentifiabilityStudyReserved3588 = 3588, + kIdentifiabilityStudyReserved3589 = 3589, + kIdentifiabilityStudyReserved3590 = 3590, + kIdentifiabilityStudyReserved3591 = 3591, + kIdentifiabilityStudyReserved3592 = 3592, + kIdentifiabilityStudyReserved3593 = 3593, + kIdentifiabilityStudyReserved3594 = 3594, + kIdentifiabilityStudyReserved3595 = 3595, + kIdentifiabilityStudyReserved3596 = 3596, + kIdentifiabilityStudyReserved3597 = 3597, + kIdentifiabilityStudyReserved3598 = 3598, + kIdentifiabilityStudyReserved3599 = 3599, + kIdentifiabilityStudyReserved3600 = 3600, + kIdentifiabilityStudyReserved3601 = 3601, + kIdentifiabilityStudyReserved3602 = 3602, + kIdentifiabilityStudyReserved3603 = 3603, + kIdentifiabilityStudyReserved3604 = 3604, + kIdentifiabilityStudyReserved3605 = 3605, + kIdentifiabilityStudyReserved3606 = 3606, + kIdentifiabilityStudyReserved3607 = 3607, + kIdentifiabilityStudyReserved3608 = 3608, + kIdentifiabilityStudyReserved3609 = 3609, + kBarcodeDetector_GetSupportedFormats = 3610, + kIdentifiabilityStudyReserved3611 = 3611, + kIdentifiabilityStudyReserved3612 = 3612, + kIdentifiabilityStudyReserved3613 = 3613, + kIdentifiabilityStudyReserved3614 = 3614, + kIdentifiabilityStudyReserved3615 = 3615, + kIdentifiabilityStudyReserved3616 = 3616, + kIdentifiabilityStudyReserved3617 = 3617, + kIdentifiabilityStudyReserved3618 = 3618, + kIdentifiabilityStudyReserved3619 = 3619, + kIdentifiabilityStudyReserved3620 = 3620, + kIdentifiabilityStudyReserved3621 = 3621, + kIdentifiabilityStudyReserved3622 = 3622, + kIdentifiabilityStudyReserved3623 = 3623, + kIdentifiabilityStudyReserved3624 = 3624, + kIdentifiabilityStudyReserved3625 = 3625, + kIdentifiabilityStudyReserved3626 = 3626, + kIdentifiabilityStudyReserved3627 = 3627, + kIdentifiabilityStudyReserved3628 = 3628, + kIdentifiabilityStudyReserved3629 = 3629, + kIdentifiabilityStudyReserved3630 = 3630, + kIdentifiabilityStudyReserved3631 = 3631, + kIdentifiabilityStudyReserved3632 = 3632, + kIdentifiabilityStudyReserved3633 = 3633, + kIdentifiabilityStudyReserved3634 = 3634, + kIdentifiabilityStudyReserved3635 = 3635, + kIdentifiabilityStudyReserved3636 = 3636, + kIdentifiabilityStudyReserved3637 = 3637, + kIdentifiabilityStudyReserved3638 = 3638, + kIdentifiabilityStudyReserved3639 = 3639, + kIdentifiabilityStudyReserved3640 = 3640, + kIdentifiabilityStudyReserved3641 = 3641, + kIdentifiabilityStudyReserved3642 = 3642, + kIdentifiabilityStudyReserved3643 = 3643, + kIdentifiabilityStudyReserved3644 = 3644, + kIdentifiabilityStudyReserved3645 = 3645, + kIdentifiabilityStudyReserved3646 = 3646, + kIdentifiabilityStudyReserved3647 = 3647, + kIdentifiabilityStudyReserved3648 = 3648, + kIdentifiabilityStudyReserved3649 = 3649, + kIdentifiabilityStudyReserved3650 = 3650, + kIdentifiabilityStudyReserved3651 = 3651, + kIdentifiabilityStudyReserved3652 = 3652, + kIdentifiabilityStudyReserved3653 = 3653, + kIdentifiabilityStudyReserved3654 = 3654, + kIdentifiabilityStudyReserved3655 = 3655, + kIdentifiabilityStudyReserved3656 = 3656, + kIdentifiabilityStudyReserved3657 = 3657, + kIdentifiabilityStudyReserved3658 = 3658, + kIdentifiabilityStudyReserved3659 = 3659, + kIdentifiabilityStudyReserved3660 = 3660, + kIdentifiabilityStudyReserved3661 = 3661, + kIdentifiabilityStudyReserved3662 = 3662, + kIdentifiabilityStudyReserved3663 = 3663, + kIdentifiabilityStudyReserved3664 = 3664, + kIdentifiabilityStudyReserved3665 = 3665, + kIdentifiabilityStudyReserved3666 = 3666, + kIdentifiabilityStudyReserved3667 = 3667, + kIdentifiabilityStudyReserved3668 = 3668, + kIdentifiabilityStudyReserved3669 = 3669, + kIdentifiabilityStudyReserved3670 = 3670, + kIdentifiabilityStudyReserved3671 = 3671, + kIdentifiabilityStudyReserved3672 = 3672, + kIdentifiabilityStudyReserved3673 = 3673, + kIdentifiabilityStudyReserved3674 = 3674, + kIdentifiabilityStudyReserved3675 = 3675, + kIdentifiabilityStudyReserved3676 = 3676, + kIdentifiabilityStudyReserved3677 = 3677, + kIdentifiabilityStudyReserved3678 = 3678, + kIdentifiabilityStudyReserved3679 = 3679, + kIdentifiabilityStudyReserved3680 = 3680, + kIdentifiabilityStudyReserved3681 = 3681, + kUndeferrableThirdPartySubresourceRequestWithCookie = 3682, + kXRDepthSensing = 3683, + kXRFrameGetDepthInformation = 3684, + kXRCPUDepthInformationGetDepth = 3685, + kXRCPUDepthInformationDataAttribute = 3686, + kOBSOLETE_InterestCohortAPI_interestCohort_Method = 3687, + kOBSOLETE_AddressSpaceLocalEmbeddedInPrivateSecureContext = 3688, + kOBSOLETE_AddressSpaceLocalEmbeddedInPrivateNonSecureContext = 3689, + kOBSOLETE_AddressSpaceLocalEmbeddedInPublicSecureContext = 3690, + kOBSOLETE_AddressSpaceLocalEmbeddedInPublicNonSecureContext = 3691, + kOBSOLETE_AddressSpaceLocalEmbeddedInUnknownSecureContext = 3692, + kOBSOLETE_AddressSpaceLocalEmbeddedInUnknownNonSecureContext = 3693, + kOBSOLETE_AddressSpacePrivateEmbeddedInPublicSecureContext = 3694, + kOBSOLETE_AddressSpacePrivateEmbeddedInPublicNonSecureContext = 3695, + kOBSOLETE_AddressSpacePrivateEmbeddedInUnknownSecureContext = 3696, + kOBSOLETE_AddressSpacePrivateEmbeddedInUnknownNonSecureContext = 3697, + // The items above roughly this point are available in the M87 branch. + + kThirdPartyAccess = 3698, + kThirdPartyActivation = 3699, + kThirdPartyAccessAndActivation = 3700, + kFullscreenAllowedByScreensChange = 3701, + kNewLayoutOverflowDifferentBlock = 3702, + kNewLayoutOverflowDifferentFlex = 3703, + kNewLayoutOverflowDifferentAndAlreadyScrollsBlock = 3704, + kNewLayoutOverflowDifferentAndAlreadyScrollsFlex = 3705, + kUnicodeBidiPlainText = 3706, + kColorSchemeDarkSupportedOnRoot = 3707, + kWebBluetoothGetAvailability = 3708, + kDigitalGoodsListPurchases = 3709, + kCompositedSVG = 3710, + kBarcodeDetectorDetect = 3711, + kFaceDetectorDetect = 3712, + kTextDetectorDetect = 3713, + kOBSOLETE_LocalStorageFirstUsedBeforeFcp = 3714, + kOBSOLETE_LocalStorageFirstUsedAfterFcp = 3715, + kOBSOLETE_CSSPseudoHostCompoundList = 3716, + kOBSOLETE_CSSPseudoHostContextCompoundList = 3717, + kOBSOLETE_CSSPseudoHostDynamicSpecificity = 3718, + kOBSOLETE_GetCurrentBrowsingContextMedia = 3719, + kMouseEventRelativePositionForInlineElement = 3720, + kV8SharedArrayBufferConstructedWithoutIsolation = 3721, + kV8HTMLVideoElement_GetVideoPlaybackQuality_Method = 3722, + kXRWebGLBindingGetReflectionCubeMap = 3723, + kXRFrameGetLightEstimate = 3724, + kV8HTMLDialogElement_Show_Method = 3725, + kV8HTMLDialogElement_ShowModal_Method = 3726, + kAdFrameDetected = 3727, + kMediaStreamTrackGenerator = 3728, + kMediaStreamTrackProcessor = 3729, + kAddEventListenerWithAbortSignal = 3730, + kXRSessionRequestLightProbe = 3731, + // The items above roughly this point are available in the M88 branch. + + kBeforematchRevealedHiddenMatchable = 3732, + kAddSourceBufferUsingConfig = 3733, + kChangeTypeUsingConfig = 3734, + kV8SourceBuffer_AppendEncodedChunks_Method = 3735, + kOversrollBehaviorOnViewportBreaks = 3736, + kSameOriginJsonTypeForScript = 3737, + kCrossOriginJsonTypeForScript = 3738, + kSameOriginStrictNosniffWouldBlock = 3739, + kCrossOriginStrictNosniffWouldBlock = 3740, + kCSSSelectorPseudoDir = 3741, + kCrossOriginSubframeWithoutEmbeddingControl = 3742, + kReadableStreamWithByteSource = 3743, + kReadableStreamBYOBReader = 3744, + kSamePartyCookieAttribute = 3746, + kSamePartyCookieExclusionOverruledSameSite = 3747, + kSamePartyCookieInclusionOverruledSameSite = 3748, + kEmbedElementWithoutTypeSrcChanged = 3749, + kPaymentHandlerStandardizedPaymentMethodIdentifier = 3750, + kWebCodecsAudioEncoder = 3751, + kEmbeddedCrossOriginFrameWithoutFrameAncestorsOrXFO = 3752, + kAddressSpacePrivateSecureContextEmbeddedLocal = 3753, + kAddressSpacePrivateNonSecureContextEmbeddedLocal = 3754, + kAddressSpacePublicSecureContextEmbeddedLocal = 3755, + kAddressSpacePublicNonSecureContextEmbeddedLocal = 3756, + kAddressSpacePublicSecureContextEmbeddedPrivate = 3757, + kAddressSpacePublicNonSecureContextEmbeddedPrivate = 3758, + kAddressSpaceUnknownSecureContextEmbeddedLocal = 3759, + kAddressSpaceUnknownNonSecureContextEmbeddedLocal = 3760, + kAddressSpaceUnknownSecureContextEmbeddedPrivate = 3761, + kAddressSpaceUnknownNonSecureContextEmbeddedPrivate = 3762, + kAddressSpacePrivateSecureContextNavigatedToLocal = 3763, + kAddressSpacePrivateNonSecureContextNavigatedToLocal = 3764, + kAddressSpacePublicSecureContextNavigatedToLocal = 3765, + kAddressSpacePublicNonSecureContextNavigatedToLocal = 3766, + kAddressSpacePublicSecureContextNavigatedToPrivate = 3767, + kAddressSpacePublicNonSecureContextNavigatedToPrivate = 3768, + kAddressSpaceUnknownSecureContextNavigatedToLocal = 3769, + kAddressSpaceUnknownNonSecureContextNavigatedToLocal = 3770, + kAddressSpaceUnknownSecureContextNavigatedToPrivate = 3771, + kAddressSpaceUnknownNonSecureContextNavigatedToPrivate = 3772, + kOBSOLETE_RTCPeerConnectionSdpSemanticsPlanB = 3773, + // The items above roughly this point are available in the M89 branch. + + kFetchRespondWithNoResponseWithUsedRequestBody = 3774, + kV8TCPSocket_Close_Method = 3775, + kV8TCPSocket_Readable_AttributeGetter = 3776, + kV8TCPSocket_Writable_AttributeGetter = 3777, + kV8TCPSocket_RemoteAddress_AttributeGetter = 3778, + kV8TCPSocket_RemotePort_AttributeGetter = 3779, + kCSSSelectorTargetText = 3780, + kOBSOLETE_PopoverAttribute = 3781, + kOBSOLETE_V8HTMLPopupElement_Show_Method = 3782, + kOBSOLETE_V8HTMLPopupElement_Hide_Method = 3783, + kOBSOLETE_WindowOpenWithAdditionalBoolParameter = 3784, + kOBSOLETE_RTCPeerConnectionConstructedWithPlanB = 3785, + kOBSOLETE_RTCPeerConnectionConstructedWithUnifiedPlan = 3786, + kOBSOLETE_RTCPeerConnectionUsingComplexPlanB = 3787, + kOBSOLETE_RTCPeerConnectionUsingComplexUnifiedPlan = 3788, + kWindowScreenIsExtended = 3789, + kWindowScreenChange = 3790, + kXRWebGLDepthInformationTextureAttribute = 3791, + kXRWebGLBindingGetDepthInformation = 3792, + kOBSOLETE_SessionStorageFirstUsedBeforeFcp = 3793, + kOBSOLETE_SessionStorageFirstUsedAfterFcp = 3794, + kGravitySensorConstructor = 3795, + kElementInternalsStates = 3796, + kWebPImage = 3797, + kAVIFImage = 3798, + kSVGTextEdited = 3799, + kV8WasmExceptionHandling = 3800, + kOverflowClipAlongEitherAxis = 3803, + kCreateJSONModuleScript = 3804, + kCreateCSSModuleScript = 3805, + kInsertHTMLCommandOnInput = 3806, + kInsertHTMLCommandOnTextarea = 3807, + kInsertHTMLCommandOnReadWritePlainText = 3808, + kCSSAtRuleCounterStyle = 3809, + kCanvasUseColorSpace = 3810, + kSelectListElement = 3811, + kOBSOLETE_RTCPeerConnectionSdpSemanticsPlanBWithReverseOriginTrial = 3812, + kWebAppManifestCaptureLinks = 3813, + kSanitizerAPICreated = 3814, + kSanitizerAPIDefaultConfiguration = 3815, + kOBSOLETE_SanitizerAPIToString = 3816, + kSanitizerAPIToFragment = 3817, + kSanitizerAPIActionTaken = 3818, + kSanitizerAPIFromString = 3819, + kSanitizerAPIFromDocument = 3820, + kSanitizerAPIFromFragment = 3821, + kOBSOLETE_StorageFoundationOpen = 3822, + kOBSOLETE_StorageFoundationRead = 3823, + kOBSOLETE_StorageFoundationReadSync = 3824, + kOBSOLETE_StorageFoundationWrite = 3825, + kOBSOLETE_StorageFoundationWriteSync = 3826, + kOBSOLETE_StorageFoundationFlush = 3827, + kOBSOLETE_StorageFoundationFlushSync = 3828, + kUnrestrictedSharedArrayBuffer = 3829, + // The items above roughly this point are available in the M90 branch. + + kFeaturePolicyJSAPIAllowsFeatureIFrame = 3830, + kFeaturePolicyJSAPIAllowsFeatureDocument = 3831, + kFeaturePolicyJSAPIAllowsFeatureOriginIFrame = 3832, + kFeaturePolicyJSAPIAllowsFeatureOriginDocument = 3833, + kFeaturePolicyJSAPIAllowedFeaturesIFrame = 3834, + kFeaturePolicyJSAPIAllowedFeaturesDocument = 3835, + kFeaturePolicyJSAPIFeaturesIFrame = 3836, + kFeaturePolicyJSAPIFeaturesDocument = 3837, + kFeaturePolicyJSAPIGetAllowlistIFrame = 3838, + kFeaturePolicyJSAPIGetAllowlistDocument = 3839, + kOBSOLETE_V8Screens_Onchange_AttributeGetter = 3840, + kOBSOLETE_V8Screens_Onchange_AttributeSetter = 3841, + kV8ScreenDetailed_Left_AttributeGetter = 3842, + kV8ScreenDetailed_Top_AttributeGetter = 3843, + kV8ScreenDetailed_IsPrimary_AttributeGetter = 3844, + kV8ScreenDetailed_IsInternal_AttributeGetter = 3845, + kV8ScreenDetailed_DevicePixelRatio_AttributeGetter = 3846, + kV8ScreenDetailed_Id_AttributeGetter = 3847, + kV8ScreenDetailed_PointerTypes_AttributeGetter = 3848, + kV8ScreenDetailed_Label_AttributeGetter = 3849, + kPermissionsPolicyHeader = 3850, + kWebAppManifestUrlHandlers = 3851, + kLaxAllowingUnsafeCookies = 3852, + kV8MediaSession_SetMicrophoneActive_Method = 3853, + kV8MediaSession_SetCameraActive_Method = 3854, + kV8Navigator_JoinAdInterestGroup_Method = 3855, + kV8Navigator_LeaveAdInterestGroup_Method = 3856, + kV8Navigator_RunAdAuction_Method = 3857, + kXHRJSONEncodingDetection = 3858, + kWorkerControlledByServiceWorkerOutOfScope = 3859, + kXRPlaneDetection = 3860, + kXRFrameDetectedPlanes = 3861, + kXRImageTracking = 3862, + kXRSessionGetTrackedImageScores = 3863, + kXRFrameGetImageTrackingResults = 3864, + kOBSOLETE_OpenWebDatabaseThirdPartyContext = 3865, + kPointerId = 3866, + kTransform3dScene = 3867, + kPrefersColorSchemeMediaFeature = 3868, + kPrefersContrastMediaFeature = 3869, + kForcedColorsMediaFeature = 3870, + kPaymentRequestCSPViolation = 3871, + kWorkerControlledByServiceWorkerWithFetchEventHandlerOutOfScope = 3872, + kAuthorizationCoveredByWildcard = 3873, + kElementGetInnerHTML = 3874, + kFileHandlingLaunch = 3875, + kSameOriginDocumentsWithDifferentCOOPStatus = 3876, + kHTMLMediaElementSetSinkId = 3877, + kPrefixedStorageQuotaThirdPartyContext = 3878, + kRequestedFileSystemPersistentThirdPartyContext = 3879, + kPrefixedStorageInfoThirdPartyContext = 3880, + kCrossOriginEmbedderPolicyCredentialless = 3881, + kPostMessageFromSecureToSecure = 3882, + kPostMessageFromInsecureToInsecure = 3883, + kWebAppManifestProtocolHandlers = 3884, + kRTCPeerConnectionOfferAllowExtmapMixedFalse = 3885, + // The items above roughly this point are available in the M91 branch. + + kOBSOLETE_NewCanvas2DAPI = 3886, + kOBSOLETE_ServiceWorkerSubresourceFilterBypassedRequest = 3887, + kWebGPURequestAdapter = 3888, + kCSSFilterColorMatrix = 3889, + kHTMLFencedFrameElement = 3890, + kCSSFilterLuminanceToAlpha = 3891, + kHandwritingRecognitionCreateRecognizer = 3892, + kOBSOLETE_HandwritingRecognitionQuerySupport = 3893, + kHandwritingRecognitionStartDrawing = 3894, + kHandwritingRecognitionGetPrediction = 3895, + kWebBluetoothManufacturerDataFilter = 3896, + kSanitizerAPIGetConfig = 3897, + kSanitizerAPIGetDefaultConfig = 3898, + kPressureObserver_Constructor = 3899, + kPressureObserver_Observe = 3900, + kOBSOLETE_ComputePressureObserver_Stop = 3901, + kWebAppWindowControlsOverlay = 3902, + kPaymentRequestShowWithoutGestureOrToken = 3903, + kV8Navigator_UpdateAdInterestGroups_Method = 3904, + kV8ScreenDetails_Onscreenschange_AttributeGetter = 3905, + kV8ScreenDetails_Onscreenschange_AttributeSetter = 3906, + kV8ScreenDetails_Oncurrentscreenchange_AttributeGetter = 3907, + kV8ScreenDetails_Oncurrentscreenchange_AttributeSetter = 3908, + kRTCOfferAnswerOptionsVoiceActivityDetection = 3909, + kMultiColAndListItem = 3910, + kCaptureHandle = 3911, + kSVGText = 3912, + kGetBBoxForText = 3913, + kSVGTextHangingFromPath = 3914, + kClientHintsPrefersColorScheme = 3915, + kOverscrollBehaviorWillBeFixed = 3916, + kControlledWorkerWillBeUncontrolled = 3917, + kOBSOLETE_kARIATouchpassthroughAttribute = 3918, + kARIAVirtualcontentAttribute = 3919, + kOBSOLETE_kAccessibilityTouchPassthroughSet = 3920, + kTextFragmentBlockedByForceLoadAtTop = 3921, + kOBSOLETE_UrnDocumentAccessedCookies = 3922, + kFontFaceAscentOverride = 3923, + kFontFaceDescentOverride = 3924, + kFontFaceLineGapOverride = 3925, + kFontFaceSizeAdjust = 3926, + kHiddenBackfaceWith3D = 3927, + kMainFrameNonSecurePrivateAddressSpace = 3928, + kHTMLMediaElementControlsListNoPlaybackRate = 3930, + kOBSOLETE_DocumentTransition = 3931, + kSpeculationRules = 3932, + kV8AbortSignal_Abort_Method = 3933, + kOBSOLETE_SelectionBackgroundColorInversion = 3934, + kOBSOLETE_RTCPeerConnectionPlanBThrewAnException = 3935, + kHTMLRootContained = 3936, + kHTMLBodyContained = 3937, + kXRFrameGetJointPose = 3938, + kXRFrameFillJointRadii = 3939, + kXRFrameFillPoses = 3940, + kOBSOLETE_kWindowOpenNewPopupBehaviorMismatch = 3941, + kExplicitPointerCaptureClickTargetDiff = 3942, + // The items above roughly this point are available in the M92 branch. + + kControlledNonBlobURLWorkerWillBeUncontrolled = 3943, + kMediaMetaThemeColor = 3944, + kClientHintsUABitness = 3945, + kDifferentPerspectiveCBOrParent = 3946, + kWebkitImageSet = 3947, + kRTCPeerConnectionWithBlockingCsp = 3948, + kSanitizerAPISanitizeFor = 3949, + kSanitizerAPIElementSetSanitized = 3950, + kTextShadowInHighlightPseudo = 3951, + kTextShadowNotNoneInHighlightPseudo = 3952, + kSameSiteNoneRequired = 3953, + kSameSiteNoneIncludedBySamePartyTopResource = 3954, + kSameSiteNoneIncludedBySamePartyAncestors = 3955, + kSameSiteNoneIncludedBySameSiteLax = 3956, + kSameSiteNoneIncludedBySameSiteStrict = 3957, + kPrivateNetworkAccessNonSecureContextsAllowedDeprecationTrial = 3958, + kV8URLPattern_Constructor = 3959, + kV8URLPattern_Test_Method = 3960, + kV8URLPattern_Exec_Method = 3961, + kSameSiteCookieInclusionChangedByCrossSiteRedirect = 3962, + // The items above roughly this point are available in the M93 branch. + + kBlobStoreAccessAcrossAgentClustersInResolveAsURLLoaderFactory = 3963, + kBlobStoreAccessAcrossAgentClustersInResolveForNavigation = 3964, + kTapDelayEnabled = 3965, + kV8URLPattern_CompareComponent_Method = 3966, + kEarlyHintsPreload = 3967, + kClientHintsUAReduced = 3968, //Removed in M116. + kSpeculationRulesPrerender = 3969, + kOBSOLETE_ExecCommandWithTrustedTypes = 3970, + kOBSOLETE_CSSSelectorPseudoHasInSnapshotProfile = 3971, + kOBSOLETE_CSSSelectorPseudoHasInLiveProfile = 3972, + kNavigatorPdfViewerEnabled = 3973, + kCanvasRenderingContext2DContextLostEvent = 3974, + kCanvasRenderingContext2DContextRestoredEvent = 3975, + // The items above roughly this point are available in the M94 branch. + + kClientHintsViewportHeight = 3976, + kV8NavigatorManagedData_GetDirectoryId_Method = 3977, + kV8NavigatorManagedData_GetHostname_Method = 3978, + kV8NavigatorManagedData_GetSerialNumber_Method = 3979, + kV8NavigatorManagedData_GetAnnotatedAssetId_Method = 3980, + kV8NavigatorManagedData_GetAnnotatedLocation_Method = 3981, + kUserDataFieldFilledPreviously = 3982, + kTableCollapsedBorderDifferentToVisual = 3983, + kHighlightAPIRegisterHighlight = 3984, + kOBSOLETE_ReadOrWriteWebDatabaseThirdPartyContext = 3985, + kOBSOLETE_FontSelectorCSSFontFamilyWebKitPrefixPictograph = 3986, + kOBSOLETE_FontSelectorCSSFontFamilyWebKitPrefixStandard = 3987, + kFontSelectorCSSFontFamilyWebKitPrefixBody = 3988, + kFontBuilderCSSFontFamilyWebKitPrefixBody = 3989, + kCapabilityDelegationOfPaymentRequest = 3990, + kCredentialManagerGetLegacyFederatedCredential = 3992, + kCredentialManagerGetPasswordCredential = 3993, + kCredentialManagerStoreFederatedCredential = 3994, + kCredentialManagerStorePasswordCredential = 3995, + kCredentialManagerCreateFederatedCredential = 3996, + kCredentialManagerCreatePasswordCredential = 3997, + kCanvasRenderingContext2DRoundRect = 3998, + kNewLayoutOverflowDifferentBlockWithNonEmptyInflowBounds = 3999, + kCanvasRenderingContext2DReset = 4000, + kCanvasRenderingContext2DLetterSpacing = 4001, + kCanvasRenderingContext2DWordSpacing = 4002, + kCanvasRenderingContext2DFontVariantCaps = 4003, + kCanvasRenderingContext2DFontKerning = 4004, + kCanvasRenderingContext2DFontStretch = 4005, + kCanvasRenderingContext2DTextRendering = 4006, + kCSSCascadeLayers = 4007, + kCanvasRenderingContext2DConicGradient = 4008, + kCanvasRenderingContext2DCanvasFilter = 4009, + kOBSOLETE_HTMLParamElementURLParameter = 4010, + kV8HTMLScriptElement_Supports_Method = 4011, + kHandwritingRecognitionQueryRecognizer = 4012, + kV8FileSystemFileHandle_CreateSyncAccessHandle_Method = 4013, + kV8FileSystemSyncAccessHandle_Read_Method = 4014, + kV8FileSystemSyncAccessHandle_Write_Method = 4015, + kV8FileSystemSyncAccessHandle_Close_Method = 4016, + kV8FileSystemSyncAccessHandle_Flush_Method = 4017, + kV8FileSystemSyncAccessHandle_GetSize_Method = 4018, + kV8FileSystemSyncAccessHandle_Truncate_Method = 4019, + kV8SharedArrayBufferConstructedInExtensionWithoutIsolation = 4020, + kMediaSourceExtensionsForWebCodecs = 4021, + // The items above roughly this point are available in the M95 branch. + + kPaymentRequestResponse = 4023, + kPaymentRequestComplete = 4024, + kHTMLCanvasElement_2D = 4025, + kHTMLCanvasElement_WebGL = 4026, + kHTMLCanvasElement_WebGL2 = 4027, + kHTMLCanvasElement_BitmapRenderer = 4028, + kHTMLCanvasElement_WebGPU = 4029, + kOffscreenCanvas_2D = 4030, + kOffscreenCanvas_WebGL = 4031, + kOffscreenCanvas_WebGL2 = 4032, + kOffscreenCanvas_BitmapRenderer = 4033, + kOffscreenCanvas_WebGPU = 4034, + kCanvasRenderingContext2DHasOverdraw = 4035, + kDigitalGoodsConsume = 4036, + kDigitalGoodsListPurchaseHistory = 4037, + kWebShareContainingFiles = 4038, + kWebShareContainingTitle = 4039, + kWebShareContainingText = 4040, + kWebShareContainingUrl = 4041, + kCoepNoneSharedWorker = 4042, + kCoepRequireCorpSharedWorker = 4043, + kCoepCredentiallessSharedWorker = 4044, + kPaymentRequestBasicCard = 4045, + kClientHintsDeviceMemory = 4046, + kClientHintsDPR = 4047, + kClientHintsResourceWidth = 4048, + kClientHintsViewportWidth = 4049, + kInlineBoxIgnoringContinuation = 4050, + kOBSOLETE_OffsetWidthOrHeightIgnoringContinuation = 4051, + kConditionalFocus = 4052, + kV8Navigator_CreateAdRequest_Method = 4053, + kV8Navigator_FinalizeAd_Method = 4054, + kRegionCapture = 4055, + kNavigationAPI = 4056, + kFlexboxAlignSingleLineDifference = 4057, + kExternalProtocolBlockedBySandbox = 4058, + kOBSOLETE_WebAssemblyDynamicTiering = 4059, + // The items above roughly this point are available in the M96 branch. + + kReadOrWriteWebDatabase = 4061, + kAutoDarkMode = 4062, + kHttpRefreshWhenScriptingDisabled = 4063, + kV8FragmentDirective_Items_AttributeGetter = 4064, + kV8FragmentDirective_CreateSelectorDirective_Method = 4065, + kCSSTransitionBlockedByAnimation = 4066, + kWebAppManifestHasComments = 4067, + kAutoExpandedDetailsForFindInPage = 4068, + kAutoExpandedDetailsForScrollToTextFragment = 4069, + kOBSOLETE_WebCodecsVideoFrameDefaultTimestamp = 4070, + kWebCodecsVideoFrameFromImage = 4071, + kWebCodecsVideoFrameFromBuffer = 4072, + kOBSOLETE_OpenWebDatabaseInsecureContext = 4073, + kScriptWebBundle = 4074, + // The items above roughly this point are available in the M97 branch. + + kRunAdAuction = 4075, + kJoinAdInterestGroup = 4076, + kFileSystemUrlNavigation = 4077, + kV8Navigator_AdAuctionComponents_Method = 4078, + kClientHintsUAFullVersionList = 4079, + kWebAppManifestLaunchHandler = 4080, + kOBSOLETE_ClientHintsMetaNameAcceptCH = 4081, + kOBSOLETE_CSSMatchMediaUnknown = 4082, + kOBSOLETE_CSSMediaListUnknown = 4083, + kOBSOLETE_CSSOMMediaConditionUnknown = 4084, + kDocumentDomainSettingWithoutOriginAgentClusterHeader = 4085, + kCrossOriginEmbedderPolicyCredentiallessReportOnly = 4086, + kCrossOriginEmbedderPolicyRequireCorpReportOnly = 4087, + kCoopAndCoepIsolatedReportOnly = 4088, + kCrossOriginOpenerPolicySameOriginAllowPopupsReportOnly = 4089, + kCrossOriginOpenerPolicySameOriginReportOnly = 4090, + kImageLoadAtDismissalEvent = 4091, + kOBSOLETE_PrivateNetworkAccessIgnoredPreflightError = 4092, + kAbortPaymentRespondWithTrue = 4093, + // The items above roughly this point are available in the M98 branch. + + kAllowPaymentRequestAttributeHasEffect = 4094, + kV8PaymentResponse_Retry_Method = 4095, + kOBSOLETE_kWebAppManifestUserPreferences = 4096, + kV8HTMLInputElement_ShowPicker_Method = 4097, + kLayerXYWithMediaTarget = 4098, + kLayerXYWithCanvasTarget = 4099, + kLayerXYWithFrameTarget = 4100, + kLayerXYWithSVGTarget = 4101, + kHTMLObjectElementFallback = 4102, + kSecureContextIncorrectForWorker = 4103, + kV8UDPSocket_Close_Method = 4104, + kHTMLInputElementSimulatedClick = 4105, + kRTCLocalSdpModificationIceUfragPwd = 4106, + kWebNfcNdefMakeReadOnly = 4107, + kV8Navigator_DeprecatedURNToURL_Method = 4108, + kOBSOLETE_WebAppManifestHandleLinks = 4109, + kOBSOLETE_HTMLParamElementURLParameterInUsePdf = 4110, + kOBSOLETE_HTMLParamElementURLParameterInUseNonPdf = 4111, + kWebTransportServerCertificateHashes = 4112, + kHiddenAttribute = 4113, + kHiddenUntilFoundAttribute = 4114, + kWindowProxyCrossOriginAccessBlur = 4115, + kWindowProxyCrossOriginAccessClose = 4116, + kWindowProxyCrossOriginAccessClosed = 4117, + kWindowProxyCrossOriginAccessFocus = 4118, + kWindowProxyCrossOriginAccessFrames = 4119, + kWindowProxyCrossOriginAccessIndexedGetter = 4120, + kWindowProxyCrossOriginAccessLength = 4121, + kWindowProxyCrossOriginAccessLocation = 4122, + kWindowProxyCrossOriginAccessNamedGetter = 4123, + kWindowProxyCrossOriginAccessOpener = 4124, + kWindowProxyCrossOriginAccessParent = 4125, + kWindowProxyCrossOriginAccessPostMessage = 4126, + kWindowProxyCrossOriginAccessSelf = 4127, + kWindowProxyCrossOriginAccessTop = 4128, + kWindowProxyCrossOriginAccessWindow = 4129, + kWindowProxyCrossOriginAccessFromOtherPageBlur = 4130, + kWindowProxyCrossOriginAccessFromOtherPageClose = 4131, + kWindowProxyCrossOriginAccessFromOtherPageClosed = 4132, + kWindowProxyCrossOriginAccessFromOtherPageFocus = 4133, + kWindowProxyCrossOriginAccessFromOtherPageFrames = 4134, + kWindowProxyCrossOriginAccessFromOtherPageIndexedGetter = 4135, + kWindowProxyCrossOriginAccessFromOtherPageLength = 4136, + kWindowProxyCrossOriginAccessFromOtherPageLocation = 4137, + kWindowProxyCrossOriginAccessFromOtherPageNamedGetter = 4138, + kWindowProxyCrossOriginAccessFromOtherPageOpener = 4139, + kWindowProxyCrossOriginAccessFromOtherPageParent = 4140, + kWindowProxyCrossOriginAccessFromOtherPagePostMessage = 4141, + kWindowProxyCrossOriginAccessFromOtherPageSelf = 4142, + kWindowProxyCrossOriginAccessFromOtherPageTop = 4143, + kWindowProxyCrossOriginAccessFromOtherPageWindow = 4144, + kPrivateNetworkAccessFetchedWorkerScript = 4145, + // The items above roughly this point are available in the M99 branch. + + kFrameNameContainsBrace = 4146, + kFrameNameContainsNewline = 4147, + kAbortSignalThrowIfAborted = 4148, + kClientHintsUAFull = 4149, // Removed in M116. + kPrivateNetworkAccessWithinWorker = 4150, + kClientHintsUAWoW64 = 4151, + kFetchSetCookieInRequestGuardedHeaders = 4152, + kOBSOLETE_V8Window_RequestPictureInPictureWindow_Method = 4153, + kV8UDPSocket_LocalPort_AttributeGetter = 4154, + kV8UDPSocket_Readable_AttributeGetter = 4155, + kV8UDPSocket_RemoteAddress_AttributeGetter = 4156, + kV8UDPSocket_RemotePort_AttributeGetter = 4157, + kV8UDPSocket_Writable_AttributeGetter = 4158, + kAbortSignalTimeout = 4159, + kOBSOLETE_ClientHintsPartitionedCookies = 4160, + kV8Document_Prerendering_AttributeGetter = 4161, + kV8Document_Onprerenderingchange_AttributeGetter = 4162, + kV8Document_Onprerenderingchange_AttributeSetter = 4163, + kCSSAtRuleFontPaletteValues = 4164, + kCSSAtRuleContainer = 4165, + kFedCm = 4166, + kFetchEventSourceLastEventIdCorsUnSafe = 4167, + kWrongBaselineOfMultiLineButtonWithNonSpace = 4168, + kBlobStoreAccessAcrossTopLevelSite = 4169, + kBlobStoreAccessUnknownTopLevelSite = 4170, + kCrossOriginAccessBasedOnDocumentDomain = 4171, + kCookieWithTruncatingChar = 4172, + kVideoTrackGenerator = 4173, + kMediaCapabilitiesDecodingInfoWebrtc = 4174, + kMediaCapabilitiesEncodingInfoWebrtc = 4175, + kUsbDeviceForget = 4176, + kPartitionedCookies = 4177, + // The items above roughly this point are available in the M100 branch. + + kSecureContextIncorrectForSharedWorker = 4178, + kV8FunctionPrototypeArguments = 4179, + kV8FunctionPrototypeCaller = 4180, + kBluetoothDeviceForget = 4181, + kTopicsAPI_BrowsingTopics_Method = 4182, + kBlockingAttributeRenderToken = 4183, + kPressureObserver_Unobserve = 4184, + kPressureObserver_Disconnect = 4185, + kPressureObserver_TakeRecords = 4186, + kPrivacySandboxAdsAPIs = 4187, + kFledge = 4188, + // The items above roughly this point are available in the M101 branch. + + kElementShowPopover = 4189, + kElementHidePopover = 4190, + kValidPopoverAttribute = 4191, + kDeprecationExample = 4192, // Used as an example Deprecation code pointer. + kRTCLocalSdpModificationOpusStereo = 4193, + kNavigatorUAData_Mobile = 4194, + kNavigatorUAData_Platform = 4195, + kNavigatorUAData_Brands = 4196, + kOldConstraintsParsed = 4197, + kOBSOLETE_OldConstraintNotReported = 4198, + kOBSOLETE_OldConstraintRejected = 4199, + kOBSOLETE_OldConstraintIgnored = 4200, + kExplicitOverflowVisibleOnReplacedElement = 4201, + kExplicitOverflowVisibleOnReplacedElementWithObjectProp = 4202, + kPrivateNetworkAccessNullIpAddress = 4203, + kOBSOLETE_LegacyConstraintGoogScreencastMinBitrate = 4204, + kOBSOLETE_RTCPeerConnectionLegacyCreateWithMediaConstraints = 4205, + kClientHintsSaveData = 4206, + kOBSOLETE_LegacyConstraintGoogIPv6 = 4207, + kOBSOLETE_LegacyConstraintGoogSuspendBelowMinBitrate = 4208, + kOBSOLETE_LegacyConstraintGoogCpuOveruseDetection = 4209, + kAudioContextOutputLatency = 4210, + kV8Window_QueryLocalFonts_Method = 4211, + // The items above roughly this point are available in the M102 branch. + + kCSSAtRuleScope = 4212, + kOBSOLETE_DeferredShapingDisabledByPositioned = 4213, + kCapabilityDelegationOfFullscreenRequest = 4214, + kSerialPortForget = 4215, + kCookieHasNotBeenRefreshedIn201To300Days = 4216, + kCookieHasNotBeenRefreshedIn301To350Days = 4217, + kCookieHasNotBeenRefreshedIn351To400Days = 4218, + kAnonymousIframe = 4219, + kOBSOLETE_GestureScrollStart = 4220, + kOBSOLETE_GestureScrollUpdate = 4221, + kOBSOLETE_GestureScrollEnd = 4222, + kArrayBufferTooBigForWebAPI = 4223, + kFedCmDisconnect = 4224, + kOBSOLETE_FedCmLogout = 4225, + kOBSOLETE_FedCmLogoutRps = 4226, + kV8Navigator_DeprecatedReplaceInURN_Method = 4227, + // The items above roughly this point are available in the M103 branch. + + kWebAppBorderless = 4228, + kPaymentInstruments = 4229, + kV8PaymentInstruments_Clear_Method = 4230, + kV8PaymentInstruments_Delete_Method = 4231, + kV8PaymentInstruments_Get_Method = 4232, + kV8PaymentInstruments_Has_Method = 4233, + kV8PaymentInstruments_Keys_Method = 4234, + kV8PaymentInstruments_Set_Method = 4235, + kPerformanceMeasureFindExistingName = 4236, + kFlexboxNewAbsPos = 4237, + kScriptSchedulingType_Defer = 4238, + kScriptSchedulingType_ParserBlocking = 4239, + kScriptSchedulingType_ParserBlockingInline = 4240, + kScriptSchedulingType_InOrder = 4241, + kScriptSchedulingType_Async = 4242, + kFocusgroup = 4243, + kV8HTMLElement_Focusgroup_AttributeGetter = 4244, + kV8HTMLElement_Focusgroup_AttributeSetter = 4245, + kV8MathMLElement_Focusgroup_AttributeGetter = 4246, + kV8MathMLElement_Focusgroup_AttributeSetter = 4247, + kV8SVGElement_Focusgroup_AttributeGetter = 4248, + kV8SVGElement_Focusgroup_AttributeSetter = 4249, + kCSSLegacyPerspectiveOrigin = 4250, + kCSSLegacyTransformOrigin = 4251, + kCSSLegacyBorderImage = 4252, + kCSSLegacyBorderImageWidth = 4253, + kCrossOriginOpenerPolicyRestrictProperties = 4254, + kCrossOriginOpenerPolicyRestrictPropertiesReportOnly = 4255, + kEventTimingInteractionId = 4256, + kSecurePaymentConfirmationOptOut = 4257, + kOBSOLETE_AnyPopoverAttribute = 4258, + kOBSOLETE_DeferredShapingWorked = 4259, + kOBSOLETE_DeferredShapingReshapedByForceLayout = 4260, + kMediaSourceGetHandle = 4261, + kIdentityInCanMakePaymentEvent = 4262, + kSharedStorageAPI_SharedStorage_DOMReference = 4263, + kSharedStorageAPI_AddModule_Method = 4264, + kSharedStorageAPI_Set_Method = 4265, + kSharedStorageAPI_Append_Method = 4266, + kSharedStorageAPI_Delete_Method = 4267, + kSharedStorageAPI_Clear_Method = 4268, + kSharedStorageAPI_SelectURL_Method = 4269, + kSharedStorageAPI_Run_Method = 4270, + kViewTimelineConstructor = 4271, + kH1UserAgentFontSizeInSectionApplied = 4272, + kOBSOLETE_kV8PendingBeacon_Constructor = 4273, + kOBSOLETE_kV8PendingBeacon_Url_AttributeGetter = 4274, + kOBSOLETE_kV8PendingBeacon_Url_AttributeSetter = 4275, + kOBSOLETE_kV8PendingBeacon_Method_AttributeGetter = 4276, + kOBSOLETE_kV8PendingBeacon_Method_AttributeSetter = 4277, + kOBSOLETE_kV8PendingBeacon_PageHideTimeout_AttributeGetter = 4278, + kOBSOLETE_kV8PendingBeacon_PageHideTimeout_AttributeSetter = 4279, + kOBSOLETE_kV8PendingBeacon_State_AttributeGetter = 4280, + kOBSOLETE_kV8PendingBeacon_Deactivate_Method = 4281, + kOBSOLETE_kV8PendingBeacon_SetData_Method = 4282, + kOBSOLETE_kV8PendingBeacon_SendNow_Method = 4283, + // The items above roughly this point are available in the M104 branch. + + kTabSharingBarSwitchToCapturer = 4284, + kTabSharingBarSwitchToCapturee = 4285, + kAutomaticLazyAds = 4286, + kAutomaticLazyEmbeds = 4287, + kOBSOLETE_TouchActionChangedAtPointerDown = 4288, + kDeviceOrientationPermissionRequested = 4289, + kDeviceOrientationUsedWithoutPermissionRequest = 4290, + kDeviceMotionPermissionRequested = 4291, + kDeviceMotionUsedWithoutPermissionRequest = 4292, + kPrivateNetworkAccessPermissionPrompt = 4293, + kPseudoBeforeAfterForDateTimeInputElement = 4294, + kOBSOLETE_kV8PendingBeacon_IsPending_AttributeGetter = 4295, + kParentOfDisabledFormControlRespondsToMouseEvents = 4296, + kUnhandledExceptionCountInMainThread = 4297, + kUnhandledExceptionCountInWorker = 4298, + kOBSOLETE_WebCodecsImageDecoderPremultiplyAlphaDeprecation = 4299, + kCookieDomainNonASCII = 4300, + kClientHintsMetaEquivDelegateCH = 4301, + kOBSOLETE_ExpectCTHeader = 4302, + kOBSOLETE_kNavigateEventTransitionWhile = 4303, + kOBSOLETE_kNavigateEventRestoreScroll = 4304, + kSendBeaconWithArrayBuffer = 4305, + kSendBeaconWithArrayBufferView = 4306, + kSendBeaconWithBlob = 4307, + kSendBeaconWithFormData = 4308, + kSendBeaconWithURLSearchParams = 4309, + kSendBeaconWithUSVString = 4310, + kReplacedElementPaintedWithOverflow = 4311, + kImageAd = 4312, + kLinkRelPrefetchAsDocumentSameOrigin = 4313, + kLinkRelPrefetchAsDocumentCrossOrigin = 4314, + kPersistentQuotaType = 4315, + kCrossOriginScrollIntoView = 4316, + kLinkRelCanonical = 4317, + kCredentialManagerIsConditionalMediationAvailable = 4318, + kOBSOLETE_kV8PendingBeacon_Pending_AttributeGetter = 4319, + kOBSOLETE_kV8PendingBeacon_BackgroundTimeout_AttributeGetter = 4320, + kOBSOLETE_kV8PendingBeacon_BackgroundTimeout_AttributeSetter = 4321, + kOBSOLETE_kV8PendingBeacon_Timeout_AttributeGetter = 4322, + kOBSOLETE_kV8PendingBeacon_Timeout_AttributeSetter = 4323, + kOBSOLETE_kV8PendingGetBeacon_Constructor = 4324, + kOBSOLETE_kV8PendingGetBeacon_SetURL_Method = 4325, + kOBSOLETE_kV8PendingPostBeacon_Constructor = 4326, + kOBSOLETE_kV8PendingPostBeacon_SetData_Method = 4327, + kContentVisibilityAutoStateChangeHandlerRegistered = 4328, + kReplacedElementPaintedWithLargeOverflow = 4329, + // The items above roughly this point are available in the M105 branch. + + kFlexboxAbsPosJustifyContent = 4330, + kMultipleFetchHandlersInServiceWorker = 4331, + kStorageAccessAPI_requestStorageAccessFor_Method = 4332, + kPrivateAggregationApiAll = 4333, + kPrivateAggregationApiFledge = 4334, + kPrivateAggregationApiSharedStorage = 4335, + // The items above roughly this point are available in the M106 branch. + + kOBSOLETE_DeferredShaping2ReshapedByComputedStyle = 4336, + kOBSOLETE_DeferredShaping2ReshapedByDomContentLoaded = 4337, + kOBSOLETE_DeferredShaping2ReshapedByFcp = 4338, + kOBSOLETE_DeferredShaping2DisabledByFragmentAnchor = 4339, + kOBSOLETE_DeferredShaping2ReshapedByFocus = 4340, + kOBSOLETE_DeferredShaping2ReshapedByGeometry = 4341, + kOBSOLETE_DeferredShaping2ReshapedByInspector = 4342, + kOBSOLETE_DeferredShaping2ReshapedByPrinting = 4343, + kOBSOLETE_DeferredShaping2ReshapedByScrolling = 4344, + kLCPCandidateImageFromOriginDirtyStyle = 4345, + kV8TurboFanOsrCompileStarted = 4346, + kV8Document_HasRedemptionRecord_Method = 4347, + kOBSOLETE_DeferredShaping2ReshapedByLastResort = 4348, + kAudioContextSinkId = 4349, + kAudioContextSetSinkId = 4350, + kViewportDependentLazyLoadedImageWithSizesAttribute = 4351, + kXRWebGLBindingGetCameraImage = 4352, + kSelectiveInOrderScript = 4353, + kV8AsyncStackTaggingCreateTaskCall = 4354, + kWebkitBoxWithoutWebkitLineClamp = 4355, + kDataUrlInSvgUse = 4356, + kWebAuthnConditionalUiGet = 4357, + kWebAuthnConditionalUiGetSuccess = 4358, + kWebAuthnRkRequiredCreationSuccess = 4359, + kDestructiveDocumentWriteAfterModuleScript = 4360, + kOBSOLETE_CSSAtSupportsDropInvalidWhileForgivingParsing = 4361, + kPermissionsPolicyUnload = 4362, + // The items above roughly this point are available in the M107 branch. + + kServiceWorkerSkippedForSubresourceLoad = 4363, + kClientHintsPrefersReducedMotion = 4364, + kOBSOLETE_WakeLockAcquireScreenLockWithoutActivation = 4365, + kInteractiveWidgetOverlaysContent = 4366, + kInteractiveWidgetResizesContent = 4367, + kInteractiveWidgetResizesVisual = 4368, + kSerivceWorkerFallbackMainResource = 4369, + kOBSOLETE_GetDisplayMediaWithoutUserActivation = 4370, + kBackForwardCacheNotRestoredReasons = 4371, + // The items above roughly this point are available in the M108 branch. + + kCSSNesting = 4372, + kSandboxIneffectiveAllowOriginAllowScript = 4373, + kDocumentOpenDifferentWindow = 4374, + kDocumentOpenMutateSandbox = 4375, + kEligibleForImageLoadingPrioritizationFix = 4376, + kExecutedNonTrivialJavaScriptURL = 4377, + kStorageBucketsOpen = 4378, + kPerformanceEntryBufferSwaps = 4379, + kClearPerformanceEntries = 4380, + kViewportDependentLazyLoadedImageWithoutSizesAttribute = 4381, + kV8MediaStreamTrack_ApplyConstraints_Method = 4382, + kViewTransition = 4383, + kElementTogglePopover = 4384, + kOBSOLETE_LayoutMediaInlineChildren = 4385, + kOBSOLETE_ReduceAcceptLanguage = 4386, + // The items above roughly this point are available in the M109 branch. + + kOBSOLETE_UuidInPackageUrlNavigation = 4387, + kCSSValueAppearanceMediaSliderRendered = 4388, + kCSSValueAppearanceMediaSliderThumbRendered = 4389, + kCSSValueAppearanceMediaVolumeSliderRendered = 4390, + kCSSValueAppearanceMediaVolumeSliderThumbRendered = 4391, + kV8PerformanceResourceTiming_DeliveryType_AttributeGetter = 4392, + kDocumentLoaderDeliveryTypeNavigationalPrefetch = 4393, + kSpeculationRulesHeader = 4394, + kSpeculationRulesDocumentRules = 4395, + kFedCmIframe = 4396, + kV8DocumentPictureInPicture_RequestWindow_Method = 4397, + kV8DocumentPictureInPicture_Window_AttributeGetter = 4398, + kV8DocumentPictureInPictureEvent_Window_AttributeGetter = 4399, + kDocumentPictureInPictureEnterEvent = 4400, + kSoftNavigationHeuristics = 4401, + kMathMLMathElement = 4402, + kMathMLMathElementInDocument = 4403, + kCSSAtRuleStylistic = 4404, + kCSSAtRuleStyleset = 4405, + kCSSAtRuleCharacterVariant = 4406, + kCSSAtRuleSwash = 4407 , + kCSSAtRuleOrnaments = 4408, + kCSSAtRuleAnnotation = 4409, + kOBSOLETE_ServiceWorkerBypassFetchHandlerForMainResource = 4410, + kV8Document_HasPrivateToken_Method = 4411, + kServiceWorkerSkippedForEmptyFetchHandler = 4412, + kImageSet = 4413, + kWindowCloseHistoryLengthOne = 4414, + kOBSOLETE_CreateNSResolverWithNonElements = 4415, + kCSSValueAppearanceNonStandard = 4416, + kOBSOLETE_CSSGetComputedAnimationDelayZero = 4417, + kGetEffectTimingDelayZero = 4418, + kScrollend = 4419, + kDOMWindowOpenCrossOriginIframe = 4420, + kStreamingDeclarativeShadowDOM = 4421, + kOBSOLETE_DialogCloseWatcherCancelSkipped = 4422, + kOBSOLETE_DialogCloseWatcherCancelSkippedAndDefaultPrevented = 4423, + kOBSOLETE_DialogCloseWatcherCloseSignalClosedMultiple = 4424, + kNoVarySearch = 4425, + kFedCmUserInfo = 4426, + // The items above roughly this point are available in the M110 branch. + + kIDNA2008DeviationCharacterInHostnameOfSubresource = 4427, + kIDNA2008DeviationCharacterInHostnameOfIFrame = 4428, + kWindowOpenPopupOnMobile = 4429, + kWindowOpenedAsPopupOnMobile = 4430, + kPrivateNetworkAccessIgnoredCrossOriginPreflightError = 4431, + kPrivateNetworkAccessIgnoredCrossSitePreflightError = 4432, + kLinkRelPrerenderSameOrigin = 4433, + kLinkRelPrerenderSameSiteCrossOrigin = 4434, + kLinkRelPrerenderCrossSite = 4435, + kCSSBackgroundClipBorder = 4436, + kCSSBackgroundClipContent = 4437, + kCSSBackgroundClipPadding = 4438, + kOBSOLETE_DisableThirdPartySessionStoragePartitioningAfterGeneralPartitioning = 4439, + kOBSOLETE_kCSSPseudoHasContainsMixOfValidAndInvalid = 4440, + kOBSOLETE_kCSSPseudoIsWhereContainsMixOfValidAndInvalid = 4441, + kPrivateNetworkAccessFetchedSubFrame = 4442, + kPrivateNetworkAccessFetchedTopFrame = 4443, + kOBSOLETE_DisableThirdPartyStoragePartitioning = 4444, + kServiceWorkerFetchHandlerAddedAfterInitialization = 4445, + kObsoleteCreateImageBitmapImageOrientationNone = 4446, + kOBSOLETE_kWindowManagementPermissionDescriptorUsed = 4447, + kOBSOLETE_kWindowPlacementPermissionDescriptorUsed = 4448, + kOBSOLETE_kWindowManagementPermissionPolicyParsed = 4449, + kOBSOLETE_kWindowPlacementPermissionPolicyParsed = 4450, + kContentDispositionInSvgUse = 4451, + kSameDocumentCrossOriginInitiator = 4452, + kServiceWorkerFetchHandlerModifiedAfterInitialization = 4453, + // The items above roughly this point are available in the M111 branch. + + kOBSOLETE_OptionLabelInQuirksMode = 4454, + kParseFromStringIncludeShadows = 4455, + kWebAppManifestScopeExtensions = 4456, + kOBSOLETE_ServiceWorkerBypassFetchHandlerForMainResourceByOriginTrial = 4457, + kOBSOLETE_V8RegExpUnicodeSetIncompatibilitiesWithUnicodeMode = 4458, + kFedCmAutoReauthn = 4459, + kTopicsAPIFetch = 4460, + kOBSOLETE_TopicsAPIXhr = 4461, + kParseFromString = 4462, + kOBSOLETE_HTMLPatternRegExpUnicodeSetIncompatibilitiesWithUnicodeMode = 4463, + kPopoverTypeAuto = 4464, + kPopoverTypeManual = 4465, + kPopoverTypeInvalid = 4466, + kCSSAnchorPositioning = 4467, + kServiceWorkerEventHandlerAddedAfterInitialization = 4468, + kServiceWorkerEventHandlerModifiedAfterInitialization = 4469, + kAuthorizationCrossOrigin = 4470, + kCSSColorMixFunction = 4471, + kOBSOLETE_CSSColorColorSpecifiedSpace = 4472, + kOBSOLETE_CSSColorLabOklab = 4473, + kOBSOLETE_CSSColorLchOklch = 4474, + kOBSOLETE_CreateNSResolverWithNonElements2 = 4475, + kGetDisplayMediaWithPreferCurrentTabTrue = 4476, + kFencedFrameConfigAttribute = 4477, + kURLSearchParams_Has_Delete_MultipleArguments = 4478, + // The items above roughly this point are available in the M112 branch. + + kPopoverTypeHint = 4480, + kOBSOLETE_WebGPUWebCodecs = 4481, + kRTCPeerConnectionLegacyGetStatsTrial = 4482, + kExecutedEmptyJavaScriptURLFromFrame = 4483, + kExecutedJavaScriptURLFromFrame = 4484, + kOBSOLETE_ServiceWorkerBypassFetchHandlerForSubResource = 4485, + kCSSAtRuleStartingStyle = 4486, + kPrivateAggregationApiFledgeExtensions = 4487, + kDeprecatedInterestGroupDailyUpdateUrl = 4488, + kCSSColorGradientColorSpace = 4489, + kDanglingMarkupInWindowName = 4490, + kDanglingMarkupInWindowNameNotEndsWithNewLineOrGT = 4491, + kDanglingMarkupInWindowNameNotEndsWithGT = 4492, + kDanglingMarkupInTarget = 4493, + kDanglingMarkupInTargetNotEndsWithGT = 4494, + kDanglingMarkupInTargetNotEndsWithNewLineOrGT = 4495, + kAttributionFencedFrameReportingBeacon = 4496, + kIframeBrowsingTopicsAttribute = 4497, + kSpeculationRulesSelectorMatches = 4498, + kSpeculationRulesExplicitEagerness = 4499, + kSpeculationRulesEagernessConservative = 4500, + kSpeculationRulesEagernessModerate = 4501, + kSpeculationRulesEagernessEager = 4502, + kOBSOLETE_URLSetPortCheckOverflow = 4503, + kV8Animation_RangeStart_AttributeGetter = 4504, + kV8Animation_RangeStart_AttributeSetter = 4505, + kV8Animation_RangeEnd_AttributeGetter = 4506, + kV8Animation_RangeEnd_AttributeSetter = 4507, + kV8StorageBucket_Persist_Method = 4508, + kV8StorageBucket_Persisted_Method = 4509, + kV8StorageBucket_Estimate_Method = 4510, + kV8StorageBucket_Durability_Method = 4511, + kV8StorageBucket_SetExpires_Method = 4512, + kV8StorageBucket_Expires_Method = 4513, + kV8StorageBucket_IndexedDB_AttributeGetter = 4514, + kV8StorageBucket_Locks_AttributeGetter = 4515, + kV8StorageBucket_Caches_AttributeGetter = 4516, + kV8StorageBucket_GetDirectory_Method = 4517, + kV8StorageBucketManager_Keys_Method = 4518, + kV8StorageBucketManager_Delete_Method = 4519, + kNavigatorUAData_GetHighEntropyValues = 4520, + kSchedulerYield = 4521, + kHtmlClipboardApiUnsanitizedRead = 4522, + kHtmlClipboardApiUnsanitizedWrite = 4523, + kAsyncClipboardAPIUnsanitizedRead = 4524, + kOBSOLETE_WindowOpenFullscreenRequested = 4525, + kOBSOLETE_FullscreenAllowedByWindowOpen = 4526, + // The items above roughly this point are available in the M113 branch. + + kAttributeValueContainsLtOrGt = 4527, + kOBSOLETE_V8ImportAssertionDeprecatedSyntax = 4528, + kImageCaptureBackgroundBlur = 4529, + kPrivateNetworkAccessPreflightError = 4530, + kPrivateNetworkAccessPreflightSuccess = 4531, + kPrivateNetworkAccessPreflightWarning = 4532, + kCSSGetComputedAnimationDurationZero = 4533, + kCSSGetComputedWebkitFontSmoothingAnimationDurationZero = 4534, + kDocumentOpenAliasedOriginDocumentDomain = 4535, + kGamepadTouchEvents = 4536, + kGamepadTouchTouchId = 4537, + kGamepadTouchSurfaceId = 4538, + kGamepadTouchPosition = 4539, + kGamepadTouchSurfaceDimension = 4540, + kSandboxViaFencedFrame = 4541, + kVisibilityStateObserver = 4542, + kV8CompileHintsMagicAll = 4543, + kOBSOLETE_TextWrapBalance = 4544, + kOBSOLETE_TextWrapBalanceFail = 4545, + kAttributionReportingCrossAppWeb = 4546, + kSecurePaymentConfirmationActivationlessShow = 4547, + kOBSOLETE_ServiceWorkerBypassFetchHandlerForAllWithRaceNetworkRequest = 4548, + // The items above roughly this point are available in the M114 branch. + + kFlexIntrinsicSizesCacheMiss = 4549, + kCSSStyleContainerQuery = 4550, + kCSSValueAppearanceMediaSlider = 4551, + kCSSValueAppearanceMediaSliderthumb = 4552, + kCSSValueAppearanceMediaVolumeSlider = 4553, + kCSSValueAppearanceMediaVolumeSliderthumb = 4554, + kCSSValueAppearanceSliderHorizontal = 4555, + kCSSValueAppearanceSliderVertical = 4556, + kCSSValueAppearanceSliderthumbHorizontal = 4557, + kCSSValueAppearanceSliderthumbVertical = 4558, + kOBSOLETE_ServiceWorkerBypassFetchHandlerForAllWithRaceNetworkRequestByOriginTrial = 4559, + kOBSOLETE_EventTimingPaintedPresentationPromiseResolvedWithEarlierPromiseUnresolved = 4560, + kLinkRelPreloadAsFont = 4561, + kCrossWindowAccessToBrowserGeneratedDocument = 4562, + kSpeculationRulesNoVarySearchHint = 4563, + kFileSystemAccessMoveRename = 4564, + kFileSystemAccessMoveReparent = 4565, + kFileSystemAccessMoveReparentAndRename = 4566, + kV8FileSystemDirectoryHandle_RemoveEntry_Method = 4567, + kV8FileSystemFileHandle_CreateWritable_Method = 4568, + kV8FileSystemFileHandle_GetFile_Method = 4569, + kV8FileSystemHandle_GetUniqueId_Method = 4570, + kV8FileSystemHandle_Remove_Method = 4571, + kPerformanceNavigateSystemEntropy = 4572, + kV8InvalidatedNumberStringNotRegexpLikeProtector = 4573, + kCriticalCHRestartNavigationTiming = 4574, + kTopLevelDocumentWithEmbeddedCredentials = 4575, + kV8Navigator_GetInterestGroupAdAuctionData_Method = 4576, + kLongAnimationFrameObserver = 4577, + kLongAnimationFrameRequested = 4578, + // The items above roughly this point are available in the M115 branch. + + kFedCmLoginHint = 4579, + kFedCmRpContext = 4580, + kEventTimingArtificialPointerupOrClick = 4581, + kAbortSignalAny = 4582, + kFedCmIdpSigninStatusApi = 4583, + kFedCmIdpSigninStatusJsApi = 4584, + kExecCommand = 4585, + kWebGPUQueueSubmit = 4586, + kWebGPUCanvasContextGetCurrentTexture = 4587, + kEditContext = 4588, + kOBSOLETE_kServiceWorkerStaticRouter_RegisterRouter = 4589, + kServiceWorkerStaticRouter_Evaluate = 4590, + kClientHintsUAFormFactors = 4591, + kURLSearchParamsHasFnBehaviourDiverged = 4592, + kURLSearchParamsDeleteFnBehaviourDiverged = 4593, + kOBSOLETE_TextWrapPretty = 4594, + kOBSOLETE_TextWrapPrettyFail = 4595, + kContainerQueryEvalUnknown = 4596, + kOBSOLETE_EventTimingPresentationPromiseResolvedAfterReport = 4597, + kGetCoalescedEventsInInsecureContext = 4598, + kCSPEESameOriginBlanketEnforcement = 4599, + // The items above roughly this point are available in the M116 branch. + + kSharedDictionaryUsed = 4601, + kSharedDictionaryUsedForNavigation = 4602, + kSharedDictionaryUsedForMainFrameNavigation = 4603, + kSharedDictionaryUsedForSubFrameNavigation = 4604, + kSharedDictionaryUsedForSubresource = 4605, + kPriceChangeConfirmation = 4606, + kPaymentRequestActivationlessShow = 4607, + kWebAppTabbed = 4608, + kFetchLater = 4609, + kURLPatternReliantOnImplicitURLComponentsInString = 4610, + kURLPatternReliantOnLaterComponentFromBaseURL = 4611, + kV8Navigator_CreateAuctionNonce_Method = 4612, + kCrossOriginWindowFrameElement = 4613, + kQuirksModeAboutBlankDocument = 4614, + kV8WasmMemory64 = 4615, + kV8WasmMultiMemory = 4616, + kV8WasmGC = 4617, + // The items above roughly this point are available in the M117 branch. + + kOBSOLETE_ORBBlockWithoutAnyEventHandler = 4618, + kOBSOLETE_ORBBlockWithOnErrorButWithoutOnLoadEventHandler = 4619, + kOBSOLETE_ORBBlockWithOnLoadButWithoutOnErrorEventHandler = 4620, + kOBSOLETE_ORBBlockWithOnLoadAndOnErrorEventHandler = 4621, + kOBSOLETE_ORBBlockWithAnyEventHandler = 4622, + kV8RTCEncodedVideoFrame_SetMetadata_Method = 4623, + kV8RTCEncodedVideoFrame_SetTimestamp_Method = 4624, + kV8RTCEncodedAudioFrame_SetTimestamp_Method = 4625, + kCSSAtRuleViewTransition = 4626, + kSharedDictionaryUsedWithSharedBrotli = 4627, + kSharedDictionaryUsedWithSharedZstd = 4628, + kZstdContentEncoding = 4629, + kGetAllScreensMedia = 4630, + kInputEventToRecentlyMovedIframeMistakenlyDiscarded = 4631, + kCSSRelativeColor = 4632, + kXPathMissingVariableParsed = 4633, + kXPathMissingVariableEvaluated = 4634, + kClientHintsPrefersReducedTransparency = 4635, + kElementCapture = 4636, + kSharedStorageAPI_Fetch_Attribute = 4637, + kSharedStorageAPI_Image_Attribute = 4638, + kSharedStorageAPI_Iframe_Attribute = 4639, + kVirtualKeyboardShow = 4640, + kVirtualKeyboardHide = 4641, + kVirtualKeyboardOverlayPolicy = 4642, + kScrollSnapNestedSnapAreas = 4643, + kScrollSnapCoveringSnapArea = 4644, + kV8RTCEncodedAudioFrame_SetMetadata_Method = 4645, + kV8FetchLaterResult_Activated_AttributeGetter = 4646, + kV8Window_FetchLater_Method = 4647, + kFetchLaterInvokeStateDeferred = 4648, + kFetchLaterInvokeStateScheduled = 4649, + kFetchLaterInvokeStateTerminated = 4650, + kFetchLaterInvokeStateAborted = 4651, + kFetchLaterInvokeStateActivated = 4652, + kFetchLaterErrorUnknownBodyLength = 4653, + kFetchLaterErrorQuotaExceeded = 4654, + kV8FileSystemHandle_GetCloudIdentifiers_Method = 4655, + kPrivateAggregationApiEnableDebugMode = 4656, + kLineBreakPhrase = 4657, + kOBSOLETE_AttributionReportingUnderscorePrefixedFilterKey = 4658, + kPercentOrCalcStickyUsedOffset = 4659, + kPercentOrCalcRelativeUsedOffset = 4660, + kAutoRelativeUsedOffset = 4661, + kViewportFitContain = 4662, + kViewportFitCover = 4663, + kViewportFitCoverOrSafeAreaInsetBottom = 4664, + // The items above roughly this point are available in the M118 branch. + + kOutOfFlowJustifySelfNoInsets = 4665, + kOutOfFlowJustifySelfSingleInset = 4666, + kOutOfFlowJustifySelfBothInsets = 4667, + kOutOfFlowAlignSelfNoInsets = 4668, + kOutOfFlowAlignSelfSingleInset = 4669, + kOutOfFlowAlignSelfBothInsets = 4670, + kV8WebAssemblyJSStringBuiltins = 4671, + kObservableConstructor = 4672, + kTextWrapBalance = 4673, + kTextWrapPretty = 4674, + // The items above roughly this point are available in the M119 branch. + + kSourceMappingUrlMagicCommentAtSign = 4676, + kHTMLDetailsElementNameAttribute = 4677, + kHTMLDetailsElementNameAttributeClosesSelf = 4678, + kHTMLDetailsElementNameAttributeClosesOther = 4679, + kCSSSubgridLayout = 4680, + kV8TemporalObject = 4681, + kChromeCSIUnknown = 4682, + kChromeCSIOnloadT = 4683, + kChromeCSIPageT = 4684, + kChromeCSIStartE = 4685, + kChromeCSITran = 4686, + kParseHTMLUnsafe = 4687, + kSetHTMLUnsafe = 4688, + kWebAssemblyModuleCompilation = 4689, + kV8MediaStreamTrack_Stats_AttributeGetter = 4690, + kElementCheckVisibility = 4691, + kV8ClipboardItem_Supports_Method = 4692, + kThirdPartyCookieAccessBlockByExperiment = 4693, + kCspWouldBlockIfWildcardDoesNotMatchWs = 4694, + kCspWouldBlockIfWildcardDoesNotMatchFtp = 4695, + kStorageAccessAPI_requestStorageAccess_BeyondCookies = 4696, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_all = 4697, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_sessionStorage = 4698, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_sessionStorage_Use = 4699, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_localStorage = 4700, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_localStorage_Use = 4701, + kElementCheckVisibilityOptionCheckVisibilityCSS = 4702, + kElementCheckVisibilityOptionCheckOpacity = 4703, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_indexedDB = 4704, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_indexedDB_Use = 4705, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_locks = 4706, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_locks_Use = 4707, + kOBSOLETE_RubyElementWithDisplayBlockAndRt = 4708, + kCSSDeclarationAfterNestedRule = 4709, + kThirdPartyCookieAdAccessBlockByExperiment = 4710, + // The items above roughly this point are available in the M120 branch. + + kServiceWorkerStaticRouter_AddRoutes = 4711, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_caches = 4712, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_caches_Use = 4713, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_getDirectory = 4714, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_getDirectory_Use = 4715, + kElementCheckVisibilityOptionContentVisibilityAuto = 4716, + kElementCheckVisibilityOptionOpacityProperty = 4717, + kElementCheckVisibilityOptionVisibilityProperty = 4718, + kAdClickMainFrameNavigation = 4719, + kLinkRelPrivacyPolicy = 4720, + kLinkRelTermsOfService = 4721, + kWebAppManifestIdField = 4722, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_estimate = 4723, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_estimate_Use = 4724, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_createObjectURL = 4725, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_createObjectURL_Use = 4726, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_revokeObjectURL = 4727, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_revokeObjectURL_Use = 4728, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_BroadcastChannel = 4729, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_BroadcastChannel_Use = 4730, + kThirdPartyCookieDeprecation_AllowByExplicitSetting = 4731, + kThirdPartyCookieDeprecation_AllowByGlobalSetting = 4732, + kThirdPartyCookieDeprecation_AllowBy3PCDMetadata = 4733, + kThirdPartyCookieDeprecation_AllowBy3PCD = 4734, + kThirdPartyCookieDeprecation_AllowBy3PCDHeuristics = 4735, + kThirdPartyCookieDeprecation_AllowByStorageAccess = 4736, + kThirdPartyCookieDeprecation_AllowByTopLevelStorageAccess = 4737, + kIframeAdAuctionHeadersAttribute = 4738, + kAutoSpeculationRulesOptedOut = 4739, + kOverrideFlashEmbedwithHTML = 4740, + kLinkRelOpener = 4741, + kLinkRelOpenerTargetingSameFrame = 4742, + kCSSSelectorPseudoHas = 4743, + kWakeLockAcquireScreenLockWithoutStickyActivation = 4744, + kSubtleCryptoDeriveBitsZeroLength = 4745, + kSubtleCryptoDeriveBitsTruncation = 4746, + kTextDirectiveInShadowDOM = 4747, + kOBSOLETE_PseudoFirstLetterOnRt = 4748, + kOBSOLETE_PseudoFirstLineOnRt = 4749, + kAutoSizesLazy = 4750, + kAutoSizesNonLazy = 4751, + kOBSOLETE_TrustedTypesIntrospection = 4752, + kTrustedTypesIsCheck = 4753, + kMouseDragOnCancelledMouseMove = 4754, + // The items above roughly this point are available in the M121 branch. + + kFedCmDomainHint = 4755, + kLCPImageWasLazy = 4756, + kEventTargetOnObservable = 4757, + kCredentialManagerCrossOriginPublicKeyCreateRequest = 4758, + kViewTransitionNameAuto = 4759, + kV8WasmJavaScriptPromiseIntegration = 4760, + kWindowMinimize = 4761, + kWindowMaximize = 4762, + kWindowRestore = 4763, + kWindowSetResizable = 4764, + kV8WasmReturnCall = 4765, + kV8WasmExtendedConst = 4766, + kV8WasmRelaxedSimd = 4767, + kV8WasmTypeReflection = 4768, + kV8WasmExnRef = 4769, + kV8WasmTypedFuncRef = 4770, + kHTMLButtonInSelect = 4771, + kHTMLDatalistInSelect = 4772, + kEffectiveAlignContentForBlock = 4773, + kEffectiveAlignContentForTableCell = 4774, + kUserFeatureNgOptimizedImage = 4775, + kCSSAtRulePageMargin = 4776, + kThirdPartyCookieDeprecation_AllowByEnterprisePolicyCookieAllowedForUrls = 4777, + kUserFeatureNgAfterRender = 4778, + kUserFeatureNgHydration = 4779, + kCapturedSurfaceControl = 4780, + kElementGetHTML = 4781, + kElementAttachSerializableShadow = 4782, + kCSSBareDeclarationShift = 4783, + kCSSNestedGroupRuleSpecificity = 4784, + kCSSRuleWithSignalingChildModified = 4785, + kUserFeatureNextThirdPartiesGA = 4786, + kUserFeatureNextThirdPartiesGTM = 4787, + kUserFeatureNextThirdPartiesYouTubeEmbed = 4788, + kUserFeatureNextThirdPartiesGoogleMapsEmbed = 4789, + kStorageAccessAPI_hasUnpartitionedCookieAccess = 4790, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_cookies = 4791, + kVisualViewportScrollEndFired = 4792, + kAttributionReportingCrossAppWebSupportHeader = 4793, + kV8Element_AriaActiveDescendantElement_AttributeGetter = 4794, + kV8Element_AriaActiveDescendantElement_AttributeSetter = 4795, + kV8Element_AriaControlsElements_AttributeGetter = 4796, + kV8Element_AriaControlsElements_AttributeSetter = 4797, + kV8Element_AriaDescribedByElements_AttributeGetter = 4798, + kV8Element_AriaDescribedByElements_AttributeSetter = 4799, + kV8Element_AriaDetailsElements_AttributeGetter = 4800, + kV8Element_AriaDetailsElements_AttributeSetter = 4801, + kV8Element_AriaErrorMessageElements_AttributeGetter = 4802, + kV8Element_AriaErrorMessageElements_AttributeSetter = 4803, + kV8Element_AriaFlowToElements_AttributeGetter = 4804, + kV8Element_AriaFlowToElements_AttributeSetter = 4805, + kV8Element_AriaLabelledByElements_AttributeGetter = 4806, + kV8Element_AriaLabelledByElements_AttributeSetter = 4807, + kV8Element_AriaOwnsElements_AttributeGetter = 4808, + kV8Element_AriaOwnsElements_AttributeSetter = 4809, + kV8ElementInternals_AriaActiveDescendantElement_AttributeGetter = 4810, + kV8ElementInternals_AriaActiveDescendantElement_AttributeSetter = 4811, + kV8ElementInternals_AriaControlsElements_AttributeGetter = 4812, + kV8ElementInternals_AriaControlsElements_AttributeSetter = 4813, + kV8ElementInternals_AriaDescribedByElements_AttributeGetter = 4814, + kV8ElementInternals_AriaDescribedByElements_AttributeSetter = 4815, + kV8ElementInternals_AriaDetailsElements_AttributeGetter = 4816, + kV8ElementInternals_AriaDetailsElements_AttributeSetter = 4817, + kV8ElementInternals_AriaErrorMessageElements_AttributeGetter = 4818, + kV8ElementInternals_AriaErrorMessageElements_AttributeSetter = 4819, + kV8ElementInternals_AriaFlowToElements_AttributeGetter = 4820, + kV8ElementInternals_AriaFlowToElements_AttributeSetter = 4821, + kV8ElementInternals_AriaLabelledByElements_AttributeGetter = 4822, + kV8ElementInternals_AriaLabelledByElements_AttributeSetter = 4823, + kV8ElementInternals_AriaOwnsElements_AttributeGetter = 4824, + kV8ElementInternals_AriaOwnsElements_AttributeSetter = 4825, + kIdentityDigitalCredentials = 4826, + kCSSSelectorPseudoState = 4827, + kSpeculationRulesPrefetch = 4828, + kSpeculationRulesAuthorPrefetchRule = 4829, + kSpeculationRulesAuthorPrerenderRule = 4830, + kSpeculationRulesBrowserPrefetchRule = 4831, + kSpeculationRulesBrowserPrerenderRule = 4832, + kFirstPartySharedWorkerSameSiteCookiesNone = 4833, + kCSSCustomStateDeprecatedSyntax = 4834, + kFullscreenAllowedByContentSetting = 4835, + kSharedStorageAPI_CreateWorklet_Method = 4836, + kCanvas2DLayers = 4837, + kUserFeatureNuxtImage = 4838, + kUserFeatureNuxtPicture = 4839, + kUserFeatureNuxtThirdPartiesGA = 4840, + kUserFeatureNuxtThirdPartiesGTM = 4841, + kUserFeatureNuxtThirdPartiesYouTubeEmbed = 4842, + kUserFeatureNuxtThirdPartiesGoogleMaps = 4843, + kSelectParserDroppedTag = 4844, + kInputTypeRangeHorizontalLtr = 4845, + kInputTypeRangeHorizontalRtl = 4846, + kInputTypeRangeVerticalLtr = 4847, + kInputTypeRangeVerticalRtl = 4848, + kMeterElementHorizontalLtr = 4849, + kMeterElementHorizontalRtl = 4850, + kMeterElementVerticalLtr = 4851, + kMeterElementVerticalRtl = 4852, + kProgressElementHorizontalLtr = 4853, + kProgressElementHorizontalRtl = 4854, + kProgressElementVerticalLtr = 4855, + kProgressElementVerticalRtl = 4856, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_SharedWorker = 4857, + kStorageAccessAPI_requestStorageAccess_BeyondCookies_SharedWorker_Use = 4858, + kV8PointerEvent_GetCoalescedEvents_Method = 4859, + kV8RTCEncodedVideoFrame_Constructor = 4860, + kCSSFunctions = 4861, + kCSSPageRule = 4862, + // The items above roughly this point are available in the M123 branch. + + kV8RTCRtpReceiver_JitterBufferTarget_AttributeGetter = 4863, + kV8RTCRtpReceiver_JitterBufferTarget_AttributeSetter = 4864, + kTrustedTypesIntrospectionAttributeType = 4865, + kTrustedTypesIntrospectionPropertyType = 4866, + kTrustedTypesIntrospectionTypeMapping = 4867, + kIndexedDBFileLastModifiedDate = 4868, + kSpeculationRulesRejectedLaxReferrerPolicy = 4869, + kSpeculationRulesUsedLinkReferrerPolicy = 4870, + kSpeculationRulesExplicitReferrerPolicy = 4871, + kDOMClobberedShadowedDocumentPropertyAccessed = 4872, + kDOMClobberedNotShadowedDocumentPropertyAccessed = 4873, + kDOMClobberedShadowedFormPropertyAccessed = 4874, + kDOMClobberedNotShadowedFormPropertyAccessed = 4875, + kTpcdCookieReadBlockedByAdHeuristics = 4876, + kUsedColorSchemeRootScrollbarsDark = 4877, + kSerialPortConnected = 4878, + kDevicePostureMediaFeature = 4879, + kDevicePosture = 4880, + kViewportSegmentsMediaFeature = 4881, + kViewportSegments = 4882, + kPrivateNetworkAccessWebSocketConnected = 4883, + kWebAppTitle = 4884, + kDOMSubtreeModifiedEventFired = 4885, + kDOMNodeInsertedEventFired = 4886, + kDOMNodeRemovedEventFired = 4887, + kDOMNodeRemovedFromDocumentEventFired = 4888, + kDOMNodeInsertedIntoDocumentEventFired = 4889, + kDOMCharacterDataModifiedEventFired = 4890, + kAnyMutationEventFired = 4891, + kAnyMutationEventListenerAdded = 4892, + kBadgeSetWithoutNotificationPermissionInBrowserWindow = 4893, + kBadgeSetWithoutNotificationPermissionInAppWindow = 4894, + kBadgeSetWithoutNotificationPermissionInWorker = 4895, + kQuirksModeCursorHand = 4896, + kTrustedTypesCreatePolicyWithEmptyName = 4897, + kV8RTCEncodedAudioFrame_Constructor = 4898, + kTCPSocketConstructor = 4899, + kTCPSocketOpenedAttribute = 4900, + kTCPSocketClosedAttribute = 4901, + kTCPSocketCloseFunction = 4902, + kUDPSocketConstructor = 4903, + kUDPSocketOpenedAttribute = 4904, + kUDPSocketClosedAttribute = 4905, + kUDPSocketCloseFunction = 4906, + kTCPServerSocketConstructor = 4907, + kTCPServerSocketOpenedAttribute = 4908, + kTCPServerSocketClosedAttribute = 4909, + kTCPServerSocketCloseFunction = 4910, + kWebPrintingGetPrintersFunction = 4911, + kWebPrinterCachedAttributesFunction = 4912, + kWebPrinterFetchAttributesFunction = 4913, + kWebPrinterPrintJobFunction = 4914, + kWebPrintJobAttributesFunction = 4915, + kWebPrintJobCancelFunction = 4916, + kWebPrintJobOnJobStateChangeEvent = 4917, + kFledgeAuctionReportBuyers = 4918, + kFledgeAuctionReportBuyerDebugModeConfig = 4919, + kFedCmButtonMode = 4920, + // The items above roughly this point are available in the M124 branch. + + kHTMLPermissionElement = 4921, + kOBSOLETE_V8ModelGenericSession_Execute_Method = 4922, + kOBSOLETE_V8ModelGenericSession_ExecuteStreaming_Method = 4923, + kOBSOLETE_V8ModelManager_CanCreateGenericSession_Method = 4924, + kOBSOLETE_V8ModelManager_CreateGenericSession_Method = 4925, + kV8Animation_Progress_AttributeGetter = 4926, + kOBSOLETE_V8ModelManager_DefaultGenericSessionOptions_Method = 4927, + kQuirksModeCursorHandApplied = 4928, + kSkippedPreloadScanning = 4929, + kCSSColor_SpaceRGB = 4930, + kCSSColor_SpaceRGB_outOfRec2020= 4931, + kCSSColor_SpaceOkLxx = 4932, + kCSSColor_SpaceOkLxx_outOfRec2020 = 4933, + kSandboxedSrcdocFrameResolvesRelativeURL = 4934, + kV8Ink_RequestPresenter_Method = 4935, + kEventTimingOrphanPointerup = 4936, + kNavigatorCookieEnabledThirdParty = 4937, + kFoldableAPIs = 4938, + kSnapEvent = 4939, + kStaticPropertyInAnimation = 4940, + kSimplifyLoadingTransparentPlaceholderImage = 4941, + kIdentityDigitalCredentialsSuccess = 4942, + kOBSOLETE_V8DeviceProperties_UniqueId_AttributeGetter = 4943, + // The items above roughly this point are available in the M125 branch. + + kSharedStorageAPI_SelectURLOverallPageloadBudgetInsufficient = 4944, + kV8LanguageTranslator_Translate_Method = 4945, + kV8Translation_CanTranslate_Method = 4946, + kV8Translation_CreateTranslator_Method = 4947, + kIdentityDigitalCredentialsDeepLink = 4948, + kV8WebView_GetExperimentalMediaIntegrityTokenProvider_Method = 4949, + kV8MediaIntegrityTokenProvider_RequestToken_Method = 4950, + kCanvas2DLayersFilters = 4951, + kCanvas2DLayersCSSFilters = 4952, + kCanvas2DLayersFilterObjects = 4953, + kCSSScrollStartTarget = 4954, + kFedCmContinueOnResponse = 4955, + kFedCmMultipleIdentityProviders = 4956, + kFedCmWithStorageAccessAPI = 4957, + kCSSSelectorUserValid = 4958, + kCSSSelectorUserInvalid = 4959, + kCrossShadowAtomicMove = 4960, + kPrefersReducedMotionMediaFeature = 4961, + kPrefersReducedTransparencyMediaFeature = 4962, + kPrefersReducedDataMediaFeature = 4963, + kScriptingMediaFeature = 4964, + kInvertedColorsMediaFeature = 4965, + kCSSLightDark = 4966, + kPrivateAggregationApiFilteringIds = 4967, + kHTMLInputInSelect = 4968, + kCanvas2DMesh = 4969, + kCaretPositionFromPoint = 4970, + kDocumentPolicyIncludeJSCallStacksInCrashReports = 4971, + kMaximumHTMLParserDOMTreeDepthHit = 4972, + // The items above roughly this point are available in the M126 branch. + + kV8ModelGenericSession_Destroy_Method = 4973, + kUsedDeviceScaleAdjustment = 4974, + kDisableThirdPartyStoragePartitioning2 = 4975, + kLinkRelPayment = 4976, + kV8GPUAdapter_RequestAdapterInfo_Method = 4977, + kOBSOLETE_V8ModelGenericSession_Destroy_Method = 4978, + kV8AITextSession_Execute_Method = 4979, + kV8AITextSession_ExecuteStreaming_Method = 4980, + kV8AI_CanCreateGenericSession_Method = 4981, + kV8AI_CreateGenericSession_Method = 4982, + kV8AI_DefaultGenericSessionOptions_Method = 4983, + kV8AITextSession_Prompt_Method = 4984, + kV8AITextSession_PromptStreaming_Method = 4985, + kV8AI_CanCreateTextSession_Method = 4986, + kV8AI_CreateTextSession_Method = 4987, + kV8AI_DefaultTextSessionOptions_Method = 4988, + kV8AITextSession_Destroy_Method = 4989, + kImportMapIntegrity = 4990, + kSelectElementAppearanceNone = 4991, + kRubyPositionAlternate = 4992, + kRubyPositionInterCharacter = 4993, + kTextSizeAdjustNotAuto = 4994, + kTextSizeAdjustPercentNot100 = 4995, + kServiceWorkerAutoPreload = 4996, + kV8InvalidatedNoUndetectableObjectsProtector = 4997, + kV8DocumentAllLegacyCall = 4998, + kV8DocumentAllLegacyConstruct = 4999, + kInsideListMarkerPositionQuirk = 5000, + kZstdContentEncodingForNavigation = 5001, + kZstdContentEncodingForMainFrameNavigation = 5002, + kZstdContentEncodingForSubFrameNavigation = 5003, + kZstdContentEncodingForSubresource = 5004, + kEventTimingOrphanPointerupWithClick = 5005, + kDisableReduceAcceptLanguage = 5006, + kSharedStorageAPI_CreateWorklet_CrossOriginScriptDefaultDataOrigin = 5007, + kDeprecatedAIModel = 5008, + kDeprecatedAICanCreateGenericSession = 5009, + kDeprecatedAICreateGenericSession = 5010, + kDeprecatedAIDefaultGenericSessionOptions = 5011, + kDeprecatedAITextSessionExecute = 5012, + kDeprecatedAITextSessionExecuteStreaming = 5013, + kARIAColIndexTextAttribute = 5014, + kARIARowIndexTextAttribute = 5015, + kV8PointerEvent_PersistentDeviceId_AttributeGetter = 5016, + kDelegatedInkExpectedImprovement = 5017, + kCSSSelectorNthChildOfSelector = 5018, + kDisableStandardizedBrowserZoom = 5019, + kV8FileSystemObserver_Constructor = 5020, + kV8FileSystemObserver_Observe_Method = 5021, + kV8FileSystemObserver_Disconnect_Method = 5022, + kV8ML_CreateContext_Method = 5023, + kV8MLContext_Compute_Method = 5024, + kV8MLContext_Dispatch_Method = 5025, + kCSSMixins = 5026, + kDurationFormat = 5027, + kSharedStorageAPI_AddModule_CrossOriginScript = 5028, + kCrossOriginOpenerPolicyNoopenerAllowPopups = 5029, + kCrossOriginOpenerPolicyNoopenerAllowPopupsReportOnly = 5030, + kV8ConsoleContext = 5031, + kButtonTypeAttrInvalid = 5032, + kButtonTypeAttrEmptyString = 5033, + kProtectedAudienceDirectFromSellerSignals = 5034, + kWebGPUSubgroupsFeatures = 5035, + kAudioContextOnError = 5036, + kNoVarySearchPrerender = 5037, + kFlexNewColumnWrapIntrinsicSize = 5043, + + // Add new features immediately above this line. Don't change assigned + // numbers of any item, and don't reuse removed slots. Also don't add extra + // spaces or comments in this file. Comments belong next to the usage of + // these constants in code. + + // Also, run update_use_counter_feature_enum.py in + // chromium/src/tools/metrics/histograms/ to update the UMA mapping. + // TODO(dcheng): Fix https://crbug.com/742517 and use the autogenerated + // constants. + kNumberOfFeatures, // This enum value must be last. +}; diff --git a/tools/under-control/src/third_party/blink/public/mojom/webpreferences/web_preferences.mojom b/tools/under-control/src/third_party/blink/public/mojom/webpreferences/web_preferences.mojom new file mode 100755 index 000000000..5560f0ff4 --- /dev/null +++ b/tools/under-control/src/third_party/blink/public/mojom/webpreferences/web_preferences.mojom @@ -0,0 +1,494 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module blink.mojom; + +import "third_party/blink/public/mojom/css/preferred_color_scheme.mojom"; +import "third_party/blink/public/mojom/css/preferred_contrast.mojom"; +import "third_party/blink/public/mojom/v8_cache_options.mojom"; +import "url/mojom/url.mojom"; +import "mojo/public/mojom/base/string16.mojom"; + +enum PointerType { + kPointerNone = 1, // 1 << 0 + kPointerFirstType = kPointerNone, + kPointerCoarseType = 2, // 1 << 1 + kPointerFineType = 4 // 1 << 2 +}; + +enum HoverType { + kHoverNone = 1, // 1 << 0 + kHoverFirstType = kHoverNone, + kHoverHoverType = 2 // 1 << 1 +}; + +// For media feature update, indicating the update ability of the output display, +// once renering is done: +// Slow - e-ink screens, underpowered devices. +// Fast - regular computer screen. +enum OutputDeviceUpdateAbilityType { + kSlowType, + kFastType +}; + +// There are multiple editing details that are different on Windows than +// Macintosh. We use a single switch for all of them. Some examples: +// +// 1) Clicking below the last line of an editable area puts the caret at the +// end of the last line on Mac, but in the middle of the last line on +// Windows. +// 2) Pushing the down arrow key on the last line puts the caret at the end +// of the last line on Mac, but does nothing on Windows. A similar case +// exists on the top line. +// +// This setting is intended to control these sorts of behaviors. There are some +// other behaviors with individual function calls on EditorClient (smart copy +// and paste and selecting the space after a double click) that could be +// combined with this if if possible in the future. +enum EditingBehavior { + kEditingMacBehavior, + kEditingWindowsBehavior, + kEditingUnixBehavior, + kEditingAndroidBehavior, + kEditingChromeOSBehavior +}; + +// ImageAnimationPolicy is used for controlling image animation +// when image frame is rendered for animation. +// See third_party/WebKit/Source/platform/graphics/ImageAnimationPolicy.h +// for information on the options. +enum ImageAnimationPolicy { + kImageAnimationPolicyAllowed, + kImageAnimationPolicyAnimateOnce, + kImageAnimationPolicyNoAnimation +}; + +enum ViewportStyle { kDefault, kMobile, kTelevision, kLast = kTelevision }; + +// Defines the autoplay policy to be used. Should match the class in +// WebSettings.h. +enum AutoplayPolicy { + kNoUserGestureRequired, + kUserGestureRequired, + kDocumentUserActivationRequired, +}; + +enum EffectiveConnectionType { + // Effective connection type reported when the network quality is unknown. + kEffectiveConnectionUnknownType, + + // Effective connection type reported when the Internet is unreachable + // because the device does not have a connection (as reported by underlying + // platform APIs). Note that due to rare but potential bugs in the platform + // APIs, it is possible that effective connection type is reported as + // EFFECTIVE_CONNECTION_TYPE_OFFLINE. Callers must use caution when using + // acting on this. + kEffectiveConnectionOfflineType, + + // Effective connection type reported when the network has the quality of a + // poor 2G connection. + kEffectiveConnectionSlow2GType, + + // Effective connection type reported when the network has the quality of a + // faster 2G connection. + kEffectiveConnection2GType, + + // Effective connection type reported when the network has the quality of a 3G + // connection. + kEffectiveConnection3GType, + + // Effective connection type reported when the network has the quality of a 4G + // connection. + kEffectiveConnection4GType, + + // Last value of the effective connection type. This value is unused. + kEffectiveConnectionTypeLast, +}; + +struct WebPreferences { + map standard_font_family_map; + map fixed_font_family_map; + map serif_font_family_map; + map sans_serif_font_family_map; + map cursive_font_family_map; + map fantasy_font_family_map; + map math_font_family_map; + int32 default_font_size; + int32 default_fixed_font_size; + int32 minimum_font_size; + int32 minimum_logical_font_size; + string default_encoding; + bool context_menu_on_mouse_up; + bool javascript_enabled; + bool web_security_enabled; + bool loads_images_automatically; + bool images_enabled; + bool plugins_enabled; + bool dom_paste_enabled; + bool shrinks_standalone_images_to_fit; + bool text_areas_are_resizable; + bool allow_scripts_to_close_windows; + bool remote_fonts_enabled; + bool javascript_can_access_clipboard; + // We don't use dns_prefetching_enabled to disable DNS prefetching. Instead, + // we disable the feature at a lower layer so that we catch non-WebKit uses + // of DNS prefetch as well. + bool dns_prefetching_enabled; + // Preference to save data. When enabled, requests will contain the header + // 'Save-Data: on'. + bool data_saver_enabled; + bool local_storage_enabled; + bool databases_enabled; + bool tabs_to_links; + bool disable_ipc_flooding_protection; + bool hyperlink_auditing_enabled; + bool allow_universal_access_from_file_urls; + bool allow_file_access_from_file_urls; + bool webgl1_enabled; + bool webgl2_enabled; + bool pepper_3d_enabled; + bool privileged_webgl_extensions_enabled; + bool webgl_errors_to_console_enabled; + bool hide_scrollbars; + bool prefers_default_scrollbar_styles; + bool accelerated_2d_canvas_enabled; + bool canvas_2d_layers_enabled; + bool antialiased_2d_canvas_disabled; + bool antialiased_clips_2d_canvas_enabled; + bool accelerated_filters_enabled; + bool deferred_filters_enabled; + bool container_culling_enabled; + bool allow_running_insecure_content; + // If true, taint32s all elements, regardless of origin. + bool disable_reading_from_canvas; + // Strict mixed content checking disables both displaying and running insecure + // mixed content, and disables embedder notifications that such content was + // requested (thereby preventing user override). + bool strict_mixed_content_checking; + // Strict powerful feature restrictions block insecure usage of powerful + // features (like device orientation) that we haven't yet disabled for the web + // at large. + bool strict_powerful_feature_restrictions; + // TODO(jww): Remove when WebView no longer needs this exception. + bool allow_geolocation_on_insecure_origins; + // Disallow user opt-in for blockable mixed content. + bool strictly_block_blockable_mixed_content; + bool block_mixed_plugin_content; + bool password_echo_enabled; + bool should_clear_document_background; + bool enable_scroll_animator; + bool prefers_reduced_motion; + bool prefers_reduced_transparency; + bool inverted_colors; + bool touch_event_feature_detection_enabled; + int32 pointer_events_max_touch_points; + int32 available_pointer_types; + PointerType primary_pointer_type; + OutputDeviceUpdateAbilityType output_device_update_ability_type; + int32 available_hover_types; + HoverType primary_hover_type; + bool dont_send_key_events_to_javascript; + bool barrel_button_for_drag_enabled; + bool sync_xhr_in_documents_enabled; + bool target_blank_implies_no_opener_enabled_will_be_removed; + bool allow_non_empty_navigator_plugins; + int32 number_of_cpu_cores; + EditingBehavior editing_behavior; + bool supports_multiple_windows; + bool viewport_enabled; + bool viewport_meta_enabled; + bool auto_zoom_focused_editable_to_legible_scale; + + // If true - Blink will clamp the minimum scale factor to the content width, + // preventing zoom beyond the visible content. This is really only needed if + // viewport_enabled is on. + bool shrinks_viewport_contents_to_fit; + + ViewportStyle viewport_style; + bool smooth_scroll_for_find_enabled; + bool main_frame_resizes_are_orientation_changes; + bool initialize_at_minimum_page_scale; + bool smart_insert_delete_enabled; + bool spatial_navigation_enabled; + V8CacheOptions v8_cache_options; + bool record_whole_document; + + // If true, stylus handwriting recognition to text input will be available in + // editable input fields which are non-password type. + bool stylus_handwriting_enabled; + + // This flags corresponds to a Page's Settings' setCookieEnabled state. It + // only controls whether or not the "document.cookie" field is properly + // connected to the backing store, for instance if you wanted to be able to + // define custom getters and setters from within a unique security content + // without raising a DOM security exception. + bool cookie_enabled; + + // This flag indicates whether H/W accelerated video decode is enabled. + // Defaults to false. + bool accelerated_video_decode_enabled; + + ImageAnimationPolicy animation_policy; + + bool user_gesture_required_for_presentation; + + bool text_tracks_enabled; + + // These fields specify the foreground and background color for WebVTT text + // tracks. Their values can be any legal CSS color descriptor. + string text_track_background_color; + string text_track_text_color; + + // These fields specify values for CSS properties used to style WebVTT text + // tracks. + // Specifies CSS font-size property in percentage. + string text_track_text_size; + string text_track_text_shadow; + string text_track_font_family; + string text_track_font_style; + // Specifies the value for CSS font-variant property. + string text_track_font_variant; + + // These fields specify values for CSS properties used to style the window + // around WebVTT text tracks. + // Window color can be any legal CSS color descriptor. + string text_track_window_color; + // Window radius is in pixels. + string text_track_window_radius; + + // Specifies the margin for WebVTT text tracks as a percentage of media + // element height/width (for horizontal/vertical text respectively). + // Cues will not be placed in this margin area. + float text_track_margin_percentage; + + bool immersive_mode_enabled; + + bool double_tap_to_zoom_enabled; + + bool fullscreen_supported; + + bool text_autosizing_enabled; + + // Representation of the Web App Manifest scope if any. + url.mojom.Url web_app_scope; + + [EnableIf=is_android] + float font_scale_factor; + + [EnableIf=is_android] + int32 font_weight_adjustment; + + [EnableIf=is_android] + int32 text_size_contrast_factor; + + [EnableIf=is_android] + float device_scale_adjustment; + + [EnableIf=is_android] + bool force_enable_zoom; + + [EnableIf=is_android] + url.mojom.Url default_video_poster_url; + + [EnableIf=is_android] + bool support_deprecated_target_density_dpi; + + [EnableIf=is_android] + bool wide_viewport_quirk; + + [EnableIf=is_android] + bool use_wide_viewport; + + [EnableIf=is_android] + bool force_zero_layout_height; + + [EnableIf=is_android] + bool viewport_meta_merge_content_quirk; + + [EnableIf=is_android] + bool viewport_meta_non_user_scalable_quirk; + + [EnableIf=is_android] + bool viewport_meta_zero_values_quirk; + + [EnableIf=is_android] + bool clobber_user_agent_initial_scale_quirk; + + [EnableIf=is_android] + bool ignore_main_frame_overflow_hidden_quirk; + + [EnableIf=is_android] + bool report_screen_size_in_physical_pixels_quirk; + + // Used by Android_WebView only to support legacy apps that inject script int32o + // a top-level initial empty document and expect it to persist on navigation. + [EnableIf=is_android] + bool reuse_global_for_unowned_main_frame; + + // Specifies default setting for spellcheck when the spellcheck attribute is + // not explicitly specified. + [EnableIf=is_android] + bool spellcheck_enabled_by_default; + + // If enabled, when a video goes fullscreen, the orientation should be locked. + [EnableIf=is_android] + bool video_fullscreen_orientation_lock_enabled; + + // If enabled, fullscreen should be entered/exited when the device is rotated + // to/from the orientation of the video. + [EnableIf=is_android] + bool video_rotate_to_fullscreen_enabled; + + [EnableIf=is_android] + bool embedded_media_experience_enabled; + + // Enable 8 (#RRGGBBAA) and 4 (#RGBA) value hex colors in CSS Android + // WebView quirk (http://crbug.com/618472). + [EnableIf=is_android] + bool css_hex_alpha_color_enabled; + + // Enable support for document.scrollingElement + // WebView sets this to false to retain old documentElement behaviour + // (http://crbug.com/761016). + [EnableIf=is_android] + bool scroll_top_left_interop_enabled; + + [EnableIf=is_android] + // Don't accelerate small canvases to avoid crashes TODO(crbug.com/1004304) + bool disable_accelerated_small_canvases; + + [EnableIf=is_android] + // Long press on links selects text instead of triggering context menu. + bool long_press_link_select_text; + + // Disable the Web Authentication (WebAuthn) API. + // TODO(crbug.com/1284805): Remove once WebView supports WebAuthn. + [EnableIf=is_android] + bool disable_webauthn; + // TODO(crbug.com/1382970): Remove once all Content embedders on Fuchsia + // support WebAuthn. + [EnableIf=is_fuchsia] + bool disable_webauthn; + + // Enable forcibly modifying content rendering to result in a light on dark + // color scheme. + bool force_dark_mode_enabled; + + // Default (used if the page or UA doesn't override these) values for page + // scale limits. These are set directly on the WebView so there's no analogue + // in WebSettings. + float default_minimum_page_scale_factor; + float default_maximum_page_scale_factor; + + // Whether download UI should be hidden on this page. + bool hide_download_ui; + + // Whether it is a presentation receiver. + bool presentation_receiver; + + // If disabled, media controls should never be used. + bool media_controls_enabled; + + // Whether we want to disable updating selection on mutating selection range. + // This is to work around Samsung's email app issue. See + // https://crbug.com/699943 for details. + // TODO(changwan): remove this once we no longer support Android N. + bool do_not_update_selection_on_mutating_selection_range; + + // Defines the current autoplay policy. + AutoplayPolicy autoplay_policy; + + // `getDisplayMedia()`'s transient activation requirement can be bypassed via + // `ScreenCaptureWithoutGestureAllowedForOrigins` policy. + bool require_transient_activation_for_get_display_media; + + // `show{OpenFile|SaveFile|Directory}Picker()`'s user activation requirement + // can be bypassed via `FileOrDirectoryPickerWithoutGestureAllowedForOrigins` + // policy. + bool require_transient_activation_for_show_file_or_directory_picker; + + // HTML Fullscreen (e.g. `Element.requestFullscreen()`)'s transient activation + // requirement can be bypassed via the "Automatic Fullscreen" content setting. + bool require_transient_activation_for_html_fullscreen; + + // `navigator.subApps.{add|remove|list}()`'s user gesture and authorization + // can be bypassed via + // `SubAppsAPIsAllowedWithoutGestureAndAuthorizationForOrigins` policy. + bool require_transient_activation_and_user_confirmation_for_subapps_api; + + // The forced colors state for the web content. The forced colors state + // is used to evaluate the forced-colors media query, as well as determining + // when to apply system color overrides to author specified styles. + bool in_forced_colors; + + // Indicates if Forced Colors mode should be disabled for this page. + // This allows users opt out of forced colors on specific sites. + // Forced colors are disabled for sites in the `kPageColorsBlockList` pref. + bool is_forced_colors_disabled; + + // The preferred color scheme set by the user's browser settings. The variable + // follows the browser's color mode setting unless a browser theme (custom or + // not) is defined, in which case the color scheme is set to the default + // value. This value is used to evaluate the used color scheme in non overlay + // root scrollbars. + PreferredColorScheme preferred_root_scrollbar_color_scheme; + + // The preferred color scheme for the web content. The scheme is used to + // evaluate the prefers-color-scheme media query and resolve UA color scheme + // to be used based on the supported-color-schemes META tag and CSS property. + PreferredColorScheme preferred_color_scheme; + + // The preferred contrast for the web content. Used to evaluate the + // prefers-contrast media query. + PreferredContrast preferred_contrast; + + // Network quality threshold below which resources from iframes are assigned + // either kVeryLow or kVeryLow Blink priority. + EffectiveConnectionType low_priority_iframes_threshold; + + // Whether Picture-in-Picture is enabled. + bool picture_in_picture_enabled; + + // Whether a translate service is available. + // blink's hrefTranslate attribute existence relies on the result. + // See https://github.com/dtapuska/html-translate + bool translate_service_available; + + // A value other than + // mojom::blink::EffectiveConnectionType::kEffectiveConnectionUnknownType + // implies that the network quality estimate related Web APIs are in the + // holdback mode. When the holdback is enabled, the related Web APIs return + // network quality estimate corresponding to + // |network_quality_estimator_web_holdback| regardless of the actual quality. + EffectiveConnectionType network_quality_estimator_web_holdback; + + // Whether lazy loading of frames and images is enabled. + bool lazy_load_enabled; + + // Setting to false disables upgrades to HTTPS for HTTP resources in HTTPS + // sites. + bool allow_mixed_content_upgrades; + + // Whether the focused element should always be indicated (for example, by + // forcing :focus-visible to match regardless of focus method). + bool always_show_focus; + + // Whether touch input can trigger HTML drag-and-drop operations. The + // default value depends on the platform. + bool touch_drag_drop_enabled; + + // Controls whether WebXR's immersive-ar is allowed. + bool webxr_immersive_ar_allowed; + + // Whether lookup of frames in the associated WebView (e.g. lookup via + // window.open or via ) should be renderer-wide (i.e. going + // beyond the usual opener-relationship-based BrowsingInstance boundaries). + bool renderer_wide_named_frame_lookup; + + bool strict_mime_type_check_for_worker_scripts_enabled = true; + + // Whether modal context menu is used. A modal context menu meaning it is + // blocking user's access to the background web content. + bool modal_context_menu = true; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/accessibility/aria_notification_options.idl b/tools/under-control/src/third_party/blink/renderer/core/accessibility/aria_notification_options.idl new file mode 100755 index 000000000..e3a91648a --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/accessibility/aria_notification_options.idl @@ -0,0 +1,8 @@ +enum AriaNotifyInterrupt { "none", "all", "pending" }; +enum AriaNotifyPriority { "none", "important" }; + +dictionary AriaNotificationOptions { + AriaNotifyInterrupt interrupt = "none"; + AriaNotifyPriority priority = "none"; + DOMString notificationId = ""; +}; \ No newline at end of file diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/animatable.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/animatable.idl new file mode 100755 index 000000000..3e816b75b --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/animatable.idl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://w3.org/TR/web-animations-1/#the-animatable-interface-mixin +interface mixin Animatable { + [CallWith=ScriptState, Measure, RaisesException] Animation animate(object? keyframes, optional (unrestricted double or KeyframeAnimationOptions) options); + sequence getAnimations(optional GetAnimationsOptions options = {}); +}; + +// https://drafts.csswg.org/web-animations-1/#extensions-to-the-element-interface +Element includes Animatable; + +// https://drafts.csswg.org/web-animations-1/#extensions-to-the-pseudoelement-interface +// TODO(smcgruer): Uncomment once CSSPseudoElement is implemented in Chromium. +// CSSPseudoElement includes Animatable; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/animation.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/animation.idl new file mode 100755 index 000000000..37fd8a23e --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/animation.idl @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2013 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://w3.org/TR/web-animations-1/#the-animation-interface + +enum AnimationPlayState { "idle", "pending", "running", "paused", "finished" }; + +enum ReplaceState { "active", "removed", "persisted" }; + +[ + Exposed=Window, + ActiveScriptWrappable +] interface Animation : EventTarget { + [CallWith=ExecutionContext, RaisesException] constructor(optional AnimationEffect? effect = null, optional AnimationTimeline? timeline); + [Measure] attribute AnimationEffect? effect; + attribute AnimationTimeline? timeline; + [Measure, RaisesException=Setter] attribute CSSNumberish? startTime; + [Measure, RaisesException=Setter] attribute CSSNumberish? currentTime; + [RuntimeEnabled=AnimationProgressAPI, Measure] readonly attribute double? progress; + [Measure, RaisesException=Setter] attribute double playbackRate; + [RuntimeEnabled=ScrollTimeline, Measure, RaisesException=Setter] attribute (TimelineRangeOffset or DOMString) rangeStart; + [RuntimeEnabled=ScrollTimeline, Measure, RaisesException=Setter] attribute (TimelineRangeOffset or DOMString) rangeEnd; + [Measure] readonly attribute AnimationPlayState playState; + [Measure] readonly attribute ReplaceState replaceState; + [Measure] readonly attribute boolean pending; + [Measure, RaisesException, CEReactions] void commitStyles(); + [Measure, RaisesException] void finish(); + [Measure, RaisesException] void play(); + [Measure, RaisesException] void pause(); + [Measure, RaisesException] void reverse(); + [Measure, RaisesException] void updatePlaybackRate(double playback_rate); + [Measure] void persist(); + [Measure] attribute DOMString id; + [Measure] void cancel(); + [Measure] attribute EventHandler onfinish; + [Measure] attribute EventHandler oncancel; + [Measure] attribute EventHandler onremove; + [CallWith=ScriptState] readonly attribute Promise finished; + [CallWith=ScriptState] readonly attribute Promise ready; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/animation_effect.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/animation_effect.idl new file mode 100755 index 000000000..5a17366ba --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/animation_effect.idl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://w3.org/TR/web-animations-1/#the-animationeffect-interface + +[Exposed=Window] +interface AnimationEffect { + EffectTiming getTiming(); + ComputedEffectTiming getComputedTiming(); + [RaisesException] void updateTiming(optional OptionalEffectTiming timing = {}); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/animation_timeline.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/animation_timeline.idl new file mode 100755 index 000000000..c4ca4f442 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/animation_timeline.idl @@ -0,0 +1,14 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#the-animationtimeline-interface + +enum TimelinePhase { "inactive", "before", "active", "after" }; +[ + Exposed=Window +] interface AnimationTimeline { + readonly attribute CSSNumberish? currentTime; + [RuntimeEnabled=ScrollTimeline] readonly attribute CSSNumberish? duration; + [RuntimeEnabled=ScrollTimelineCurrentTime] CSSNumericValue? getCurrentTime(optional DOMString rangeName = "cover"); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/base_keyframe.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/base_keyframe.idl new file mode 100755 index 000000000..e8d6c2b22 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/base_keyframe.idl @@ -0,0 +1,14 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#dictdef-basekeyframe + +enum CompositeOperationOrAuto {"replace", "add", "accumulate", "auto"}; + +typedef (double or TimelineRangeOffset or DOMString) KeyframeOffset; +dictionary BaseKeyframe { + KeyframeOffset? offset = null; + DOMString easing = "linear"; + CompositeOperationOrAuto composite = "auto"; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl new file mode 100755 index 000000000..dd0ff76cc --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/base_property_indexed_keyframe.idl @@ -0,0 +1,11 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#dictdef-basepropertyindexedkeyframe + +dictionary BasePropertyIndexedKeyframe { + (KeyframeOffset? or sequence) offset = []; + (DOMString or sequence) easing = []; + (CompositeOperationOrAuto or sequence) composite = []; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/computed_effect_timing.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/computed_effect_timing.idl new file mode 100755 index 000000000..4dd6557e9 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/computed_effect_timing.idl @@ -0,0 +1,13 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#the-computedeffecttiming-dictionary + +dictionary ComputedEffectTiming : EffectTiming { + CSSNumberish endTime; + CSSNumberish activeDuration; + CSSNumberish? localTime; + double? progress; + unrestricted double? currentIteration; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/css/css_animation.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/css/css_animation.idl new file mode 100755 index 000000000..cfbfa6d74 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/css/css_animation.idl @@ -0,0 +1,10 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-animations-2/#the-CSSAnimation-interface + +[Exposed=Window] +interface CSSAnimation : Animation { + readonly attribute CSSOMString animationName; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/css/css_transition.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/css/css_transition.idl new file mode 100755 index 000000000..a5dc5eaa4 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/css/css_transition.idl @@ -0,0 +1,10 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-transitions-2/#the-CSSTransition-interface + +[Exposed=Window] +interface CSSTransition : Animation { + readonly attribute CSSOMString transitionProperty; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/document_animation.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/document_animation.idl new file mode 100755 index 000000000..b0c52901d --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/document_animation.idl @@ -0,0 +1,11 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#extensions-to-the-document-interface + +[ + ImplementedAs=DocumentAnimation +] partial interface Document { + readonly attribute DocumentTimeline timeline; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/document_timeline.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/document_timeline.idl new file mode 100755 index 000000000..06686627b --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/document_timeline.idl @@ -0,0 +1,11 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#the-documenttimeline-interface + +[ + Exposed=Window +] interface DocumentTimeline : AnimationTimeline { + [CallWith=ExecutionContext] constructor(optional DocumentTimelineOptions options = {}); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/document_timeline_options.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/document_timeline_options.idl new file mode 100755 index 000000000..84ad2d9e0 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/document_timeline_options.idl @@ -0,0 +1,9 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#dictdef-documenttimelineoptions + +dictionary DocumentTimelineOptions { + DOMHighResTimeStamp originTime = 0; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/effect_timing.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/effect_timing.idl new file mode 100755 index 000000000..8742513a4 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/effect_timing.idl @@ -0,0 +1,19 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#the-effecttiming-dictionaries + +enum FillMode { "none", "forwards", "backwards", "both", "auto" }; +enum PlaybackDirection { "normal", "reverse", "alternate", "alternate-reverse" }; + +dictionary EffectTiming { + (double or CSSNumericValue) delay = 0; + (double or CSSNumericValue) endDelay = 0; + FillMode fill = "auto"; + double iterationStart = 0.0; + unrestricted double iterations = 1.0; + (unrestricted double or CSSNumericValue or DOMString) duration = "auto"; + PlaybackDirection direction = "normal"; + DOMString easing = "linear"; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/get_animations_options.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/get_animations_options.idl new file mode 100755 index 000000000..bf27144c5 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/get_animations_options.idl @@ -0,0 +1,9 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/web-animations-1/#the-animatable-interface-mixin + +dictionary GetAnimationsOptions { + boolean subtree = false; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_animation_options.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_animation_options.idl new file mode 100755 index 000000000..a58acd101 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_animation_options.idl @@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#dictdef-keyframeanimationoptions + +// TODO(kevers): Add scroll-animations-1 link once range(Start|End) are fully +// speced. + +enum TimelineRange { + "none", + "cover", + "contain", + "entry", + "entry-crossing", + "exit", + "exit-crossing" }; + +dictionary TimelineRangeOffset { + TimelineRange rangeName; + CSSNumericValue offset; +}; + +dictionary KeyframeAnimationOptions : KeyframeEffectOptions { + DOMString id = ""; + AnimationTimeline? timeline; + (DOMString or TimelineRangeOffset) rangeStart = "normal"; + (DOMString or TimelineRangeOffset) rangeEnd = "normal"; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_effect.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_effect.idl new file mode 100755 index 000000000..5077101b9 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_effect.idl @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://w3.org/TR/web-animations-1/#the-keyframeeffect-interface + +enum CompositeOperation { "replace", "add", "accumulate" }; + +[ + Exposed=Window +] interface KeyframeEffect : AnimationEffect { + [CallWith=ScriptState, RaisesException, Measure] constructor(Element? target, object? keyframes, optional (unrestricted double or KeyframeEffectOptions) options); + [CallWith=ScriptState, RaisesException, Measure] constructor(KeyframeEffect source); + attribute Element? target; + [RaisesException=Setter] attribute CSSOMString? pseudoElement; + attribute CompositeOperation composite; + [CallWith=ScriptState] sequence getKeyframes(); + [CallWith=ScriptState, RaisesException] void setKeyframes(object? keyframes); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_effect_options.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_effect_options.idl new file mode 100755 index 000000000..1f4ec7d71 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/keyframe_effect_options.idl @@ -0,0 +1,11 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://w3.org/TR/web-animations-1/#the-keyframeeffectoptions-dictionary + +dictionary KeyframeEffectOptions : EffectTiming { + // TODO(alancutter): Implement iterationComposite + CompositeOperation composite = "replace"; + CSSOMString? pseudoElement = null; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/optional_effect_timing.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/optional_effect_timing.idl new file mode 100755 index 000000000..0164badc6 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/optional_effect_timing.idl @@ -0,0 +1,19 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/web-animations-1/#the-effecttiming-dictionaries + +dictionary OptionalEffectTiming { + (double or CSSNumericValue) delay; + (double or CSSNumericValue) endDelay; + FillMode fill; + double iterationStart; + unrestricted double iterations; + // CSSNumericValue is only included here so that it continues to match + // EffectTiming which allows code that expects them to match to continue + // working. Duration cannot be set using CSSNumericValue. + (unrestricted double or CSSNumericValue or DOMString) duration; + PlaybackDirection direction; + DOMString easing; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/scroll_timeline.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/scroll_timeline.idl new file mode 100755 index 000000000..58f7cb23e --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/scroll_timeline.idl @@ -0,0 +1,15 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +enum ScrollAxis { "block", "inline", "x", "y" }; + +// https://wicg.github.io/scroll-animations/#scrolltimeline-interface +[ + RuntimeEnabled=ScrollTimeline, + Exposed=Window +] interface ScrollTimeline : AnimationTimeline { + [CallWith=Document, RaisesException, MeasureAs=ScrollTimelineConstructor] constructor(optional ScrollTimelineOptions options = {}); + readonly attribute Element? source; + readonly attribute ScrollAxis axis; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/scroll_timeline_options.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/scroll_timeline_options.idl new file mode 100755 index 000000000..b49daa96f --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/scroll_timeline_options.idl @@ -0,0 +1,10 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://wicg.github.io/scroll-animations/#dictdef-scrolltimelineoptions + +dictionary ScrollTimelineOptions { + Element? source; + ScrollAxis axis = "block"; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/view_timeline.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/view_timeline.idl new file mode 100755 index 000000000..9301a84c8 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/view_timeline.idl @@ -0,0 +1,16 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// TODO(crbug.com/1329159): Update link once rewrite replaces the draft +// version. +// https://drafts.csswg.org/scroll-animations-1/rewrite#viewtimeline-interface +[ + RuntimeEnabled=ScrollTimeline, + Exposed=Window +] interface ViewTimeline : ScrollTimeline { + [CallWith=Document, RaisesException, MeasureAs=ViewTimelineConstructor] constructor(optional ViewTimelineOptions options = {}); + readonly attribute Element? subject; + readonly attribute CSSNumericValue? startOffset; + readonly attribute CSSNumericValue? endOffset; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/animation/view_timeline_options.idl b/tools/under-control/src/third_party/blink/renderer/core/animation/view_timeline_options.idl new file mode 100755 index 000000000..f81b11221 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/animation/view_timeline_options.idl @@ -0,0 +1,13 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/scroll-animations-1/rewrite#viewtimeline-interface + +dictionary ViewTimelineOptions { + Element subject; + ScrollAxis axis = "block"; + // String in CSS format or sequence of TypedOM values. + // DOMString within sequence is for keyword "auto". + (DOMString or sequence<(DOMString or CSSNumericValue)>) inset = []; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/aom/accessible_node.idl b/tools/under-control/src/third_party/blink/renderer/core/aom/accessible_node.idl new file mode 100755 index 000000000..04ce76e22 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/aom/accessible_node.idl @@ -0,0 +1,74 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Accessibility Object Model node +// Explainer: https://github.com/WICG/aom/blob/gh-pages/explainer.md +// Spec: https://wicg.github.io/aom/spec/ +[ + Exposed=Window, + RuntimeEnabled=AccessibilityObjectModel +] interface AccessibleNode : EventTarget { + [CallWith=Document] constructor(); + attribute AccessibleNode? activeDescendant; + attribute boolean? atomic; + attribute DOMString? autocomplete; + attribute boolean? busy; + attribute DOMString? checked; + attribute long? colCount; + attribute unsigned long? colIndex; + [RuntimeEnabled=AriaRowColIndexText] attribute DOMString? colIndexText; + attribute unsigned long? colSpan; + attribute AccessibleNodeList? controls; + attribute DOMString? current; + attribute AccessibleNodeList? describedBy; + attribute AccessibleNodeList? details; + attribute boolean? disabled; + attribute AccessibleNodeList? errorMessage; + attribute boolean? expanded; + attribute AccessibleNodeList? flowTo; + attribute DOMString? hasPopup; + attribute boolean? hidden; + attribute DOMString? invalid; + attribute DOMString? keyShortcuts; + attribute DOMString? label; + attribute AccessibleNodeList? labeledBy; + attribute unsigned long? level; + attribute DOMString? live; + attribute boolean? modal; + attribute boolean? multiline; + attribute boolean? multiselectable; + attribute DOMString? orientation; + attribute AccessibleNodeList? owns; + attribute DOMString? placeholder; + attribute unsigned long? posInSet; + attribute DOMString? pressed; + attribute boolean? readOnly; + attribute DOMString? relevant; + attribute boolean? required; + attribute DOMString? role; + attribute DOMString? roleDescription; + attribute long? rowCount; + attribute unsigned long? rowIndex; + [RuntimeEnabled=AriaRowColIndexText] attribute DOMString? rowIndexText; + attribute unsigned long? rowSpan; + attribute boolean? selected; + attribute long? setSize; + attribute DOMString? sort; + attribute double? valueMax; + attribute double? valueMin; + attribute double? valueNow; + attribute DOMString? valueText; + + attribute EventHandler onaccessibleclick; + attribute EventHandler onaccessiblecontextmenu; + attribute EventHandler onaccessibledecrement; + attribute EventHandler onaccessiblefocus; + attribute EventHandler onaccessibleincrement; + attribute EventHandler onaccessiblescrollintoview; + + readonly attribute AccessibleNodeList childNodes; + + [RaisesException] void appendChild(AccessibleNode child); + [RaisesException] void removeChild(AccessibleNode child); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/aom/accessible_node_list.idl b/tools/under-control/src/third_party/blink/renderer/core/aom/accessible_node_list.idl new file mode 100755 index 000000000..c742c8f99 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/aom/accessible_node_list.idl @@ -0,0 +1,18 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Accessibility Object Model node list +// Explainer: https://github.com/WICG/aom/blob/gh-pages/explainer.md +// Spec: https://wicg.github.io/aom/spec/ +[ + Exposed=Window, + RuntimeEnabled=AccessibilityObjectModel +] interface AccessibleNodeList { + constructor(optional sequence nodes = []); + attribute unsigned long length; + getter AccessibleNode? item(unsigned long index); + [RaisesException] setter void (unsigned long index, AccessibleNode node); + void add(AccessibleNode node, optional AccessibleNode? before = null); + void remove(long index); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/aom/computed_accessible_node.idl b/tools/under-control/src/third_party/blink/renderer/core/aom/computed_accessible_node.idl new file mode 100755 index 000000000..5a810b35f --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/aom/computed_accessible_node.idl @@ -0,0 +1,54 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Computed Accessibility node +// Explainer: https://github.com/WICG/aom/blob/gh-pages/explainer.md +// Spec: https://wicg.github.io/aom/spec/ +[ + Exposed=Window, + RuntimeEnabled=AccessibilityObjectModel +] interface ComputedAccessibleNode { + + readonly attribute boolean? atomic; + readonly attribute boolean? busy; + readonly attribute boolean? disabled; + readonly attribute boolean? expanded; + readonly attribute boolean? modal; + readonly attribute boolean? multiline; + readonly attribute boolean? multiselectable; + readonly attribute boolean? readOnly; + readonly attribute boolean? required; + readonly attribute boolean? selected; + + readonly attribute long? colCount; + readonly attribute unsigned long? colIndex; + readonly attribute unsigned long? colSpan; + readonly attribute unsigned long? level; + readonly attribute unsigned long? posInSet; + readonly attribute long? rowCount; + readonly attribute unsigned long? rowIndex; + readonly attribute unsigned long? rowSpan; + readonly attribute long? setSize; + + readonly attribute double? valueMax; + readonly attribute double? valueMin; + readonly attribute double? valueNow; + + readonly attribute DOMString? autocomplete; + readonly attribute DOMString? checked; + readonly attribute DOMString? keyShortcuts; + readonly attribute DOMString? name; + readonly attribute DOMString? placeholder; + readonly attribute DOMString? role; + readonly attribute DOMString? roleDescription; + readonly attribute DOMString? valueText; + + readonly attribute ComputedAccessibleNode? parent; + readonly attribute ComputedAccessibleNode? firstChild; + readonly attribute ComputedAccessibleNode? lastChild; + readonly attribute ComputedAccessibleNode? previousSibling; + readonly attribute ComputedAccessibleNode? nextSibling; + + [CallWith=ScriptState] Promise ensureUpToDate(); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer.idl b/tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer.idl new file mode 100755 index 000000000..7209dd85b --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer.idl @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://html.spec.whatwg.org/C/#the-datatransfer-interface + +[ + Exposed=Window +] interface DataTransfer { + constructor(); + attribute DOMString dropEffect; + attribute DOMString effectAllowed; + + [SameObject] readonly attribute DataTransferItemList items; + + void setDragImage(Element image, long x, long y); + + /* old interface */ + [CachedAttribute=hasDataStoreItemListChanged] readonly attribute FrozenArray types; + DOMString getData(DOMString format); + void setData(DOMString format, DOMString data); + void clearData(optional DOMString format); + [SameObject] readonly attribute FileList files; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer_item.idl b/tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer_item.idl new file mode 100755 index 000000000..3e163a8fa --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer_item.idl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://html.spec.whatwg.org/C/#the-datatransferitem-interface + +[ + Exposed=Window +] interface DataTransferItem { + readonly attribute DOMString kind; + readonly attribute DOMString type; + [CallWith=ScriptState] void getAsString(FunctionStringCallback? callback); + File? getAsFile(); +}; \ No newline at end of file diff --git a/tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer_item_list.idl b/tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer_item_list.idl new file mode 100755 index 000000000..240358558 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/clipboard/data_transfer_item_list.idl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://html.spec.whatwg.org/C/#the-datatransferitemlist-interface + +[ + Exposed=Window +] interface DataTransferItemList { + readonly attribute unsigned long length; + [ImplementedAs=item] getter DataTransferItem (unsigned long index); + [RaisesException] DataTransferItem? add(DOMString data, DOMString type); + DataTransferItem? add(File file); + [RaisesException, ImplementedAs=deleteItem] void remove(unsigned long index); + void clear(); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css.idl new file mode 100755 index 000000000..02f8f48f9 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css.idl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 Motorola Mobility Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * 3. Neither the name of Motorola Mobility Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://drafts.csswg.org/css-conditional/#the-css-interface + +[ + Exposed=Window, + ImplementedAs=DOMWindowCSS +] namespace CSS { + [CallWith=ExecutionContext] boolean supports(DOMString property, DOMString value); + [CallWith=ExecutionContext] boolean supports(DOMString conditionText); + DOMString escape(DOMString ident); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_condition_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_condition_rule.idl new file mode 100755 index 000000000..c306ae783 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_condition_rule.idl @@ -0,0 +1,12 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-conditional/#the-cssconditionrule-interface + +[ + Exposed=Window +] interface CSSConditionRule : CSSGroupingRule { + // TODO(xing.xu): readonly should be removed. + readonly attribute DOMString conditionText; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_container_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_container_rule.idl new file mode 100755 index 000000000..5f7eff68d --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_container_rule.idl @@ -0,0 +1,11 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + Exposed=Window +] interface CSSContainerRule : CSSConditionRule { + // TODO(crbug.com/1145970): Spec and implement. + readonly attribute DOMString containerName; + readonly attribute DOMString containerQuery; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_counter_style_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_counter_style_rule.idl new file mode 100755 index 000000000..35d9b98f3 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_counter_style_rule.idl @@ -0,0 +1,19 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-counter-styles-3/#the-csscounterstylerule-interface +[Exposed=Window] +interface CSSCounterStyleRule : CSSRule { + [SetterCallWith=ExecutionContext] attribute CSSOMString name; + [SetterCallWith=ExecutionContext] attribute CSSOMString system; + [SetterCallWith=ExecutionContext] attribute CSSOMString symbols; + [SetterCallWith=ExecutionContext] attribute CSSOMString additiveSymbols; + [SetterCallWith=ExecutionContext] attribute CSSOMString negative; + [SetterCallWith=ExecutionContext] attribute CSSOMString prefix; + [SetterCallWith=ExecutionContext] attribute CSSOMString suffix; + [SetterCallWith=ExecutionContext] attribute CSSOMString range; + [SetterCallWith=ExecutionContext] attribute CSSOMString pad; + [SetterCallWith=ExecutionContext] attribute CSSOMString speakAs; + [SetterCallWith=ExecutionContext] attribute CSSOMString fallback; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_font_face_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_font_face_rule.idl new file mode 100755 index 000000000..074647a4b --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_font_face_rule.idl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// https://drafts.csswg.org/css-fonts/#om-fontface + +[ + Exposed=Window +] interface CSSFontFaceRule : CSSRule { + [Measure] readonly attribute CSSStyleDeclaration style; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_font_feature_values_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_font_feature_values_rule.idl new file mode 100755 index 000000000..0ee238658 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_font_feature_values_rule.idl @@ -0,0 +1,22 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-fonts-4/#om-fontfeaturevalues + +interface CSSFontFeatureValuesRule : CSSRule { + attribute CSSOMString fontFamily; + + readonly attribute CSSFontFeatureValuesMap annotation; + readonly attribute CSSFontFeatureValuesMap ornaments; + readonly attribute CSSFontFeatureValuesMap stylistic; + readonly attribute CSSFontFeatureValuesMap swash; + readonly attribute CSSFontFeatureValuesMap characterVariant; + readonly attribute CSSFontFeatureValuesMap styleset; +}; + +interface CSSFontFeatureValuesMap { + maplike>; + undefined set(CSSOMString featureValueName, + (unsigned long or sequence) values); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_font_palette_values_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_font_palette_values_rule.idl new file mode 100755 index 000000000..64a8fcf2b --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_font_palette_values_rule.idl @@ -0,0 +1,13 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-fonts-4/#om-fontpalettevalues + +[Exposed=Window] +interface CSSFontPaletteValuesRule : CSSRule { + readonly attribute CSSOMString name; + readonly attribute CSSOMString fontFamily; + readonly attribute CSSOMString basePalette; + readonly attribute CSSOMString overrideColors; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_grouping_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_grouping_rule.idl new file mode 100755 index 000000000..2a3db7783 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_grouping_rule.idl @@ -0,0 +1,13 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/cssom/#the-cssgroupingrule-interface + +[ + Exposed=Window +] interface CSSGroupingRule : CSSRule { + [SameObject] readonly attribute CSSRuleList cssRules; + [RaisesException, CallWith=ExecutionContext] unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0); + [RaisesException] void deleteRule(unsigned long index); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_import_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_import_rule.idl new file mode 100755 index 000000000..6f4d85fbd --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_import_rule.idl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// https://drafts.csswg.org/cssom/#the-cssimportrule-interface + +[ + Exposed=Window +] interface CSSImportRule : CSSRule { + // TODO(bhagirathi.s@samsung.com): href should be USVString. + readonly attribute DOMString href; + [SameObject, PutForwards=mediaText] readonly attribute MediaList media; + [SameObject] readonly attribute CSSStyleSheet styleSheet; + + readonly attribute CSSOMString? layerName; + readonly attribute CSSOMString? supportsText; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_keyframe_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_keyframe_rule.idl new file mode 100755 index 000000000..16d3d0883 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_keyframe_rule.idl @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://drafts.csswg.org/css-animations/#interface-csskeyframerule + +[ + Exposed=Window +] interface CSSKeyframeRule : CSSRule { + [RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString keyText; + [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_keyframes_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_keyframes_rule.idl new file mode 100755 index 000000000..0f1ef7ecc --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_keyframes_rule.idl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://drafts.csswg.org/css-animations/#interface-csskeyframesrule + +[ + Exposed=Window +] interface CSSKeyframesRule : CSSRule { + attribute DOMString name; + readonly attribute CSSRuleList cssRules; + [RuntimeEnabled=CSSKeyframesRuleLength] readonly attribute unsigned long length; + + getter CSSKeyframeRule (unsigned long index); + [CallWith=ExecutionContext] void appendRule(DOMString rule); + [CallWith=ExecutionContext] void deleteRule(DOMString select); + [CallWith=ExecutionContext] CSSKeyframeRule? findRule(DOMString select); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_layer_block_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_layer_block_rule.idl new file mode 100755 index 000000000..e7ed02d57 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_layer_block_rule.idl @@ -0,0 +1,10 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-cascade-5/#the-csslayerblockrule-interface +[ + Exposed=Window +] interface CSSLayerBlockRule : CSSGroupingRule { + readonly attribute CSSOMString name; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_layer_statement_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_layer_statement_rule.idl new file mode 100755 index 000000000..4b3b095c0 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_layer_statement_rule.idl @@ -0,0 +1,10 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-cascade-5/#the-csslayerstatementrule-interface +[ + Exposed=Window +] interface CSSLayerStatementRule : CSSRule { + readonly attribute FrozenArray nameList; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_margin_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_margin_rule.idl new file mode 100755 index 000000000..7b0b139d0 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_margin_rule.idl @@ -0,0 +1,13 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/cssom/#the-cssmarginrule-interface + +[ + Exposed=Window, + RuntimeEnabled=PageMarginBoxes +] interface CSSMarginRule : CSSRule { + readonly attribute DOMString name; + [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_media_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_media_rule.idl new file mode 100755 index 000000000..d4e480955 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_media_rule.idl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// https://drafts.csswg.org/cssom/#the-cssmediarule-interface + +[ + Exposed=Window +] interface CSSMediaRule : CSSConditionRule { + [SameObject, PutForwards=mediaText] readonly attribute MediaList media; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_namespace_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_namespace_rule.idl new file mode 100755 index 000000000..d73a481b5 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_namespace_rule.idl @@ -0,0 +1,13 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/cssom/#the-cssnamespacerule-interface + +[ + Exposed=Window +] interface CSSNamespaceRule : CSSRule { + + readonly attribute DOMString namespaceURI; + readonly attribute DOMString prefix; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_page_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_page_rule.idl new file mode 100755 index 000000000..3849156aa --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_page_rule.idl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// https://drafts.csswg.org/cssom/#the-csspagerule-interface + +[ + Exposed=Window +] interface CSSPageRule : CSSGroupingRule { + [SetterCallWith=ExecutionContext] attribute DOMString selectorText; + [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_position_try_descriptors.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_position_try_descriptors.idl new file mode 100755 index 000000000..6c8f8c921 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_position_try_descriptors.idl @@ -0,0 +1,79 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-anchor-position-1/#om-position-try + +[Exposed=Window, RuntimeEnabled=CSSAnchorPositioning] +interface CSSPositionTryDescriptors : CSSStyleDeclaration { + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString margin; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginTop; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginRight; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginBottom; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginLeft; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginBlock; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginBlockStart; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginBlockEnd; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginInline; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginInlineStart; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString marginInlineEnd; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginTop] attribute CSSOMString margin-top; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginRight] attribute CSSOMString margin-right; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginBottom] attribute CSSOMString margin-bottom; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginLeft] attribute CSSOMString margin-left; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginBlock] attribute CSSOMString margin-block; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginBlockStart] attribute CSSOMString margin-block-start; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginBlockEnd] attribute CSSOMString margin-block-end; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginInline] attribute CSSOMString margin-inline; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginInlineStart] attribute CSSOMString margin-inline-start; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=marginInlineEnd] attribute CSSOMString margin-inline-end; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString inset; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString insetBlock; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString insetBlockStart; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString insetBlockEnd; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString insetInline; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString insetInlineStart; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString insetInlineEnd; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString top; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString left; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString right; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString bottom; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=insetBlock] attribute CSSOMString inset-block; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=insetBlockStart] attribute CSSOMString inset-block-start; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=insetBlockEnd] attribute CSSOMString inset-block-end; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=insetInline] attribute CSSOMString inset-inline; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=insetInlineStart] attribute CSSOMString inset-inline-start; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=insetInlineEnd] attribute CSSOMString inset-inline-end; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString width; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString minWidth; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString maxWidth; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString height; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString minHeight; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString maxHeight; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString blockSize; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString minBlockSize; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString maxBlockSize; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString inlineSize; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString minInlineSize; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString maxInlineSize; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=minWidth] attribute CSSOMString min-width; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=maxWidth] attribute CSSOMString max-width; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=minHeight] attribute CSSOMString min-height; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=maxHeight] attribute CSSOMString max-height; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=blockSize] attribute CSSOMString block-size; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=minBlockSize] attribute CSSOMString min-block-size; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=maxBlockSize] attribute CSSOMString max-block-size; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=inlineSize] attribute CSSOMString inline-size; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=minInlineSize] attribute CSSOMString min-inline-size; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=maxInlineSize] attribute CSSOMString max-inline-size; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString placeSelf; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString alignSelf; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString justifySelf; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=placeSelf] attribute CSSOMString place-self; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=alignSelf] attribute CSSOMString align-self; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=justifySelf] attribute CSSOMString justify-self; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString positionAnchor; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=positionAnchor] attribute CSSOMString position-anchor; + [SetterCallWith=ExecutionContext, RaisesException=Setter] attribute CSSOMString insetArea; + [SetterCallWith=ExecutionContext, RaisesException=Setter, ImplementedAs=insetArea] attribute CSSOMString inset-area; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_position_try_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_position_try_rule.idl new file mode 100755 index 000000000..4b4bee2a4 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_position_try_rule.idl @@ -0,0 +1,11 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.csswg.org/css-anchor-position-1/#idl-index + +[Exposed=Window, RuntimeEnabled=CSSAnchorPositioning] +interface CSSPositionTryRule : CSSRule { + readonly attribute CSSOMString name; + [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_property_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_property_rule.idl new file mode 100755 index 000000000..c7f02d784 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_property_rule.idl @@ -0,0 +1,12 @@ +// Copyright 2019 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + Exposed=Window +] interface CSSPropertyRule : CSSRule { + readonly attribute CSSOMString name; + readonly attribute CSSOMString syntax; + readonly attribute boolean inherits; + readonly attribute CSSOMString? initialValue; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_rule.idl new file mode 100755 index 000000000..194f50e0a --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_rule.idl @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// https://drafts.csswg.org/cssom/#the-cssrule-interface + +[ + Exposed=Window +] interface CSSRule { + const unsigned short STYLE_RULE = 1; + const unsigned short CHARSET_RULE = 2; + const unsigned short IMPORT_RULE = 3; + const unsigned short MEDIA_RULE = 4; + const unsigned short FONT_FACE_RULE = 5; + const unsigned short PAGE_RULE = 6; + [RuntimeEnabled=PageMarginBoxes] const unsigned short MARGIN_RULE = 9; + const unsigned short NAMESPACE_RULE = 10; + readonly attribute unsigned short type; + attribute DOMString cssText; + readonly attribute CSSRule? parentRule; + readonly attribute CSSStyleSheet? parentStyleSheet; + + // CSS Animations + // https://drafts.csswg.org/css-animations/#interface-cssrule + const unsigned short KEYFRAMES_RULE = 7; + const unsigned short KEYFRAME_RULE = 8; + + // CSS Counter Styles + // https://drafts.csswg.org/css-counter-styles-3/#extentions-to-cssrule-interface + const unsigned short COUNTER_STYLE_RULE = 11; + + // CSS Fonts Level 4 + // https://drafts.csswg.org/css-fonts-4/#font-feature-values + const unsigned short FONT_FEATURE_VALUES_RULE = 14; + + // CSS Conditional Rules + // https://drafts.csswg.org/css-conditional/#extentions-to-cssrule-interface + const unsigned short SUPPORTS_RULE = 12; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_rule_list.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_rule_list.idl new file mode 100755 index 000000000..1ed135b73 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_rule_list.idl @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://drafts.csswg.org/cssom/#the-cssrulelist-interface + +[ + Exposed=Window +] interface CSSRuleList { + [Measure] getter CSSRule? item(unsigned long index); + readonly attribute unsigned long length; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_scope_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_scope_rule.idl new file mode 100755 index 000000000..24b1a296c --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_scope_rule.idl @@ -0,0 +1,10 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + Exposed=Window +] interface CSSScopeRule : CSSGroupingRule { + readonly attribute CSSOMString? start; + readonly attribute CSSOMString? end; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_starting_style_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_starting_style_rule.idl new file mode 100755 index 000000000..040d019b0 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_starting_style_rule.idl @@ -0,0 +1,8 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + Exposed=Window +] interface CSSStartingStyleRule : CSSGroupingRule { +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_style_declaration.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_style_declaration.idl new file mode 100755 index 000000000..8f1cee005 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_style_declaration.idl @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// https://drafts.csswg.org/cssom/#the-cssstyledeclaration-interface + +[ + Exposed=Window +] interface CSSStyleDeclaration { + [CEReactions, RaisesException=Setter, SetterCallWith=ExecutionContext] attribute DOMString cssText; + readonly attribute unsigned long length; + [Affects=Nothing] getter DOMString item(unsigned long index); + DOMString getPropertyValue(DOMString property); + DOMString getPropertyPriority(DOMString property); + [CEReactions, RaisesException, CallWith=ExecutionContext] void setProperty(DOMString property, [LegacyNullToEmptyString] DOMString value, optional [LegacyNullToEmptyString] DOMString priority = ""); + // void setPropertyValue(DOMString property, [LegacyNullToEmptyString] DOMString value); + // void setPropertyPriority(DOMString property, [LegacyNullToEmptyString] DOMString priority); + [CEReactions, RaisesException] DOMString removeProperty(DOMString property); + readonly attribute CSSRule? parentRule; + [CEReactions, SetterCallWith=ExecutionContext, RaisesException=Setter] attribute [LegacyNullToEmptyString] DOMString cssFloat; + + // The camel-cased and dashed attribute getters have custom bindings. + // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-camel-cased-attribute + // https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-dashed-attribute + [Affects=Nothing] getter DOMString (DOMString name); + // The type of `propertyValue` is `any` in order not to perform any type + // conversion which may have side effect (c.f. https://crbug.com/1310062 ). + [CEReactions, CallWith=ScriptState] setter void (DOMString property, any propertyValue); + deleter void (DOMString property); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_style_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_style_rule.idl new file mode 100755 index 000000000..94bac7f9b --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_style_rule.idl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// https://drafts.csswg.org/cssom/#the-cssstylerule-interface + +[ + Exposed=Window +] interface CSSStyleRule : CSSRule { + [SetterCallWith=ExecutionContext] attribute DOMString selectorText; + [SameObject, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; + [SameObject, MeasureAs=CSSTypedOMStylePropertyMap] readonly attribute StylePropertyMap styleMap; + + // https://drafts.csswg.org/css-nesting-1/#cssom-style + [SameObject] readonly attribute CSSRuleList cssRules; + [RaisesException, CallWith=ExecutionContext] unsigned long insertRule(DOMString rule, optional unsigned long index = 0); + [RaisesException] void deleteRule(unsigned long index); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_style_sheet.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_style_sheet.idl new file mode 100755 index 000000000..8057a34f2 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_style_sheet.idl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2006 Samuel Weinig + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +// https://drafts.csswg.org/cssom/#the-cssstylesheet-interface + +[ + Exposed=Window +] interface CSSStyleSheet : StyleSheet { + [CallWith=Document, RaisesException] constructor(optional CSSStyleSheetInit options = {}); + readonly attribute CSSRule? ownerRule; + [SameObject, RaisesException] readonly attribute CSSRuleList cssRules; + [RaisesException] unsigned long insertRule(DOMString rule, optional unsigned long index = 0); + [RaisesException] void deleteRule(unsigned long index); + + [MeasureAs=CSSStyleSheetReplace, CallWith=ScriptState, RaisesException] Promise replace(DOMString text); + [MeasureAs=CSSStyleSheetReplaceSync, RaisesException] void replaceSync(DOMString text); + + // Non-standard APIs + [MeasureAs=CSSStyleSheetRules, RaisesException] readonly attribute CSSRuleList rules; + [MeasureAs=CSSStyleSheetAddRule, RaisesException] long addRule(optional DOMString selector = "undefined", optional DOMString style = "undefined", optional unsigned long index); + [MeasureAs=CSSStyleSheetRemoveRule, RaisesException] void removeRule(optional unsigned long index = 0); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_style_sheet_init.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_style_sheet_init.idl new file mode 100755 index 000000000..001278c95 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_style_sheet_init.idl @@ -0,0 +1,10 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +dictionary CSSStyleSheetInit { + (MediaList or DOMString) media = ""; + DOMString title = ""; + boolean alternate = false; + boolean disabled = false; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_supports_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_supports_rule.idl new file mode 100755 index 000000000..2cfb26558 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_supports_rule.idl @@ -0,0 +1,34 @@ +/* Copyright (C) 2012 Motorola Mobility Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the distribution. + * 3. Neither the name of Motorola Mobility Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// https://drafts.csswg.org/css-conditional/#the-csssupportsrule-interface + +[ + Exposed=Window +] interface CSSSupportsRule : CSSConditionRule { +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/css_view_transition_rule.idl b/tools/under-control/src/third_party/blink/renderer/core/css/css_view_transition_rule.idl new file mode 100755 index 000000000..d073ef848 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/css_view_transition_rule.idl @@ -0,0 +1,11 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + Exposed=Window, + RuntimeEnabled=ViewTransitionOnNavigation +] interface CSSViewTransitionRule : CSSRule { + [SetterCallWith=ExecutionContext] readonly attribute CSSOMString navigation; + [RuntimeEnabled=ViewTransitionTypes, SameObject, SaveSameObject] readonly attribute FrozenArray types; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/caret_position.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/caret_position.idl new file mode 100755 index 000000000..b784b4565 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/caret_position.idl @@ -0,0 +1,13 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://www.w3.org/TR/cssom-view/#caretposition +[ + RuntimeEnabled=CaretPositionFromPoint, + Exposed=Window +] interface CaretPosition { + readonly attribute Node offsetNode; + readonly attribute unsigned long offset; + [NewObject] DOMRect? getClientRect(); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_color_value.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_color_value.idl new file mode 100755 index 000000000..d13ff37b3 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_color_value.idl @@ -0,0 +1,17 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// CSSColorValue is the base class used for the various CSS color interfaces. +// It can be used to convert between color spaces. +// https://drafts.css-houdini.org/css-typed-om-1/#colorvalue-objects +[ + Exposed=(Window,LayoutWorklet,PaintWorklet), + RuntimeEnabled=CSSColorTypedOM +] interface CSSColorValue { + CSSRGB toRGB(); + CSSHSL toHSL(); + CSSHWB toHWB(); + + [RaisesException, NewObject, Exposed=Window, CallWith=ExecutionContext] static (CSSColorValue or CSSStyleValue) parse(USVString cssText); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_hsl.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_hsl.idl new file mode 100755 index 000000000..3633de86e --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_hsl.idl @@ -0,0 +1,16 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents an hsl color. +// https://drafts.css-houdini.org/css-typed-om-1/#csshsl +[ + Exposed=(Window,LayoutWorklet,PaintWorklet), + RuntimeEnabled=CSSColorTypedOM +] interface CSSHSL : CSSColorValue { + [RaisesException] constructor(CSSNumericValue h, CSSNumberish s, CSSNumberish l, optional CSSNumberish alpha = 1); + [RaisesException=Setter] attribute CSSNumericValue h; + [RaisesException=Setter] attribute CSSNumberish s; + [RaisesException=Setter] attribute CSSNumberish l; + [RaisesException=Setter] attribute CSSNumberish alpha; +}; \ No newline at end of file diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_hwb.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_hwb.idl new file mode 100755 index 000000000..2c1efb0e9 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_hwb.idl @@ -0,0 +1,18 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents an hwb color. +// https://drafts.css-houdini.org/css-typed-om-1/#csshwb +[ + Exposed = (Window, LayoutWorklet, PaintWorklet), RuntimeEnabled = + CSSColorTypedOM +] interface CSSHWB : CSSColorValue { + [RaisesException] constructor(CSSNumericValue h, CSSNumberish w, + CSSNumberish b, + optional CSSNumberish alpha = 1); + [RaisesException = Setter] attribute CSSNumericValue h; + [RaisesException = Setter] attribute CSSNumberish w; + [RaisesException = Setter] attribute CSSNumberish b; + [RaisesException = Setter] attribute CSSNumberish alpha; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_image_value.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_image_value.idl new file mode 100755 index 000000000..a2167bb45 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_image_value.idl @@ -0,0 +1,12 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// CSSImageValue is the base class for Typed OM's representation of various +// image types. +// https://drafts.css-houdini.org/css-typed-om/#imagevalue-objects +[ + Exposed=(Window,LayoutWorklet,PaintWorklet), + ImplementedAs=CSSStyleImageValue +] interface CSSImageValue : CSSStyleValue { +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl new file mode 100755 index 000000000..a4a628eba --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_keyword_value.idl @@ -0,0 +1,15 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +typedef (DOMString or CSSKeywordValue) CSSKeywordish; + +// CSSKeywordValue represents CSS Values that are specified as keywords, for +// example "initial". +// https://drafts.css-houdini.org/css-typed-om/#keywordvalue-objects +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSKeywordValue : CSSStyleValue { + [RaisesException] constructor(CSSOMString keyword); + [RaisesException=Setter] attribute CSSOMString value; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_clamp.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_clamp.idl new file mode 100755 index 000000000..ae19b28d8 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_clamp.idl @@ -0,0 +1,14 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents the central calculation of three CSSNumericValues. +// https://drafts.css-houdini.org/css-typed-om/#cssmathclamp +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSMathClamp : CSSMathValue { + [RaisesException] constructor(CSSNumberish lower, CSSNumberish value, CSSNumberish upper); + readonly attribute CSSNumberish lower; + readonly attribute CSSNumberish value; + readonly attribute CSSNumberish upper; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_invert.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_invert.idl new file mode 100755 index 000000000..9d13e779e --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_invert.idl @@ -0,0 +1,12 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents the inverse a CSSNumericValue. +// https://drafts.css-houdini.org/css-typed-om/#cssmathinvert +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSMathInvert : CSSMathValue { + constructor(CSSNumberish arg); + readonly attribute CSSNumberish value; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_max.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_max.idl new file mode 100755 index 000000000..f01b016b4 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_max.idl @@ -0,0 +1,12 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents the maximum of one or more CSSNumericValues. +// https://drafts.css-houdini.org/css-typed-om/#cssmathsum +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSMathMax : CSSMathValue { + [RaisesException] constructor(CSSNumberish... args); + readonly attribute CSSNumericArray values; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_min.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_min.idl new file mode 100755 index 000000000..152274af6 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_min.idl @@ -0,0 +1,12 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents the minimum of one or more CSSNumericValues. +// https://drafts.css-houdini.org/css-typed-om/#cssmathsum +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSMathMin : CSSMathValue { + [RaisesException] constructor(CSSNumberish... args); + readonly attribute CSSNumericArray values; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_negate.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_negate.idl new file mode 100755 index 000000000..59fed01df --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_negate.idl @@ -0,0 +1,12 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents the negation of a CSSNumericValue. +// https://drafts.css-houdini.org/css-typed-om/#cssmathnegate +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSMathNegate : CSSMathValue { + constructor(CSSNumberish arg); + readonly attribute CSSNumberish value; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_product.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_product.idl new file mode 100755 index 000000000..1b085e3a0 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_product.idl @@ -0,0 +1,12 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents the product of one or more CSSNumericValues. +// https://drafts.css-houdini.org/css-typed-om/#cssmathsub +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSMathProduct : CSSMathValue { + [RaisesException] constructor(CSSNumberish... args); + readonly attribute CSSNumericArray values; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_sum.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_sum.idl new file mode 100755 index 000000000..a34bc0045 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_sum.idl @@ -0,0 +1,12 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents the sum of one or more CSSNumericValues. +// https://drafts.css-houdini.org/css-typed-om/#cssmathsum +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSMathSum : CSSMathValue { + [RaisesException] constructor(CSSNumberish... args); + readonly attribute CSSNumericArray values; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_value.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_value.idl new file mode 100755 index 000000000..d0f3df3ee --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_math_value.idl @@ -0,0 +1,20 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents mathematical expresssions that form a tree. +// https://drafts.css-houdini.org/css-typed-om/#cssmathvalue +enum CSSMathOperator { + "sum", + "product", + "negate", + "invert", + "min", + "max" +}; + +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSMathValue : CSSNumericValue { + [ImplementedAs=getOperator] readonly attribute CSSMathOperator operator; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_matrix_component.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_matrix_component.idl new file mode 100755 index 000000000..819165867 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_matrix_component.idl @@ -0,0 +1,14 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents a matrix value in a CSSTransformValue used for properties like +// "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om/#cssmatrixcomponent +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSMatrixComponent : CSSTransformComponent { + constructor(DOMMatrixReadOnly matrix, + optional CSSMatrixComponentOptions options = {}); + attribute DOMMatrix matrix; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_matrix_component_options.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_matrix_component_options.idl new file mode 100755 index 000000000..8bd9b5cca --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_matrix_component_options.idl @@ -0,0 +1,10 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Options for creating a CSSMatrixComponent. See CSSMatrixComponent for usage. +// Spec: https://drafts.css-houdini.org/css-typed-om/#dictdef-cssmatrixcomponentoptions +dictionary CSSMatrixComponentOptions { + boolean is2D; +}; + diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_array.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_array.idl new file mode 100755 index 000000000..34bfac3e3 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_array.idl @@ -0,0 +1,13 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents the sum of one or more CSSNumericValues. +// https://drafts.css-houdini.org/css-typed-om/#cssmathsum +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSNumericArray { + iterable; + readonly attribute unsigned long length; + getter CSSNumericValue(unsigned long index); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_type.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_type.idl new file mode 100755 index 000000000..2da98c09e --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_type.idl @@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.css-houdini.org/css-typed-om/#enumdef-cssnumericbasetype +enum CSSNumericBaseType { + "length", + "angle", + "time", + "frequency", + "resolution", + "flex", + "percent", +}; + +// https://drafts.css-houdini.org/css-typed-om/#dictdef-cssnumerictype +dictionary CSSNumericType { + long length; + long angle; + long time; + long frequency; + long resolution; + long flex; + long percent; + CSSNumericBaseType percentHint; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_value.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_value.idl new file mode 100755 index 000000000..25825967c --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_numeric_value.idl @@ -0,0 +1,28 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// CSSNumericValue is the base class for numeric and length typed CSS Values. +// https://drafts.css-houdini.org/css-typed-om/#numeric-objects +typedef (double or CSSNumericValue) CSSNumberish; + +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSNumericValue : CSSStyleValue { + [RaisesException, NewObject] CSSNumericValue add(CSSNumberish... values); + [RaisesException, NewObject] CSSNumericValue sub(CSSNumberish... values); + [RaisesException, NewObject] CSSNumericValue mul(CSSNumberish... values); + [RaisesException, NewObject] CSSNumericValue div(CSSNumberish... values); + [RaisesException, NewObject] CSSNumericValue min(CSSNumberish... values); + [RaisesException, NewObject] CSSNumericValue max(CSSNumberish... values); + + boolean equals(CSSNumberish... values); + + [RaisesException, NewObject] CSSUnitValue to(CSSOMString unit); + [RaisesException, NewObject] CSSMathSum toSum(CSSOMString... units); + CSSNumericType type(); + + // Putting Exposed=Window in the next line makes |parse| not exposed to PaintWorklet. + [RaisesException, NewObject, Exposed=Window, CallWith=ExecutionContext] + static CSSNumericValue parse(CSSOMString cssText); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_perspective.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_perspective.idl new file mode 100755 index 000000000..f5b28c68f --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_perspective.idl @@ -0,0 +1,15 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +typedef (CSSNumericValue or CSSKeywordish) CSSPerspectiveValue; + +// Represents a perspective value in a CSSTransformValue used for properties +// like "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om/#cssperspective +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSPerspective : CSSTransformComponent { + [RaisesException] constructor(CSSPerspectiveValue length); + [RaisesException=Setter] attribute CSSPerspectiveValue length; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_position_value.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_position_value.idl new file mode 100755 index 000000000..99196696b --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_position_value.idl @@ -0,0 +1,14 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents a value, i.e. a coordinate for properties like +// background-position. +// Spec: https://drafts.css-houdini.org/css-typed-om/#positionvalue-objects +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSPositionValue : CSSStyleValue { + [RaisesException] constructor(CSSNumericValue x, CSSNumericValue y); + [RaisesException=Setter] attribute CSSNumericValue x; + [RaisesException=Setter] attribute CSSNumericValue y; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_rgb.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_rgb.idl new file mode 100755 index 000000000..fc1c28601 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_rgb.idl @@ -0,0 +1,16 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents an RGB color. +// Spec: https://drafts.css-houdini.org/css-typed-om-1/#cssrgb +[ + Exposed=(Window,LayoutWorklet,PaintWorklet), + RuntimeEnabled=CSSColorTypedOM +] interface CSSRGB : CSSColorValue { + [RaisesException] constructor(CSSNumberish r, CSSNumberish g, CSSNumberish b, optional CSSNumberish alpha = 1); + [RaisesException=Setter] attribute CSSNumberish r; + [RaisesException=Setter] attribute CSSNumberish g; + [RaisesException=Setter] attribute CSSNumberish b; + [RaisesException=Setter] attribute CSSNumberish alpha; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_rotate.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_rotate.idl new file mode 100755 index 000000000..d71c02fa9 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_rotate.idl @@ -0,0 +1,17 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents a rotation value in a CSSTransformValue used for properties like +// "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om/#cssrotate +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSRotate : CSSTransformComponent { + [RaisesException] constructor(CSSNumericValue angleValue); + [RaisesException] constructor(CSSNumberish x, CSSNumberish y, CSSNumberish z, CSSNumericValue angle); + [RaisesException=Setter] attribute CSSNumericValue angle; + [RaisesException=Setter] attribute CSSNumberish x; + [RaisesException=Setter] attribute CSSNumberish y; + [RaisesException=Setter] attribute CSSNumberish z; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_scale.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_scale.idl new file mode 100755 index 000000000..cd52b70a0 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_scale.idl @@ -0,0 +1,15 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents a scale value in a CSSTransformValue used for properties like +// "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om/#cssscale +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSScale : CSSTransformComponent { + [RaisesException] constructor(CSSNumberish x, CSSNumberish y, optional CSSNumberish z); + [RaisesException=Setter] attribute CSSNumberish x; + [RaisesException=Setter] attribute CSSNumberish y; + [RaisesException=Setter] attribute CSSNumberish z; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew.idl new file mode 100755 index 000000000..63cd81505 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew.idl @@ -0,0 +1,14 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents a skew value in a CSSTransformValue used for properties like +// "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om/#cssskew +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSSkew : CSSTransformComponent { + [RaisesException] constructor(CSSNumericValue ax, CSSNumericValue ay); + [RaisesException=Setter] attribute CSSNumericValue ax; + [RaisesException=Setter] attribute CSSNumericValue ay; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew_x.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew_x.idl new file mode 100755 index 000000000..2f485b514 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew_x.idl @@ -0,0 +1,13 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents a skewX value in a CSSTransformValue used for properties like +// "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om/#cssskewx +[ + Exposed=(Window, Worker, PaintWorklet, LayoutWorklet) +] interface CSSSkewX : CSSTransformComponent { + [RaisesException] constructor(CSSNumericValue ax); + [RaisesException=Setter] attribute CSSNumericValue ax; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew_y.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew_y.idl new file mode 100755 index 000000000..385fed35c --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_skew_y.idl @@ -0,0 +1,13 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents a skewX value in a CSSTransformValue used for properties like +// "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om/#cssskewy +[ + Exposed=(Window, Worker, PaintWorklet, LayoutWorklet) +] interface CSSSkewY : CSSTransformComponent { + [RaisesException] constructor(CSSNumericValue ay); + [RaisesException=Setter] attribute CSSNumericValue ay; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_style_value.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_style_value.idl new file mode 100755 index 000000000..738338dad --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_style_value.idl @@ -0,0 +1,16 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// CSSStyleValue is the base class for all CSS values accessible from Typed OM. +// Values that are not yet supported as specific types are also returned as +// base CSSStyleValues. +// Spec: https://drafts.css-houdini.org/css-typed-om/#stylevalue-objects +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSStyleValue { + stringifier; + // Putting Exposed=Window in the next line makes |parse| not exposed to Worklets. + [RaisesException, Exposed=Window, CallWith=ExecutionContext] static CSSStyleValue parse(CSSOMString property, CSSOMString cssText); + [RaisesException, Exposed=Window, CallWith=ExecutionContext] static sequence parseAll(CSSOMString property, CSSOMString cssText); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_transform_component.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_transform_component.idl new file mode 100755 index 000000000..27631b0c0 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_transform_component.idl @@ -0,0 +1,15 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// CSSTransformComponent is the base class used for the representations of +// the individual CSS transforms. They are combined in a CSSTransformValue +// before they can be used as a value for properties like "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om/#csstransformcomponent +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSTransformComponent { + stringifier; + attribute boolean is2D; + [RaisesException] DOMMatrix toMatrix(); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_transform_value.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_transform_value.idl new file mode 100755 index 000000000..e77093215 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_transform_value.idl @@ -0,0 +1,16 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSTransformValue : CSSStyleValue { + [RaisesException] constructor(sequence transforms); + iterable; + readonly attribute unsigned long length; + getter CSSTransformComponent (unsigned long index); + [RaisesException] setter CSSTransformComponent (unsigned long index, CSSTransformComponent val); + + readonly attribute boolean is2D; + [RaisesException] DOMMatrix toMatrix(); +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_translate.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_translate.idl new file mode 100755 index 000000000..19b033433 --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_translate.idl @@ -0,0 +1,16 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents a translation value in a CSSTransformValue used for properties +// like "transform". +// Spec: https://drafts.css-houdini.org/css-typed-om/#csstranslate +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSTranslate : CSSTransformComponent { + [RaisesException] constructor(CSSNumericValue x, CSSNumericValue y, + optional CSSNumericValue z); + [RaisesException=Setter] attribute CSSNumericValue x; + [RaisesException=Setter] attribute CSSNumericValue y; + [RaisesException=Setter] attribute CSSNumericValue z; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_unit_value.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_unit_value.idl new file mode 100755 index 000000000..bbef22baf --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_unit_value.idl @@ -0,0 +1,14 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Represents numeric values that can be expressed as a single number plus a +// unit (or a naked number or percentage). +// https://drafts.css-houdini.org/css-typed-om/#cssunitvalue +[ + Exposed=(Window,LayoutWorklet,PaintWorklet) +] interface CSSUnitValue : CSSNumericValue { + [RaisesException] constructor(double value, CSSOMString unit); + attribute double value; + readonly attribute CSSOMString unit; +}; diff --git a/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_unit_values.idl b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_unit_values.idl new file mode 100755 index 000000000..e5fa1a98f --- /dev/null +++ b/tools/under-control/src/third_party/blink/renderer/core/css/cssom/css_unit_values.idl @@ -0,0 +1,91 @@ +// Copyright 2017 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// https://drafts.css-houdini.org/css-typed-om/#numeric-factory + +[ + ImplementedAs=CSSUnitValues +] partial namespace CSS { + [NewObject] CSSUnitValue number(double value); + [NewObject] CSSUnitValue percent(double value); + + // + [NewObject] CSSUnitValue em(double value); + [NewObject] CSSUnitValue rem(double value); + [NewObject] CSSUnitValue ex(double value); + [NewObject] CSSUnitValue rex(double value); + [NewObject] CSSUnitValue ch(double value); + [NewObject] CSSUnitValue rch(double value); + [NewObject] CSSUnitValue ic(double value); + [NewObject] CSSUnitValue ric(double value); + [NewObject] CSSUnitValue lh(double value); + [NewObject] CSSUnitValue rlh(double value); + [NewObject] CSSUnitValue cap(double value); + [NewObject] CSSUnitValue rcap(double value); + [NewObject] CSSUnitValue vw(double value); + [NewObject] CSSUnitValue vh(double value); + [NewObject] CSSUnitValue vi(double value); + [NewObject] CSSUnitValue vb(double value); + [NewObject] CSSUnitValue vmin(double value); + [NewObject] CSSUnitValue vmax(double value); + + [NewObject] CSSUnitValue svw(double value); + [NewObject] CSSUnitValue svh(double value); + [NewObject] CSSUnitValue svi(double value); + [NewObject] CSSUnitValue svb(double value); + [NewObject] CSSUnitValue svmin(double value); + [NewObject] CSSUnitValue svmax(double value); + + [NewObject] CSSUnitValue lvw(double value); + [NewObject] CSSUnitValue lvh(double value); + [NewObject] CSSUnitValue lvi(double value); + [NewObject] CSSUnitValue lvb(double value); + [NewObject] CSSUnitValue lvmin(double value); + [NewObject] CSSUnitValue lvmax(double value); + + [NewObject] CSSUnitValue dvw(double value); + [NewObject] CSSUnitValue dvh(double value); + [NewObject] CSSUnitValue dvi(double value); + [NewObject] CSSUnitValue dvb(double value); + [NewObject] CSSUnitValue dvmin(double value); + [NewObject] CSSUnitValue dvmax(double value); + + [NewObject] CSSUnitValue cqw(double value); + [NewObject] CSSUnitValue cqh(double value); + [NewObject] CSSUnitValue cqi(double value); + [NewObject] CSSUnitValue cqb(double value); + [NewObject] CSSUnitValue cqmin(double value); + [NewObject] CSSUnitValue cqmax(double value); + + [NewObject] CSSUnitValue cm(double value); + [NewObject] CSSUnitValue mm(double value); + [NewObject] CSSUnitValue in(double value); + [NewObject] CSSUnitValue pt(double value); + [NewObject] CSSUnitValue pc(double value); + [NewObject] CSSUnitValue px(double value); + [NewObject] CSSUnitValue Q(double value); + + // + [NewObject] CSSUnitValue deg(double value); + [NewObject] CSSUnitValue grad(double value); + [NewObject] CSSUnitValue rad(double value); + [NewObject] CSSUnitValue turn(double value); + + //