summaryrefslogtreecommitdiff
path: root/chromium/ui
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-03 13:42:47 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-15 10:27:51 +0000
commit8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (patch)
treed29d987c4d7b173cf853279b79a51598f104b403 /chromium/ui
parent830c9e163d31a9180fadca926b3e1d7dfffb5021 (diff)
downloadqtwebengine-chromium-8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec.tar.gz
BASELINE: Update Chromium to 66.0.3359.156
Change-Id: I0c9831ad39911a086b6377b16f995ad75a51e441 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/ui')
-rw-r--r--chromium/ui/PRESUBMIT.py34
-rw-r--r--chromium/ui/accelerated_widget_mac/accelerated_widget_mac.mm17
-rw-r--r--chromium/ui/accessibility/BUILD.gn39
-rw-r--r--chromium/ui/accessibility/OWNERS3
-rw-r--r--chromium/ui/accessibility/PRESUBMIT.py50
-rw-r--r--chromium/ui/accessibility/ax_action_data.cc16
-rw-r--r--chromium/ui/accessibility/ax_action_data.h10
-rw-r--r--chromium/ui/accessibility/ax_enum_util.cc2233
-rw-r--r--chromium/ui/accessibility/ax_enum_util.h130
-rw-r--r--chromium/ui/accessibility/ax_enums.idl756
-rw-r--r--chromium/ui/accessibility/ax_enums.mojom820
-rw-r--r--chromium/ui/accessibility/ax_event_generator.cc164
-rw-r--r--chromium/ui/accessibility/ax_event_generator.h20
-rw-r--r--chromium/ui/accessibility/ax_event_generator_unittest.cc303
-rw-r--r--chromium/ui/accessibility/ax_node.cc90
-rw-r--r--chromium/ui/accessibility/ax_node.h11
-rw-r--r--chromium/ui/accessibility/ax_node_data.cc760
-rw-r--r--chromium/ui/accessibility/ax_node_data.h158
-rw-r--r--chromium/ui/accessibility/ax_node_position.cc22
-rw-r--r--chromium/ui/accessibility/ax_node_position.h1
-rw-r--r--chromium/ui/accessibility/ax_node_position_unittest.cc257
-rw-r--r--chromium/ui/accessibility/ax_position.h70
-rw-r--r--chromium/ui/accessibility/ax_role_properties.cc190
-rw-r--r--chromium/ui/accessibility/ax_role_properties.h21
-rw-r--r--chromium/ui/accessibility/ax_text_utils.cc60
-rw-r--r--chromium/ui/accessibility/ax_text_utils.h19
-rw-r--r--chromium/ui/accessibility/ax_text_utils_unittest.cc42
-rw-r--r--chromium/ui/accessibility/ax_tree.cc46
-rw-r--r--chromium/ui/accessibility/ax_tree.h42
-rw-r--r--chromium/ui/accessibility/ax_tree_combiner.cc9
-rw-r--r--chromium/ui/accessibility/ax_tree_combiner_unittest.cc85
-rw-r--r--chromium/ui/accessibility/ax_tree_data.cc1
-rw-r--r--chromium/ui/accessibility/ax_tree_data.h8
-rw-r--r--chromium/ui/accessibility/ax_tree_unittest.cc232
-rw-r--r--chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_ar.xtb20
-rw-r--r--chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_de.xtb2
-rw-r--r--chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_es-419.xtb2
-rw-r--r--chromium/ui/accessibility/platform/aura_window_properties.cc6
-rw-r--r--chromium/ui/accessibility/platform/aura_window_properties.h5
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.cc16
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node.h4
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc206
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_auralinux.h4
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc39
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_base.cc136
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_base.h39
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_delegate.h20
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_mac.h10
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_mac.mm489
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_unittest.cc80
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_win.cc876
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_win.h12
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc227
-rw-r--r--chromium/ui/accessibility/platform/ax_platform_relation_win.cc64
-rw-r--r--chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.cc242
-rw-r--r--chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.h8
-rw-r--r--chromium/ui/accessibility/platform/ax_system_caret_win.cc24
-rw-r--r--chromium/ui/accessibility/platform/ax_system_caret_win.h7
-rw-r--r--chromium/ui/accessibility/platform/test_ax_node_wrapper.cc34
-rw-r--r--chromium/ui/accessibility/platform/test_ax_node_wrapper.h9
-rw-r--r--chromium/ui/android/BUILD.gn5
-rw-r--r--chromium/ui/android/OWNERS3
-rw-r--r--chromium/ui/android/delegated_frame_host_android.cc92
-rw-r--r--chromium/ui/android/delegated_frame_host_android.h18
-rw-r--r--chromium/ui/android/event_forwarder.cc35
-rw-r--r--chromium/ui/android/event_forwarder.h13
-rw-r--r--chromium/ui/android/resources/resource_manager_impl.cc50
-rw-r--r--chromium/ui/android/resources/resource_manager_impl_unittest.cc4
-rw-r--r--chromium/ui/app_list/BUILD.gn17
-rw-r--r--chromium/ui/app_list/presenter/BUILD.gn6
-rw-r--r--chromium/ui/arc/notification/arc_notification_content_view.cc57
-rw-r--r--chromium/ui/arc/notification/arc_notification_content_view.h6
-rw-r--r--chromium/ui/arc/notification/arc_notification_content_view_delegate.h4
-rw-r--r--chromium/ui/arc/notification/arc_notification_content_view_unittest.cc3
-rw-r--r--chromium/ui/arc/notification/arc_notification_delegate.cc7
-rw-r--r--chromium/ui/arc/notification/arc_notification_delegate.h2
-rw-r--r--chromium/ui/arc/notification/arc_notification_item.h3
-rw-r--r--chromium/ui/arc/notification/arc_notification_item_impl.cc30
-rw-r--r--chromium/ui/arc/notification/arc_notification_item_impl.h3
-rw-r--r--chromium/ui/arc/notification/arc_notification_manager_unittest.cc3
-rw-r--r--chromium/ui/arc/notification/arc_notification_view.cc59
-rw-r--r--chromium/ui/arc/notification/arc_notification_view.h14
-rw-r--r--chromium/ui/arc/notification/arc_notification_view_unittest.cc70
-rw-r--r--chromium/ui/aura/BUILD.gn8
-rw-r--r--chromium/ui/aura/DEPS3
-rw-r--r--chromium/ui/aura/client/aura_constants.cc1
-rw-r--r--chromium/ui/aura/client/aura_constants.h4
-rw-r--r--chromium/ui/aura/env.cc16
-rw-r--r--chromium/ui/aura/env.h12
-rw-r--r--chromium/ui/aura/env_input_state_controller.cc2
-rw-r--r--chromium/ui/aura/hit_test_data_provider_aura.cc5
-rw-r--r--chromium/ui/aura/hit_test_data_provider_aura.h3
-rw-r--r--chromium/ui/aura/hit_test_data_provider_aura_unittest.cc44
-rw-r--r--chromium/ui/aura/local/layer_tree_frame_sink_local.cc27
-rw-r--r--chromium/ui/aura/local/layer_tree_frame_sink_local.h6
-rw-r--r--chromium/ui/aura/local/window_port_local.cc42
-rw-r--r--chromium/ui/aura/local/window_port_local.h7
-rw-r--r--chromium/ui/aura/mus/client_surface_embedder.cc12
-rw-r--r--chromium/ui/aura/mus/client_surface_embedder.h14
-rw-r--r--chromium/ui/aura/mus/drag_drop_controller_mus.cc2
-rw-r--r--chromium/ui/aura/mus/mus_context_factory.cc7
-rw-r--r--chromium/ui/aura/mus/mus_context_factory.h6
-rw-r--r--chromium/ui/aura/mus/mus_types.h12
-rw-r--r--chromium/ui/aura/mus/property_converter.cc8
-rw-r--r--chromium/ui/aura/mus/system_input_injector_mus.cc1
-rw-r--r--chromium/ui/aura/mus/text_input_client_impl.cc4
-rw-r--r--chromium/ui/aura/mus/text_input_client_impl.h2
-rw-r--r--chromium/ui/aura/mus/window_mus.h6
-rw-r--r--chromium/ui/aura/mus/window_port_mus.cc79
-rw-r--r--chromium/ui/aura/mus/window_port_mus.h11
-rw-r--r--chromium/ui/aura/mus/window_port_mus_unittest.cc27
-rw-r--r--chromium/ui/aura/mus/window_tree_client.cc168
-rw-r--r--chromium/ui/aura/mus/window_tree_client.h110
-rw-r--r--chromium/ui/aura/mus/window_tree_client_delegate.h2
-rw-r--r--chromium/ui/aura/mus/window_tree_client_unittest.cc67
-rw-r--r--chromium/ui/aura/mus/window_tree_host_mus.cc6
-rw-r--r--chromium/ui/aura/scoped_keyboard_hook.cc24
-rw-r--r--chromium/ui/aura/scoped_keyboard_hook.h35
-rw-r--r--chromium/ui/aura/window.cc96
-rw-r--r--chromium/ui/aura/window.h77
-rw-r--r--chromium/ui/aura/window_delegate.h8
-rw-r--r--chromium/ui/aura/window_event_dispatcher.cc36
-rw-r--r--chromium/ui/aura/window_event_dispatcher.h4
-rw-r--r--chromium/ui/aura/window_event_dispatcher_unittest.cc7
-rw-r--r--chromium/ui/aura/window_occlusion_tracker.cc200
-rw-r--r--chromium/ui/aura/window_occlusion_tracker.h54
-rw-r--r--chromium/ui/aura/window_occlusion_tracker_unittest.cc657
-rw-r--r--chromium/ui/aura/window_port.h9
-rw-r--r--chromium/ui/aura/window_port_for_shutdown.cc12
-rw-r--r--chromium/ui/aura/window_port_for_shutdown.h5
-rw-r--r--chromium/ui/aura/window_targeter_unittest.cc2
-rw-r--r--chromium/ui/aura/window_tree_host.cc11
-rw-r--r--chromium/ui/aura/window_tree_host.h23
-rw-r--r--chromium/ui/aura/window_tree_host_platform.cc9
-rw-r--r--chromium/ui/aura/window_tree_host_platform.h3
-rw-r--r--chromium/ui/aura/window_unittest.cc83
-rw-r--r--chromium/ui/base/BUILD.gn17
-rw-r--r--chromium/ui/base/accelerators/media_keys_listener.cc13
-rw-r--r--chromium/ui/base/accelerators/media_keys_listener.h60
-rw-r--r--chromium/ui/base/accelerators/media_keys_listener_mac.mm214
-rw-r--r--chromium/ui/base/accelerators/media_keys_listener_stub.cc16
-rw-r--r--chromium/ui/base/cocoa/text_services_context_menu.cc152
-rw-r--r--chromium/ui/base/cocoa/text_services_context_menu.h74
-rw-r--r--chromium/ui/base/ime/ime_bridge.cc28
-rw-r--r--chromium/ui/base/ime/ime_bridge.h7
-rw-r--r--chromium/ui/base/ime/ime_bridge_observer.h23
-rw-r--r--chromium/ui/base/ime/ime_engine_handler_interface.h4
-rw-r--r--chromium/ui/base/ime/input_method_base.cc9
-rw-r--r--chromium/ui/base/ime/input_method_chromeos.cc34
-rw-r--r--chromium/ui/base/ime/input_method_chromeos_unittest.cc201
-rw-r--r--chromium/ui/base/l10n/l10n_util_win_unittest.cc2
-rw-r--r--chromium/ui/base/layout.cc4
-rw-r--r--chromium/ui/base/layout_mac.mm37
-rw-r--r--chromium/ui/base/material_design/material_design_controller.cc7
-rw-r--r--chromium/ui/base/material_design/material_design_controller.h7
-rw-r--r--chromium/ui/base/models/menu_model.cc4
-rw-r--r--chromium/ui/base/models/menu_model.h5
-rw-r--r--chromium/ui/base/models/simple_menu_model.cc106
-rw-r--r--chromium/ui/base/models/simple_menu_model.h32
-rw-r--r--chromium/ui/base/mojo/DEPS2
-rw-r--r--chromium/ui/base/mojo/clipboard.typemap2
-rw-r--r--chromium/ui/base/mojo/clipboard_struct_traits.h2
-rw-r--r--chromium/ui/base/resource/resource_bundle.cc43
-rw-r--r--chromium/ui/base/resource/resource_bundle_android.cc5
-rw-r--r--chromium/ui/base/ui_base_features.cc62
-rw-r--r--chromium/ui/base/ui_base_features.h23
-rw-r--r--chromium/ui/base/ui_base_switches.cc29
-rw-r--r--chromium/ui/base/ui_base_switches.h16
-rw-r--r--chromium/ui/base/ui_base_switches_util.cc15
-rw-r--r--chromium/ui/base/ui_base_switches_util.h6
-rw-r--r--chromium/ui/base/ui_features.gni4
-rw-r--r--chromium/ui/base/win/direct_manipulation.cc (renamed from chromium/ui/gfx/win/direct_manipulation.cc)32
-rw-r--r--chromium/ui/base/win/direct_manipulation.h (renamed from chromium/ui/gfx/win/direct_manipulation.h)20
-rw-r--r--chromium/ui/base/win/on_screen_keyboard_display_manager_tab_tip.cc379
-rw-r--r--chromium/ui/base/win/on_screen_keyboard_display_manager_tab_tip.h60
-rw-r--r--chromium/ui/base/win/shell.cc50
-rw-r--r--chromium/ui/base/win/shell.h4
-rw-r--r--chromium/ui/chromeos/BUILD.gn8
-rw-r--r--chromium/ui/chromeos/search_box/BUILD.gn24
-rw-r--r--chromium/ui/compositor/BUILD.gn3
-rw-r--r--chromium/ui/compositor/canvas_painter.cc22
-rw-r--r--chromium/ui/compositor/canvas_painter.h8
-rw-r--r--chromium/ui/compositor/canvas_painter_unittest.cc121
-rw-r--r--chromium/ui/compositor/compositor.cc25
-rw-r--r--chromium/ui/compositor/compositor.h6
-rw-r--r--chromium/ui/compositor/dip_util.cc9
-rw-r--r--chromium/ui/compositor/layer.cc30
-rw-r--r--chromium/ui/compositor/layer.h11
-rw-r--r--chromium/ui/compositor/layer_animation_element.cc38
-rw-r--r--chromium/ui/compositor/layer_animation_element.h10
-rw-r--r--chromium/ui/compositor/layer_animation_element_unittest.cc2
-rw-r--r--chromium/ui/compositor/layer_animation_sequence_unittest.cc4
-rw-r--r--chromium/ui/compositor/layer_animator.cc51
-rw-r--r--chromium/ui/compositor/layer_animator.h19
-rw-r--r--chromium/ui/compositor/layer_owner_unittest.cc26
-rw-r--r--chromium/ui/compositor/layer_threaded_animation_delegate.h8
-rw-r--r--chromium/ui/compositor/layer_unittest.cc127
-rw-r--r--chromium/ui/display/OWNERS1
-rw-r--r--chromium/ui/display/display.cc13
-rw-r--r--chromium/ui/display/display.h43
-rw-r--r--chromium/ui/display/display_switches.cc11
-rw-r--r--chromium/ui/display/display_switches.h5
-rw-r--r--chromium/ui/display/mac/screen_mac.mm4
-rw-r--r--chromium/ui/display/manager/chromeos/display_configurator.cc8
-rw-r--r--chromium/ui/display/manager/chromeos/touch_device_manager.cc4
-rw-r--r--chromium/ui/display/manager/chromeos/update_display_configuration_task.cc5
-rw-r--r--chromium/ui/display/manager/chromeos/update_display_configuration_task.h2
-rw-r--r--chromium/ui/display/manager/display_manager.cc24
-rw-r--r--chromium/ui/display/manager/display_manager.h17
-rw-r--r--chromium/ui/display/manager/managed_display_info.cc18
-rw-r--r--chromium/ui/display/mojo/display_struct_traits.cc24
-rw-r--r--chromium/ui/display/mojo/display_struct_traits_unittest.cc4
-rw-r--r--chromium/ui/display/win/color_profile_reader.cc4
-rw-r--r--chromium/ui/events/BUILD.gn16
-rw-r--r--chromium/ui/events/android/gesture_event_android.cc19
-rw-r--r--chromium/ui/events/android/gesture_event_android.h24
-rw-r--r--chromium/ui/events/android/motion_event_android.cc141
-rw-r--r--chromium/ui/events/android/motion_event_android.h9
-rw-r--r--chromium/ui/events/android/motion_event_android_unittest.cc10
-rw-r--r--chromium/ui/events/base_event_utils.cc6
-rw-r--r--chromium/ui/events/base_event_utils.h4
-rw-r--r--chromium/ui/events/blink/blink_event_util.cc134
-rw-r--r--chromium/ui/events/blink/blink_event_util.h5
-rw-r--r--chromium/ui/events/blink/blink_event_util_unittest.cc20
-rw-r--r--chromium/ui/events/blink/input_handler_proxy.cc23
-rw-r--r--chromium/ui/events/blink/input_handler_proxy.h7
-rw-r--r--chromium/ui/events/blink/input_handler_proxy_client.h3
-rw-r--r--chromium/ui/events/blink/input_handler_proxy_unittest.cc111
-rw-r--r--chromium/ui/events/blink/web_input_event_traits.cc5
-rw-r--r--chromium/ui/events/blink/web_input_event_traits_unittest.cc10
-rw-r--r--chromium/ui/events/chromecast/scroller.cc477
-rw-r--r--chromium/ui/events/chromecast/scroller.h151
-rw-r--r--chromium/ui/events/chromecast/scroller_unittest.cc178
-rw-r--r--chromium/ui/events/devices/x11/touch_factory_x11.cc8
-rw-r--r--chromium/ui/events/event.cc5
-rw-r--r--chromium/ui/events/event.h7
-rw-r--r--chromium/ui/events/event_constants.h6
-rw-r--r--chromium/ui/events/event_unittest.cc121
-rw-r--r--chromium/ui/events/event_utils.cc21
-rw-r--r--chromium/ui/events/event_utils.h8
-rw-r--r--chromium/ui/events/gesture_detection/filtered_gesture_provider.cc2
-rw-r--r--chromium/ui/events/gesture_detection/gesture_detector.cc104
-rw-r--r--chromium/ui/events/gesture_detection/gesture_event_data.cc15
-rw-r--r--chromium/ui/events/gesture_detection/gesture_event_data_packet.cc24
-rw-r--r--chromium/ui/events/gesture_detection/gesture_event_data_packet_unittest.cc31
-rw-r--r--chromium/ui/events/gesture_detection/gesture_provider.cc125
-rw-r--r--chromium/ui/events/gesture_detection/gesture_provider_unittest.cc876
-rw-r--r--chromium/ui/events/gesture_detection/gesture_touch_uma_histogram.cc6
-rw-r--r--chromium/ui/events/gesture_detection/motion_event.cc9
-rw-r--r--chromium/ui/events/gesture_detection/motion_event.h48
-rw-r--r--chromium/ui/events/gesture_detection/motion_event_buffer.cc16
-rw-r--r--chromium/ui/events/gesture_detection/motion_event_buffer_unittest.cc91
-rw-r--r--chromium/ui/events/gesture_detection/motion_event_generic.cc17
-rw-r--r--chromium/ui/events/gesture_detection/motion_event_generic_unittest.cc39
-rw-r--r--chromium/ui/events/gesture_detection/scale_gesture_detector.cc20
-rw-r--r--chromium/ui/events/gesture_detection/scale_gesture_detector.h4
-rw-r--r--chromium/ui/events/gesture_detection/snap_scroll_controller.cc8
-rw-r--r--chromium/ui/events/gesture_detection/touch_disposition_gesture_filter.cc2
-rw-r--r--chromium/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc2
-rw-r--r--chromium/ui/events/gesture_detection/velocity_tracker.cc44
-rw-r--r--chromium/ui/events/gesture_detection/velocity_tracker_unittest.cc20
-rw-r--r--chromium/ui/events/gesture_event_details.cc1
-rw-r--r--chromium/ui/events/gestures/blink/web_gesture_curve_impl.cc6
-rw-r--r--chromium/ui/events/gestures/motion_event_aura.cc27
-rw-r--r--chromium/ui/events/gestures/motion_event_aura_unittest.cc40
-rw-r--r--chromium/ui/events/keyboard_hook.h40
-rw-r--r--chromium/ui/events/keyboard_hook_base.cc34
-rw-r--r--chromium/ui/events/keyboard_hook_base.h42
-rw-r--r--chromium/ui/events/keycodes/keyboard_code_conversion_android.cc5
-rw-r--r--chromium/ui/events/keycodes/keyboard_code_conversion_xkb.cc6
-rw-r--r--chromium/ui/events/keycodes/platform_key_map_win.cc23
-rw-r--r--chromium/ui/events/keycodes/platform_key_map_win.h12
-rw-r--r--chromium/ui/events/keycodes/platform_key_map_win_unittest.cc89
-rw-r--r--chromium/ui/events/ozone/BUILD.gn2
-rw-r--r--chromium/ui/events/ozone/evdev/input_device_factory_evdev.cc11
-rw-r--r--chromium/ui/events/ozone/evdev/input_device_factory_evdev.h4
-rw-r--r--chromium/ui/events/ozone/evdev/input_injector_evdev.cc1
-rw-r--r--chromium/ui/events/ozone/evdev/input_injector_evdev_unittest.cc6
-rw-r--r--chromium/ui/events/ozone/evdev/keyboard_evdev.cc89
-rw-r--r--chromium/ui/events/ozone/evdev/keyboard_evdev.h27
-rw-r--r--chromium/ui/events/ozone/evdev/touch_evdev_types.h7
-rw-r--r--chromium/ui/events/ozone/evdev/touch_event_converter_evdev.cc24
-rw-r--r--chromium/ui/events/ozone/evdev/touch_event_converter_evdev.h1
-rw-r--r--chromium/ui/events/ozone/keyboard/event_auto_repeat_handler.cc103
-rw-r--r--chromium/ui/events/ozone/keyboard/event_auto_repeat_handler.h71
-rw-r--r--chromium/ui/events/win/keyboard_hook_win.cc131
-rw-r--r--chromium/ui/events/x/events_x_unittest.cc30
-rw-r--r--chromium/ui/events/x/events_x_utils.cc5
-rw-r--r--chromium/ui/events/x/events_x_utils.h3
-rw-r--r--chromium/ui/events/x/keyboard_hook_posix.cc43
-rw-r--r--chromium/ui/gfx/BUILD.gn8
-rw-r--r--chromium/ui/gfx/animation/slide_animation.h2
-rw-r--r--chromium/ui/gfx/buffer_format_util.cc37
-rw-r--r--chromium/ui/gfx/buffer_types.h1
-rw-r--r--chromium/ui/gfx/canvas_unittest.cc3
-rw-r--r--chromium/ui/gfx/canvas_unittest_mac.mm15
-rw-r--r--chromium/ui/gfx/color_palette.h35
-rw-r--r--chromium/ui/gfx/color_space.cc8
-rw-r--r--chromium/ui/gfx/color_space.h3
-rw-r--r--chromium/ui/gfx/color_transform.cc11
-rw-r--r--chromium/ui/gfx/font_list_unittest.cc6
-rw-r--r--chromium/ui/gfx/font_names_testing.cc2
-rw-r--r--chromium/ui/gfx/geometry/mojo/BUILD.gn2
-rw-r--r--chromium/ui/gfx/geometry/vector2d.h9
-rw-r--r--chromium/ui/gfx/geometry/vector2d_f.h6
-rw-r--r--chromium/ui/gfx/ipc/color/BUILD.gn2
-rw-r--r--chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.cc111
-rw-r--r--chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.h11
-rw-r--r--chromium/ui/gfx/ipc/skia/gfx_skia_param_traits_macros.h16
-rw-r--r--chromium/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc18
-rw-r--r--chromium/ui/gfx/mac/io_surface.cc28
-rw-r--r--chromium/ui/gfx/mojo/buffer_types.mojom1
-rw-r--r--chromium/ui/gfx/mojo/buffer_types_struct_traits.h5
-rw-r--r--chromium/ui/gfx/mojo/ca_layer_params.mojom8
-rw-r--r--chromium/ui/gfx/mojo/ca_layer_params_struct_traits.cc41
-rw-r--r--chromium/ui/gfx/mojo/ca_layer_params_struct_traits.h10
-rw-r--r--chromium/ui/gfx/paint_vector_icon.cc8
-rw-r--r--chromium/ui/gfx/paint_vector_icon_unittest.cc4
-rw-r--r--chromium/ui/gfx/platform_font_win.cc2
-rw-r--r--chromium/ui/gfx/render_text.cc34
-rw-r--r--chromium/ui/gfx/render_text.h30
-rw-r--r--chromium/ui/gfx/render_text_harfbuzz.cc74
-rw-r--r--chromium/ui/gfx/render_text_harfbuzz.h16
-rw-r--r--chromium/ui/gfx/render_text_mac.mm6
-rw-r--r--chromium/ui/gfx/render_text_test_api.h87
-rw-r--r--chromium/ui/gfx/render_text_unittest.cc200
-rw-r--r--chromium/ui/gfx/sequential_id_generator_unittest.cc1
-rw-r--r--chromium/ui/gfx/shadow_value.cc14
-rw-r--r--chromium/ui/gfx/shadow_value.h31
-rw-r--r--chromium/ui/gfx/shadow_value_unittest.cc66
-rw-r--r--chromium/ui/gfx/skia_paint_util.cc5
-rw-r--r--chromium/ui/gfx/text_constants.h1
-rw-r--r--chromium/ui/gfx/text_utils.cc10
-rw-r--r--chromium/ui/gfx/text_utils.h3
-rw-r--r--chromium/ui/gfx/vector_icon_types.h22
-rw-r--r--chromium/ui/gfx/vsync_provider.cc6
-rw-r--r--chromium/ui/gfx/vsync_provider.h8
-rw-r--r--chromium/ui/gfx/win/rendering_window_manager.cc12
-rw-r--r--chromium/ui/gfx/x/x11.h29
-rw-r--r--chromium/ui/gfx/x/x11_types.cc12
-rw-r--r--chromium/ui/gl/BUILD.gn17
-rw-r--r--chromium/ui/gl/features.gni8
-rw-r--r--chromium/ui/gl/gl_bindings.h9
-rw-r--r--chromium/ui/gl/gl_fence_android_native_fence_sync.cc2
-rw-r--r--chromium/ui/gl/gl_gl_api_implementation.cc30
-rw-r--r--chromium/ui/gl/gl_gl_api_implementation.h3
-rw-r--r--chromium/ui/gl/gl_image_io_surface.h5
-rw-r--r--chromium/ui/gl/gl_image_io_surface.mm61
-rw-r--r--chromium/ui/gl/gl_image_io_surface_egl.h35
-rw-r--r--chromium/ui/gl/gl_image_io_surface_egl.mm154
-rw-r--r--chromium/ui/gl/gl_image_io_surface_unittest.cc39
-rw-r--r--chromium/ui/gl/gl_image_memory.cc32
-rw-r--r--chromium/ui/gl/gl_image_native_pixmap.cc16
-rw-r--r--chromium/ui/gl/gl_image_shared_memory_unittest.cc8
-rw-r--r--chromium/ui/gl/gl_surface_egl.cc56
-rw-r--r--chromium/ui/gl/gl_surface_egl.h7
-rw-r--r--chromium/ui/gl/gl_surface_glx.cc44
-rw-r--r--chromium/ui/gl/gl_surface_presentation_helper.cc47
-rw-r--r--chromium/ui/gl/gl_surface_presentation_helper.h24
-rw-r--r--chromium/ui/gl/init/BUILD.gn8
-rw-r--r--chromium/ui/gl/init/create_gr_gl_interface.cc8
-rw-r--r--chromium/ui/gl/init/gl_factory_mac.cc31
-rw-r--r--chromium/ui/gl/init/gl_initializer_mac.cc68
-rw-r--r--chromium/ui/gl/init/ozone_util.h2
-rw-r--r--chromium/ui/gl/sync_control_vsync_provider.cc8
-rw-r--r--chromium/ui/gl/sync_control_vsync_provider.h2
-rw-r--r--chromium/ui/gl/vsync_provider_win.cc6
-rw-r--r--chromium/ui/gl/vsync_provider_win.h3
-rw-r--r--chromium/ui/keyboard/BUILD.gn2
-rw-r--r--chromium/ui/keyboard/container_behavior.h6
-rw-r--r--chromium/ui/keyboard/container_floating_behavior.cc70
-rw-r--r--chromium/ui/keyboard/container_floating_behavior.h28
-rw-r--r--chromium/ui/keyboard/container_floating_behavior_unittest.cc69
-rw-r--r--chromium/ui/keyboard/container_full_width_behavior.cc6
-rw-r--r--chromium/ui/keyboard/container_full_width_behavior.h6
-rw-r--r--chromium/ui/keyboard/keyboard_controller.cc85
-rw-r--r--chromium/ui/keyboard/keyboard_controller.h19
-rw-r--r--chromium/ui/keyboard/keyboard_controller_observer.h10
-rw-r--r--chromium/ui/keyboard/keyboard_controller_unittest.cc167
-rw-r--r--chromium/ui/keyboard/keyboard_util.cc5
-rw-r--r--chromium/ui/keyboard/notification_manager.cc10
-rw-r--r--chromium/ui/keyboard/queued_container_type.cc24
-rw-r--r--chromium/ui/keyboard/queued_container_type.h37
-rw-r--r--chromium/ui/keyboard/resources/inputview_adapter.js7
-rw-r--r--chromium/ui/latency/latency_tracker.cc15
-rw-r--r--chromium/ui/latency/latency_tracker.h5
-rw-r--r--chromium/ui/login/account_picker/md_user_pod_template.css25
-rw-r--r--chromium/ui/login/display_manager.js45
-rw-r--r--chromium/ui/message_center/BUILD.gn42
-rw-r--r--chromium/ui/message_center/change_queue.cc164
-rw-r--r--chromium/ui/message_center/change_queue.h73
-rw-r--r--chromium/ui/message_center/change_queue_unittest.cc133
-rw-r--r--chromium/ui/message_center/cocoa/notification_controller.mm2
-rw-r--r--chromium/ui/message_center/cocoa/notification_controller_unittest.mm18
-rw-r--r--chromium/ui/message_center/cocoa/popup_collection_unittest.mm2
-rw-r--r--chromium/ui/message_center/cocoa/popup_controller_unittest.mm2
-rw-r--r--chromium/ui/message_center/fake_message_center.cc2
-rw-r--r--chromium/ui/message_center/fake_message_center.h3
-rw-r--r--chromium/ui/message_center/message_center.h5
-rw-r--r--chromium/ui/message_center/message_center_impl.cc264
-rw-r--r--chromium/ui/message_center/message_center_impl.h30
-rw-r--r--chromium/ui/message_center/message_center_impl_unittest.cc58
-rw-r--r--chromium/ui/message_center/message_center_observer.h2
-rw-r--r--chromium/ui/message_center/message_center_stats_collector.cc153
-rw-r--r--chromium/ui/message_center/message_center_stats_collector.h89
-rw-r--r--chromium/ui/message_center/message_center_switches.h20
-rw-r--r--chromium/ui/message_center/mojo/notification.mojom49
-rw-r--r--chromium/ui/message_center/mojo/notification_struct_traits.cc138
-rw-r--r--chromium/ui/message_center/mojo/notification_struct_traits.h101
-rw-r--r--chromium/ui/message_center/notification_blocker.h2
-rw-r--r--chromium/ui/message_center/notification_delegate.h89
-rw-r--r--chromium/ui/message_center/notification_list.cc12
-rw-r--r--chromium/ui/message_center/notification_list.h7
-rw-r--r--chromium/ui/message_center/notification_list_unittest.cc114
-rw-r--r--chromium/ui/message_center/notification_types.cc22
-rw-r--r--chromium/ui/message_center/notification_types.h57
-rw-r--r--chromium/ui/message_center/public/DEPS4
-rw-r--r--chromium/ui/message_center/public/cpp/BUILD.gn15
-rw-r--r--chromium/ui/message_center/public/cpp/features.cc18
-rw-r--r--chromium/ui/message_center/public/cpp/features.h19
-rw-r--r--chromium/ui/message_center/public/cpp/message_center_constants.h42
-rw-r--r--chromium/ui/message_center/public/cpp/message_center_switches.cc36
-rw-r--r--chromium/ui/message_center/public/cpp/message_center_switches.h27
-rw-r--r--chromium/ui/message_center/public/cpp/notification.cc (renamed from chromium/ui/message_center/notification.cc)134
-rw-r--r--chromium/ui/message_center/public/cpp/notification.h (renamed from chromium/ui/message_center/notification.h)83
-rw-r--r--chromium/ui/message_center/public/cpp/notification_delegate.cc (renamed from chromium/ui/message_center/notification_delegate.cc)45
-rw-r--r--chromium/ui/message_center/public/cpp/notification_delegate.h119
-rw-r--r--chromium/ui/message_center/public/cpp/notification_delegate_unittest.cc (renamed from chromium/ui/message_center/notification_delegate_unittest.cc)2
-rw-r--r--chromium/ui/message_center/public/cpp/notification_types.h39
-rw-r--r--chromium/ui/message_center/public/cpp/notifier_id.cc (renamed from chromium/ui/message_center/notifier_id.cc)2
-rw-r--r--chromium/ui/message_center/public/cpp/notifier_id.h (renamed from chromium/ui/message_center/notifier_id.h)11
-rw-r--r--chromium/ui/message_center/public/mojo/BUILD.gn (renamed from chromium/ui/message_center/mojo/BUILD.gn)6
-rw-r--r--chromium/ui/message_center/public/mojo/DEPS (renamed from chromium/ui/message_center/mojo/DEPS)0
-rw-r--r--chromium/ui/message_center/public/mojo/OWNERS (renamed from chromium/ui/message_center/mojo/OWNERS)0
-rw-r--r--chromium/ui/message_center/public/mojo/notification.mojom93
-rw-r--r--chromium/ui/message_center/public/mojo/notification.typemap (renamed from chromium/ui/message_center/mojo/notification.typemap)11
-rw-r--r--chromium/ui/message_center/public/mojo/notification_struct_traits.cc268
-rw-r--r--chromium/ui/message_center/public/mojo/notification_struct_traits.h215
-rw-r--r--chromium/ui/message_center/public/mojo/notifier_id.mojom (renamed from chromium/ui/message_center/mojo/notifier_id.mojom)12
-rw-r--r--chromium/ui/message_center/public/mojo/notifier_id.typemap (renamed from chromium/ui/message_center/mojo/notifier_id.typemap)9
-rw-r--r--chromium/ui/message_center/public/mojo/notifier_id_struct_traits.cc (renamed from chromium/ui/message_center/mojo/notifier_id_struct_traits.cc)4
-rw-r--r--chromium/ui/message_center/public/mojo/notifier_id_struct_traits.h (renamed from chromium/ui/message_center/mojo/notifier_id_struct_traits.h)10
-rw-r--r--chromium/ui/message_center/public/mojo/struct_traits_unittest.cc (renamed from chromium/ui/message_center/mojo/struct_traits_unittest.cc)25
-rw-r--r--chromium/ui/message_center/public/mojo/traits_test_service.mojom (renamed from chromium/ui/message_center/mojo/traits_test_service.mojom)2
-rw-r--r--chromium/ui/message_center/public/mojo/typemaps.gni (renamed from chromium/ui/message_center/mojo/typemaps.gni)4
-rw-r--r--chromium/ui/message_center/ui_controller.cc30
-rw-r--r--chromium/ui/message_center/ui_controller.h15
-rw-r--r--chromium/ui/message_center/ui_controller_unittest.cc23
-rw-r--r--chromium/ui/message_center/vector_icons/OWNERS1
-rw-r--r--chromium/ui/message_center/vector_icons/notification_inline_reply.icon13
-rw-r--r--chromium/ui/message_center/vector_icons/vector_icons.cc.template6
-rw-r--r--chromium/ui/message_center/views/bounded_label.cc6
-rw-r--r--chromium/ui/message_center/views/bounded_label.h2
-rw-r--r--chromium/ui/message_center/views/constants.h42
-rw-r--r--chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc2
-rw-r--r--chromium/ui/message_center/views/desktop_popup_alignment_delegate.h2
-rw-r--r--chromium/ui/message_center/views/message_popup_collection.cc199
-rw-r--r--chromium/ui/message_center/views/message_popup_collection.h48
-rw-r--r--chromium/ui/message_center/views/message_popup_collection_unittest.cc140
-rw-r--r--chromium/ui/message_center/views/message_view.cc44
-rw-r--r--chromium/ui/message_center/views/message_view.h21
-rw-r--r--chromium/ui/message_center/views/message_view_context_menu_controller.cc6
-rw-r--r--chromium/ui/message_center/views/message_view_factory.cc7
-rw-r--r--chromium/ui/message_center/views/message_view_factory.h3
-rw-r--r--chromium/ui/message_center/views/notification_button.cc37
-rw-r--r--chromium/ui/message_center/views/notification_control_buttons_view.cc13
-rw-r--r--chromium/ui/message_center/views/notification_control_buttons_view.h4
-rw-r--r--chromium/ui/message_center/views/notification_header_view.cc69
-rw-r--r--chromium/ui/message_center/views/notification_header_view.h3
-rw-r--r--chromium/ui/message_center/views/notification_menu_model.h2
-rw-r--r--chromium/ui/message_center/views/notification_menu_model_unittest.cc17
-rw-r--r--chromium/ui/message_center/views/notification_view.cc35
-rw-r--r--chromium/ui/message_center/views/notification_view.h2
-rw-r--r--chromium/ui/message_center/views/notification_view_md.cc550
-rw-r--r--chromium/ui/message_center/views/notification_view_md.h129
-rw-r--r--chromium/ui/message_center/views/notification_view_md_unittest.cc116
-rw-r--r--chromium/ui/message_center/views/notification_view_unittest.cc35
-rw-r--r--chromium/ui/message_center/views/popup_alignment_delegate.cc2
-rw-r--r--chromium/ui/message_center/views/popup_alignment_delegate.h2
-rw-r--r--chromium/ui/message_center/views/proportional_image_view.cc2
-rw-r--r--chromium/ui/message_center/views/toast_contents_view.cc27
-rw-r--r--chromium/ui/message_center/views/toast_contents_view.h5
-rw-r--r--chromium/ui/native_theme/native_theme_aura.cc2
-rw-r--r--chromium/ui/ozone/demo/BUILD.gn8
-rw-r--r--chromium/ui/ozone/demo/gl_renderer.cc77
-rw-r--r--chromium/ui/ozone/demo/gl_renderer.h52
-rw-r--r--chromium/ui/ozone/demo/ozone_demo.cc25
-rw-r--r--chromium/ui/ozone/demo/renderer_base.cc7
-rw-r--r--chromium/ui/ozone/demo/renderer_base.h1
-rw-r--r--chromium/ui/ozone/demo/skia_renderer.cc243
-rw-r--r--chromium/ui/ozone/demo/skia_renderer.h86
-rw-r--r--chromium/ui/ozone/demo/surfaceless_gl_renderer.h74
-rw-r--r--chromium/ui/ozone/demo/surfaceless_skia_renderer.cc (renamed from chromium/ui/ozone/demo/surfaceless_gl_renderer.cc)162
-rw-r--r--chromium/ui/ozone/demo/surfaceless_skia_renderer.h51
-rw-r--r--chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc13
-rw-r--r--chromium/ui/ozone/platform/cast/BUILD.gn2
-rw-r--r--chromium/ui/ozone/platform/cast/DEPS2
-rw-r--r--chromium/ui/ozone/platform/cast/ozone_platform_cast.cc2
-rw-r--r--chromium/ui/ozone/platform/drm/BUILD.gn2
-rw-r--r--chromium/ui/ozone/platform/drm/DEPS1
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc6
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/crtc_controller.h4
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc13
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread.cc18
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread.h12
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc4
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc12
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h2
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.cc6
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.h3
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc85
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h2
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc33
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h7
-rw-r--r--chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc6
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_device_connector.cc137
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_device_connector.h73
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc11
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h4
-rw-r--r--chromium/ui/ozone/platform/drm/host/drm_overlay_manager.h2
-rw-r--r--chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc22
-rw-r--r--chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h15
-rw-r--r--chromium/ui/ozone/platform/drm/host/host_drm_device.cc147
-rw-r--r--chromium/ui/ozone/platform/drm/host/host_drm_device.h56
-rw-r--r--chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc169
-rw-r--r--chromium/ui/ozone/platform/wayland/BUILD.gn8
-rw-r--r--chromium/ui/ozone/platform/wayland/fake_server.cc26
-rw-r--r--chromium/ui/ozone/platform/wayland/fake_server.h16
-rw-r--r--chromium/ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.cc22
-rw-r--r--chromium/ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.h42
-rw-r--r--chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc2
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_connection.cc17
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_connection.h2
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_keyboard.cc106
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_keyboard.h21
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_keyboard_unittest.cc136
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_object.cc14
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_object.h14
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_test.cc4
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_touch.cc167
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_touch.h80
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_touch_unittest.cc89
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_window.cc93
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_window.h10
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_window_unittest.cc174
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.cc17
-rw-r--r--chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h16
-rw-r--r--chromium/ui/ozone/platform/x11/BUILD.gn7
-rw-r--r--chromium/ui/ozone/platform/x11/ozone_platform_x11.cc4
-rw-r--r--chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h2
-rw-r--r--chromium/ui/ozone/platform/x11/x11_cursor_ozone.cc (renamed from chromium/ui/platform_window/x11/x11_cursor_ozone.cc)2
-rw-r--r--chromium/ui/ozone/platform/x11/x11_cursor_ozone.h (renamed from chromium/ui/platform_window/x11/x11_cursor_ozone.h)15
-rw-r--r--chromium/ui/ozone/platform/x11/x11_window_manager_ozone.cc (renamed from chromium/ui/platform_window/x11/x11_window_manager_ozone.cc)4
-rw-r--r--chromium/ui/ozone/platform/x11/x11_window_manager_ozone.h (renamed from chromium/ui/platform_window/x11/x11_window_manager_ozone.h)9
-rw-r--r--chromium/ui/ozone/platform/x11/x11_window_ozone.cc (renamed from chromium/ui/platform_window/x11/x11_window_ozone.cc)6
-rw-r--r--chromium/ui/ozone/platform/x11/x11_window_ozone.h (renamed from chromium/ui/platform_window/x11/x11_window_ozone.h)13
-rw-r--r--chromium/ui/ozone/public/DEPS (renamed from chromium/ui/ozone/public/interfaces/DEPS)0
-rw-r--r--chromium/ui/ozone/public/client_native_pixmap_factory_ozone.cc43
-rw-r--r--chromium/ui/ozone/public/client_native_pixmap_factory_ozone.h7
-rw-r--r--chromium/ui/ozone/public/gpu_platform_support_host.cc4
-rw-r--r--chromium/ui/ozone/public/gpu_platform_support_host.h14
-rw-r--r--chromium/ui/ozone/public/ozone_platform.cc2
-rw-r--r--chromium/ui/ozone/public/ozone_platform.h28
-rw-r--r--chromium/ui/ozone/public/ozone_switches.cc5
-rw-r--r--chromium/ui/ozone/public/ozone_switches.h2
-rw-r--r--chromium/ui/platform_window/x11/BUILD.gn15
-rw-r--r--chromium/ui/platform_window/x11/x11_window.cc2
-rw-r--r--chromium/ui/platform_window/x11/x11_window_base.cc44
-rw-r--r--chromium/ui/platform_window/x11/x11_window_base.h12
-rw-r--r--chromium/ui/resources/default_100_percent/common/easy_unlock_spinner.pngbin18036 -> 14528 bytes
-rw-r--r--chromium/ui/resources/default_100_percent/common/menu_overflow_down.pngbin85 -> 84 bytes
-rw-r--r--chromium/ui/resources/default_100_percent/common/menu_overflow_up.pngbin87 -> 83 bytes
-rw-r--r--chromium/ui/resources/default_100_percent/common/pointers/crosshair.pngbin190 -> 172 bytes
-rw-r--r--chromium/ui/resources/default_100_percent/common/pointers/crosshair_big.pngbin485 -> 428 bytes
-rw-r--r--chromium/ui/resources/default_100_percent/common/pointers/xterm.pngbin302 -> 160 bytes
-rw-r--r--chromium/ui/resources/default_100_percent/common/pointers/xterm_big.pngbin843 -> 446 bytes
-rw-r--r--chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz.pngbin249 -> 159 bytes
-rw-r--r--chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz_big.pngbin717 -> 404 bytes
-rw-r--r--chromium/ui/resources/default_200_percent/common/default_favicon.pngbin127 -> 126 bytes
-rw-r--r--chromium/ui/resources/default_200_percent/common/easy_unlock_spinner.pngbin40877 -> 26655 bytes
-rw-r--r--chromium/ui/resources/default_200_percent/common/menu_overflow_down.pngbin143 -> 142 bytes
-rw-r--r--chromium/ui/resources/default_200_percent/common/pointers/crosshair.pngbin313 -> 280 bytes
-rw-r--r--chromium/ui/resources/default_200_percent/common/pointers/xterm.pngbin493 -> 255 bytes
-rw-r--r--chromium/ui/resources/default_200_percent/common/pointers/xterm_horiz.pngbin463 -> 247 bytes
-rw-r--r--chromium/ui/resources/default_300_percent/common/default_favicon_64.pngbin909 -> 908 bytes
-rw-r--r--chromium/ui/resources/ui_resources.grd2
-rw-r--r--chromium/ui/shell_dialogs/BUILD.gn30
-rw-r--r--chromium/ui/shell_dialogs/run_all_unittests.cc5
-rw-r--r--chromium/ui/shell_dialogs/select_file_dialog_android.cc11
-rw-r--r--chromium/ui/shell_dialogs/select_file_dialog_mac.mm49
-rw-r--r--chromium/ui/shell_dialogs/select_file_dialog_mac_unittest.mm41
-rw-r--r--chromium/ui/snapshot/BUILD.gn1
-rw-r--r--chromium/ui/snapshot/screenshot_grabber.cc133
-rw-r--r--chromium/ui/snapshot/screenshot_grabber.h65
-rw-r--r--chromium/ui/snapshot/screenshot_grabber_observer.h39
-rw-r--r--chromium/ui/snapshot/snapshot.cc2
-rw-r--r--chromium/ui/snapshot/snapshot_android.cc5
-rw-r--r--chromium/ui/strings/translations/ui_strings_am.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_ar.xtb16
-rw-r--r--chromium/ui/strings/translations/ui_strings_bg.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_bn.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_ca.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_cs.xtb14
-rw-r--r--chromium/ui/strings/translations/ui_strings_da.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_de.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_el.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_en-GB.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_es-419.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_es.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_et.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_fa.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_fi.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_fil.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_fr.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_gu.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_hi.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_hr.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_hu.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_id.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_it.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_iw.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_ja.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_kn.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_ko.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_lt.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_lv.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_ml.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_mr.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_ms.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_nl.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_no.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_pl.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_pt-BR.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_pt-PT.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_ro.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_ru.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_sk.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_sl.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_sr.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_sv.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_sw.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_ta.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_te.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_th.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_tr.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_uk.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_vi.xtb16
-rw-r--r--chromium/ui/strings/translations/ui_strings_zh-CN.xtb12
-rw-r--r--chromium/ui/strings/translations/ui_strings_zh-TW.xtb14
-rw-r--r--chromium/ui/strings/ui_strings.grd43
-rw-r--r--chromium/ui/touch_selection/longpress_drag_selector.cc8
-rw-r--r--chromium/ui/touch_selection/touch_handle.cc10
-rw-r--r--chromium/ui/touch_selection/touch_handle_unittest.cc99
-rw-r--r--chromium/ui/touch_selection/touch_selection_controller.cc55
-rw-r--r--chromium/ui/touch_selection/touch_selection_controller.h10
-rw-r--r--chromium/ui/touch_selection/touch_selection_controller_unittest.cc281
-rw-r--r--chromium/ui/views/BUILD.gn14
-rw-r--r--chromium/ui/views/DEPS1
-rw-r--r--chromium/ui/views/accessibility/ax_aura_obj_cache.cc4
-rw-r--r--chromium/ui/views/accessibility/ax_aura_obj_cache.h6
-rw-r--r--chromium/ui/views/accessibility/ax_view_obj_wrapper.cc3
-rw-r--r--chromium/ui/views/accessibility/ax_widget_obj_wrapper.cc2
-rw-r--r--chromium/ui/views/accessibility/ax_window_obj_wrapper.cc63
-rw-r--r--chromium/ui/views/accessibility/native_view_accessibility.h4
-rw-r--r--chromium/ui/views/accessibility/native_view_accessibility_auralinux.cc15
-rw-r--r--chromium/ui/views/accessibility/native_view_accessibility_base.cc51
-rw-r--r--chromium/ui/views/accessibility/native_view_accessibility_base.h12
-rw-r--r--chromium/ui/views/accessibility/native_view_accessibility_unittest.cc30
-rw-r--r--chromium/ui/views/accessibility/native_view_accessibility_win.cc17
-rw-r--r--chromium/ui/views/accessibility/native_view_accessibility_win.h3
-rw-r--r--chromium/ui/views/accessibility/native_view_accessibility_win_unittest.cc123
-rw-r--r--chromium/ui/views/accessibility/view_accessibility.cc90
-rw-r--r--chromium/ui/views/accessibility/view_accessibility.h16
-rw-r--r--chromium/ui/views/accessible_pane_view.cc2
-rw-r--r--chromium/ui/views/animation/bounds_animator.cc79
-rw-r--r--chromium/ui/views/animation/bounds_animator.h29
-rw-r--r--chromium/ui/views/animation/bounds_animator_unittest.cc21
-rw-r--r--chromium/ui/views/animation/ink_drop.h9
-rw-r--r--chromium/ui/views/animation/ink_drop_host_view.cc26
-rw-r--r--chromium/ui/views/animation/ink_drop_host_view.h6
-rw-r--r--chromium/ui/views/animation/ink_drop_impl.cc9
-rw-r--r--chromium/ui/views/animation/ink_drop_impl.h1
-rw-r--r--chromium/ui/views/animation/ink_drop_mask.cc8
-rw-r--r--chromium/ui/views/animation/ink_drop_mask.h4
-rw-r--r--chromium/ui/views/animation/ink_drop_ripple.cc2
-rw-r--r--chromium/ui/views/animation/ink_drop_ripple.h2
-rw-r--r--chromium/ui/views/animation/ink_drop_ripple_unittest.cc10
-rw-r--r--chromium/ui/views/animation/ink_drop_stub.cc2
-rw-r--r--chromium/ui/views/animation/ink_drop_stub.h1
-rw-r--r--chromium/ui/views/bubble/bubble_border.cc78
-rw-r--r--chromium/ui/views/bubble/bubble_border.h30
-rw-r--r--chromium/ui/views/bubble/bubble_dialog_delegate.cc13
-rw-r--r--chromium/ui/views/bubble/tooltip_icon.cc2
-rw-r--r--chromium/ui/views/bubble/tray_bubble_view.cc15
-rw-r--r--chromium/ui/views/cocoa/bridged_native_widget.h4
-rw-r--r--chromium/ui/views/cocoa/bridged_native_widget.mm46
-rw-r--r--chromium/ui/views/cocoa/bridged_native_widget_unittest.mm12
-rw-r--r--chromium/ui/views/controls/button/button.cc29
-rw-r--r--chromium/ui/views/controls/button/button_unittest.cc52
-rw-r--r--chromium/ui/views/controls/button/checkbox.cc43
-rw-r--r--chromium/ui/views/controls/button/checkbox.h6
-rw-r--r--chromium/ui/views/controls/button/image_button.cc9
-rw-r--r--chromium/ui/views/controls/button/image_button.h2
-rw-r--r--chromium/ui/views/controls/button/label_button.cc10
-rw-r--r--chromium/ui/views/controls/button/label_button_unittest.cc56
-rw-r--r--chromium/ui/views/controls/button/md_text_button.h3
-rw-r--r--chromium/ui/views/controls/button/menu_button.cc11
-rw-r--r--chromium/ui/views/controls/button/radio_button.cc2
-rw-r--r--chromium/ui/views/controls/button/toggle_button.cc23
-rw-r--r--chromium/ui/views/controls/combobox/combobox.cc28
-rw-r--r--chromium/ui/views/controls/combobox/combobox_unittest.cc12
-rw-r--r--chromium/ui/views/controls/image_view.cc10
-rw-r--r--chromium/ui/views/controls/image_view.h2
-rw-r--r--chromium/ui/views/controls/image_view_unittest.cc134
-rw-r--r--chromium/ui/views/controls/label.cc43
-rw-r--r--chromium/ui/views/controls/label.h6
-rw-r--r--chromium/ui/views/controls/label_unittest.cc10
-rw-r--r--chromium/ui/views/controls/link.cc2
-rw-r--r--chromium/ui/views/controls/menu/menu_config_win.cc2
-rw-r--r--chromium/ui/views/controls/menu/menu_controller.cc10
-rw-r--r--chromium/ui/views/controls/menu/menu_item_view.cc99
-rw-r--r--chromium/ui/views/controls/menu/menu_item_view.h16
-rw-r--r--chromium/ui/views/controls/menu/menu_item_view_unittest.cc69
-rw-r--r--chromium/ui/views/controls/menu/menu_model_adapter.cc14
-rw-r--r--chromium/ui/views/controls/menu/menu_scroll_view_container.cc2
-rw-r--r--chromium/ui/views/controls/menu/submenu_view.cc15
-rw-r--r--chromium/ui/views/controls/message_box_view.cc7
-rw-r--r--chromium/ui/views/controls/native/native_view_host.cc2
-rw-r--r--chromium/ui/views/controls/progress_bar.cc2
-rw-r--r--chromium/ui/views/controls/progress_bar_unittest.cc8
-rw-r--r--chromium/ui/views/controls/resize_area.cc2
-rw-r--r--chromium/ui/views/controls/scrollbar/base_scroll_bar.cc88
-rw-r--r--chromium/ui/views/controls/scrollbar/base_scroll_bar.h13
-rw-r--r--chromium/ui/views/controls/scrollbar/scroll_bar.cc2
-rw-r--r--chromium/ui/views/controls/separator.cc2
-rw-r--r--chromium/ui/views/controls/slider.cc13
-rw-r--r--chromium/ui/views/controls/slider.h3
-rw-r--r--chromium/ui/views/controls/slider_unittest.cc5
-rw-r--r--chromium/ui/views/controls/styled_label.cc273
-rw-r--r--chromium/ui/views/controls/styled_label.h32
-rw-r--r--chromium/ui/views/controls/styled_label_unittest.cc169
-rw-r--r--chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc441
-rw-r--r--chromium/ui/views/controls/tabbed_pane/tabbed_pane.h41
-rw-r--r--chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc109
-rw-r--r--chromium/ui/views/controls/table/table_view.cc22
-rw-r--r--chromium/ui/views/controls/textfield/textfield.cc71
-rw-r--r--chromium/ui/views/controls/textfield/textfield.h25
-rw-r--r--chromium/ui/views/controls/textfield/textfield_test_api.cc7
-rw-r--r--chromium/ui/views/controls/textfield/textfield_test_api.h4
-rw-r--r--chromium/ui/views/controls/textfield/textfield_unittest.cc58
-rw-r--r--chromium/ui/views/controls/tree/tree_view.cc11
-rw-r--r--chromium/ui/views/controls/views_text_services_context_menu.cc25
-rw-r--r--chromium/ui/views/controls/views_text_services_context_menu.h41
-rw-r--r--chromium/ui/views/controls/views_text_services_context_menu_mac.mm83
-rw-r--r--chromium/ui/views/controls/webview/webview.cc68
-rw-r--r--chromium/ui/views/controls/webview/webview.h7
-rw-r--r--chromium/ui/views/controls/webview/webview_unittest.cc87
-rw-r--r--chromium/ui/views/examples/label_example.cc2
-rw-r--r--chromium/ui/views/mus/BUILD.gn5
-rw-r--r--chromium/ui/views/mus/aura_init.cc4
-rw-r--r--chromium/ui/views/mus/desktop_window_tree_host_mus_unittest.cc8
-rw-r--r--chromium/ui/views/mus/mus_client.cc10
-rw-r--r--chromium/ui/views/mus/views_mus_test_suite.cc11
-rw-r--r--chromium/ui/views/mus/views_mus_test_suite.h3
-rw-r--r--chromium/ui/views/selection_controller.cc5
-rw-r--r--chromium/ui/views/selection_controller.h5
-rw-r--r--chromium/ui/views/style/platform_style.cc7
-rw-r--r--chromium/ui/views/style/platform_style.h8
-rw-r--r--chromium/ui/views/style/platform_style_mac.mm1
-rw-r--r--chromium/ui/views/touchui/touch_selection_menu_runner_views.cc13
-rw-r--r--chromium/ui/views/vector_icons/OWNERS1
-rw-r--r--chromium/ui/views/vector_icons/vector_icons.cc.template6
-rw-r--r--chromium/ui/views/view.cc150
-rw-r--r--chromium/ui/views/view.h28
-rw-r--r--chromium/ui/views/view_unittest.cc21
-rw-r--r--chromium/ui/views/views_delegate.cc3
-rw-r--r--chromium/ui/views/views_delegate.h5
-rw-r--r--chromium/ui/views/views_perftests.cc2
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc4
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc23
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h11
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc64
-rw-r--r--chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h12
-rw-r--r--chromium/ui/views/widget/desktop_aura/window_event_filter.cc7
-rw-r--r--chromium/ui/views/widget/native_widget_aura.cc16
-rw-r--r--chromium/ui/views/widget/native_widget_mac.mm25
-rw-r--r--chromium/ui/views/widget/native_widget_mac_accessibility_unittest.mm59
-rw-r--r--chromium/ui/views/widget/native_widget_mac_unittest.mm70
-rw-r--r--chromium/ui/views/widget/widget.cc2
-rw-r--r--chromium/ui/views/widget/widget.h8
-rw-r--r--chromium/ui/views/widget/widget_delegate.cc12
-rw-r--r--chromium/ui/views/widget/widget_delegate.h8
-rw-r--r--chromium/ui/views/widget/widget_hwnd_utils.cc2
-rw-r--r--chromium/ui/views/widget/widget_interactive_uitest.cc147
-rw-r--r--chromium/ui/views/widget/widget_unittest.cc228
-rw-r--r--chromium/ui/views/win/hwnd_message_handler.cc66
-rw-r--r--chromium/ui/views/win/hwnd_message_handler.h24
-rw-r--r--chromium/ui/views/win/hwnd_message_handler_delegate.h12
-rw-r--r--chromium/ui/views/win/pen_event_processor.cc3
-rw-r--r--chromium/ui/views/window/client_view.cc2
-rw-r--r--chromium/ui/views/window/dialog_client_view.cc8
-rw-r--r--chromium/ui/views/window/dialog_delegate.cc6
-rw-r--r--chromium/ui/views/window/dialog_delegate.h4
-rw-r--r--chromium/ui/views/window/non_client_view.cc4
-rw-r--r--chromium/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.html8
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html2
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/compiled_resources2.gyp7
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_config.html13
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_config.js153
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_config_input.html4
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html1
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js3
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html2
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_property_list.html4
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.html12
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.js57
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html2
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.html4
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.js4
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html4
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/compiled_resources2.gyp16
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.html266
-rw-r--r--chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js416
-rw-r--r--chromium/ui/webui/resources/cr_components/cr_components_resources.grdp11
-rw-r--r--chromium/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js1
-rw-r--r--chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js27
-rw-r--r--chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html1
-rw-r--r--chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js128
-rw-r--r--chromium/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js12
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp1
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html14
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js65
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html17
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html6
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js5
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_icons_css.html2
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html2
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html4
-rw-r--r--chromium/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html2
-rw-r--r--chromium/ui/webui/resources/cr_elements/paper_toggle_style_css.html2
-rw-r--r--chromium/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js2
-rw-r--r--chromium/ui/webui/resources/cr_elements/search_highlight_style_css.html48
-rw-r--r--chromium/ui/webui/resources/cr_elements/shared_style_css.html12
-rw-r--r--chromium/ui/webui/resources/cr_elements/shared_vars_css.html6
-rw-r--r--chromium/ui/webui/resources/cr_elements_resources.grdp4
-rw-r--r--chromium/ui/webui/resources/cr_polymer_resources.grdp47
-rw-r--r--chromium/ui/webui/resources/html/action_link_css.html2
-rw-r--r--chromium/ui/webui/resources/html/search_highlight_utils.html1
-rw-r--r--chromium/ui/webui/resources/images/200-logo_chrome.pngbin2321 -> 2175 bytes
-rw-r--r--chromium/ui/webui/resources/images/200-logo_googleg.pngbin927 -> 612 bytes
-rw-r--r--chromium/ui/webui/resources/images/2x/apps/topbar_button_maximize.pngbin128 -> 127 bytes
-rw-r--r--chromium/ui/webui/resources/images/2x/apps/topbar_button_minimize.pngbin110 -> 109 bytes
-rw-r--r--chromium/ui/webui/resources/images/apps/button_butter_bar_close.pngbin108 -> 103 bytes
-rw-r--r--chromium/ui/webui/resources/images/apps/topbar_button_maximize.pngbin103 -> 101 bytes
-rw-r--r--chromium/ui/webui/resources/images/apps/topbar_button_minimize.pngbin96 -> 94 bytes
-rw-r--r--chromium/ui/webui/resources/images/check.pngbin161 -> 160 bytes
-rw-r--r--chromium/ui/webui/resources/images/checkbox_black.pngbin120 -> 118 bytes
-rw-r--r--chromium/ui/webui/resources/images/disabled_select.pngbin131 -> 130 bytes
-rw-r--r--chromium/ui/webui/resources/images/select.pngbin139 -> 138 bytes
-rw-r--r--chromium/ui/webui/resources/js/compiled_resources2.gyp7
-rw-r--r--chromium/ui/webui/resources/js/cr/ui/tree.js2
-rw-r--r--chromium/ui/webui/resources/js/icon.js7
-rw-r--r--chromium/ui/webui/resources/js/search_highlight_utils.js130
-rw-r--r--chromium/ui/webui/resources/js/util.js2
-rw-r--r--chromium/ui/webui/resources/polymer_resources.grdp44
-rw-r--r--chromium/ui/webui/resources/webui_resources.grd35
-rw-r--r--chromium/ui/wm/core/shadow.cc20
-rw-r--r--chromium/ui/wm/core/shadow.h14
-rw-r--r--chromium/ui/wm/core/shadow_controller.cc96
-rw-r--r--chromium/ui/wm/core/shadow_controller.h4
-rw-r--r--chromium/ui/wm/core/shadow_controller_unittest.cc31
-rw-r--r--chromium/ui/wm/core/shadow_types.cc21
-rw-r--r--chromium/ui/wm/core/shadow_types.h43
-rw-r--r--chromium/ui/wm/core/shadow_unittest.cc20
-rw-r--r--chromium/ui/wm/core/window_util.cc5
875 files changed, 24460 insertions, 11721 deletions
diff --git a/chromium/ui/PRESUBMIT.py b/chromium/ui/PRESUBMIT.py
index 7c0c787afbd..810c0919e1f 100644
--- a/chromium/ui/PRESUBMIT.py
+++ b/chromium/ui/PRESUBMIT.py
@@ -8,39 +8,6 @@ See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details about the presubmit API built into depot_tools.
"""
-INCLUDE_CPP_FILES_ONLY = (
- r'.*\.(cc|h|mm)$',
-)
-
-def CheckUniquePtr(input_api, output_api,
- white_list=INCLUDE_CPP_FILES_ONLY, black_list=None):
- black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST)
- source_file_filter = lambda x: input_api.FilterSourceFile(x,
- white_list,
- black_list)
- errors = []
- for f in input_api.AffectedSourceFiles(source_file_filter):
- for line_number, line in f.ChangedContents():
- # Disallow:
- # return std::unique_ptr<T>(foo);
- # bar = std::unique_ptr<T>(foo);
- # But allow:
- # return std::unique_ptr<T[]>(foo);
- # bar = std::unique_ptr<T[]>(foo);
- if input_api.re.search(
- r'(=|\breturn)\s*std::unique_ptr<[^\[\]>]+>\([^)]+\)', line):
- errors.append(output_api.PresubmitError(
- ('%s:%d uses explicit std::unique_ptr constructor. ' +
- 'Use std::make_unique<T>() or base::WrapUnique() instead.') %
- (f.LocalPath(), line_number)))
- # Disallow:
- # std::unique_ptr<T>()
- if input_api.re.search(r'\bstd::unique_ptr<[^<>]+>\(\)', line):
- errors.append(output_api.PresubmitError(
- '%s:%d uses std::unique_ptr<T>(). Use nullptr instead.' %
- (f.LocalPath(), line_number)))
- return errors
-
def CheckX11HeaderUsage(input_api, output_api):
"""X11 headers pollute the global namespace with macros for common
names so instead code should include "ui/gfx/x/x11.h" which hide the
@@ -68,7 +35,6 @@ dangerous macros inside the x11 namespace."""
def CheckChange(input_api, output_api):
results = []
- results += CheckUniquePtr(input_api, output_api)
results += CheckX11HeaderUsage(input_api, output_api)
return results
diff --git a/chromium/ui/accelerated_widget_mac/accelerated_widget_mac.mm b/chromium/ui/accelerated_widget_mac/accelerated_widget_mac.mm
index 7ff59beee63..8306398431d 100644
--- a/chromium/ui/accelerated_widget_mac/accelerated_widget_mac.mm
+++ b/chromium/ui/accelerated_widget_mac/accelerated_widget_mac.mm
@@ -6,6 +6,7 @@
#include <map>
+#include "base/debug/dump_without_crashing.h"
#include "base/lazy_instance.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
@@ -24,6 +25,10 @@
namespace ui {
namespace {
+// The maximum number of times to dump before throttling (to avoid sending
+// thousands of crash dumps).
+const int kMaxCrashDumps = 10;
+
typedef std::map<gfx::AcceleratedWidget,AcceleratedWidgetMac*>
WidgetToHelperMap;
base::LazyInstance<WidgetToHelperMap>::DestructorAtExit g_widget_to_helper_map;
@@ -148,14 +153,24 @@ void AcceleratedWidgetMac::UpdateCALayerTree(
GotCALayerFrame(base::scoped_nsobject<CALayer>(remote_layer_.get(),
base::scoped_policy::RETAIN),
ca_layer_params.pixel_size, ca_layer_params.scale_factor);
- } else {
+ } else if (ca_layer_params.io_surface_mach_port) {
base::ScopedCFTypeRef<IOSurfaceRef> io_surface(
IOSurfaceLookupFromMachPort(ca_layer_params.io_surface_mach_port));
if (!io_surface) {
LOG(ERROR) << "Unable to open IOSurface for frame.";
+ static int dump_counter = kMaxCrashDumps;
+ if (dump_counter) {
+ dump_counter -= 1;
+ base::debug::DumpWithoutCrashing();
+ }
}
GotIOSurfaceFrame(io_surface, ca_layer_params.pixel_size,
ca_layer_params.scale_factor);
+ } else {
+ LOG(ERROR) << "Frame had neither valid CAContext nor valid IOSurface.";
+ base::ScopedCFTypeRef<IOSurfaceRef> io_surface;
+ GotIOSurfaceFrame(io_surface, ca_layer_params.pixel_size,
+ ca_layer_params.scale_factor);
}
if (view_)
view_->AcceleratedWidgetSwapCompleted();
diff --git a/chromium/ui/accessibility/BUILD.gn b/chromium/ui/accessibility/BUILD.gn
index b5a6c772be0..d497360d8d8 100644
--- a/chromium/ui/accessibility/BUILD.gn
+++ b/chromium/ui/accessibility/BUILD.gn
@@ -6,6 +6,7 @@ import("//build/config/linux/gtk/gtk.gni")
import("//build/config/linux/pkg_config.gni")
import("//build/config/features.gni")
import("//build/config/ui.gni")
+import("//mojo/public/tools/bindings/mojom.gni")
import("//testing/libfuzzer/fuzzer_test.gni")
import("//testing/test.gni")
import("//tools/json_schema_compiler/json_schema_api.gni")
@@ -15,10 +16,18 @@ if (is_android) {
import("//build/config/android/rules.gni")
}
+mojom("ax_enums_mojo") {
+ sources = [
+ "ax_enums.mojom",
+ ]
+}
+
component("accessibility") {
sources = [
"ax_action_data.cc",
"ax_action_data.h",
+ "ax_enum_util.cc",
+ "ax_enum_util.h",
"ax_event_generator.cc",
"ax_event_generator.h",
"ax_export.h",
@@ -81,7 +90,7 @@ component("accessibility") {
defines = [ "ACCESSIBILITY_IMPLEMENTATION" ]
public_deps = [
- ":ax_gen",
+ ":ax_enums_mojo",
"//base",
"//base:i18n",
"//ui/base",
@@ -134,21 +143,6 @@ component("accessibility") {
}
}
-if (is_android) {
- android_library("ui_accessibility_java") {
- deps = [
- "//third_party/android_tools:android_support_annotations_java",
- ]
- srcjar_deps = [ ":ax_enumerations_srcjar" ]
- }
-
- java_cpp_enum("ax_enumerations_srcjar") {
- sources = [
- "ax_enums.idl",
- ]
- }
-}
-
static_library("test_support") {
testonly = true
sources = [
@@ -186,7 +180,7 @@ test("accessibility_unittests") {
deps = [
":accessibility",
- ":ax_gen",
+ ":ax_enums_mojo",
":test_support",
"//base",
"//base/test:run_all_unittests",
@@ -207,17 +201,6 @@ test("accessibility_unittests") {
}
}
-json_schema_api("ax_gen") {
- sources = [
- "ax_enums.idl",
- ]
- deps = [
- "//base/third_party/dynamic_annotations",
- ]
- root_namespace = "ui"
- schemas = true
-}
-
fuzzer_test("ax_tree_fuzzer") {
sources = [
"ax_tree_fuzzer.cc",
diff --git a/chromium/ui/accessibility/OWNERS b/chromium/ui/accessibility/OWNERS
index 72709ebff2a..bdb5819a93b 100644
--- a/chromium/ui/accessibility/OWNERS
+++ b/chromium/ui/accessibility/OWNERS
@@ -5,5 +5,8 @@ nektar@chromium.org
dougt@chromium.org
aleventhal@chromium.org
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
# TEAM: chromium-accessibility@chromium.org
# COMPONENT: Internals>Accessibility
diff --git a/chromium/ui/accessibility/PRESUBMIT.py b/chromium/ui/accessibility/PRESUBMIT.py
index f953d4f98a6..500b1cc607e 100644
--- a/chromium/ui/accessibility/PRESUBMIT.py
+++ b/chromium/ui/accessibility/PRESUBMIT.py
@@ -4,9 +4,9 @@
"""Presubmit script for ui/accessibility."""
-import os, re
+import os, re, json
-AX_IDL = 'ui/accessibility/ax_enums.idl'
+AX_MOJOM = 'ui/accessibility/ax_enums.mojom'
AUTOMATION_IDL = 'chrome/common/extensions/api/automation.idl'
AX_JS_FILE = 'content/browser/resources/accessibility/accessibility.js'
@@ -16,7 +16,15 @@ def InitialLowerCamelCase(unix_name):
words = unix_name.split('_')
return words[0] + ''.join(word.capitalize() for word in words[1:])
-# Given a full path to an IDL file containing enum definitions,
+def CamelToLowerHacker(str):
+ out = ''
+ for i in range(len(str)):
+ if str[i] >= 'A' and str[i] <= 'Z' and out:
+ out += '_'
+ out += str[i]
+ return out.lower()
+
+# Given a full path to an IDL or MOJOM file containing enum definitions,
# parse the file for enums and return a dict mapping the enum name
# to a list of values for that enum.
def GetEnumsFromFile(fullpath):
@@ -45,7 +53,15 @@ def GetEnumsFromFile(fullpath):
m = re.search('([\w]+)', line)
if m:
enums.setdefault(enum_name, [])
- enums[enum_name].append(m.group(1))
+ enum_value = m.group(1)
+ if (enum_value[0] == 'k' and
+ enum_value[1] == enum_value[1].upper()):
+ enum_value = CamelToLowerHacker(enum_value[1:])
+ if enum_value == 'none' or enum_value == 'last':
+ continue
+ if enum_value == 'active_descendant_changed':
+ enum_value = 'activedescendantchanged'
+ enums[enum_name].append(enum_value)
return enums
@@ -57,7 +73,7 @@ def CheckMatchingEnum(ax_enums,
output_api):
if ax_enum_name not in ax_enums:
errs.append(output_api.PresubmitError(
- 'Expected %s to have an enum named %s' % (AX_IDL, ax_enum_name)))
+ 'Expected %s to have an enum named %s' % (AX_MOJOM, ax_enum_name)))
return
if automation_enum_name not in automation_enums:
errs.append(output_api.PresubmitError(
@@ -73,7 +89,7 @@ def CheckMatchingEnum(ax_enums,
else:
errs.append(output_api.PresubmitError(
'Found %s.%s in %s, but did not find %s.%s in %s' % (
- ax_enum_name, value, AX_IDL,
+ ax_enum_name, value, AX_MOJOM,
automation_enum_name, InitialLowerCamelCase(value),
AUTOMATION_IDL)))
# Should be no remaining items
@@ -82,11 +98,11 @@ def CheckMatchingEnum(ax_enums,
'Found %s.%s in %s, but did not find %s.%s in %s' % (
automation_enum_name, value, AUTOMATION_IDL,
ax_enum_name, InitialLowerCamelCase(value),
- AX_IDL)))
+ AX_MOJOM)))
def CheckEnumsMatch(input_api, output_api):
repo_root = input_api.change.RepositoryRoot()
- ax_enums = GetEnumsFromFile(os.path.join(repo_root, AX_IDL))
+ ax_enums = GetEnumsFromFile(os.path.join(repo_root, AX_MOJOM))
automation_enums = GetEnumsFromFile(os.path.join(repo_root, AUTOMATION_IDL))
# Focused state only exists in automation.
@@ -95,15 +111,15 @@ def CheckEnumsMatch(input_api, output_api):
automation_enums['StateType'].remove('offscreen')
errs = []
- CheckMatchingEnum(ax_enums, 'AXRole', automation_enums, 'RoleType', errs,
+ CheckMatchingEnum(ax_enums, 'Role', automation_enums, 'RoleType', errs,
output_api)
- CheckMatchingEnum(ax_enums, 'AXState', automation_enums, 'StateType', errs,
+ CheckMatchingEnum(ax_enums, 'State', automation_enums, 'StateType', errs,
output_api)
- CheckMatchingEnum(ax_enums, 'AXEvent', automation_enums, 'EventType', errs,
+ CheckMatchingEnum(ax_enums, 'Event', automation_enums, 'EventType', errs,
output_api)
- CheckMatchingEnum(ax_enums, 'AXNameFrom', automation_enums, 'NameFromType',
+ CheckMatchingEnum(ax_enums, 'NameFrom', automation_enums, 'NameFromType',
errs, output_api)
- CheckMatchingEnum(ax_enums, 'AXRestriction', automation_enums,
+ CheckMatchingEnum(ax_enums, 'Restriction', automation_enums,
'Restriction', errs, output_api)
return errs
@@ -180,7 +196,7 @@ def CheckChangeOnUpload(input_api, output_api):
errs = []
for path in input_api.LocalPaths():
path = path.replace('\\', '/')
- if AX_IDL == path:
+ if AX_MOJOM == path:
errs.extend(CheckEnumsMatch(input_api, output_api))
if AX_MODE_HEADER == path:
@@ -192,10 +208,14 @@ def CheckChangeOnCommit(input_api, output_api):
errs = []
for path in input_api.LocalPaths():
path = path.replace('\\', '/')
- if AX_IDL == path:
+ if AX_MOJOM == path:
errs.extend(CheckEnumsMatch(input_api, output_api))
if AX_MODE_HEADER == path:
errs.extend(CheckModesMatch(input_api, output_api))
return errs
+
+# Run this script directly to dump its keys, for debugging.
+if __name__ == '__main__':
+ print json.dumps(GetEnumsFromFile(AX_MOJOM), sort_keys=True, indent=4)
diff --git a/chromium/ui/accessibility/ax_action_data.cc b/chromium/ui/accessibility/ax_action_data.cc
index bca145a9119..3024f145491 100644
--- a/chromium/ui/accessibility/ax_action_data.cc
+++ b/chromium/ui/accessibility/ax_action_data.cc
@@ -10,6 +10,7 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "ui/accessibility/ax_enum_util.h"
using base::IntToString;
@@ -19,18 +20,27 @@ AXActionData::AXActionData() = default;
AXActionData::AXActionData(const AXActionData& other) = default;
AXActionData::~AXActionData() = default;
+namespace {
+
+bool IsFlagSet(uint32_t bitfield, ax::mojom::ActionFlags flag) {
+ return 0 != (bitfield & (1 << static_cast<uint32_t>(flag)));
+}
+
+} // namespace
+
// Note that this includes an initial space character if nonempty, but
-// that works fine because this is normally printed by AXAction::ToString.
+// that works fine because this is normally printed by
+// ax::mojom::Action::ToString.
std::string AXActionData::ToString() const {
std::string result = ui::ToString(action);
if (target_node_id != -1)
result += " target_node_id=" + IntToString(target_node_id);
- if (flags & (1 << ui::AX_ACTION_FLAGS_REQUEST_IMAGES))
+ if (IsFlagSet(flags, ax::mojom::ActionFlags::kRequestImages))
result += " flag_request_images";
- if (flags & (1 << ui::AX_ACTION_FLAGS_REQUEST_INLINE_TEXT_BOXES))
+ if (IsFlagSet(flags, ax::mojom::ActionFlags::kRequestInlineTextBoxes))
result += " flag_request_inline_text_boxes";
if (anchor_node_id != -1) {
diff --git a/chromium/ui/accessibility/ax_action_data.h b/chromium/ui/accessibility/ax_action_data.h
index 5cd03eed7a3..37efaffb9cc 100644
--- a/chromium/ui/accessibility/ax_action_data.h
+++ b/chromium/ui/accessibility/ax_action_data.h
@@ -6,7 +6,7 @@
#define UI_ACCESSIBILITY_AX_ACTION_DATA_H_
#include "base/strings/string16.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_export.h"
#include "ui/gfx/geometry/rect.h"
@@ -25,11 +25,11 @@ struct AX_EXPORT AXActionData {
// This is a simple serializable struct. All member variables should be
// public and copyable.
- // See the AXAction enums in ax_enums.idl for explanations of which
+ // See the ax::mojom::Action enums in ax_enums.idl for explanations of which
// parameters apply.
// The action to take.
- AXAction action = AX_ACTION_NONE;
+ ax::mojom::Action action = ax::mojom::Action::kNone;
// The ID of the tree that this action should be performed on.
int target_tree_id = -1;
@@ -43,7 +43,7 @@ struct AX_EXPORT AXActionData {
// The request id of this action tracked by the client.
int request_id = -1;
- // Use enums from AXActionFlags
+ // Use enums from ax::mojom::ActionFlags
int flags = 0;
// For an action that creates a selection, the selection anchor and focus
@@ -67,7 +67,7 @@ struct AX_EXPORT AXActionData {
base::string16 value;
// The event to fire in response to a HIT_TEST action.
- AXEvent hit_test_event_to_fire = AX_EVENT_NONE;
+ ax::mojom::Event hit_test_event_to_fire = ax::mojom::Event::kNone;
};
} // namespace ui
diff --git a/chromium/ui/accessibility/ax_enum_util.cc b/chromium/ui/accessibility/ax_enum_util.cc
new file mode 100644
index 00000000000..f47b11a714e
--- /dev/null
+++ b/chromium/ui/accessibility/ax_enum_util.cc
@@ -0,0 +1,2233 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/accessibility/ax_enum_util.h"
+
+namespace ui {
+
+const char* ToString(ax::mojom::Event event) {
+ switch (event) {
+ case ax::mojom::Event::kNone:
+ return "none";
+ case ax::mojom::Event::kActiveDescendantChanged:
+ return "activedescendantchanged";
+ case ax::mojom::Event::kAlert:
+ return "alert";
+ case ax::mojom::Event::kAriaAttributeChanged:
+ return "ariaAttributeChanged";
+ case ax::mojom::Event::kAutocorrectionOccured:
+ return "autocorrectionOccured";
+ case ax::mojom::Event::kBlur:
+ return "blur";
+ case ax::mojom::Event::kCheckedStateChanged:
+ return "checkedStateChanged";
+ case ax::mojom::Event::kChildrenChanged:
+ return "childrenChanged";
+ case ax::mojom::Event::kClicked:
+ return "clicked";
+ case ax::mojom::Event::kDocumentSelectionChanged:
+ return "documentSelectionChanged";
+ case ax::mojom::Event::kExpandedChanged:
+ return "expandedChanged";
+ case ax::mojom::Event::kFocus:
+ return "focus";
+ case ax::mojom::Event::kHide:
+ return "hide";
+ case ax::mojom::Event::kHitTestResult:
+ return "hitTestResult";
+ case ax::mojom::Event::kHover:
+ return "hover";
+ case ax::mojom::Event::kImageFrameUpdated:
+ return "imageFrameUpdated";
+ case ax::mojom::Event::kInvalidStatusChanged:
+ return "invalidStatusChanged";
+ case ax::mojom::Event::kLayoutComplete:
+ return "layoutComplete";
+ case ax::mojom::Event::kLiveRegionCreated:
+ return "liveRegionCreated";
+ case ax::mojom::Event::kLiveRegionChanged:
+ return "liveRegionChanged";
+ case ax::mojom::Event::kLoadComplete:
+ return "loadComplete";
+ case ax::mojom::Event::kLocationChanged:
+ return "locationChanged";
+ case ax::mojom::Event::kMediaStartedPlaying:
+ return "mediaStartedPlaying";
+ case ax::mojom::Event::kMediaStoppedPlaying:
+ return "mediaStoppedPlaying";
+ case ax::mojom::Event::kMenuEnd:
+ return "menuEnd";
+ case ax::mojom::Event::kMenuListItemSelected:
+ return "menuListItemSelected";
+ case ax::mojom::Event::kMenuListValueChanged:
+ return "menuListValueChanged";
+ case ax::mojom::Event::kMenuPopupEnd:
+ return "menuPopupEnd";
+ case ax::mojom::Event::kMenuPopupStart:
+ return "menuPopupStart";
+ case ax::mojom::Event::kMenuStart:
+ return "menuStart";
+ case ax::mojom::Event::kMouseCanceled:
+ return "mouseCanceled";
+ case ax::mojom::Event::kMouseDragged:
+ return "mouseDragged";
+ case ax::mojom::Event::kMouseMoved:
+ return "mouseMoved";
+ case ax::mojom::Event::kMousePressed:
+ return "mousePressed";
+ case ax::mojom::Event::kMouseReleased:
+ return "mouseReleased";
+ case ax::mojom::Event::kRowCollapsed:
+ return "rowCollapsed";
+ case ax::mojom::Event::kRowCountChanged:
+ return "rowCountChanged";
+ case ax::mojom::Event::kRowExpanded:
+ return "rowExpanded";
+ case ax::mojom::Event::kScrollPositionChanged:
+ return "scrollPositionChanged";
+ case ax::mojom::Event::kScrolledToAnchor:
+ return "scrolledToAnchor";
+ case ax::mojom::Event::kSelectedChildrenChanged:
+ return "selectedChildrenChanged";
+ case ax::mojom::Event::kSelection:
+ return "selection";
+ case ax::mojom::Event::kSelectionAdd:
+ return "selectionAdd";
+ case ax::mojom::Event::kSelectionRemove:
+ return "selectionRemove";
+ case ax::mojom::Event::kShow:
+ return "show";
+ case ax::mojom::Event::kTextChanged:
+ return "textChanged";
+ case ax::mojom::Event::kTextSelectionChanged:
+ return "textSelectionChanged";
+ case ax::mojom::Event::kTreeChanged:
+ return "treeChanged";
+ case ax::mojom::Event::kValueChanged:
+ return "valueChanged";
+ }
+
+ return "";
+}
+
+ax::mojom::Event ParseEvent(const char* event) {
+ if (0 == strcmp(event, "none"))
+ return ax::mojom::Event::kNone;
+ if (0 == strcmp(event, "activedescendantchanged"))
+ return ax::mojom::Event::kActiveDescendantChanged;
+ if (0 == strcmp(event, "alert"))
+ return ax::mojom::Event::kAlert;
+ if (0 == strcmp(event, "ariaAttributeChanged"))
+ return ax::mojom::Event::kAriaAttributeChanged;
+ if (0 == strcmp(event, "autocorrectionOccured"))
+ return ax::mojom::Event::kAutocorrectionOccured;
+ if (0 == strcmp(event, "blur"))
+ return ax::mojom::Event::kBlur;
+ if (0 == strcmp(event, "checkedStateChanged"))
+ return ax::mojom::Event::kCheckedStateChanged;
+ if (0 == strcmp(event, "childrenChanged"))
+ return ax::mojom::Event::kChildrenChanged;
+ if (0 == strcmp(event, "clicked"))
+ return ax::mojom::Event::kClicked;
+ if (0 == strcmp(event, "documentSelectionChanged"))
+ return ax::mojom::Event::kDocumentSelectionChanged;
+ if (0 == strcmp(event, "expandedChanged"))
+ return ax::mojom::Event::kExpandedChanged;
+ if (0 == strcmp(event, "focus"))
+ return ax::mojom::Event::kFocus;
+ if (0 == strcmp(event, "hide"))
+ return ax::mojom::Event::kHide;
+ if (0 == strcmp(event, "hitTestResult"))
+ return ax::mojom::Event::kHitTestResult;
+ if (0 == strcmp(event, "hover"))
+ return ax::mojom::Event::kHover;
+ if (0 == strcmp(event, "imageFrameUpdated"))
+ return ax::mojom::Event::kImageFrameUpdated;
+ if (0 == strcmp(event, "invalidStatusChanged"))
+ return ax::mojom::Event::kInvalidStatusChanged;
+ if (0 == strcmp(event, "layoutComplete"))
+ return ax::mojom::Event::kLayoutComplete;
+ if (0 == strcmp(event, "liveRegionCreated"))
+ return ax::mojom::Event::kLiveRegionCreated;
+ if (0 == strcmp(event, "liveRegionChanged"))
+ return ax::mojom::Event::kLiveRegionChanged;
+ if (0 == strcmp(event, "loadComplete"))
+ return ax::mojom::Event::kLoadComplete;
+ if (0 == strcmp(event, "locationChanged"))
+ return ax::mojom::Event::kLocationChanged;
+ if (0 == strcmp(event, "mediaStartedPlaying"))
+ return ax::mojom::Event::kMediaStartedPlaying;
+ if (0 == strcmp(event, "mediaStoppedPlaying"))
+ return ax::mojom::Event::kMediaStoppedPlaying;
+ if (0 == strcmp(event, "menuEnd"))
+ return ax::mojom::Event::kMenuEnd;
+ if (0 == strcmp(event, "menuListItemSelected"))
+ return ax::mojom::Event::kMenuListItemSelected;
+ if (0 == strcmp(event, "menuListValueChanged"))
+ return ax::mojom::Event::kMenuListValueChanged;
+ if (0 == strcmp(event, "menuPopupEnd"))
+ return ax::mojom::Event::kMenuPopupEnd;
+ if (0 == strcmp(event, "menuPopupStart"))
+ return ax::mojom::Event::kMenuPopupStart;
+ if (0 == strcmp(event, "menuStart"))
+ return ax::mojom::Event::kMenuStart;
+ if (0 == strcmp(event, "mouseCanceled"))
+ return ax::mojom::Event::kMouseCanceled;
+ if (0 == strcmp(event, "mouseDragged"))
+ return ax::mojom::Event::kMouseDragged;
+ if (0 == strcmp(event, "mouseMoved"))
+ return ax::mojom::Event::kMouseMoved;
+ if (0 == strcmp(event, "mousePressed"))
+ return ax::mojom::Event::kMousePressed;
+ if (0 == strcmp(event, "mouseReleased"))
+ return ax::mojom::Event::kMouseReleased;
+ if (0 == strcmp(event, "rowCollapsed"))
+ return ax::mojom::Event::kRowCollapsed;
+ if (0 == strcmp(event, "rowCountChanged"))
+ return ax::mojom::Event::kRowCountChanged;
+ if (0 == strcmp(event, "rowExpanded"))
+ return ax::mojom::Event::kRowExpanded;
+ if (0 == strcmp(event, "scrollPositionChanged"))
+ return ax::mojom::Event::kScrollPositionChanged;
+ if (0 == strcmp(event, "scrolledToAnchor"))
+ return ax::mojom::Event::kScrolledToAnchor;
+ if (0 == strcmp(event, "selectedChildrenChanged"))
+ return ax::mojom::Event::kSelectedChildrenChanged;
+ if (0 == strcmp(event, "selection"))
+ return ax::mojom::Event::kSelection;
+ if (0 == strcmp(event, "selectionAdd"))
+ return ax::mojom::Event::kSelectionAdd;
+ if (0 == strcmp(event, "selectionRemove"))
+ return ax::mojom::Event::kSelectionRemove;
+ if (0 == strcmp(event, "show"))
+ return ax::mojom::Event::kShow;
+ if (0 == strcmp(event, "textChanged"))
+ return ax::mojom::Event::kTextChanged;
+ if (0 == strcmp(event, "textSelectionChanged"))
+ return ax::mojom::Event::kTextSelectionChanged;
+ if (0 == strcmp(event, "treeChanged"))
+ return ax::mojom::Event::kTreeChanged;
+ if (0 == strcmp(event, "valueChanged"))
+ return ax::mojom::Event::kValueChanged;
+ return ax::mojom::Event::kNone;
+}
+
+const char* ToString(ax::mojom::Role role) {
+ switch (role) {
+ case ax::mojom::Role::kNone:
+ return "none";
+ case ax::mojom::Role::kAbbr:
+ return "abbr";
+ case ax::mojom::Role::kAlertDialog:
+ return "alertDialog";
+ case ax::mojom::Role::kAlert:
+ return "alert";
+ case ax::mojom::Role::kAnchor:
+ return "anchor";
+ case ax::mojom::Role::kAnnotation:
+ return "annotation";
+ case ax::mojom::Role::kApplication:
+ return "application";
+ case ax::mojom::Role::kArticle:
+ return "article";
+ case ax::mojom::Role::kAudio:
+ return "audio";
+ case ax::mojom::Role::kBanner:
+ return "banner";
+ case ax::mojom::Role::kBlockquote:
+ return "blockquote";
+ case ax::mojom::Role::kButton:
+ return "button";
+ case ax::mojom::Role::kCanvas:
+ return "canvas";
+ case ax::mojom::Role::kCaption:
+ return "caption";
+ case ax::mojom::Role::kCaret:
+ return "caret";
+ case ax::mojom::Role::kCell:
+ return "cell";
+ case ax::mojom::Role::kCheckBox:
+ return "checkBox";
+ case ax::mojom::Role::kClient:
+ return "client";
+ case ax::mojom::Role::kColorWell:
+ return "colorWell";
+ case ax::mojom::Role::kColumnHeader:
+ return "columnHeader";
+ case ax::mojom::Role::kColumn:
+ return "column";
+ case ax::mojom::Role::kComboBoxGrouping:
+ return "comboBoxGrouping";
+ case ax::mojom::Role::kComboBoxMenuButton:
+ return "comboBoxMenuButton";
+ case ax::mojom::Role::kComplementary:
+ return "complementary";
+ case ax::mojom::Role::kContentInfo:
+ return "contentInfo";
+ case ax::mojom::Role::kDate:
+ return "date";
+ case ax::mojom::Role::kDateTime:
+ return "dateTime";
+ case ax::mojom::Role::kDefinition:
+ return "definition";
+ case ax::mojom::Role::kDescriptionListDetail:
+ return "descriptionListDetail";
+ case ax::mojom::Role::kDescriptionList:
+ return "descriptionList";
+ case ax::mojom::Role::kDescriptionListTerm:
+ return "descriptionListTerm";
+ case ax::mojom::Role::kDesktop:
+ return "desktop";
+ case ax::mojom::Role::kDetails:
+ return "details";
+ case ax::mojom::Role::kDialog:
+ return "dialog";
+ case ax::mojom::Role::kDirectory:
+ return "directory";
+ case ax::mojom::Role::kDisclosureTriangle:
+ return "disclosureTriangle";
+ case ax::mojom::Role::kDocument:
+ return "document";
+ case ax::mojom::Role::kEmbeddedObject:
+ return "embeddedObject";
+ case ax::mojom::Role::kFeed:
+ return "feed";
+ case ax::mojom::Role::kFigcaption:
+ return "figcaption";
+ case ax::mojom::Role::kFigure:
+ return "figure";
+ case ax::mojom::Role::kFooter:
+ return "footer";
+ case ax::mojom::Role::kForm:
+ return "form";
+ case ax::mojom::Role::kGenericContainer:
+ return "genericContainer";
+ case ax::mojom::Role::kGrid:
+ return "grid";
+ case ax::mojom::Role::kGroup:
+ return "group";
+ case ax::mojom::Role::kHeading:
+ return "heading";
+ case ax::mojom::Role::kIframe:
+ return "iframe";
+ case ax::mojom::Role::kIframePresentational:
+ return "iframePresentational";
+ case ax::mojom::Role::kIgnored:
+ return "ignored";
+ case ax::mojom::Role::kImageMap:
+ return "imageMap";
+ case ax::mojom::Role::kImage:
+ return "image";
+ case ax::mojom::Role::kInlineTextBox:
+ return "inlineTextBox";
+ case ax::mojom::Role::kInputTime:
+ return "inputTime";
+ case ax::mojom::Role::kLabelText:
+ return "labelText";
+ case ax::mojom::Role::kLayoutTable:
+ return "layoutTable";
+ case ax::mojom::Role::kLayoutTableCell:
+ return "layoutTableCell";
+ case ax::mojom::Role::kLayoutTableColumn:
+ return "layoutTableColumn";
+ case ax::mojom::Role::kLayoutTableRow:
+ return "layoutTableRow";
+ case ax::mojom::Role::kLegend:
+ return "legend";
+ case ax::mojom::Role::kLineBreak:
+ return "lineBreak";
+ case ax::mojom::Role::kLink:
+ return "link";
+ case ax::mojom::Role::kListBoxOption:
+ return "listBoxOption";
+ case ax::mojom::Role::kListBox:
+ return "listBox";
+ case ax::mojom::Role::kListItem:
+ return "listItem";
+ case ax::mojom::Role::kListMarker:
+ return "listMarker";
+ case ax::mojom::Role::kList:
+ return "list";
+ case ax::mojom::Role::kLocationBar:
+ return "locationBar";
+ case ax::mojom::Role::kLog:
+ return "log";
+ case ax::mojom::Role::kMain:
+ return "main";
+ case ax::mojom::Role::kMark:
+ return "mark";
+ case ax::mojom::Role::kMarquee:
+ return "marquee";
+ case ax::mojom::Role::kMath:
+ return "math";
+ case ax::mojom::Role::kMenu:
+ return "menu";
+ case ax::mojom::Role::kMenuBar:
+ return "menuBar";
+ case ax::mojom::Role::kMenuButton:
+ return "menuButton";
+ case ax::mojom::Role::kMenuItem:
+ return "menuItem";
+ case ax::mojom::Role::kMenuItemCheckBox:
+ return "menuItemCheckBox";
+ case ax::mojom::Role::kMenuItemRadio:
+ return "menuItemRadio";
+ case ax::mojom::Role::kMenuListOption:
+ return "menuListOption";
+ case ax::mojom::Role::kMenuListPopup:
+ return "menuListPopup";
+ case ax::mojom::Role::kMeter:
+ return "meter";
+ case ax::mojom::Role::kNavigation:
+ return "navigation";
+ case ax::mojom::Role::kNote:
+ return "note";
+ case ax::mojom::Role::kPane:
+ return "pane";
+ case ax::mojom::Role::kParagraph:
+ return "paragraph";
+ case ax::mojom::Role::kPopUpButton:
+ return "popUpButton";
+ case ax::mojom::Role::kPre:
+ return "pre";
+ case ax::mojom::Role::kPresentational:
+ return "presentational";
+ case ax::mojom::Role::kProgressIndicator:
+ return "progressIndicator";
+ case ax::mojom::Role::kRadioButton:
+ return "radioButton";
+ case ax::mojom::Role::kRadioGroup:
+ return "radioGroup";
+ case ax::mojom::Role::kRegion:
+ return "region";
+ case ax::mojom::Role::kRootWebArea:
+ return "rootWebArea";
+ case ax::mojom::Role::kRowHeader:
+ return "rowHeader";
+ case ax::mojom::Role::kRow:
+ return "row";
+ case ax::mojom::Role::kRuby:
+ return "ruby";
+ case ax::mojom::Role::kSvgRoot:
+ return "svgRoot";
+ case ax::mojom::Role::kScrollBar:
+ return "scrollBar";
+ case ax::mojom::Role::kSearch:
+ return "search";
+ case ax::mojom::Role::kSearchBox:
+ return "searchBox";
+ case ax::mojom::Role::kSlider:
+ return "slider";
+ case ax::mojom::Role::kSliderThumb:
+ return "sliderThumb";
+ case ax::mojom::Role::kSpinButtonPart:
+ return "spinButtonPart";
+ case ax::mojom::Role::kSpinButton:
+ return "spinButton";
+ case ax::mojom::Role::kSplitter:
+ return "splitter";
+ case ax::mojom::Role::kStaticText:
+ return "staticText";
+ case ax::mojom::Role::kStatus:
+ return "status";
+ case ax::mojom::Role::kSwitch:
+ return "switch";
+ case ax::mojom::Role::kTabList:
+ return "tabList";
+ case ax::mojom::Role::kTabPanel:
+ return "tabPanel";
+ case ax::mojom::Role::kTab:
+ return "tab";
+ case ax::mojom::Role::kTableHeaderContainer:
+ return "tableHeaderContainer";
+ case ax::mojom::Role::kTable:
+ return "table";
+ case ax::mojom::Role::kTerm:
+ return "term";
+ case ax::mojom::Role::kTextField:
+ return "textField";
+ case ax::mojom::Role::kTextFieldWithComboBox:
+ return "textFieldWithComboBox";
+ case ax::mojom::Role::kTime:
+ return "time";
+ case ax::mojom::Role::kTimer:
+ return "timer";
+ case ax::mojom::Role::kTitleBar:
+ return "titleBar";
+ case ax::mojom::Role::kToggleButton:
+ return "toggleButton";
+ case ax::mojom::Role::kToolbar:
+ return "toolbar";
+ case ax::mojom::Role::kTreeGrid:
+ return "treeGrid";
+ case ax::mojom::Role::kTreeItem:
+ return "treeItem";
+ case ax::mojom::Role::kTree:
+ return "tree";
+ case ax::mojom::Role::kUnknown:
+ return "unknown";
+ case ax::mojom::Role::kTooltip:
+ return "tooltip";
+ case ax::mojom::Role::kVideo:
+ return "video";
+ case ax::mojom::Role::kWebArea:
+ return "webArea";
+ case ax::mojom::Role::kWebView:
+ return "webView";
+ case ax::mojom::Role::kWindow:
+ return "window";
+ }
+
+ return "";
+}
+
+ax::mojom::Role ParseRole(const char* role) {
+ if (0 == strcmp(role, "none"))
+ return ax::mojom::Role::kNone;
+ if (0 == strcmp(role, "abbr"))
+ return ax::mojom::Role::kAbbr;
+ if (0 == strcmp(role, "alertDialog"))
+ return ax::mojom::Role::kAlertDialog;
+ if (0 == strcmp(role, "alert"))
+ return ax::mojom::Role::kAlert;
+ if (0 == strcmp(role, "anchor"))
+ return ax::mojom::Role::kAnchor;
+ if (0 == strcmp(role, "annotation"))
+ return ax::mojom::Role::kAnnotation;
+ if (0 == strcmp(role, "application"))
+ return ax::mojom::Role::kApplication;
+ if (0 == strcmp(role, "article"))
+ return ax::mojom::Role::kArticle;
+ if (0 == strcmp(role, "audio"))
+ return ax::mojom::Role::kAudio;
+ if (0 == strcmp(role, "banner"))
+ return ax::mojom::Role::kBanner;
+ if (0 == strcmp(role, "blockquote"))
+ return ax::mojom::Role::kBlockquote;
+ if (0 == strcmp(role, "button"))
+ return ax::mojom::Role::kButton;
+ if (0 == strcmp(role, "canvas"))
+ return ax::mojom::Role::kCanvas;
+ if (0 == strcmp(role, "caption"))
+ return ax::mojom::Role::kCaption;
+ if (0 == strcmp(role, "caret"))
+ return ax::mojom::Role::kCaret;
+ if (0 == strcmp(role, "cell"))
+ return ax::mojom::Role::kCell;
+ if (0 == strcmp(role, "checkBox"))
+ return ax::mojom::Role::kCheckBox;
+ if (0 == strcmp(role, "client"))
+ return ax::mojom::Role::kClient;
+ if (0 == strcmp(role, "colorWell"))
+ return ax::mojom::Role::kColorWell;
+ if (0 == strcmp(role, "columnHeader"))
+ return ax::mojom::Role::kColumnHeader;
+ if (0 == strcmp(role, "column"))
+ return ax::mojom::Role::kColumn;
+ if (0 == strcmp(role, "comboBoxGrouping"))
+ return ax::mojom::Role::kComboBoxGrouping;
+ if (0 == strcmp(role, "comboBoxMenuButton"))
+ return ax::mojom::Role::kComboBoxMenuButton;
+ if (0 == strcmp(role, "complementary"))
+ return ax::mojom::Role::kComplementary;
+ if (0 == strcmp(role, "contentInfo"))
+ return ax::mojom::Role::kContentInfo;
+ if (0 == strcmp(role, "date"))
+ return ax::mojom::Role::kDate;
+ if (0 == strcmp(role, "dateTime"))
+ return ax::mojom::Role::kDateTime;
+ if (0 == strcmp(role, "definition"))
+ return ax::mojom::Role::kDefinition;
+ if (0 == strcmp(role, "descriptionListDetail"))
+ return ax::mojom::Role::kDescriptionListDetail;
+ if (0 == strcmp(role, "descriptionList"))
+ return ax::mojom::Role::kDescriptionList;
+ if (0 == strcmp(role, "descriptionListTerm"))
+ return ax::mojom::Role::kDescriptionListTerm;
+ if (0 == strcmp(role, "desktop"))
+ return ax::mojom::Role::kDesktop;
+ if (0 == strcmp(role, "details"))
+ return ax::mojom::Role::kDetails;
+ if (0 == strcmp(role, "dialog"))
+ return ax::mojom::Role::kDialog;
+ if (0 == strcmp(role, "directory"))
+ return ax::mojom::Role::kDirectory;
+ if (0 == strcmp(role, "disclosureTriangle"))
+ return ax::mojom::Role::kDisclosureTriangle;
+ if (0 == strcmp(role, "document"))
+ return ax::mojom::Role::kDocument;
+ if (0 == strcmp(role, "embeddedObject"))
+ return ax::mojom::Role::kEmbeddedObject;
+ if (0 == strcmp(role, "feed"))
+ return ax::mojom::Role::kFeed;
+ if (0 == strcmp(role, "figcaption"))
+ return ax::mojom::Role::kFigcaption;
+ if (0 == strcmp(role, "figure"))
+ return ax::mojom::Role::kFigure;
+ if (0 == strcmp(role, "footer"))
+ return ax::mojom::Role::kFooter;
+ if (0 == strcmp(role, "form"))
+ return ax::mojom::Role::kForm;
+ if (0 == strcmp(role, "genericContainer"))
+ return ax::mojom::Role::kGenericContainer;
+ if (0 == strcmp(role, "grid"))
+ return ax::mojom::Role::kGrid;
+ if (0 == strcmp(role, "group"))
+ return ax::mojom::Role::kGroup;
+ if (0 == strcmp(role, "heading"))
+ return ax::mojom::Role::kHeading;
+ if (0 == strcmp(role, "iframe"))
+ return ax::mojom::Role::kIframe;
+ if (0 == strcmp(role, "iframePresentational"))
+ return ax::mojom::Role::kIframePresentational;
+ if (0 == strcmp(role, "ignored"))
+ return ax::mojom::Role::kIgnored;
+ if (0 == strcmp(role, "imageMap"))
+ return ax::mojom::Role::kImageMap;
+ if (0 == strcmp(role, "image"))
+ return ax::mojom::Role::kImage;
+ if (0 == strcmp(role, "inlineTextBox"))
+ return ax::mojom::Role::kInlineTextBox;
+ if (0 == strcmp(role, "inputTime"))
+ return ax::mojom::Role::kInputTime;
+ if (0 == strcmp(role, "labelText"))
+ return ax::mojom::Role::kLabelText;
+ if (0 == strcmp(role, "layoutTable"))
+ return ax::mojom::Role::kLayoutTable;
+ if (0 == strcmp(role, "layoutTableCell"))
+ return ax::mojom::Role::kLayoutTableCell;
+ if (0 == strcmp(role, "layoutTableColumn"))
+ return ax::mojom::Role::kLayoutTableColumn;
+ if (0 == strcmp(role, "layoutTableRow"))
+ return ax::mojom::Role::kLayoutTableRow;
+ if (0 == strcmp(role, "legend"))
+ return ax::mojom::Role::kLegend;
+ if (0 == strcmp(role, "lineBreak"))
+ return ax::mojom::Role::kLineBreak;
+ if (0 == strcmp(role, "link"))
+ return ax::mojom::Role::kLink;
+ if (0 == strcmp(role, "listBoxOption"))
+ return ax::mojom::Role::kListBoxOption;
+ if (0 == strcmp(role, "listBox"))
+ return ax::mojom::Role::kListBox;
+ if (0 == strcmp(role, "listItem"))
+ return ax::mojom::Role::kListItem;
+ if (0 == strcmp(role, "listMarker"))
+ return ax::mojom::Role::kListMarker;
+ if (0 == strcmp(role, "list"))
+ return ax::mojom::Role::kList;
+ if (0 == strcmp(role, "locationBar"))
+ return ax::mojom::Role::kLocationBar;
+ if (0 == strcmp(role, "log"))
+ return ax::mojom::Role::kLog;
+ if (0 == strcmp(role, "main"))
+ return ax::mojom::Role::kMain;
+ if (0 == strcmp(role, "mark"))
+ return ax::mojom::Role::kMark;
+ if (0 == strcmp(role, "marquee"))
+ return ax::mojom::Role::kMarquee;
+ if (0 == strcmp(role, "math"))
+ return ax::mojom::Role::kMath;
+ if (0 == strcmp(role, "menu"))
+ return ax::mojom::Role::kMenu;
+ if (0 == strcmp(role, "menuBar"))
+ return ax::mojom::Role::kMenuBar;
+ if (0 == strcmp(role, "menuButton"))
+ return ax::mojom::Role::kMenuButton;
+ if (0 == strcmp(role, "menuItem"))
+ return ax::mojom::Role::kMenuItem;
+ if (0 == strcmp(role, "menuItemCheckBox"))
+ return ax::mojom::Role::kMenuItemCheckBox;
+ if (0 == strcmp(role, "menuItemRadio"))
+ return ax::mojom::Role::kMenuItemRadio;
+ if (0 == strcmp(role, "menuListOption"))
+ return ax::mojom::Role::kMenuListOption;
+ if (0 == strcmp(role, "menuListPopup"))
+ return ax::mojom::Role::kMenuListPopup;
+ if (0 == strcmp(role, "meter"))
+ return ax::mojom::Role::kMeter;
+ if (0 == strcmp(role, "navigation"))
+ return ax::mojom::Role::kNavigation;
+ if (0 == strcmp(role, "note"))
+ return ax::mojom::Role::kNote;
+ if (0 == strcmp(role, "pane"))
+ return ax::mojom::Role::kPane;
+ if (0 == strcmp(role, "paragraph"))
+ return ax::mojom::Role::kParagraph;
+ if (0 == strcmp(role, "popUpButton"))
+ return ax::mojom::Role::kPopUpButton;
+ if (0 == strcmp(role, "pre"))
+ return ax::mojom::Role::kPre;
+ if (0 == strcmp(role, "presentational"))
+ return ax::mojom::Role::kPresentational;
+ if (0 == strcmp(role, "progressIndicator"))
+ return ax::mojom::Role::kProgressIndicator;
+ if (0 == strcmp(role, "radioButton"))
+ return ax::mojom::Role::kRadioButton;
+ if (0 == strcmp(role, "radioGroup"))
+ return ax::mojom::Role::kRadioGroup;
+ if (0 == strcmp(role, "region"))
+ return ax::mojom::Role::kRegion;
+ if (0 == strcmp(role, "rootWebArea"))
+ return ax::mojom::Role::kRootWebArea;
+ if (0 == strcmp(role, "rowHeader"))
+ return ax::mojom::Role::kRowHeader;
+ if (0 == strcmp(role, "row"))
+ return ax::mojom::Role::kRow;
+ if (0 == strcmp(role, "ruby"))
+ return ax::mojom::Role::kRuby;
+ if (0 == strcmp(role, "svgRoot"))
+ return ax::mojom::Role::kSvgRoot;
+ if (0 == strcmp(role, "scrollBar"))
+ return ax::mojom::Role::kScrollBar;
+ if (0 == strcmp(role, "search"))
+ return ax::mojom::Role::kSearch;
+ if (0 == strcmp(role, "searchBox"))
+ return ax::mojom::Role::kSearchBox;
+ if (0 == strcmp(role, "slider"))
+ return ax::mojom::Role::kSlider;
+ if (0 == strcmp(role, "sliderThumb"))
+ return ax::mojom::Role::kSliderThumb;
+ if (0 == strcmp(role, "spinButtonPart"))
+ return ax::mojom::Role::kSpinButtonPart;
+ if (0 == strcmp(role, "spinButton"))
+ return ax::mojom::Role::kSpinButton;
+ if (0 == strcmp(role, "splitter"))
+ return ax::mojom::Role::kSplitter;
+ if (0 == strcmp(role, "staticText"))
+ return ax::mojom::Role::kStaticText;
+ if (0 == strcmp(role, "status"))
+ return ax::mojom::Role::kStatus;
+ if (0 == strcmp(role, "switch"))
+ return ax::mojom::Role::kSwitch;
+ if (0 == strcmp(role, "tabList"))
+ return ax::mojom::Role::kTabList;
+ if (0 == strcmp(role, "tabPanel"))
+ return ax::mojom::Role::kTabPanel;
+ if (0 == strcmp(role, "tab"))
+ return ax::mojom::Role::kTab;
+ if (0 == strcmp(role, "tableHeaderContainer"))
+ return ax::mojom::Role::kTableHeaderContainer;
+ if (0 == strcmp(role, "table"))
+ return ax::mojom::Role::kTable;
+ if (0 == strcmp(role, "term"))
+ return ax::mojom::Role::kTerm;
+ if (0 == strcmp(role, "textField"))
+ return ax::mojom::Role::kTextField;
+ if (0 == strcmp(role, "textFieldWithComboBox"))
+ return ax::mojom::Role::kTextFieldWithComboBox;
+ if (0 == strcmp(role, "time"))
+ return ax::mojom::Role::kTime;
+ if (0 == strcmp(role, "timer"))
+ return ax::mojom::Role::kTimer;
+ if (0 == strcmp(role, "titleBar"))
+ return ax::mojom::Role::kTitleBar;
+ if (0 == strcmp(role, "toggleButton"))
+ return ax::mojom::Role::kToggleButton;
+ if (0 == strcmp(role, "toolbar"))
+ return ax::mojom::Role::kToolbar;
+ if (0 == strcmp(role, "treeGrid"))
+ return ax::mojom::Role::kTreeGrid;
+ if (0 == strcmp(role, "treeItem"))
+ return ax::mojom::Role::kTreeItem;
+ if (0 == strcmp(role, "tree"))
+ return ax::mojom::Role::kTree;
+ if (0 == strcmp(role, "unknown"))
+ return ax::mojom::Role::kUnknown;
+ if (0 == strcmp(role, "tooltip"))
+ return ax::mojom::Role::kTooltip;
+ if (0 == strcmp(role, "video"))
+ return ax::mojom::Role::kVideo;
+ if (0 == strcmp(role, "webArea"))
+ return ax::mojom::Role::kWebArea;
+ if (0 == strcmp(role, "webView"))
+ return ax::mojom::Role::kWebView;
+ if (0 == strcmp(role, "window"))
+ return ax::mojom::Role::kWindow;
+ return ax::mojom::Role::kNone;
+}
+
+const char* ToString(ax::mojom::State state) {
+ switch (state) {
+ case ax::mojom::State::kNone:
+ return "none";
+ case ax::mojom::State::kCollapsed:
+ return "collapsed";
+ case ax::mojom::State::kDefault:
+ return "default";
+ case ax::mojom::State::kEditable:
+ return "editable";
+ case ax::mojom::State::kExpanded:
+ return "expanded";
+ case ax::mojom::State::kFocusable:
+ return "focusable";
+ case ax::mojom::State::kHaspopup:
+ return "haspopup";
+ case ax::mojom::State::kHorizontal:
+ return "horizontal";
+ case ax::mojom::State::kHovered:
+ return "hovered";
+ case ax::mojom::State::kIgnored:
+ return "ignored";
+ case ax::mojom::State::kInvisible:
+ return "invisible";
+ case ax::mojom::State::kLinked:
+ return "linked";
+ case ax::mojom::State::kMultiline:
+ return "multiline";
+ case ax::mojom::State::kMultiselectable:
+ return "multiselectable";
+ case ax::mojom::State::kProtected:
+ return "protected";
+ case ax::mojom::State::kRequired:
+ return "required";
+ case ax::mojom::State::kRichlyEditable:
+ return "richlyEditable";
+ case ax::mojom::State::kSelectable:
+ return "selectable";
+ case ax::mojom::State::kSelected:
+ return "selected";
+ case ax::mojom::State::kVertical:
+ return "vertical";
+ case ax::mojom::State::kVisited:
+ return "visited";
+ }
+
+ return "";
+}
+
+ax::mojom::State ParseState(const char* state) {
+ if (0 == strcmp(state, "none"))
+ return ax::mojom::State::kNone;
+ if (0 == strcmp(state, "collapsed"))
+ return ax::mojom::State::kCollapsed;
+ if (0 == strcmp(state, "default"))
+ return ax::mojom::State::kDefault;
+ if (0 == strcmp(state, "editable"))
+ return ax::mojom::State::kEditable;
+ if (0 == strcmp(state, "expanded"))
+ return ax::mojom::State::kExpanded;
+ if (0 == strcmp(state, "focusable"))
+ return ax::mojom::State::kFocusable;
+ if (0 == strcmp(state, "haspopup"))
+ return ax::mojom::State::kHaspopup;
+ if (0 == strcmp(state, "horizontal"))
+ return ax::mojom::State::kHorizontal;
+ if (0 == strcmp(state, "hovered"))
+ return ax::mojom::State::kHovered;
+ if (0 == strcmp(state, "ignored"))
+ return ax::mojom::State::kIgnored;
+ if (0 == strcmp(state, "invisible"))
+ return ax::mojom::State::kInvisible;
+ if (0 == strcmp(state, "linked"))
+ return ax::mojom::State::kLinked;
+ if (0 == strcmp(state, "multiline"))
+ return ax::mojom::State::kMultiline;
+ if (0 == strcmp(state, "multiselectable"))
+ return ax::mojom::State::kMultiselectable;
+ if (0 == strcmp(state, "protected"))
+ return ax::mojom::State::kProtected;
+ if (0 == strcmp(state, "required"))
+ return ax::mojom::State::kRequired;
+ if (0 == strcmp(state, "richlyEditable"))
+ return ax::mojom::State::kRichlyEditable;
+ if (0 == strcmp(state, "selectable"))
+ return ax::mojom::State::kSelectable;
+ if (0 == strcmp(state, "selected"))
+ return ax::mojom::State::kSelected;
+ if (0 == strcmp(state, "vertical"))
+ return ax::mojom::State::kVertical;
+ if (0 == strcmp(state, "visited"))
+ return ax::mojom::State::kVisited;
+ return ax::mojom::State::kNone;
+}
+
+const char* ToString(ax::mojom::Action action) {
+ switch (action) {
+ case ax::mojom::Action::kNone:
+ return "none";
+ case ax::mojom::Action::kBlur:
+ return "blur";
+ case ax::mojom::Action::kCustomAction:
+ return "customAction";
+ case ax::mojom::Action::kDecrement:
+ return "decrement";
+ case ax::mojom::Action::kDoDefault:
+ return "doDefault";
+ case ax::mojom::Action::kFocus:
+ return "focus";
+ case ax::mojom::Action::kGetImageData:
+ return "getImageData";
+ case ax::mojom::Action::kHitTest:
+ return "hitTest";
+ case ax::mojom::Action::kIncrement:
+ return "increment";
+ case ax::mojom::Action::kLoadInlineTextBoxes:
+ return "loadInlineTextBoxes";
+ case ax::mojom::Action::kReplaceSelectedText:
+ return "replaceSelectedText";
+ case ax::mojom::Action::kScrollBackward:
+ return "scrollBackward";
+ case ax::mojom::Action::kScrollForward:
+ return "scrollForward";
+ case ax::mojom::Action::kScrollUp:
+ return "scrollUp";
+ case ax::mojom::Action::kScrollDown:
+ return "scrollDown";
+ case ax::mojom::Action::kScrollLeft:
+ return "scrollLeft";
+ case ax::mojom::Action::kScrollRight:
+ return "scrollRight";
+ case ax::mojom::Action::kScrollToMakeVisible:
+ return "scrollToMakeVisible";
+ case ax::mojom::Action::kScrollToPoint:
+ return "scrollToPoint";
+ case ax::mojom::Action::kSetScrollOffset:
+ return "setScrollOffset";
+ case ax::mojom::Action::kSetSelection:
+ return "setSelection";
+ case ax::mojom::Action::kSetSequentialFocusNavigationStartingPoint:
+ return "setSequentialFocusNavigationStartingPoint";
+ case ax::mojom::Action::kSetValue:
+ return "setValue";
+ case ax::mojom::Action::kShowContextMenu:
+ return "showContextMenu";
+ }
+
+ return "";
+}
+
+ax::mojom::Action ParseAction(const char* action) {
+ if (0 == strcmp(action, "none"))
+ return ax::mojom::Action::kNone;
+ if (0 == strcmp(action, "blur"))
+ return ax::mojom::Action::kBlur;
+ if (0 == strcmp(action, "customAction"))
+ return ax::mojom::Action::kCustomAction;
+ if (0 == strcmp(action, "decrement"))
+ return ax::mojom::Action::kDecrement;
+ if (0 == strcmp(action, "doDefault"))
+ return ax::mojom::Action::kDoDefault;
+ if (0 == strcmp(action, "focus"))
+ return ax::mojom::Action::kFocus;
+ if (0 == strcmp(action, "getImageData"))
+ return ax::mojom::Action::kGetImageData;
+ if (0 == strcmp(action, "hitTest"))
+ return ax::mojom::Action::kHitTest;
+ if (0 == strcmp(action, "increment"))
+ return ax::mojom::Action::kIncrement;
+ if (0 == strcmp(action, "loadInlineTextBoxes"))
+ return ax::mojom::Action::kLoadInlineTextBoxes;
+ if (0 == strcmp(action, "replaceSelectedText"))
+ return ax::mojom::Action::kReplaceSelectedText;
+ if (0 == strcmp(action, "scrollBackward"))
+ return ax::mojom::Action::kScrollBackward;
+ if (0 == strcmp(action, "scrollForward"))
+ return ax::mojom::Action::kScrollForward;
+ if (0 == strcmp(action, "scrollUp"))
+ return ax::mojom::Action::kScrollUp;
+ if (0 == strcmp(action, "scrollDown"))
+ return ax::mojom::Action::kScrollDown;
+ if (0 == strcmp(action, "scrollLeft"))
+ return ax::mojom::Action::kScrollLeft;
+ if (0 == strcmp(action, "scrollRight"))
+ return ax::mojom::Action::kScrollRight;
+ if (0 == strcmp(action, "scrollToMakeVisible"))
+ return ax::mojom::Action::kScrollToMakeVisible;
+ if (0 == strcmp(action, "scrollToPoint"))
+ return ax::mojom::Action::kScrollToPoint;
+ if (0 == strcmp(action, "setScrollOffset"))
+ return ax::mojom::Action::kSetScrollOffset;
+ if (0 == strcmp(action, "setSelection"))
+ return ax::mojom::Action::kSetSelection;
+ if (0 == strcmp(action, "setSequentialFocusNavigationStartingPoint"))
+ return ax::mojom::Action::kSetSequentialFocusNavigationStartingPoint;
+ if (0 == strcmp(action, "setValue"))
+ return ax::mojom::Action::kSetValue;
+ if (0 == strcmp(action, "showContextMenu"))
+ return ax::mojom::Action::kShowContextMenu;
+ return ax::mojom::Action::kNone;
+}
+
+const char* ToString(ax::mojom::ActionFlags action_flags) {
+ switch (action_flags) {
+ case ax::mojom::ActionFlags::kNone:
+ return "none";
+ case ax::mojom::ActionFlags::kRequestImages:
+ return "requestImages";
+ case ax::mojom::ActionFlags::kRequestInlineTextBoxes:
+ return "requestInlineTextBoxes";
+ }
+
+ return "";
+}
+
+ax::mojom::ActionFlags ParseActionFlags(const char* action_flags) {
+ if (0 == strcmp(action_flags, "none"))
+ return ax::mojom::ActionFlags::kNone;
+ if (0 == strcmp(action_flags, "requestImages"))
+ return ax::mojom::ActionFlags::kRequestImages;
+ if (0 == strcmp(action_flags, "requestInlineTextBoxes"))
+ return ax::mojom::ActionFlags::kRequestInlineTextBoxes;
+ return ax::mojom::ActionFlags::kNone;
+}
+
+const char* ToString(ax::mojom::DefaultActionVerb default_action_verb) {
+ switch (default_action_verb) {
+ case ax::mojom::DefaultActionVerb::kNone:
+ return "none";
+ case ax::mojom::DefaultActionVerb::kActivate:
+ return "activate";
+ case ax::mojom::DefaultActionVerb::kCheck:
+ return "check";
+ case ax::mojom::DefaultActionVerb::kClick:
+ return "click";
+ case ax::mojom::DefaultActionVerb::kClickAncestor:
+ return "clickAncestor";
+ case ax::mojom::DefaultActionVerb::kJump:
+ return "jump";
+ case ax::mojom::DefaultActionVerb::kOpen:
+ return "open";
+ case ax::mojom::DefaultActionVerb::kPress:
+ return "press";
+ case ax::mojom::DefaultActionVerb::kSelect:
+ return "select";
+ case ax::mojom::DefaultActionVerb::kUncheck:
+ return "uncheck";
+ }
+
+ return "";
+}
+
+ax::mojom::DefaultActionVerb ParseDefaultActionVerb(
+ const char* default_action_verb) {
+ if (0 == strcmp(default_action_verb, "none"))
+ return ax::mojom::DefaultActionVerb::kNone;
+ if (0 == strcmp(default_action_verb, "activate"))
+ return ax::mojom::DefaultActionVerb::kActivate;
+ if (0 == strcmp(default_action_verb, "check"))
+ return ax::mojom::DefaultActionVerb::kCheck;
+ if (0 == strcmp(default_action_verb, "click"))
+ return ax::mojom::DefaultActionVerb::kClick;
+ if (0 == strcmp(default_action_verb, "clickAncestor"))
+ return ax::mojom::DefaultActionVerb::kClickAncestor;
+ if (0 == strcmp(default_action_verb, "jump"))
+ return ax::mojom::DefaultActionVerb::kJump;
+ if (0 == strcmp(default_action_verb, "open"))
+ return ax::mojom::DefaultActionVerb::kOpen;
+ if (0 == strcmp(default_action_verb, "press"))
+ return ax::mojom::DefaultActionVerb::kPress;
+ if (0 == strcmp(default_action_verb, "select"))
+ return ax::mojom::DefaultActionVerb::kSelect;
+ if (0 == strcmp(default_action_verb, "uncheck"))
+ return ax::mojom::DefaultActionVerb::kUncheck;
+ return ax::mojom::DefaultActionVerb::kNone;
+}
+
+const char* ToString(ax::mojom::Mutation mutation) {
+ switch (mutation) {
+ case ax::mojom::Mutation::kNone:
+ return "none";
+ case ax::mojom::Mutation::kNodeCreated:
+ return "nodeCreated";
+ case ax::mojom::Mutation::kSubtreeCreated:
+ return "subtreeCreated";
+ case ax::mojom::Mutation::kNodeChanged:
+ return "nodeChanged";
+ case ax::mojom::Mutation::kNodeRemoved:
+ return "nodeRemoved";
+ }
+
+ return "";
+}
+
+ax::mojom::Mutation ParseMutation(const char* mutation) {
+ if (0 == strcmp(mutation, "none"))
+ return ax::mojom::Mutation::kNone;
+ if (0 == strcmp(mutation, "nodeCreated"))
+ return ax::mojom::Mutation::kNodeCreated;
+ if (0 == strcmp(mutation, "subtreeCreated"))
+ return ax::mojom::Mutation::kSubtreeCreated;
+ if (0 == strcmp(mutation, "nodeChanged"))
+ return ax::mojom::Mutation::kNodeChanged;
+ if (0 == strcmp(mutation, "nodeRemoved"))
+ return ax::mojom::Mutation::kNodeRemoved;
+ return ax::mojom::Mutation::kNone;
+}
+
+const char* ToString(ax::mojom::StringAttribute string_attribute) {
+ switch (string_attribute) {
+ case ax::mojom::StringAttribute::kNone:
+ return "none";
+ case ax::mojom::StringAttribute::kAccessKey:
+ return "accessKey";
+ case ax::mojom::StringAttribute::kAriaInvalidValue:
+ return "ariaInvalidValue";
+ case ax::mojom::StringAttribute::kAutoComplete:
+ return "autoComplete";
+ case ax::mojom::StringAttribute::kChromeChannel:
+ return "chromeChannel";
+ case ax::mojom::StringAttribute::kClassName:
+ return "className";
+ case ax::mojom::StringAttribute::kContainerLiveRelevant:
+ return "containerLiveRelevant";
+ case ax::mojom::StringAttribute::kContainerLiveStatus:
+ return "containerLiveStatus";
+ case ax::mojom::StringAttribute::kDescription:
+ return "description";
+ case ax::mojom::StringAttribute::kDisplay:
+ return "display";
+ case ax::mojom::StringAttribute::kFontFamily:
+ return "fontFamily";
+ case ax::mojom::StringAttribute::kHtmlTag:
+ return "htmlTag";
+ case ax::mojom::StringAttribute::kImageDataUrl:
+ return "imageDataUrl";
+ case ax::mojom::StringAttribute::kInnerHtml:
+ return "innerHtml";
+ case ax::mojom::StringAttribute::kKeyShortcuts:
+ return "keyShortcuts";
+ case ax::mojom::StringAttribute::kLanguage:
+ return "language";
+ case ax::mojom::StringAttribute::kName:
+ return "name";
+ case ax::mojom::StringAttribute::kLiveRelevant:
+ return "liveRelevant";
+ case ax::mojom::StringAttribute::kLiveStatus:
+ return "liveStatus";
+ case ax::mojom::StringAttribute::kPlaceholder:
+ return "placeholder";
+ case ax::mojom::StringAttribute::kRole:
+ return "role";
+ case ax::mojom::StringAttribute::kRoleDescription:
+ return "roleDescription";
+ case ax::mojom::StringAttribute::kUrl:
+ return "url";
+ case ax::mojom::StringAttribute::kValue:
+ return "value";
+ }
+
+ return "";
+}
+
+ax::mojom::StringAttribute ParseStringAttribute(const char* string_attribute) {
+ if (0 == strcmp(string_attribute, "none"))
+ return ax::mojom::StringAttribute::kNone;
+ if (0 == strcmp(string_attribute, "accessKey"))
+ return ax::mojom::StringAttribute::kAccessKey;
+ if (0 == strcmp(string_attribute, "ariaInvalidValue"))
+ return ax::mojom::StringAttribute::kAriaInvalidValue;
+ if (0 == strcmp(string_attribute, "autoComplete"))
+ return ax::mojom::StringAttribute::kAutoComplete;
+ if (0 == strcmp(string_attribute, "chromeChannel"))
+ return ax::mojom::StringAttribute::kChromeChannel;
+ if (0 == strcmp(string_attribute, "className"))
+ return ax::mojom::StringAttribute::kClassName;
+ if (0 == strcmp(string_attribute, "containerLiveRelevant"))
+ return ax::mojom::StringAttribute::kContainerLiveRelevant;
+ if (0 == strcmp(string_attribute, "containerLiveStatus"))
+ return ax::mojom::StringAttribute::kContainerLiveStatus;
+ if (0 == strcmp(string_attribute, "description"))
+ return ax::mojom::StringAttribute::kDescription;
+ if (0 == strcmp(string_attribute, "display"))
+ return ax::mojom::StringAttribute::kDisplay;
+ if (0 == strcmp(string_attribute, "fontFamily"))
+ return ax::mojom::StringAttribute::kFontFamily;
+ if (0 == strcmp(string_attribute, "htmlTag"))
+ return ax::mojom::StringAttribute::kHtmlTag;
+ if (0 == strcmp(string_attribute, "imageDataUrl"))
+ return ax::mojom::StringAttribute::kImageDataUrl;
+ if (0 == strcmp(string_attribute, "innerHtml"))
+ return ax::mojom::StringAttribute::kInnerHtml;
+ if (0 == strcmp(string_attribute, "keyShortcuts"))
+ return ax::mojom::StringAttribute::kKeyShortcuts;
+ if (0 == strcmp(string_attribute, "language"))
+ return ax::mojom::StringAttribute::kLanguage;
+ if (0 == strcmp(string_attribute, "name"))
+ return ax::mojom::StringAttribute::kName;
+ if (0 == strcmp(string_attribute, "liveRelevant"))
+ return ax::mojom::StringAttribute::kLiveRelevant;
+ if (0 == strcmp(string_attribute, "liveStatus"))
+ return ax::mojom::StringAttribute::kLiveStatus;
+ if (0 == strcmp(string_attribute, "placeholder"))
+ return ax::mojom::StringAttribute::kPlaceholder;
+ if (0 == strcmp(string_attribute, "role"))
+ return ax::mojom::StringAttribute::kRole;
+ if (0 == strcmp(string_attribute, "roleDescription"))
+ return ax::mojom::StringAttribute::kRoleDescription;
+ if (0 == strcmp(string_attribute, "url"))
+ return ax::mojom::StringAttribute::kUrl;
+ if (0 == strcmp(string_attribute, "value"))
+ return ax::mojom::StringAttribute::kValue;
+ return ax::mojom::StringAttribute::kNone;
+}
+
+const char* ToString(ax::mojom::IntAttribute int_attribute) {
+ switch (int_attribute) {
+ case ax::mojom::IntAttribute::kNone:
+ return "none";
+ case ax::mojom::IntAttribute::kDefaultActionVerb:
+ return "defaultActionVerb";
+ case ax::mojom::IntAttribute::kScrollX:
+ return "scrollX";
+ case ax::mojom::IntAttribute::kScrollXMin:
+ return "scrollXMin";
+ case ax::mojom::IntAttribute::kScrollXMax:
+ return "scrollXMax";
+ case ax::mojom::IntAttribute::kScrollY:
+ return "scrollY";
+ case ax::mojom::IntAttribute::kScrollYMin:
+ return "scrollYMin";
+ case ax::mojom::IntAttribute::kScrollYMax:
+ return "scrollYMax";
+ case ax::mojom::IntAttribute::kTextSelStart:
+ return "textSelStart";
+ case ax::mojom::IntAttribute::kTextSelEnd:
+ return "textSelEnd";
+ case ax::mojom::IntAttribute::kAriaColumnCount:
+ return "ariaColumnCount";
+ case ax::mojom::IntAttribute::kAriaCellColumnIndex:
+ return "ariaCellColumnIndex";
+ case ax::mojom::IntAttribute::kAriaRowCount:
+ return "ariaRowCount";
+ case ax::mojom::IntAttribute::kAriaCellRowIndex:
+ return "ariaCellRowIndex";
+ case ax::mojom::IntAttribute::kTableRowCount:
+ return "tableRowCount";
+ case ax::mojom::IntAttribute::kTableColumnCount:
+ return "tableColumnCount";
+ case ax::mojom::IntAttribute::kTableHeaderId:
+ return "tableHeaderId";
+ case ax::mojom::IntAttribute::kTableRowIndex:
+ return "tableRowIndex";
+ case ax::mojom::IntAttribute::kTableRowHeaderId:
+ return "tableRowHeaderId";
+ case ax::mojom::IntAttribute::kTableColumnIndex:
+ return "tableColumnIndex";
+ case ax::mojom::IntAttribute::kTableColumnHeaderId:
+ return "tableColumnHeaderId";
+ case ax::mojom::IntAttribute::kTableCellColumnIndex:
+ return "tableCellColumnIndex";
+ case ax::mojom::IntAttribute::kTableCellColumnSpan:
+ return "tableCellColumnSpan";
+ case ax::mojom::IntAttribute::kTableCellRowIndex:
+ return "tableCellRowIndex";
+ case ax::mojom::IntAttribute::kTableCellRowSpan:
+ return "tableCellRowSpan";
+ case ax::mojom::IntAttribute::kSortDirection:
+ return "sortDirection";
+ case ax::mojom::IntAttribute::kHierarchicalLevel:
+ return "hierarchicalLevel";
+ case ax::mojom::IntAttribute::kNameFrom:
+ return "nameFrom";
+ case ax::mojom::IntAttribute::kDescriptionFrom:
+ return "descriptionFrom";
+ case ax::mojom::IntAttribute::kActivedescendantId:
+ return "activedescendantId";
+ case ax::mojom::IntAttribute::kDetailsId:
+ return "detailsId";
+ case ax::mojom::IntAttribute::kErrormessageId:
+ return "errormessageId";
+ case ax::mojom::IntAttribute::kInPageLinkTargetId:
+ return "inPageLinkTargetId";
+ case ax::mojom::IntAttribute::kMemberOfId:
+ return "memberOfId";
+ case ax::mojom::IntAttribute::kNextOnLineId:
+ return "nextOnLineId";
+ case ax::mojom::IntAttribute::kPreviousOnLineId:
+ return "previousOnLineId";
+ case ax::mojom::IntAttribute::kChildTreeId:
+ return "childTreeId";
+ case ax::mojom::IntAttribute::kRestriction:
+ return "restriction";
+ case ax::mojom::IntAttribute::kSetSize:
+ return "setSize";
+ case ax::mojom::IntAttribute::kPosInSet:
+ return "posInSet";
+ case ax::mojom::IntAttribute::kColorValue:
+ return "colorValue";
+ case ax::mojom::IntAttribute::kAriaCurrentState:
+ return "ariaCurrentState";
+ case ax::mojom::IntAttribute::kBackgroundColor:
+ return "backgroundColor";
+ case ax::mojom::IntAttribute::kColor:
+ return "color";
+ case ax::mojom::IntAttribute::kInvalidState:
+ return "invalidState";
+ case ax::mojom::IntAttribute::kCheckedState:
+ return "checkedState";
+ case ax::mojom::IntAttribute::kTextDirection:
+ return "textDirection";
+ case ax::mojom::IntAttribute::kTextStyle:
+ return "textStyle";
+ case ax::mojom::IntAttribute::kPreviousFocusId:
+ return "previousFocusId";
+ case ax::mojom::IntAttribute::kNextFocusId:
+ return "nextFocusId";
+ }
+
+ return "";
+}
+
+ax::mojom::IntAttribute ParseIntAttribute(const char* int_attribute) {
+ if (0 == strcmp(int_attribute, "none"))
+ return ax::mojom::IntAttribute::kNone;
+ if (0 == strcmp(int_attribute, "defaultActionVerb"))
+ return ax::mojom::IntAttribute::kDefaultActionVerb;
+ if (0 == strcmp(int_attribute, "scrollX"))
+ return ax::mojom::IntAttribute::kScrollX;
+ if (0 == strcmp(int_attribute, "scrollXMin"))
+ return ax::mojom::IntAttribute::kScrollXMin;
+ if (0 == strcmp(int_attribute, "scrollXMax"))
+ return ax::mojom::IntAttribute::kScrollXMax;
+ if (0 == strcmp(int_attribute, "scrollY"))
+ return ax::mojom::IntAttribute::kScrollY;
+ if (0 == strcmp(int_attribute, "scrollYMin"))
+ return ax::mojom::IntAttribute::kScrollYMin;
+ if (0 == strcmp(int_attribute, "scrollYMax"))
+ return ax::mojom::IntAttribute::kScrollYMax;
+ if (0 == strcmp(int_attribute, "textSelStart"))
+ return ax::mojom::IntAttribute::kTextSelStart;
+ if (0 == strcmp(int_attribute, "textSelEnd"))
+ return ax::mojom::IntAttribute::kTextSelEnd;
+ if (0 == strcmp(int_attribute, "ariaColumnCount"))
+ return ax::mojom::IntAttribute::kAriaColumnCount;
+ if (0 == strcmp(int_attribute, "ariaCellColumnIndex"))
+ return ax::mojom::IntAttribute::kAriaCellColumnIndex;
+ if (0 == strcmp(int_attribute, "ariaRowCount"))
+ return ax::mojom::IntAttribute::kAriaRowCount;
+ if (0 == strcmp(int_attribute, "ariaCellRowIndex"))
+ return ax::mojom::IntAttribute::kAriaCellRowIndex;
+ if (0 == strcmp(int_attribute, "tableRowCount"))
+ return ax::mojom::IntAttribute::kTableRowCount;
+ if (0 == strcmp(int_attribute, "tableColumnCount"))
+ return ax::mojom::IntAttribute::kTableColumnCount;
+ if (0 == strcmp(int_attribute, "tableHeaderId"))
+ return ax::mojom::IntAttribute::kTableHeaderId;
+ if (0 == strcmp(int_attribute, "tableRowIndex"))
+ return ax::mojom::IntAttribute::kTableRowIndex;
+ if (0 == strcmp(int_attribute, "tableRowHeaderId"))
+ return ax::mojom::IntAttribute::kTableRowHeaderId;
+ if (0 == strcmp(int_attribute, "tableColumnIndex"))
+ return ax::mojom::IntAttribute::kTableColumnIndex;
+ if (0 == strcmp(int_attribute, "tableColumnHeaderId"))
+ return ax::mojom::IntAttribute::kTableColumnHeaderId;
+ if (0 == strcmp(int_attribute, "tableCellColumnIndex"))
+ return ax::mojom::IntAttribute::kTableCellColumnIndex;
+ if (0 == strcmp(int_attribute, "tableCellColumnSpan"))
+ return ax::mojom::IntAttribute::kTableCellColumnSpan;
+ if (0 == strcmp(int_attribute, "tableCellRowIndex"))
+ return ax::mojom::IntAttribute::kTableCellRowIndex;
+ if (0 == strcmp(int_attribute, "tableCellRowSpan"))
+ return ax::mojom::IntAttribute::kTableCellRowSpan;
+ if (0 == strcmp(int_attribute, "sortDirection"))
+ return ax::mojom::IntAttribute::kSortDirection;
+ if (0 == strcmp(int_attribute, "hierarchicalLevel"))
+ return ax::mojom::IntAttribute::kHierarchicalLevel;
+ if (0 == strcmp(int_attribute, "nameFrom"))
+ return ax::mojom::IntAttribute::kNameFrom;
+ if (0 == strcmp(int_attribute, "descriptionFrom"))
+ return ax::mojom::IntAttribute::kDescriptionFrom;
+ if (0 == strcmp(int_attribute, "activedescendantId"))
+ return ax::mojom::IntAttribute::kActivedescendantId;
+ if (0 == strcmp(int_attribute, "detailsId"))
+ return ax::mojom::IntAttribute::kDetailsId;
+ if (0 == strcmp(int_attribute, "errormessageId"))
+ return ax::mojom::IntAttribute::kErrormessageId;
+ if (0 == strcmp(int_attribute, "inPageLinkTargetId"))
+ return ax::mojom::IntAttribute::kInPageLinkTargetId;
+ if (0 == strcmp(int_attribute, "memberOfId"))
+ return ax::mojom::IntAttribute::kMemberOfId;
+ if (0 == strcmp(int_attribute, "nextOnLineId"))
+ return ax::mojom::IntAttribute::kNextOnLineId;
+ if (0 == strcmp(int_attribute, "previousOnLineId"))
+ return ax::mojom::IntAttribute::kPreviousOnLineId;
+ if (0 == strcmp(int_attribute, "childTreeId"))
+ return ax::mojom::IntAttribute::kChildTreeId;
+ if (0 == strcmp(int_attribute, "restriction"))
+ return ax::mojom::IntAttribute::kRestriction;
+ if (0 == strcmp(int_attribute, "setSize"))
+ return ax::mojom::IntAttribute::kSetSize;
+ if (0 == strcmp(int_attribute, "posInSet"))
+ return ax::mojom::IntAttribute::kPosInSet;
+ if (0 == strcmp(int_attribute, "colorValue"))
+ return ax::mojom::IntAttribute::kColorValue;
+ if (0 == strcmp(int_attribute, "ariaCurrentState"))
+ return ax::mojom::IntAttribute::kAriaCurrentState;
+ if (0 == strcmp(int_attribute, "backgroundColor"))
+ return ax::mojom::IntAttribute::kBackgroundColor;
+ if (0 == strcmp(int_attribute, "color"))
+ return ax::mojom::IntAttribute::kColor;
+ if (0 == strcmp(int_attribute, "invalidState"))
+ return ax::mojom::IntAttribute::kInvalidState;
+ if (0 == strcmp(int_attribute, "checkedState"))
+ return ax::mojom::IntAttribute::kCheckedState;
+ if (0 == strcmp(int_attribute, "textDirection"))
+ return ax::mojom::IntAttribute::kTextDirection;
+ if (0 == strcmp(int_attribute, "textStyle"))
+ return ax::mojom::IntAttribute::kTextStyle;
+ if (0 == strcmp(int_attribute, "previousFocusId"))
+ return ax::mojom::IntAttribute::kPreviousFocusId;
+ if (0 == strcmp(int_attribute, "nextFocusId"))
+ return ax::mojom::IntAttribute::kNextFocusId;
+ return ax::mojom::IntAttribute::kNone;
+}
+
+const char* ToString(ax::mojom::FloatAttribute float_attribute) {
+ switch (float_attribute) {
+ case ax::mojom::FloatAttribute::kNone:
+ return "none";
+ case ax::mojom::FloatAttribute::kValueForRange:
+ return "valueForRange";
+ case ax::mojom::FloatAttribute::kMinValueForRange:
+ return "minValueForRange";
+ case ax::mojom::FloatAttribute::kMaxValueForRange:
+ return "maxValueForRange";
+ case ax::mojom::FloatAttribute::kStepValueForRange:
+ return "stepValueForRange";
+ case ax::mojom::FloatAttribute::kFontSize:
+ return "fontSize";
+ }
+
+ return "";
+}
+
+ax::mojom::FloatAttribute ParseFloatAttribute(const char* float_attribute) {
+ if (0 == strcmp(float_attribute, "none"))
+ return ax::mojom::FloatAttribute::kNone;
+ if (0 == strcmp(float_attribute, "valueForRange"))
+ return ax::mojom::FloatAttribute::kValueForRange;
+ if (0 == strcmp(float_attribute, "minValueForRange"))
+ return ax::mojom::FloatAttribute::kMinValueForRange;
+ if (0 == strcmp(float_attribute, "maxValueForRange"))
+ return ax::mojom::FloatAttribute::kMaxValueForRange;
+ if (0 == strcmp(float_attribute, "stepValueForRange"))
+ return ax::mojom::FloatAttribute::kStepValueForRange;
+ if (0 == strcmp(float_attribute, "fontSize"))
+ return ax::mojom::FloatAttribute::kFontSize;
+ return ax::mojom::FloatAttribute::kNone;
+}
+
+const char* ToString(ax::mojom::BoolAttribute bool_attribute) {
+ switch (bool_attribute) {
+ case ax::mojom::BoolAttribute::kNone:
+ return "none";
+ case ax::mojom::BoolAttribute::kBusy:
+ return "busy";
+ case ax::mojom::BoolAttribute::kEditableRoot:
+ return "editableRoot";
+ case ax::mojom::BoolAttribute::kContainerLiveAtomic:
+ return "containerLiveAtomic";
+ case ax::mojom::BoolAttribute::kContainerLiveBusy:
+ return "containerLiveBusy";
+ case ax::mojom::BoolAttribute::kLiveAtomic:
+ return "liveAtomic";
+ case ax::mojom::BoolAttribute::kModal:
+ return "modal";
+ case ax::mojom::BoolAttribute::kUpdateLocationOnly:
+ return "updateLocationOnly";
+ case ax::mojom::BoolAttribute::kCanvasHasFallback:
+ return "canvasHasFallback";
+ case ax::mojom::BoolAttribute::kScrollable:
+ return "scrollable";
+ case ax::mojom::BoolAttribute::kClickable:
+ return "clickable";
+ case ax::mojom::BoolAttribute::kClipsChildren:
+ return "clipsChildren";
+ }
+
+ return "";
+}
+
+ax::mojom::BoolAttribute ParseBoolAttribute(const char* bool_attribute) {
+ if (0 == strcmp(bool_attribute, "none"))
+ return ax::mojom::BoolAttribute::kNone;
+ if (0 == strcmp(bool_attribute, "busy"))
+ return ax::mojom::BoolAttribute::kBusy;
+ if (0 == strcmp(bool_attribute, "editableRoot"))
+ return ax::mojom::BoolAttribute::kEditableRoot;
+ if (0 == strcmp(bool_attribute, "containerLiveAtomic"))
+ return ax::mojom::BoolAttribute::kContainerLiveAtomic;
+ if (0 == strcmp(bool_attribute, "containerLiveBusy"))
+ return ax::mojom::BoolAttribute::kContainerLiveBusy;
+ if (0 == strcmp(bool_attribute, "liveAtomic"))
+ return ax::mojom::BoolAttribute::kLiveAtomic;
+ if (0 == strcmp(bool_attribute, "modal"))
+ return ax::mojom::BoolAttribute::kModal;
+ if (0 == strcmp(bool_attribute, "updateLocationOnly"))
+ return ax::mojom::BoolAttribute::kUpdateLocationOnly;
+ if (0 == strcmp(bool_attribute, "canvasHasFallback"))
+ return ax::mojom::BoolAttribute::kCanvasHasFallback;
+ if (0 == strcmp(bool_attribute, "scrollable"))
+ return ax::mojom::BoolAttribute::kScrollable;
+ if (0 == strcmp(bool_attribute, "clickable"))
+ return ax::mojom::BoolAttribute::kClickable;
+ if (0 == strcmp(bool_attribute, "clipsChildren"))
+ return ax::mojom::BoolAttribute::kClipsChildren;
+ return ax::mojom::BoolAttribute::kNone;
+}
+
+const char* ToString(ax::mojom::IntListAttribute int_list_attribute) {
+ switch (int_list_attribute) {
+ case ax::mojom::IntListAttribute::kNone:
+ return "none";
+ case ax::mojom::IntListAttribute::kIndirectChildIds:
+ return "indirectChildIds";
+ case ax::mojom::IntListAttribute::kControlsIds:
+ return "controlsIds";
+ case ax::mojom::IntListAttribute::kDescribedbyIds:
+ return "describedbyIds";
+ case ax::mojom::IntListAttribute::kFlowtoIds:
+ return "flowtoIds";
+ case ax::mojom::IntListAttribute::kLabelledbyIds:
+ return "labelledbyIds";
+ case ax::mojom::IntListAttribute::kRadioGroupIds:
+ return "radioGroupIds";
+ case ax::mojom::IntListAttribute::kLineBreaks:
+ return "lineBreaks";
+ case ax::mojom::IntListAttribute::kMarkerTypes:
+ return "markerTypes";
+ case ax::mojom::IntListAttribute::kMarkerStarts:
+ return "markerStarts";
+ case ax::mojom::IntListAttribute::kMarkerEnds:
+ return "markerEnds";
+ case ax::mojom::IntListAttribute::kCellIds:
+ return "cellIds";
+ case ax::mojom::IntListAttribute::kUniqueCellIds:
+ return "uniqueCellIds";
+ case ax::mojom::IntListAttribute::kCharacterOffsets:
+ return "characterOffsets";
+ case ax::mojom::IntListAttribute::kCachedLineStarts:
+ return "cachedLineStarts";
+ case ax::mojom::IntListAttribute::kWordStarts:
+ return "wordStarts";
+ case ax::mojom::IntListAttribute::kWordEnds:
+ return "wordEnds";
+ case ax::mojom::IntListAttribute::kCustomActionIds:
+ return "customActionIds";
+ }
+
+ return "";
+}
+
+ax::mojom::IntListAttribute ParseIntListAttribute(
+ const char* int_list_attribute) {
+ if (0 == strcmp(int_list_attribute, "none"))
+ return ax::mojom::IntListAttribute::kNone;
+ if (0 == strcmp(int_list_attribute, "indirectChildIds"))
+ return ax::mojom::IntListAttribute::kIndirectChildIds;
+ if (0 == strcmp(int_list_attribute, "controlsIds"))
+ return ax::mojom::IntListAttribute::kControlsIds;
+ if (0 == strcmp(int_list_attribute, "describedbyIds"))
+ return ax::mojom::IntListAttribute::kDescribedbyIds;
+ if (0 == strcmp(int_list_attribute, "flowtoIds"))
+ return ax::mojom::IntListAttribute::kFlowtoIds;
+ if (0 == strcmp(int_list_attribute, "labelledbyIds"))
+ return ax::mojom::IntListAttribute::kLabelledbyIds;
+ if (0 == strcmp(int_list_attribute, "radioGroupIds"))
+ return ax::mojom::IntListAttribute::kRadioGroupIds;
+ if (0 == strcmp(int_list_attribute, "lineBreaks"))
+ return ax::mojom::IntListAttribute::kLineBreaks;
+ if (0 == strcmp(int_list_attribute, "markerTypes"))
+ return ax::mojom::IntListAttribute::kMarkerTypes;
+ if (0 == strcmp(int_list_attribute, "markerStarts"))
+ return ax::mojom::IntListAttribute::kMarkerStarts;
+ if (0 == strcmp(int_list_attribute, "markerEnds"))
+ return ax::mojom::IntListAttribute::kMarkerEnds;
+ if (0 == strcmp(int_list_attribute, "cellIds"))
+ return ax::mojom::IntListAttribute::kCellIds;
+ if (0 == strcmp(int_list_attribute, "uniqueCellIds"))
+ return ax::mojom::IntListAttribute::kUniqueCellIds;
+ if (0 == strcmp(int_list_attribute, "characterOffsets"))
+ return ax::mojom::IntListAttribute::kCharacterOffsets;
+ if (0 == strcmp(int_list_attribute, "cachedLineStarts"))
+ return ax::mojom::IntListAttribute::kCachedLineStarts;
+ if (0 == strcmp(int_list_attribute, "wordStarts"))
+ return ax::mojom::IntListAttribute::kWordStarts;
+ if (0 == strcmp(int_list_attribute, "wordEnds"))
+ return ax::mojom::IntListAttribute::kWordEnds;
+ if (0 == strcmp(int_list_attribute, "customActionIds"))
+ return ax::mojom::IntListAttribute::kCustomActionIds;
+ return ax::mojom::IntListAttribute::kNone;
+}
+
+const char* ToString(ax::mojom::StringListAttribute string_list_attribute) {
+ switch (string_list_attribute) {
+ case ax::mojom::StringListAttribute::kNone:
+ return "none";
+ case ax::mojom::StringListAttribute::kCustomActionDescriptions:
+ return "customActionDescriptions";
+ }
+
+ return "";
+}
+
+ax::mojom::StringListAttribute ParseStringListAttribute(
+ const char* string_list_attribute) {
+ if (0 == strcmp(string_list_attribute, "none"))
+ return ax::mojom::StringListAttribute::kNone;
+ if (0 == strcmp(string_list_attribute, "customActionDescriptions"))
+ return ax::mojom::StringListAttribute::kCustomActionDescriptions;
+ return ax::mojom::StringListAttribute::kNone;
+}
+
+const char* ToString(ax::mojom::MarkerType marker_type) {
+ switch (marker_type) {
+ case ax::mojom::MarkerType::kNone:
+ return "none";
+ case ax::mojom::MarkerType::kSpelling:
+ return "spelling";
+ case ax::mojom::MarkerType::kGrammar:
+ return "grammar";
+ case ax::mojom::MarkerType::kSpellingGrammar:
+ return "spellingGrammar";
+ case ax::mojom::MarkerType::kTextMatch:
+ return "textMatch";
+ case ax::mojom::MarkerType::kSpellingTextMatch:
+ return "spellingTextMatch";
+ case ax::mojom::MarkerType::kGrammarTextMatch:
+ return "grammarTextMatch";
+ case ax::mojom::MarkerType::kSpellingGrammarTextMatch:
+ return "spellingGrammarTextMatch";
+ case ax::mojom::MarkerType::kActiveSuggestion:
+ return "activeSuggestion";
+ case ax::mojom::MarkerType::kSpellingActiveSuggestion:
+ return "spellingActiveSuggestion";
+ case ax::mojom::MarkerType::kGrammarActiveSuggestion:
+ return "grammarActiveSuggestion";
+ case ax::mojom::MarkerType::kSpellingGrammarActiveSuggestion:
+ return "spellingGrammarActiveSuggestion";
+ case ax::mojom::MarkerType::kTextMatchActiveSuggestion:
+ return "textMatchActiveSuggestion";
+ case ax::mojom::MarkerType::kSpellingTextMatchActiveSuggestion:
+ return "spellingTextMatchActiveSuggestion";
+ case ax::mojom::MarkerType::kGrammarTextMatchActiveSuggestion:
+ return "grammarTextMatchActiveSuggestion";
+ case ax::mojom::MarkerType::kSpellingGrammarTextMatchActiveSuggestion:
+ return "spellingGrammarTextMatchActiveSuggestion";
+ case ax::mojom::MarkerType::kSuggestion:
+ return "suggestion";
+ case ax::mojom::MarkerType::kSpellingSuggestion:
+ return "spellingSuggestion";
+ case ax::mojom::MarkerType::kGrammarSuggestion:
+ return "grammarSuggestion";
+ case ax::mojom::MarkerType::kSpellingGrammarSuggestion:
+ return "spellingGrammarSuggestion";
+ case ax::mojom::MarkerType::kTextMatchSuggestion:
+ return "textMatchSuggestion";
+ case ax::mojom::MarkerType::kSpellingTextMatchSuggestion:
+ return "spellingTextMatchSuggestion";
+ case ax::mojom::MarkerType::kGrammarTextMatchSuggestion:
+ return "grammarTextMatchSuggestion";
+ case ax::mojom::MarkerType::kSpellingGrammarTextMatchSuggestion:
+ return "spellingGrammarTextMatchSuggestion";
+ case ax::mojom::MarkerType::kActiveSuggestionSuggestion:
+ return "activeSuggestionSuggestion";
+ case ax::mojom::MarkerType::kSpellingActiveSuggestionSuggestion:
+ return "spellingActiveSuggestionSuggestion";
+ case ax::mojom::MarkerType::kGrammarActiveSuggestionSuggestion:
+ return "grammarActiveSuggestionSuggestion";
+ case ax::mojom::MarkerType::kSpellingGrammarActiveSuggestionSuggestion:
+ return "spellingGrammarActiveSuggestionSuggestion";
+ case ax::mojom::MarkerType::kTextMatchActiveSuggestionSuggestion:
+ return "textMatchActiveSuggestionSuggestion";
+ case ax::mojom::MarkerType::kSpellingTextMatchActiveSuggestionSuggestion:
+ return "spellingTextMatchActiveSuggestionSuggestion";
+ case ax::mojom::MarkerType::kGrammarTextMatchActiveSuggestionSuggestion:
+ return "grammarTextMatchActiveSuggestionSuggestion";
+ case ax::mojom::MarkerType::
+ kSpellingGrammarTextMatchActiveSuggestionSuggestion:
+ return "spellingGrammarTextMatchActiveSuggestionSuggestion";
+ }
+
+ return "";
+}
+
+ax::mojom::MarkerType ParseMarkerType(const char* marker_type) {
+ if (0 == strcmp(marker_type, "none"))
+ return ax::mojom::MarkerType::kNone;
+ if (0 == strcmp(marker_type, "spelling"))
+ return ax::mojom::MarkerType::kSpelling;
+ if (0 == strcmp(marker_type, "grammar"))
+ return ax::mojom::MarkerType::kGrammar;
+ if (0 == strcmp(marker_type, "spellingGrammar"))
+ return ax::mojom::MarkerType::kSpellingGrammar;
+ if (0 == strcmp(marker_type, "textMatch"))
+ return ax::mojom::MarkerType::kTextMatch;
+ if (0 == strcmp(marker_type, "spellingTextMatch"))
+ return ax::mojom::MarkerType::kSpellingTextMatch;
+ if (0 == strcmp(marker_type, "grammarTextMatch"))
+ return ax::mojom::MarkerType::kGrammarTextMatch;
+ if (0 == strcmp(marker_type, "spellingGrammarTextMatch"))
+ return ax::mojom::MarkerType::kSpellingGrammarTextMatch;
+ if (0 == strcmp(marker_type, "activeSuggestion"))
+ return ax::mojom::MarkerType::kActiveSuggestion;
+ if (0 == strcmp(marker_type, "spellingActiveSuggestion"))
+ return ax::mojom::MarkerType::kSpellingActiveSuggestion;
+ if (0 == strcmp(marker_type, "grammarActiveSuggestion"))
+ return ax::mojom::MarkerType::kGrammarActiveSuggestion;
+ if (0 == strcmp(marker_type, "spellingGrammarActiveSuggestion"))
+ return ax::mojom::MarkerType::kSpellingGrammarActiveSuggestion;
+ if (0 == strcmp(marker_type, "textMatchActiveSuggestion"))
+ return ax::mojom::MarkerType::kTextMatchActiveSuggestion;
+ if (0 == strcmp(marker_type, "spellingTextMatchActiveSuggestion"))
+ return ax::mojom::MarkerType::kSpellingTextMatchActiveSuggestion;
+ if (0 == strcmp(marker_type, "grammarTextMatchActiveSuggestion"))
+ return ax::mojom::MarkerType::kGrammarTextMatchActiveSuggestion;
+ if (0 == strcmp(marker_type, "spellingGrammarTextMatchActiveSuggestion"))
+ return ax::mojom::MarkerType::kSpellingGrammarTextMatchActiveSuggestion;
+ if (0 == strcmp(marker_type, "suggestion"))
+ return ax::mojom::MarkerType::kSuggestion;
+ if (0 == strcmp(marker_type, "spellingSuggestion"))
+ return ax::mojom::MarkerType::kSpellingSuggestion;
+ if (0 == strcmp(marker_type, "grammarSuggestion"))
+ return ax::mojom::MarkerType::kGrammarSuggestion;
+ if (0 == strcmp(marker_type, "spellingGrammarSuggestion"))
+ return ax::mojom::MarkerType::kSpellingGrammarSuggestion;
+ if (0 == strcmp(marker_type, "textMatchSuggestion"))
+ return ax::mojom::MarkerType::kTextMatchSuggestion;
+ if (0 == strcmp(marker_type, "spellingTextMatchSuggestion"))
+ return ax::mojom::MarkerType::kSpellingTextMatchSuggestion;
+ if (0 == strcmp(marker_type, "grammarTextMatchSuggestion"))
+ return ax::mojom::MarkerType::kGrammarTextMatchSuggestion;
+ if (0 == strcmp(marker_type, "spellingGrammarTextMatchSuggestion"))
+ return ax::mojom::MarkerType::kSpellingGrammarTextMatchSuggestion;
+ if (0 == strcmp(marker_type, "activeSuggestionSuggestion"))
+ return ax::mojom::MarkerType::kActiveSuggestionSuggestion;
+ if (0 == strcmp(marker_type, "spellingActiveSuggestionSuggestion"))
+ return ax::mojom::MarkerType::kSpellingActiveSuggestionSuggestion;
+ if (0 == strcmp(marker_type, "grammarActiveSuggestionSuggestion"))
+ return ax::mojom::MarkerType::kGrammarActiveSuggestionSuggestion;
+ if (0 == strcmp(marker_type, "spellingGrammarActiveSuggestionSuggestion"))
+ return ax::mojom::MarkerType::kSpellingGrammarActiveSuggestionSuggestion;
+ if (0 == strcmp(marker_type, "textMatchActiveSuggestionSuggestion"))
+ return ax::mojom::MarkerType::kTextMatchActiveSuggestionSuggestion;
+ if (0 == strcmp(marker_type, "spellingTextMatchActiveSuggestionSuggestion"))
+ return ax::mojom::MarkerType::kSpellingTextMatchActiveSuggestionSuggestion;
+ if (0 == strcmp(marker_type, "grammarTextMatchActiveSuggestionSuggestion"))
+ return ax::mojom::MarkerType::kGrammarTextMatchActiveSuggestionSuggestion;
+ if (0 ==
+ strcmp(marker_type, "spellingGrammarTextMatchActiveSuggestionSuggestion"))
+ return ax::mojom::MarkerType::
+ kSpellingGrammarTextMatchActiveSuggestionSuggestion;
+ return ax::mojom::MarkerType::kNone;
+}
+
+const char* ToString(ax::mojom::TextDirection text_direction) {
+ switch (text_direction) {
+ case ax::mojom::TextDirection::kNone:
+ return "none";
+ case ax::mojom::TextDirection::kLtr:
+ return "ltr";
+ case ax::mojom::TextDirection::kRtl:
+ return "rtl";
+ case ax::mojom::TextDirection::kTtb:
+ return "ttb";
+ case ax::mojom::TextDirection::kBtt:
+ return "btt";
+ }
+
+ return "";
+}
+
+ax::mojom::TextDirection ParseTextDirection(const char* text_direction) {
+ if (0 == strcmp(text_direction, "none"))
+ return ax::mojom::TextDirection::kNone;
+ if (0 == strcmp(text_direction, "ltr"))
+ return ax::mojom::TextDirection::kLtr;
+ if (0 == strcmp(text_direction, "rtl"))
+ return ax::mojom::TextDirection::kRtl;
+ if (0 == strcmp(text_direction, "ttb"))
+ return ax::mojom::TextDirection::kTtb;
+ if (0 == strcmp(text_direction, "btt"))
+ return ax::mojom::TextDirection::kBtt;
+ return ax::mojom::TextDirection::kNone;
+}
+
+const char* ToString(ax::mojom::TextStyle text_style) {
+ switch (text_style) {
+ case ax::mojom::TextStyle::kNone:
+ return "none";
+ case ax::mojom::TextStyle::kTextStyleBold:
+ return "textStyleBold";
+ case ax::mojom::TextStyle::kTextStyleItalic:
+ return "textStyleItalic";
+ case ax::mojom::TextStyle::kTextStyleBoldItalic:
+ return "textStyleBoldItalic";
+ case ax::mojom::TextStyle::kTextStyleUnderline:
+ return "textStyleUnderline";
+ case ax::mojom::TextStyle::kTextStyleBoldUnderline:
+ return "textStyleBoldUnderline";
+ case ax::mojom::TextStyle::kTextStyleItalicUnderline:
+ return "textStyleItalicUnderline";
+ case ax::mojom::TextStyle::kTextStyleBoldItalicUnderline:
+ return "textStyleBoldItalicUnderline";
+ case ax::mojom::TextStyle::kTextStyleLineThrough:
+ return "textStyleLineThrough";
+ case ax::mojom::TextStyle::kTextStyleBoldLineThrough:
+ return "textStyleBoldLineThrough";
+ case ax::mojom::TextStyle::kTextStyleItalicLineThrough:
+ return "textStyleItalicLineThrough";
+ case ax::mojom::TextStyle::kTextStyleBoldItalicLineThrough:
+ return "textStyleBoldItalicLineThrough";
+ case ax::mojom::TextStyle::kTextStyleUnderlineLineThrough:
+ return "textStyleUnderlineLineThrough";
+ case ax::mojom::TextStyle::kTextStyleBoldUnderlineLineThrough:
+ return "textStyleBoldUnderlineLineThrough";
+ case ax::mojom::TextStyle::kTextStyleItalicUnderlineLineThrough:
+ return "textStyleItalicUnderlineLineThrough";
+ case ax::mojom::TextStyle::kTextStyleBoldItalicUnderlineLineThrough:
+ return "textStyleBoldItalicUnderlineLineThrough";
+ }
+
+ return "";
+}
+
+ax::mojom::TextStyle ParseTextStyle(const char* text_style) {
+ if (0 == strcmp(text_style, "none"))
+ return ax::mojom::TextStyle::kNone;
+ if (0 == strcmp(text_style, "textStyleBold"))
+ return ax::mojom::TextStyle::kTextStyleBold;
+ if (0 == strcmp(text_style, "textStyleItalic"))
+ return ax::mojom::TextStyle::kTextStyleItalic;
+ if (0 == strcmp(text_style, "textStyleBoldItalic"))
+ return ax::mojom::TextStyle::kTextStyleBoldItalic;
+ if (0 == strcmp(text_style, "textStyleUnderline"))
+ return ax::mojom::TextStyle::kTextStyleUnderline;
+ if (0 == strcmp(text_style, "textStyleBoldUnderline"))
+ return ax::mojom::TextStyle::kTextStyleBoldUnderline;
+ if (0 == strcmp(text_style, "textStyleItalicUnderline"))
+ return ax::mojom::TextStyle::kTextStyleItalicUnderline;
+ if (0 == strcmp(text_style, "textStyleBoldItalicUnderline"))
+ return ax::mojom::TextStyle::kTextStyleBoldItalicUnderline;
+ if (0 == strcmp(text_style, "textStyleLineThrough"))
+ return ax::mojom::TextStyle::kTextStyleLineThrough;
+ if (0 == strcmp(text_style, "textStyleBoldLineThrough"))
+ return ax::mojom::TextStyle::kTextStyleBoldLineThrough;
+ if (0 == strcmp(text_style, "textStyleItalicLineThrough"))
+ return ax::mojom::TextStyle::kTextStyleItalicLineThrough;
+ if (0 == strcmp(text_style, "textStyleBoldItalicLineThrough"))
+ return ax::mojom::TextStyle::kTextStyleBoldItalicLineThrough;
+ if (0 == strcmp(text_style, "textStyleUnderlineLineThrough"))
+ return ax::mojom::TextStyle::kTextStyleUnderlineLineThrough;
+ if (0 == strcmp(text_style, "textStyleBoldUnderlineLineThrough"))
+ return ax::mojom::TextStyle::kTextStyleBoldUnderlineLineThrough;
+ if (0 == strcmp(text_style, "textStyleItalicUnderlineLineThrough"))
+ return ax::mojom::TextStyle::kTextStyleItalicUnderlineLineThrough;
+ if (0 == strcmp(text_style, "textStyleBoldItalicUnderlineLineThrough"))
+ return ax::mojom::TextStyle::kTextStyleBoldItalicUnderlineLineThrough;
+ return ax::mojom::TextStyle::kNone;
+}
+
+const char* ToString(ax::mojom::AriaCurrentState aria_current_state) {
+ switch (aria_current_state) {
+ case ax::mojom::AriaCurrentState::kNone:
+ return "none";
+ case ax::mojom::AriaCurrentState::kFalse:
+ return "false";
+ case ax::mojom::AriaCurrentState::kTrue:
+ return "true";
+ case ax::mojom::AriaCurrentState::kPage:
+ return "page";
+ case ax::mojom::AriaCurrentState::kStep:
+ return "step";
+ case ax::mojom::AriaCurrentState::kLocation:
+ return "location";
+ case ax::mojom::AriaCurrentState::kUnclippedLocation:
+ return "unclippedLocation";
+ case ax::mojom::AriaCurrentState::kDate:
+ return "date";
+ case ax::mojom::AriaCurrentState::kTime:
+ return "time";
+ }
+
+ return "";
+}
+
+ax::mojom::AriaCurrentState ParseAriaCurrentState(
+ const char* aria_current_state) {
+ if (0 == strcmp(aria_current_state, "none"))
+ return ax::mojom::AriaCurrentState::kNone;
+ if (0 == strcmp(aria_current_state, "false"))
+ return ax::mojom::AriaCurrentState::kFalse;
+ if (0 == strcmp(aria_current_state, "true"))
+ return ax::mojom::AriaCurrentState::kTrue;
+ if (0 == strcmp(aria_current_state, "page"))
+ return ax::mojom::AriaCurrentState::kPage;
+ if (0 == strcmp(aria_current_state, "step"))
+ return ax::mojom::AriaCurrentState::kStep;
+ if (0 == strcmp(aria_current_state, "location"))
+ return ax::mojom::AriaCurrentState::kLocation;
+ if (0 == strcmp(aria_current_state, "unclippedLocation"))
+ return ax::mojom::AriaCurrentState::kUnclippedLocation;
+ if (0 == strcmp(aria_current_state, "date"))
+ return ax::mojom::AriaCurrentState::kDate;
+ if (0 == strcmp(aria_current_state, "time"))
+ return ax::mojom::AriaCurrentState::kTime;
+ return ax::mojom::AriaCurrentState::kNone;
+}
+
+const char* ToString(ax::mojom::InvalidState invalid_state) {
+ switch (invalid_state) {
+ case ax::mojom::InvalidState::kNone:
+ return "none";
+ case ax::mojom::InvalidState::kFalse:
+ return "false";
+ case ax::mojom::InvalidState::kTrue:
+ return "true";
+ case ax::mojom::InvalidState::kSpelling:
+ return "spelling";
+ case ax::mojom::InvalidState::kGrammar:
+ return "grammar";
+ case ax::mojom::InvalidState::kOther:
+ return "other";
+ }
+
+ return "";
+}
+
+ax::mojom::InvalidState ParseInvalidState(const char* invalid_state) {
+ if (0 == strcmp(invalid_state, "none"))
+ return ax::mojom::InvalidState::kNone;
+ if (0 == strcmp(invalid_state, "false"))
+ return ax::mojom::InvalidState::kFalse;
+ if (0 == strcmp(invalid_state, "true"))
+ return ax::mojom::InvalidState::kTrue;
+ if (0 == strcmp(invalid_state, "spelling"))
+ return ax::mojom::InvalidState::kSpelling;
+ if (0 == strcmp(invalid_state, "grammar"))
+ return ax::mojom::InvalidState::kGrammar;
+ if (0 == strcmp(invalid_state, "other"))
+ return ax::mojom::InvalidState::kOther;
+ return ax::mojom::InvalidState::kNone;
+}
+
+const char* ToString(ax::mojom::Restriction restriction) {
+ switch (restriction) {
+ case ax::mojom::Restriction::kNone:
+ return "none";
+ case ax::mojom::Restriction::kReadOnly:
+ return "readOnly";
+ case ax::mojom::Restriction::kDisabled:
+ return "disabled";
+ }
+
+ return "";
+}
+
+ax::mojom::Restriction ParseRestriction(const char* restriction) {
+ if (0 == strcmp(restriction, "none"))
+ return ax::mojom::Restriction::kNone;
+ if (0 == strcmp(restriction, "readOnly"))
+ return ax::mojom::Restriction::kReadOnly;
+ if (0 == strcmp(restriction, "disabled"))
+ return ax::mojom::Restriction::kDisabled;
+ return ax::mojom::Restriction::kNone;
+}
+
+const char* ToString(ax::mojom::CheckedState checked_state) {
+ switch (checked_state) {
+ case ax::mojom::CheckedState::kNone:
+ return "none";
+ case ax::mojom::CheckedState::kFalse:
+ return "false";
+ case ax::mojom::CheckedState::kTrue:
+ return "true";
+ case ax::mojom::CheckedState::kMixed:
+ return "mixed";
+ }
+
+ return "";
+}
+
+ax::mojom::CheckedState ParseCheckedState(const char* checked_state) {
+ if (0 == strcmp(checked_state, "none"))
+ return ax::mojom::CheckedState::kNone;
+ if (0 == strcmp(checked_state, "false"))
+ return ax::mojom::CheckedState::kFalse;
+ if (0 == strcmp(checked_state, "true"))
+ return ax::mojom::CheckedState::kTrue;
+ if (0 == strcmp(checked_state, "mixed"))
+ return ax::mojom::CheckedState::kMixed;
+ return ax::mojom::CheckedState::kNone;
+}
+
+const char* ToString(ax::mojom::SortDirection sort_direction) {
+ switch (sort_direction) {
+ case ax::mojom::SortDirection::kNone:
+ return "none";
+ case ax::mojom::SortDirection::kUnsorted:
+ return "unsorted";
+ case ax::mojom::SortDirection::kAscending:
+ return "ascending";
+ case ax::mojom::SortDirection::kDescending:
+ return "descending";
+ case ax::mojom::SortDirection::kOther:
+ return "other";
+ }
+
+ return "";
+}
+
+ax::mojom::SortDirection ParseSortDirection(const char* sort_direction) {
+ if (0 == strcmp(sort_direction, "none"))
+ return ax::mojom::SortDirection::kNone;
+ if (0 == strcmp(sort_direction, "unsorted"))
+ return ax::mojom::SortDirection::kUnsorted;
+ if (0 == strcmp(sort_direction, "ascending"))
+ return ax::mojom::SortDirection::kAscending;
+ if (0 == strcmp(sort_direction, "descending"))
+ return ax::mojom::SortDirection::kDescending;
+ if (0 == strcmp(sort_direction, "other"))
+ return ax::mojom::SortDirection::kOther;
+ return ax::mojom::SortDirection::kNone;
+}
+
+const char* ToString(ax::mojom::NameFrom name_from) {
+ switch (name_from) {
+ case ax::mojom::NameFrom::kNone:
+ return "none";
+ case ax::mojom::NameFrom::kUninitialized:
+ return "uninitialized";
+ case ax::mojom::NameFrom::kAttribute:
+ return "attribute";
+ case ax::mojom::NameFrom::kAttributeExplicitlyEmpty:
+ return "attributeExplicitlyEmpty";
+ case ax::mojom::NameFrom::kContents:
+ return "contents";
+ case ax::mojom::NameFrom::kPlaceholder:
+ return "placeholder";
+ case ax::mojom::NameFrom::kRelatedElement:
+ return "relatedElement";
+ case ax::mojom::NameFrom::kValue:
+ return "value";
+ }
+
+ return "";
+}
+
+ax::mojom::NameFrom ParseNameFrom(const char* name_from) {
+ if (0 == strcmp(name_from, "none"))
+ return ax::mojom::NameFrom::kNone;
+ if (0 == strcmp(name_from, "uninitialized"))
+ return ax::mojom::NameFrom::kUninitialized;
+ if (0 == strcmp(name_from, "attribute"))
+ return ax::mojom::NameFrom::kAttribute;
+ if (0 == strcmp(name_from, "attributeExplicitlyEmpty"))
+ return ax::mojom::NameFrom::kAttributeExplicitlyEmpty;
+ if (0 == strcmp(name_from, "contents"))
+ return ax::mojom::NameFrom::kContents;
+ if (0 == strcmp(name_from, "placeholder"))
+ return ax::mojom::NameFrom::kPlaceholder;
+ if (0 == strcmp(name_from, "relatedElement"))
+ return ax::mojom::NameFrom::kRelatedElement;
+ if (0 == strcmp(name_from, "value"))
+ return ax::mojom::NameFrom::kValue;
+ return ax::mojom::NameFrom::kNone;
+}
+
+const char* ToString(ax::mojom::DescriptionFrom description_from) {
+ switch (description_from) {
+ case ax::mojom::DescriptionFrom::kNone:
+ return "none";
+ case ax::mojom::DescriptionFrom::kUninitialized:
+ return "uninitialized";
+ case ax::mojom::DescriptionFrom::kAttribute:
+ return "attribute";
+ case ax::mojom::DescriptionFrom::kContents:
+ return "contents";
+ case ax::mojom::DescriptionFrom::kPlaceholder:
+ return "placeholder";
+ case ax::mojom::DescriptionFrom::kRelatedElement:
+ return "relatedElement";
+ }
+
+ return "";
+}
+
+ax::mojom::DescriptionFrom ParseDescriptionFrom(const char* description_from) {
+ if (0 == strcmp(description_from, "none"))
+ return ax::mojom::DescriptionFrom::kNone;
+ if (0 == strcmp(description_from, "uninitialized"))
+ return ax::mojom::DescriptionFrom::kUninitialized;
+ if (0 == strcmp(description_from, "attribute"))
+ return ax::mojom::DescriptionFrom::kAttribute;
+ if (0 == strcmp(description_from, "contents"))
+ return ax::mojom::DescriptionFrom::kContents;
+ if (0 == strcmp(description_from, "placeholder"))
+ return ax::mojom::DescriptionFrom::kPlaceholder;
+ if (0 == strcmp(description_from, "relatedElement"))
+ return ax::mojom::DescriptionFrom::kRelatedElement;
+ return ax::mojom::DescriptionFrom::kNone;
+}
+
+const char* ToString(ax::mojom::EventFrom event_from) {
+ switch (event_from) {
+ case ax::mojom::EventFrom::kNone:
+ return "none";
+ case ax::mojom::EventFrom::kUser:
+ return "user";
+ case ax::mojom::EventFrom::kPage:
+ return "page";
+ case ax::mojom::EventFrom::kAction:
+ return "action";
+ }
+
+ return "";
+}
+
+ax::mojom::EventFrom ParseEventFrom(const char* event_from) {
+ if (0 == strcmp(event_from, "none"))
+ return ax::mojom::EventFrom::kNone;
+ if (0 == strcmp(event_from, "user"))
+ return ax::mojom::EventFrom::kUser;
+ if (0 == strcmp(event_from, "page"))
+ return ax::mojom::EventFrom::kPage;
+ if (0 == strcmp(event_from, "action"))
+ return ax::mojom::EventFrom::kAction;
+ return ax::mojom::EventFrom::kNone;
+}
+
+const char* ToString(ax::mojom::Gesture gesture) {
+ switch (gesture) {
+ case ax::mojom::Gesture::kNone:
+ return "none";
+ case ax::mojom::Gesture::kClick:
+ return "click";
+ case ax::mojom::Gesture::kSwipeLeft1:
+ return "swipeLeft1";
+ case ax::mojom::Gesture::kSwipeUp1:
+ return "swipeUp1";
+ case ax::mojom::Gesture::kSwipeRight1:
+ return "swipeRight1";
+ case ax::mojom::Gesture::kSwipeDown1:
+ return "swipeDown1";
+ case ax::mojom::Gesture::kSwipeLeft2:
+ return "swipeLeft2";
+ case ax::mojom::Gesture::kSwipeUp2:
+ return "swipeUp2";
+ case ax::mojom::Gesture::kSwipeRight2:
+ return "swipeRight2";
+ case ax::mojom::Gesture::kSwipeDown2:
+ return "swipeDown2";
+ case ax::mojom::Gesture::kSwipeLeft3:
+ return "swipeLeft3";
+ case ax::mojom::Gesture::kSwipeUp3:
+ return "swipeUp3";
+ case ax::mojom::Gesture::kSwipeRight3:
+ return "swipeRight3";
+ case ax::mojom::Gesture::kSwipeDown3:
+ return "swipeDown3";
+ case ax::mojom::Gesture::kSwipeLeft4:
+ return "swipeLeft4";
+ case ax::mojom::Gesture::kSwipeUp4:
+ return "swipeUp4";
+ case ax::mojom::Gesture::kSwipeRight4:
+ return "swipeRight4";
+ case ax::mojom::Gesture::kSwipeDown4:
+ return "swipeDown4";
+ case ax::mojom::Gesture::kTap2:
+ return "tap2";
+ }
+
+ return "";
+}
+
+ax::mojom::Gesture ParseGesture(const char* gesture) {
+ if (0 == strcmp(gesture, "none"))
+ return ax::mojom::Gesture::kNone;
+ if (0 == strcmp(gesture, "click"))
+ return ax::mojom::Gesture::kClick;
+ if (0 == strcmp(gesture, "swipeLeft1"))
+ return ax::mojom::Gesture::kSwipeLeft1;
+ if (0 == strcmp(gesture, "swipeUp1"))
+ return ax::mojom::Gesture::kSwipeUp1;
+ if (0 == strcmp(gesture, "swipeRight1"))
+ return ax::mojom::Gesture::kSwipeRight1;
+ if (0 == strcmp(gesture, "swipeDown1"))
+ return ax::mojom::Gesture::kSwipeDown1;
+ if (0 == strcmp(gesture, "swipeLeft2"))
+ return ax::mojom::Gesture::kSwipeLeft2;
+ if (0 == strcmp(gesture, "swipeUp2"))
+ return ax::mojom::Gesture::kSwipeUp2;
+ if (0 == strcmp(gesture, "swipeRight2"))
+ return ax::mojom::Gesture::kSwipeRight2;
+ if (0 == strcmp(gesture, "swipeDown2"))
+ return ax::mojom::Gesture::kSwipeDown2;
+ if (0 == strcmp(gesture, "swipeLeft3"))
+ return ax::mojom::Gesture::kSwipeLeft3;
+ if (0 == strcmp(gesture, "swipeUp3"))
+ return ax::mojom::Gesture::kSwipeUp3;
+ if (0 == strcmp(gesture, "swipeRight3"))
+ return ax::mojom::Gesture::kSwipeRight3;
+ if (0 == strcmp(gesture, "swipeDown3"))
+ return ax::mojom::Gesture::kSwipeDown3;
+ if (0 == strcmp(gesture, "swipeLeft4"))
+ return ax::mojom::Gesture::kSwipeLeft4;
+ if (0 == strcmp(gesture, "swipeUp4"))
+ return ax::mojom::Gesture::kSwipeUp4;
+ if (0 == strcmp(gesture, "swipeRight4"))
+ return ax::mojom::Gesture::kSwipeRight4;
+ if (0 == strcmp(gesture, "swipeDown4"))
+ return ax::mojom::Gesture::kSwipeDown4;
+ if (0 == strcmp(gesture, "tap2"))
+ return ax::mojom::Gesture::kTap2;
+ return ax::mojom::Gesture::kNone;
+}
+
+const char* ToString(ax::mojom::TextAffinity text_affinity) {
+ switch (text_affinity) {
+ case ax::mojom::TextAffinity::kNone:
+ return "none";
+ case ax::mojom::TextAffinity::kDownstream:
+ return "downstream";
+ case ax::mojom::TextAffinity::kUpstream:
+ return "upstream";
+ }
+
+ return "";
+}
+
+ax::mojom::TextAffinity ParseTextAffinity(const char* text_affinity) {
+ if (0 == strcmp(text_affinity, "none"))
+ return ax::mojom::TextAffinity::kNone;
+ if (0 == strcmp(text_affinity, "downstream"))
+ return ax::mojom::TextAffinity::kDownstream;
+ if (0 == strcmp(text_affinity, "upstream"))
+ return ax::mojom::TextAffinity::kUpstream;
+ return ax::mojom::TextAffinity::kNone;
+}
+
+const char* ToString(ax::mojom::TreeOrder tree_order) {
+ switch (tree_order) {
+ case ax::mojom::TreeOrder::kNone:
+ return "none";
+ case ax::mojom::TreeOrder::kUndefined:
+ return "undefined";
+ case ax::mojom::TreeOrder::kBefore:
+ return "before";
+ case ax::mojom::TreeOrder::kEqual:
+ return "equal";
+ case ax::mojom::TreeOrder::kAfter:
+ return "after";
+ }
+
+ return "";
+}
+
+ax::mojom::TreeOrder ParseTreeOrder(const char* tree_order) {
+ if (0 == strcmp(tree_order, "none"))
+ return ax::mojom::TreeOrder::kNone;
+ if (0 == strcmp(tree_order, "undefined"))
+ return ax::mojom::TreeOrder::kUndefined;
+ if (0 == strcmp(tree_order, "before"))
+ return ax::mojom::TreeOrder::kBefore;
+ if (0 == strcmp(tree_order, "equal"))
+ return ax::mojom::TreeOrder::kEqual;
+ if (0 == strcmp(tree_order, "after"))
+ return ax::mojom::TreeOrder::kAfter;
+ return ax::mojom::TreeOrder::kNone;
+}
+
+} // namespace ui
diff --git a/chromium/ui/accessibility/ax_enum_util.h b/chromium/ui/accessibility/ax_enum_util.h
new file mode 100644
index 00000000000..e331b4ea41a
--- /dev/null
+++ b/chromium/ui/accessibility/ax_enum_util.h
@@ -0,0 +1,130 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/accessibility/ax_enums.mojom.h"
+#include "ui/accessibility/ax_export.h"
+
+namespace ui {
+
+// ax::mojom::Event
+AX_EXPORT const char* ToString(ax::mojom::Event event);
+AX_EXPORT ax::mojom::Event ParseEvent(const char* event);
+
+// ax::mojom::Role
+AX_EXPORT const char* ToString(ax::mojom::Role role);
+AX_EXPORT ax::mojom::Role ParseRole(const char* role);
+
+// ax::mojom::State
+AX_EXPORT const char* ToString(ax::mojom::State state);
+AX_EXPORT ax::mojom::State ParseState(const char* state);
+
+// ax::mojom::Action
+AX_EXPORT const char* ToString(ax::mojom::Action action);
+AX_EXPORT ax::mojom::Action ParseAction(const char* action);
+
+// ax::mojom::ActionFlags
+AX_EXPORT const char* ToString(ax::mojom::ActionFlags action_flags);
+AX_EXPORT ax::mojom::ActionFlags ParseActionFlags(const char* action_flags);
+
+// ax::mojom::DefaultActionVerb
+AX_EXPORT const char* ToString(
+ ax::mojom::DefaultActionVerb default_action_verb);
+AX_EXPORT ax::mojom::DefaultActionVerb ParseDefaultActionVerb(
+ const char* default_action_verb);
+
+// ax::mojom::Mutation
+AX_EXPORT const char* ToString(ax::mojom::Mutation mutation);
+AX_EXPORT ax::mojom::Mutation ParseMutation(const char* mutation);
+
+// ax::mojom::StringAttribute
+AX_EXPORT const char* ToString(ax::mojom::StringAttribute string_attribute);
+AX_EXPORT ax::mojom::StringAttribute ParseStringAttribute(
+ const char* string_attribute);
+
+// ax::mojom::IntAttribute
+AX_EXPORT const char* ToString(ax::mojom::IntAttribute int_attribute);
+AX_EXPORT ax::mojom::IntAttribute ParseIntAttribute(const char* int_attribute);
+
+// ax::mojom::FloatAttribute
+AX_EXPORT const char* ToString(ax::mojom::FloatAttribute float_attribute);
+AX_EXPORT ax::mojom::FloatAttribute ParseFloatAttribute(
+ const char* float_attribute);
+
+// ax::mojom::BoolAttribute
+AX_EXPORT const char* ToString(ax::mojom::BoolAttribute bool_attribute);
+AX_EXPORT ax::mojom::BoolAttribute ParseBoolAttribute(
+ const char* bool_attribute);
+
+// ax::mojom::IntListAttribute
+AX_EXPORT const char* ToString(ax::mojom::IntListAttribute int_list_attribute);
+AX_EXPORT ax::mojom::IntListAttribute ParseIntListAttribute(
+ const char* int_list_attribute);
+
+// ax::mojom::StringListAttribute
+AX_EXPORT const char* ToString(
+ ax::mojom::StringListAttribute string_list_attribute);
+AX_EXPORT ax::mojom::StringListAttribute ParseStringListAttribute(
+ const char* string_list_attribute);
+
+// ax::mojom::MarkerType
+AX_EXPORT const char* ToString(ax::mojom::MarkerType marker_type);
+AX_EXPORT ax::mojom::MarkerType ParseMarkerType(const char* marker_type);
+
+// ax::mojom::TextDirection
+AX_EXPORT const char* ToString(ax::mojom::TextDirection text_direction);
+AX_EXPORT ax::mojom::TextDirection ParseTextDirection(
+ const char* text_direction);
+
+// ax::mojom::TextStyle
+AX_EXPORT const char* ToString(ax::mojom::TextStyle text_style);
+AX_EXPORT ax::mojom::TextStyle ParseTextStyle(const char* text_style);
+
+// ax::mojom::AriaCurrentState
+AX_EXPORT const char* ToString(ax::mojom::AriaCurrentState aria_current_state);
+AX_EXPORT ax::mojom::AriaCurrentState ParseAriaCurrentState(
+ const char* aria_current_state);
+
+// ax::mojom::InvalidState
+AX_EXPORT const char* ToString(ax::mojom::InvalidState invalid_state);
+AX_EXPORT ax::mojom::InvalidState ParseInvalidState(const char* invalid_state);
+
+// ax::mojom::Restriction
+AX_EXPORT const char* ToString(ax::mojom::Restriction restriction);
+AX_EXPORT ax::mojom::Restriction ParseRestriction(const char* restriction);
+
+// ax::mojom::CheckedState
+AX_EXPORT const char* ToString(ax::mojom::CheckedState checked_state);
+AX_EXPORT ax::mojom::CheckedState ParseCheckedState(const char* checked_state);
+
+// ax::mojom::SortDirection
+AX_EXPORT const char* ToString(ax::mojom::SortDirection sort_direction);
+AX_EXPORT ax::mojom::SortDirection ParseSortDirection(
+ const char* sort_direction);
+
+// ax::mojom::NameFrom
+AX_EXPORT const char* ToString(ax::mojom::NameFrom name_from);
+AX_EXPORT ax::mojom::NameFrom ParseNameFrom(const char* name_from);
+
+// ax::mojom::DescriptionFrom
+AX_EXPORT const char* ToString(ax::mojom::DescriptionFrom description_from);
+AX_EXPORT ax::mojom::DescriptionFrom ParseDescriptionFrom(
+ const char* description_from);
+
+// ax::mojom::EventFrom
+AX_EXPORT const char* ToString(ax::mojom::EventFrom event_from);
+AX_EXPORT ax::mojom::EventFrom ParseEventFrom(const char* event_from);
+
+// ax::mojom::Gesture
+AX_EXPORT const char* ToString(ax::mojom::Gesture gesture);
+AX_EXPORT ax::mojom::Gesture ParseGesture(const char* gesture);
+
+// ax::mojom::TextAffinity
+AX_EXPORT const char* ToString(ax::mojom::TextAffinity text_affinity);
+AX_EXPORT ax::mojom::TextAffinity ParseTextAffinity(const char* text_affinity);
+
+// ax::mojom::TreeOrder
+AX_EXPORT const char* ToString(ax::mojom::TreeOrder tree_order);
+AX_EXPORT ax::mojom::TreeOrder ParseTreeOrder(const char* tree_order);
+
+} // namespace ui
diff --git a/chromium/ui/accessibility/ax_enums.idl b/chromium/ui/accessibility/ax_enums.idl
deleted file mode 100644
index c3c73442e9b..00000000000
--- a/chromium/ui/accessibility/ax_enums.idl
+++ /dev/null
@@ -1,756 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// TODO(nektar): Migrate entire file to Mojoq.
-// Must also be kept in sync with chrome/common/extensions/api/automation.idl.
-[camel_case_enum_to_string=true] namespace ui {
-
- // For new entries to the following four enums, also add to
- // chrome/common/extensions/api/automation.idl. This is enforced
- // by a PRESUBMIT check.
- //
- // Explanation of the comments next to these events:
- //
- // Web: this event is only used in web content. Unless a specific platform
- // is specified, it fires a native event on multiple platforms.
- //
- // Native: this event is only used in native UI.
- //
- // Implicit: it would be cleaner if we just updated the AX node
- // and each platform fired the appropriate events to indicate which
- // platform-specific attributes changed.
- //
- // If unspecified, the event is used across web and native on multiple
- // platforms.
- enum AXEvent {
- activedescendantchanged, // Web
- alert,
- aria_attribute_changed, // Implicit
- autocorrection_occured, // Unknown: http://crbug.com/392498
- blur, // Remove: http://crbug.com/392502
- checked_state_changed, // Implicit
- children_changed,
- clicked,
- document_selection_changed,
- expanded_changed, // Web
- focus,
- hide, // Remove: http://crbug.com/392502
- hit_test_result,
- hover,
- image_frame_updated, // Web
- invalid_status_changed, // Implicit
- layout_complete, // Web
- live_region_created, // Implicit
- live_region_changed, // Web
- load_complete, // Web
- location_changed, // Web
- media_started_playing, // Automation
- media_stopped_playing, // Automation
- menu_end, // Native / Win
- menu_list_item_selected, // Web
- menu_list_value_changed, // Web
- menu_popup_end, // Native / Win
- menu_popup_start, // Native / Win
- menu_start, // Native / Win
- mouse_canceled,
- mouse_dragged,
- mouse_moved,
- mouse_pressed,
- mouse_released,
- row_collapsed, // Web / Mac
- row_count_changed, // Web / Mac
- row_expanded, // Web / Mac
- scroll_position_changed, // Web
- scrolled_to_anchor, // Web
- selected_children_changed, // Web
- selection, // Native
- selection_add, // Native
- selection_remove, // Native
- show, // Remove: http://crbug.com/392502
- text_changed,
- text_selection_changed,
- tree_changed, // Accessibility tree changed. Don't
- // explicitly fire an accessibility event,
- // only implicitly due to the change.
- value_changed
- };
-
- enum AXRole {
- abbr,
- alert_dialog,
- alert,
- anchor,
- annotation,
- application,
- article,
- audio,
- banner,
- blockquote,
- button,
- button_drop_down, // Not used on Web.
- canvas,
- caption,
- caret,
- cell,
- check_box,
- client,
- color_well,
- column_header,
- column,
- combo_box_grouping,
- combo_box_menu_button,
- complementary,
- content_info,
- date,
- date_time,
- definition,
- description_list_detail,
- description_list,
- description_list_term,
- desktop,
- details,
- dialog,
- directory,
- disclosure_triangle,
- document,
- embedded_object,
- feed,
- figcaption,
- figure,
- footer,
- form,
- generic_container,
- grid,
- group,
- heading,
- iframe,
- iframe_presentational,
- ignored,
- image_map,
- image,
- inline_text_box,
- input_time,
- label_text,
- legend,
- line_break,
- link,
- list_box_option,
- list_box,
- list_item,
- list_marker,
- list,
- location_bar,
- log,
- main,
- mark,
- marquee,
- math,
- menu,
- menu_bar,
- menu_button,
- menu_item,
- menu_item_check_box,
- menu_item_radio,
- menu_list_option,
- menu_list_popup,
- meter,
- navigation,
- note,
- pane,
- paragraph,
- pop_up_button,
- pre,
- presentational,
- progress_indicator,
- radio_button,
- radio_group,
- region,
- root_web_area,
- row_header,
- row,
- ruby,
- svg_root,
- scroll_bar,
- search,
- search_box,
- slider,
- slider_thumb,
- spin_button_part,
- spin_button,
- splitter,
- static_text,
- status,
- switch,
- tab_list,
- tab_panel,
- tab,
- table_header_container,
- table,
- term,
- text_field,
- text_field_with_combo_box,
- time,
- timer,
- title_bar,
- toggle_button,
- toolbar,
- tree_grid,
- tree_item,
- tree,
- unknown,
- tooltip,
- video,
- web_area,
- web_view,
- window
- };
-
- enum AXState {
- collapsed,
- default,
- editable,
- expanded,
- focusable,
- haspopup,
- // Grows horizontally, e.g. most toolbars and separators.
- horizontal,
- hovered,
- invisible,
- linked,
- multiline,
- multiselectable,
- protected,
- required,
- richly_editable,
- selectable,
- selected,
- // Grows vertically, e.g. menu or combo box.
- vertical,
- visited
- };
-
- // An action to be taken on an accessibility node.
- // In contrast to |AXDefaultActionVerb|, these describe what happens to the
- // object, e.g. "FOCUS".
- enum AXAction {
- blur,
-
- custom_action,
-
- // Decrement a slider or range control by one step value.
- decrement,
-
- // Do the default action for an object, typically this means "click".
- do_default,
-
- focus,
-
- // Return the content of this image object in the image_data attribute.
- get_image_data,
-
- // Given a point, find the object it corresponds to and fire a
- // |AXActionData.hit_test_event_to_fire| event on it in response.
- hit_test,
-
- // Increment a slider or range control by one step value.
- increment,
-
- // Load inline text boxes for this subtree, providing information
- // about word boundaries, line layout, and individual character
- // bounding boxes.
- load_inline_text_boxes,
-
- // Delete any selected text in the control's text value and
- // insert |AXActionData::value| in its place, like when typing or pasting.
- replace_selected_text,
-
- // Scrolls by approximately one screen in a specific direction. Should be
- // called on a node that has scrollable boolean set to true.
- scroll_backward,
- scroll_forward,
- scroll_up,
- scroll_down,
- scroll_left,
- scroll_right,
-
- // Scroll any scrollable containers to make the target object visible
- // on the screen. Optionally pass a subfocus rect in
- // AXActionData.target_rect, in node-local coordinates.
- scroll_to_make_visible,
-
- // Scroll the given object to a specified point on the screen in
- // global screen coordinates. Pass a point in AXActionData.target_point.
- scroll_to_point,
-
- set_scroll_offset,
- set_selection,
-
- // Don't focus this node, but set it as the sequential focus navigation
- // starting point, so that pressing Tab moves to the next element
- // following this one, for example.
- set_sequential_focus_navigation_starting_point,
-
- // Replace the value of the control with AXActionData::value and
- // reset the selection, if applicable.
- set_value,
-
- show_context_menu
- };
-
- enum AXActionFlags {
- request_images,
- request_inline_text_boxes
- };
-
- // A list of valid values for the |AXIntAttribute| |default_action_verb|.
- // These will describe the action that will be performed on a given node when
- // executing the default action, which is a click.
- // In contrast to |AXAction|, these describe what the user can do on the
- // object, e.g. "PRESS", not what happens to the object as a result.
- // Only one verb can be used at a time to describe the default action.
- enum AXDefaultActionVerb {
- activate,
- check,
- click,
-
- // A click will be performed on one of the node's ancestors.
- // This happens when the node itself is not clickable, but one of its
- // ancestors has click handlers attached which are able to capture the click
- // as it bubbles up.
- click_ancestor,
-
- jump,
- open,
- press,
- select,
- uncheck
- };
-
- // A change to the accessibility tree.
- enum AXMutation {
- node_created,
- subtree_created,
- node_changed,
- node_removed
- };
-
- [cpp_enum_prefix_override="ax_attr"] enum AXStringAttribute {
- access_key,
- // Only used when invalid_state == invalid_state_other.
- aria_invalid_value,
- auto_complete,
- chrome_channel, // Automation only.
- class_name, // views and Android
- container_live_relevant,
- container_live_status,
- description,
- display,
- // Only present when different from parent.
- font_family,
- html_tag,
- image_data_url,
- inner_html,
- key_shortcuts,
- // Only present when different from parent.
- language,
- name,
- live_relevant,
- live_status,
- placeholder,
- role,
- role_description,
- url,
- value
- };
-
- [cpp_enum_prefix_override="ax_attr"] enum AXIntAttribute {
- default_action_verb,
- // Scrollable container attributes.
- scroll_x,
- scroll_x_min,
- scroll_x_max,
- scroll_y,
- scroll_y_min,
- scroll_y_max,
-
- // Attributes for retrieving the endpoints of a selection.
- text_sel_start,
- text_sel_end,
-
- // aria_col* and aria_row* attributes
- aria_column_count,
- aria_cell_column_index,
- aria_row_count,
- aria_cell_row_index,
-
- // Table attributes.
- table_row_count,
- table_column_count,
- table_header_id,
-
- // Table row attributes.
- table_row_index,
- table_row_header_id,
-
- // Table column attributes.
- table_column_index,
- table_column_header_id,
-
- // Table cell attributes.
- table_cell_column_index,
- table_cell_column_span,
- table_cell_row_index,
- table_cell_row_span,
- sort_direction,
-
- // Tree control attributes.
- hierarchical_level,
-
- // What information was used to compute the object's name
- // (of type AXNameFrom).
- name_from,
-
- // What information was used to compute the object's description
- // (of type AXDescriptionFrom).
- description_from,
-
- // Relationships between this element and other elements.
- activedescendant_id,
- details_id,
- errormessage_id,
- in_page_link_target_id,
- member_of_id,
- next_on_line_id,
- previous_on_line_id,
-
- // Identifies a child tree which this node hosts.
- child_tree_id,
-
- // Input restriction, if any, such as readonly or disabled.
- // Of type AXRestriction, see below.
- // No value or enabled control or other object that is not disabled.
- restriction,
-
- // Position or Number of items in current set of listitems or treeitems
- set_size,
- pos_in_set,
-
- // In the case of AX_ROLE_COLOR_WELL, specifies the selected color.
- color_value,
-
- // Indicates the element that represents the current item within a container
- // or set of related elements.
- aria_current_state,
-
- // Text attributes.
-
- // Foreground and background color in RGBA.
- background_color,
- color,
-
- // Indicates if a form control has invalid input or
- // if an element has an aria-invalid attribute.
- invalid_state,
-
- // Of type AXCheckedState
- checked_state,
-
- // Specifies the direction of the text, e.g., right-to-left.
- text_direction,
-
- // Bold, italic, underline, etc.
- text_style,
-
- // Focus traversal in views and Android.
- previous_focus_id,
- next_focus_id
- };
-
- [cpp_enum_prefix_override="ax_attr"] enum AXFloatAttribute {
- // Range attributes.
- value_for_range,
- min_value_for_range,
- max_value_for_range,
- step_value_for_range,
-
- // Text attributes.
- // Font size is in pixels.
- font_size
- };
-
- [cpp_enum_prefix_override="ax_attr"] enum AXBoolAttribute {
- // Generic busy state, does not have to be on a live region.
- busy,
- // The object is at the root of an editable field, such as a content
- // editable.
- editable_root,
-
- // Live region attributes.
- container_live_atomic,
- container_live_busy,
- live_atomic,
-
- // If a dialog box is marked as explicitly modal
- modal,
-
- // If this is set, all of the other fields in this struct should
- // be ignored and only the locations should change.
- update_location_only,
-
- // Set on a canvas element if it has fallback content.
- canvas_has_fallback,
-
- // Indicates this node is scrollable (Android only).
- scrollable,
-
- // A hint to clients that the node is clickable.
- clickable,
-
- // Indicates that this node clips its children, i.e. may have
- // overflow: hidden or clip children by default.
- clips_children
- };
-
- [cpp_enum_prefix_override="ax_attr"] enum AXIntListAttribute {
- // Ids of nodes that are children of this node logically, but are
- // not children of this node in the tree structure. As an example,
- // a table cell is a child of a row, and an 'indirect' child of a
- // column.
- indirect_child_ids,
-
- // Relationships between this element and other elements.
- controls_ids,
- describedby_ids,
- flowto_ids,
- labelledby_ids,
- radio_group_ids,
-
- // For static text. Character indices where line breaks occur. Note that
- // this attribute is only available on Chrome OS and will be deprecated
- // soon.
- line_breaks,
-
- // For static text. These int lists must be the same size; they represent
- // the start and end character offset of each marker. Examples of markers
- // include spelling and grammar errors, and find-in-page matches.
- marker_types,
- marker_starts,
- marker_ends,
-
- // For a table, the cell ids in row-major order, with duplicate entries
- // when there's a rowspan or colspan, and with -1 for missing cells.
- // There are always exactly rows * columns entries.
- cell_ids,
-
- // For a table, the unique cell ids in row-major order of their first
- // occurrence.
- unique_cell_ids,
-
- // For inline text. This is the pixel position of the end of this
- // character within the bounding rectangle of this object, in the
- // direction given by AX_ATTR_TEXT_DIRECTION. For example, for left-to-right
- // text, the first offset is the right coordinate of the first character
- // within the object's bounds, the second offset is the right coordinate
- // of the second character, and so on.
- character_offsets,
-
- // Used for caching. Do not read directly. Use
- // |AXNode::GetOrComputeLineStartOffsets|
- // For all text fields and content editable roots: A list of the start
- // offsets of each line inside this object.
- cached_line_starts,
-
- // For inline text. These int lists must be the same size; they represent
- // the start and end character offset of each word within this text.
- word_starts,
- word_ends,
-
- // Used for an UI element to define custom actions for it. For example, a
- // list UI will allow a user to reorder items in the list by dragging the
- // items. Developer can expose those actions as custom actions. Currently
- // custom actions are used only in Android window.
- custom_action_ids
- };
-
- [cpp_enum_prefix_override="ax_attr"] enum AXStringListAttribute {
- // Descriptions for custom actions. This must be aligned with
- // custom_action_ids.
- custom_action_descriptions
- };
-
- // TODO(dmazzoni, nektar): make this list not grow exponentially as new
- // MarkerTypes are added
- enum AXMarkerType {
- // Assignments are ignored by the parser, but are kept here for clarity.
- spelling = 1,
- grammar = 2,
- spelling_grammar = 3,
- text_match = 4,
- spelling_text_match = 5,
- grammar_text_match = 6,
- spelling_grammar_text_match = 7,
- // DocumentMarker::MarkerType::Composition = 8 is ignored for accessibility
- // purposes
- active_suggestion = 16,
- spelling_active_suggestion = 17,
- grammar_active_suggestion = 18,
- spelling_grammar_active_suggestion = 19,
- text_match_active_suggestion = 20,
- spelling_text_match_active_suggestion = 21,
- grammar_text_match_active_suggestion = 22,
- spelling_grammar_text_match_active_suggestion = 23,
- suggestion = 32,
- spelling_suggestion = 33,
- grammar_suggestion = 34,
- spelling_grammar_suggestion = 35,
- text_match_suggestion = 36,
- spelling_text_match_suggestion = 37,
- grammar_text_match_suggestion = 38,
- spelling_grammar_text_match_suggestion = 39,
- // We again skip over DocumentMarker::MarkerType::Composition = 8 here
- active_suggestion_suggestion = 48,
- spelling_active_suggestion_suggestion = 49,
- grammar_active_suggestion_suggestion = 50,
- spelling_grammar_active_suggestion_suggestion = 51,
- text_match_active_suggestion_suggestion = 52,
- spelling_text_match_active_suggestion_suggestion = 53,
- grammar_text_match_active_suggestion_suggestion = 54,
- spelling_grammar_text_match_active_suggestion_suggestion = 55
- };
-
- enum AXTextDirection {
- ltr,
- rtl,
- ttb,
- btt
- };
-
- // A Java counterpart will be generated for this enum.
- // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.ui.accessibility
- [cpp_enum_prefix_override="ax"] enum AXTextStyle {
- // Assignments are ignored by the parser, but are kept here for clarity.
- text_style_bold = 1,
- text_style_italic = 2,
- text_style_bold_italic = 3,
- text_style_underline = 4,
- text_style_bold_underline = 5,
- text_style_italic_underline = 6,
- text_style_bold_italic_underline = 7,
- text_style_line_through = 8,
- text_style_bold_line_through = 9,
- text_style_italic_line_through = 10,
- text_style_bold_italic_line_through = 11,
- text_style_underline_line_through = 12,
- text_style_bold_underline_line_through = 13,
- text_style_italic_underline_line_through = 14,
- text_style_bold_italic_underline_line_through = 15
- };
-
- enum AXAriaCurrentState {
- false,
- true,
- page,
- step,
- location,
- unclipped_location,
- date,
- time
- };
-
- enum AXInvalidState {
- false,
- true,
- spelling,
- grammar,
- other
- };
-
- // Input restriction associated with an object.
- // No value for a control means it is enabled.
- // Use read_only for a textbox that allows focus/selection but not input.
- // Use disabled for a control or group of controls that disallows input.
- enum AXRestriction {
- read_only,
- disabled
- };
-
- enum AXCheckedState {
- false,
- true,
- mixed
- };
-
- enum AXSortDirection {
- unsorted,
- ascending,
- descending,
- other
- };
-
- enum AXNameFrom {
- uninitialized,
- attribute,
- attribute_explicitly_empty,
- contents,
- placeholder,
- related_element,
- value
- };
-
- enum AXDescriptionFrom {
- uninitialized,
- attribute,
- contents,
- placeholder,
- related_element
- };
-
- enum AXEventFrom {
- user,
- page,
- action
- };
-
- // Touch gestures on Chrome OS.
- enum AXGesture {
- click,
- swipe_left_1,
- swipe_up_1,
- swipe_right_1,
- swipe_down_1,
- swipe_left_2,
- swipe_up_2,
- swipe_right_2,
- swipe_down_2,
- swipe_left_3,
- swipe_up_3,
- swipe_right_3,
- swipe_down_3,
- swipe_left_4,
- swipe_up_4,
- swipe_right_4,
- swipe_down_4,
- tap_2
- };
-
- enum AXTextAffinity {
- downstream,
- upstream
- };
-
- // Compares two nodes in an accessibility tree in pre-order traversal.
- enum AXTreeOrder {
- // Not in the same tree, or other error.
- undefined,
-
- // First node is before the second one.
- before,
-
- // Nodes are the same.
- equal,
-
- // First node is after the second one.
- after
- };
-};
diff --git a/chromium/ui/accessibility/ax_enums.mojom b/chromium/ui/accessibility/ax_enums.mojom
new file mode 100644
index 00000000000..7d0d2a3e026
--- /dev/null
+++ b/chromium/ui/accessibility/ax_enums.mojom
@@ -0,0 +1,820 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// TODO(nektar): Migrate entire file to Mojoq.
+// Must also be kept in sync with chrome/common/extensions/api/automation.idl.
+module ax.mojom;
+
+ // For new entries to the following four enums, also add to
+ // chrome/common/extensions/api/automation.idl. This is enforced
+ // by a PRESUBMIT check.
+ //
+ // Explanation of the comments next to these events:
+ //
+ // Web: this event is only used in web content. Unless a specific platform
+ // is specified, it fires a native event on multiple platforms.
+ //
+ // Native: this event is only used in native UI.
+ //
+ // Implicit: it would be cleaner if we just updated the AX node
+ // and each platform fired the appropriate events to indicate which
+ // platform-specific attributes changed.
+ //
+ // If unspecified, the event is used across web and native on multiple
+ // platforms.
+enum Event {
+ kNone,
+ kActiveDescendantChanged, // Web
+ kAlert,
+ kAriaAttributeChanged, // Implicit
+ kAutocorrectionOccured, // Unknown: http://crbug.com/392498
+ kBlur, // Remove: http://crbug.com/392502
+ kCheckedStateChanged, // Implicit
+ kChildrenChanged,
+ kClicked,
+ kDocumentSelectionChanged,
+ kExpandedChanged, // Web
+ kFocus,
+ kHide, // Remove: http://crbug.com/392502
+ kHitTestResult,
+ kHover,
+ kImageFrameUpdated, // Web
+ kInvalidStatusChanged, // Implicit
+ kLayoutComplete, // Web
+ kLiveRegionCreated, // Implicit
+ kLiveRegionChanged, // Web
+ kLoadComplete, // Web
+ kLocationChanged, // Web
+ kMediaStartedPlaying, // Automation
+ kMediaStoppedPlaying, // Automation
+ kMenuEnd, // Native / Win
+ kMenuListItemSelected, // Web
+ kMenuListValueChanged, // Web
+ kMenuPopupEnd, // Native / Win
+ kMenuPopupStart, // Native / Win
+ kMenuStart, // Native / Win
+ kMouseCanceled,
+ kMouseDragged,
+ kMouseMoved,
+ kMousePressed,
+ kMouseReleased,
+ kRowCollapsed, // Web / Mac
+ kRowCountChanged, // Web / Mac
+ kRowExpanded, // Web / Mac
+ kScrollPositionChanged, // Web
+ kScrolledToAnchor, // Web
+ kSelectedChildrenChanged, // Web
+ kSelection, // Native
+ kSelectionAdd, // Native
+ kSelectionRemove, // Native
+ kShow, // Remove: http://crbug.com/392502
+ kTextChanged,
+ kTextSelectionChanged,
+ kTreeChanged, // Accessibility tree changed. Don't
+ // explicitly fire an accessibility event,
+ // only implicitly due to the change.
+ kValueChanged,
+ kLast = kValueChanged,
+};
+
+// Explanation:
+// The majority of these roles come from the ARIA specification. Reference
+// the latest draft for proper usage.
+//
+// Roles not included by the ARIA specification should be avoided, especially
+// internal roles used by the accessibility infrastructure.
+enum Role {
+ kNone,
+ kAbbr,
+ kAlertDialog,
+ kAlert,
+ kAnchor,
+ kAnnotation,
+ kApplication,
+ kArticle,
+ kAudio,
+ kBanner,
+ kBlockquote,
+ kButton,
+ kCanvas,
+ kCaption,
+ kCaret,
+ kCell,
+ kCheckBox,
+ kClient,
+ kColorWell,
+ kColumnHeader,
+ kColumn,
+ kComboBoxGrouping,
+ kComboBoxMenuButton,
+ kComplementary,
+ kContentInfo,
+ kDate,
+ kDateTime,
+ kDefinition,
+ kDescriptionListDetail,
+ kDescriptionList,
+ kDescriptionListTerm,
+ kDesktop, // internal
+ kDetails,
+ kDialog,
+ kDirectory,
+ kDisclosureTriangle,
+ kDocument,
+ kEmbeddedObject,
+ kFeed,
+ kFigcaption,
+ kFigure,
+ kFooter,
+ kForm,
+ kGenericContainer,
+ kGrid,
+ kGroup,
+ kHeading,
+ kIframe,
+ kIframePresentational,
+ kIgnored,
+ kImageMap,
+ kImage,
+ kInlineTextBox,
+ kInputTime,
+ kLabelText,
+ kLayoutTable,
+ kLayoutTableCell,
+ kLayoutTableColumn,
+ kLayoutTableRow,
+ kLegend,
+ kLineBreak,
+ kLink,
+ kListBoxOption,
+ kListBox,
+ kListItem,
+ kListMarker,
+ kList,
+ kLocationBar,
+ kLog,
+ kMain,
+ kMark,
+ kMarquee,
+ kMath,
+ kMenu,
+ kMenuBar,
+ kMenuButton,
+ kMenuItem,
+ kMenuItemCheckBox,
+ kMenuItemRadio,
+ kMenuListOption,
+ kMenuListPopup,
+ kMeter,
+ kNavigation,
+ kNote,
+ kPane,
+ kParagraph,
+ kPopUpButton,
+ kPre,
+ kPresentational,
+ kProgressIndicator,
+ kRadioButton,
+ kRadioGroup,
+ kRegion,
+ kRootWebArea,
+ kRowHeader,
+ kRow,
+ kRuby,
+ kSvgRoot,
+ kScrollBar,
+ kSearch,
+ kSearchBox,
+ kSlider,
+ kSliderThumb,
+ kSpinButtonPart,
+ kSpinButton,
+ kSplitter,
+ kStaticText,
+ kStatus,
+ kSwitch,
+ kTabList,
+ kTabPanel,
+ kTab,
+ kTableHeaderContainer,
+ kTable,
+ kTerm,
+ kTextField,
+ kTextFieldWithComboBox,
+ kTime,
+ kTimer,
+ kTitleBar,
+ kToggleButton,
+ kToolbar,
+ kTreeGrid,
+ kTreeItem,
+ kTree,
+ kUnknown,
+ kTooltip,
+ kVideo,
+ kWebArea,
+ kWebView,
+ kWindow,
+ kLast = kWindow,
+};
+
+enum State {
+ kNone,
+ kCollapsed,
+ kDefault,
+ kEditable,
+ kExpanded,
+ kFocusable,
+ kHaspopup,
+ // Grows horizontally, e.g. most toolbars and separators.
+ kHorizontal,
+ kHovered,
+ // Skip over this node in the accessibility tree, but keep its subtree.
+ kIgnored,
+ kInvisible,
+ kLinked,
+ kMultiline,
+ kMultiselectable,
+ kProtected,
+ kRequired,
+ kRichlyEditable,
+ kSelectable,
+ kSelected,
+ // Grows vertically, e.g. menu or combo box.
+ kVertical,
+ kVisited,
+ kLast = kVisited,
+};
+
+ // An action to be taken on an accessibility node.
+ // In contrast to |AXDefaultActionVerb|, these describe what happens to the
+ // object, e.g. "FOCUS".
+enum Action {
+ kNone,
+ kBlur,
+
+ kCustomAction,
+
+ // Decrement a slider or range control by one step value.
+ kDecrement,
+
+ // Do the default action for an object, typically this means "click".
+ kDoDefault,
+
+ kFocus,
+
+ // Return the content of this image object in the image_data attribute.
+ kGetImageData,
+
+ // Given a point, find the object it corresponds to and fire a
+ // |AXActionData.hit_test_event_to_fire| event on it in response.
+ kHitTest,
+
+ // Increment a slider or range control by one step value.
+ kIncrement,
+
+ // Load inline text boxes for this subtree, providing information
+ // about word boundaries, line layout, and individual character
+ // bounding boxes.
+ kLoadInlineTextBoxes,
+
+ // Delete any selected text in the control's text value and
+ // insert |AXActionData::value| in its place, like when typing or pasting.
+ kReplaceSelectedText,
+
+ // Scrolls by approximately one screen in a specific direction. Should be
+ // called on a node that has scrollable boolean set to true.
+ kScrollBackward,
+ kScrollForward,
+ kScrollUp,
+ kScrollDown,
+ kScrollLeft,
+ kScrollRight,
+
+ // Scroll any scrollable containers to make the target object visible
+ // on the screen. Optionally pass a subfocus rect in
+ // AXActionData.target_rect, in node-local coordinates.
+ kScrollToMakeVisible,
+
+ // Scroll the given object to a specified point on the screen in
+ // global screen coordinates. Pass a point in AXActionData.target_point.
+ kScrollToPoint,
+
+ kSetScrollOffset,
+ kSetSelection,
+
+ // Don't focus this node, but set it as the sequential focus navigation
+ // starting point, so that pressing Tab moves to the next element
+ // following this one, for example.
+ kSetSequentialFocusNavigationStartingPoint,
+
+ // Replace the value of the control with AXActionData::value and
+ // reset the selection, if applicable.
+ kSetValue,
+
+ kShowContextMenu,
+ kLast = kShowContextMenu,
+};
+
+enum ActionFlags {
+ kNone,
+ kRequestImages,
+ kRequestInlineTextBoxes,
+ kLast = kRequestInlineTextBoxes,
+};
+
+ // A list of valid values for the |AXIntAttribute| |default_action_verb|.
+ // These will describe the action that will be performed on a given node when
+ // executing the default action, which is a click.
+ // In contrast to |AXAction|, these describe what the user can do on the
+ // object, e.g. "PRESS", not what happens to the object as a result.
+ // Only one verb can be used at a time to describe the default action.
+enum DefaultActionVerb {
+ kNone,
+ kActivate,
+ kCheck,
+ kClick,
+
+ // A click will be performed on one of the node's ancestors.
+ // This happens when the node itself is not clickable, but one of its
+ // ancestors has click handlers attached which are able to capture the click
+ // as it bubbles up.
+ kClickAncestor,
+
+ kJump,
+ kOpen,
+ kPress,
+ kSelect,
+ kUncheck,
+ kLast = kUncheck,
+};
+
+ // A change to the accessibility tree.
+enum Mutation {
+ kNone,
+ kNodeCreated,
+ kSubtreeCreated,
+ kNodeChanged,
+ kNodeRemoved,
+ kLast = kNodeRemoved,
+};
+
+enum StringAttribute {
+ kNone,
+ kAccessKey,
+ // Only used when invalid_state == invalid_state_other.
+ kAriaInvalidValue,
+ kAutoComplete,
+ kChromeChannel, // Automation only.
+ kClassName, // views and Android
+ kContainerLiveRelevant,
+ kContainerLiveStatus,
+ kDescription,
+ kDisplay,
+ // Only present when different from parent.
+ kFontFamily,
+ kHtmlTag,
+ kImageDataUrl,
+ kInnerHtml,
+ kKeyShortcuts,
+ // Only present when different from parent.
+ kLanguage,
+ kName,
+ kLiveRelevant,
+ kLiveStatus,
+ kPlaceholder,
+ kRole,
+ kRoleDescription,
+ kUrl,
+ kValue,
+ kLast = kValue,
+};
+
+enum IntAttribute {
+ kNone,
+ kDefaultActionVerb,
+ // Scrollable container attributes.
+ kScrollX,
+ kScrollXMin,
+ kScrollXMax,
+ kScrollY,
+ kScrollYMin,
+ kScrollYMax,
+
+ // Attributes for retrieving the endpoints of a selection.
+ kTextSelStart,
+ kTextSelEnd,
+
+ // aria_col* and aria_row* attributes
+ kAriaColumnCount,
+ kAriaCellColumnIndex,
+ kAriaRowCount,
+ kAriaCellRowIndex,
+
+ // Table attributes.
+ kTableRowCount,
+ kTableColumnCount,
+ kTableHeaderId,
+
+ // Table row attributes.
+ kTableRowIndex,
+ kTableRowHeaderId,
+
+ // Table column attributes.
+ kTableColumnIndex,
+ kTableColumnHeaderId,
+
+ // Table cell attributes.
+ kTableCellColumnIndex,
+ kTableCellColumnSpan,
+ kTableCellRowIndex,
+ kTableCellRowSpan,
+ kSortDirection,
+
+ // Tree control attributes.
+ kHierarchicalLevel,
+
+ // What information was used to compute the object's name
+ // (of type AXNameFrom).
+ kNameFrom,
+
+ // What information was used to compute the object's description
+ // (of type AXDescriptionFrom).
+ kDescriptionFrom,
+
+ // Relationships between this element and other elements.
+ kActivedescendantId,
+ kDetailsId,
+ kErrormessageId,
+ kInPageLinkTargetId,
+ kMemberOfId,
+ kNextOnLineId,
+ kPreviousOnLineId,
+
+ // Identifies a child tree which this node hosts.
+ kChildTreeId,
+
+ // Input restriction, if any, such as readonly or disabled.
+ // Of type AXRestriction, see below.
+ // No value or enabled control or other object that is not disabled.
+ kRestriction,
+
+ // Position or Number of items in current set of listitems or treeitems
+ kSetSize,
+ kPosInSet,
+
+ // In the case of Role::kColorWell, specifies the selected color.
+ kColorValue,
+
+ // Indicates the element that represents the current item within a container
+ // or set of related elements.
+ kAriaCurrentState,
+
+ // Text attributes.
+
+ // Foreground and background color in RGBA.
+ kBackgroundColor,
+ kColor,
+
+ // Indicates if a form control has invalid input or
+ // if an element has an aria-invalid attribute.
+ kInvalidState,
+
+ // Of type AXCheckedState
+ kCheckedState,
+
+ // Specifies the direction of the text, e.g., right-to-left.
+ kTextDirection,
+
+ // Bold, italic, underline, etc.
+ kTextStyle,
+
+ // Focus traversal in views and Android.
+ kPreviousFocusId,
+ kNextFocusId,
+ kLast = kNextFocusId,
+};
+
+enum FloatAttribute {
+ kNone,
+ // Range attributes.
+ kValueForRange,
+ kMinValueForRange,
+ kMaxValueForRange,
+ kStepValueForRange,
+
+ // Text attributes.
+ // Font size is in pixels.
+ kFontSize,
+ kLast = kFontSize,
+};
+
+enum BoolAttribute {
+ kNone,
+ // Generic busy state, does not have to be on a live region.
+ kBusy,
+ // The object is at the root of an editable field, such as a content
+ // editable.
+ kEditableRoot,
+
+ // Live region attributes.
+ kContainerLiveAtomic,
+ kContainerLiveBusy,
+ kLiveAtomic,
+
+ // If a dialog box is marked as explicitly modal
+ kModal,
+
+ // If this is set, all of the other fields in this struct should
+ // be ignored and only the locations should change.
+ kUpdateLocationOnly,
+
+ // Set on a canvas element if it has fallback content.
+ kCanvasHasFallback,
+
+ // Indicates this node is scrollable (Android only).
+ kScrollable,
+
+ // A hint to clients that the node is clickable.
+ kClickable,
+
+ // Indicates that this node clips its children, i.e. may have
+ // overflow: hidden or clip children by default.
+ kClipsChildren,
+ kLast = kClipsChildren,
+};
+
+enum IntListAttribute {
+ kNone,
+ // Ids of nodes that are children of this node logically, but are
+ // not children of this node in the tree structure. As an example,
+ // a table cell is a child of a row, and an 'indirect' child of a
+ // column.
+ kIndirectChildIds,
+
+ // Relationships between this element and other elements.
+ kControlsIds,
+ kDescribedbyIds,
+ kFlowtoIds,
+ kLabelledbyIds,
+ kRadioGroupIds,
+
+ // For static text. Character indices where line breaks occur. Note that
+ // this attribute is only available on Chrome OS and will be deprecated
+ // soon.
+ kLineBreaks,
+
+ // For static text. These int lists must be the same size; they represent
+ // the start and end character offset of each marker. Examples of markers
+ // include spelling and grammar errors, and find-in-page matches.
+ kMarkerTypes,
+ kMarkerStarts,
+ kMarkerEnds,
+
+ // For a table, the cell ids in row-major order, with duplicate entries
+ // when there's a rowspan or colspan, and with -1 for missing cells.
+ // There are always exactly rows * columns entries.
+ kCellIds,
+
+ // For a table, the unique cell ids in row-major order of their first
+ // occurrence.
+ kUniqueCellIds,
+
+ // For inline text. This is the pixel position of the end of this
+ // character within the bounding rectangle of this object, in the
+ // direction given by StringAttribute::kTextDirection. For example,
+ // for left-to-right text, the first offset is the right coordinate of
+ // the first character within the object's bounds, the second offset
+ // is the right coordinate of the second character, and so on.
+ kCharacterOffsets,
+
+ // Used for caching. Do not read directly. Use
+ // |AXNode::GetOrComputeLineStartOffsets|
+ // For all text fields and content editable roots: A list of the start
+ // offsets of each line inside this object.
+ kCachedLineStarts,
+
+ // For inline text. These int lists must be the same size; they represent
+ // the start and end character offset of each word within this text.
+ kWordStarts,
+ kWordEnds,
+
+ // Used for an UI element to define custom actions for it. For example, a
+ // list UI will allow a user to reorder items in the list by dragging the
+ // items. Developer can expose those actions as custom actions. Currently
+ // custom actions are used only in Android window.
+ kCustomActionIds,
+ kLast = kCustomActionIds,
+};
+
+enum StringListAttribute {
+ kNone,
+ // Descriptions for custom actions. This must be aligned with
+ // custom_action_ids.
+ kCustomActionDescriptions,
+ kLast = kCustomActionDescriptions,
+};
+
+ // TODO(dmazzoni, nektar): make this list not grow exponentially as new
+ // MarkerTypes are added
+enum MarkerType {
+ kNone,
+ // Assignments are ignored by the parser, but are kept here for clarity.
+ kSpelling = 1,
+ kGrammar = 2,
+ kSpellingGrammar = 3,
+ kTextMatch = 4,
+ kSpellingTextMatch = 5,
+ kGrammarTextMatch = 6,
+ kSpellingGrammarTextMatch = 7,
+ // DocumentMarker::MarkerType::Composition = 8 is ignored for accessibility
+ // purposes
+ kActiveSuggestion = 16,
+ kSpellingActiveSuggestion = 17,
+ kGrammarActiveSuggestion = 18,
+ kSpellingGrammarActiveSuggestion = 19,
+ kTextMatchActiveSuggestion = 20,
+ kSpellingTextMatchActiveSuggestion = 21,
+ kGrammarTextMatchActiveSuggestion = 22,
+ kSpellingGrammarTextMatchActiveSuggestion = 23,
+ kSuggestion = 32,
+ kSpellingSuggestion = 33,
+ kGrammarSuggestion = 34,
+ kSpellingGrammarSuggestion = 35,
+ kTextMatchSuggestion = 36,
+ kSpellingTextMatchSuggestion = 37,
+ kGrammarTextMatchSuggestion = 38,
+ kSpellingGrammarTextMatchSuggestion = 39,
+ // We again skip over DocumentMarker::MarkerType::Composition = 8 here
+ kActiveSuggestionSuggestion = 48,
+ kSpellingActiveSuggestionSuggestion = 49,
+ kGrammarActiveSuggestionSuggestion = 50,
+ kSpellingGrammarActiveSuggestionSuggestion = 51,
+ kTextMatchActiveSuggestionSuggestion = 52,
+ kSpellingTextMatchActiveSuggestionSuggestion = 53,
+ kGrammarTextMatchActiveSuggestionSuggestion = 54,
+ kSpellingGrammarTextMatchActiveSuggestionSuggestion = 55,
+ kLast = kSpellingGrammarTextMatchActiveSuggestionSuggestion,
+};
+
+enum TextDirection {
+ kNone,
+ kLtr,
+ kRtl,
+ kTtb,
+ kBtt,
+ kLast = kBtt,
+};
+
+ // A Java counterpart will be generated for this enum.
+ // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.ui.accessibility
+enum TextStyle {
+ kNone,
+ // Assignments are ignored by the parser, but are kept here for clarity.
+ kTextStyleBold = 1,
+ kTextStyleItalic = 2,
+ kTextStyleBoldItalic = 3,
+ kTextStyleUnderline = 4,
+ kTextStyleBoldUnderline = 5,
+ kTextStyleItalicUnderline = 6,
+ kTextStyleBoldItalicUnderline = 7,
+ kTextStyleLineThrough = 8,
+ kTextStyleBoldLineThrough = 9,
+ kTextStyleItalicLineThrough = 10,
+ kTextStyleBoldItalicLineThrough = 11,
+ kTextStyleUnderlineLineThrough = 12,
+ kTextStyleBoldUnderlineLineThrough = 13,
+ kTextStyleItalicUnderlineLineThrough = 14,
+ kTextStyleBoldItalicUnderlineLineThrough = 15,
+ kLast = kTextStyleBoldItalicUnderlineLineThrough,
+};
+
+enum AriaCurrentState {
+ kNone,
+ kFalse,
+ kTrue,
+ kPage,
+ kStep,
+ kLocation,
+ kUnclippedLocation,
+ kDate,
+ kTime,
+ kLast = kTime,
+};
+
+enum InvalidState {
+ kNone,
+ kFalse,
+ kTrue,
+ kSpelling,
+ kGrammar,
+ kOther,
+ kLast = kOther,
+};
+
+ // Input restriction associated with an object.
+ // No value for a control means it is enabled.
+ // Use read_only for a textbox that allows focus/selection but not input.
+ // Use disabled for a control or group of controls that disallows input.
+enum Restriction {
+ kNone,
+ kReadOnly,
+ kDisabled,
+ kLast = kDisabled,
+};
+
+enum CheckedState {
+ kNone,
+ kFalse,
+ kTrue,
+ kMixed,
+ kLast = kMixed,
+};
+
+enum SortDirection {
+ kNone,
+ kUnsorted,
+ kAscending,
+ kDescending,
+ kOther,
+ kLast = kOther,
+};
+
+enum NameFrom {
+ kNone,
+ kUninitialized,
+ kAttribute,
+ kAttributeExplicitlyEmpty,
+ kContents,
+ kPlaceholder,
+ kRelatedElement,
+ kValue,
+ kLast = kValue,
+};
+
+enum DescriptionFrom {
+ kNone,
+ kUninitialized,
+ kAttribute,
+ kContents,
+ kPlaceholder,
+ kRelatedElement,
+ kLast = kRelatedElement,
+};
+
+enum EventFrom {
+ kNone,
+ kUser,
+ kPage,
+ kAction,
+ kLast = kAction,
+};
+
+ // Touch gestures on Chrome OS.
+enum Gesture {
+ kNone,
+ kClick,
+ kSwipeLeft1,
+ kSwipeUp1,
+ kSwipeRight1,
+ kSwipeDown1,
+ kSwipeLeft2,
+ kSwipeUp2,
+ kSwipeRight2,
+ kSwipeDown2,
+ kSwipeLeft3,
+ kSwipeUp3,
+ kSwipeRight3,
+ kSwipeDown3,
+ kSwipeLeft4,
+ kSwipeUp4,
+ kSwipeRight4,
+ kSwipeDown4,
+ kTap2,
+ kLast = kTap2,
+};
+
+enum TextAffinity {
+ kNone,
+ kDownstream,
+ kUpstream,
+ kLast = kUpstream,
+};
+
+ // Compares two nodes in an accessibility tree in pre-order traversal.
+enum TreeOrder {
+ kNone,
+ // Not in the same tree, or other error.
+ kUndefined,
+
+ // First node is before the second one.
+ kBefore,
+
+ // Nodes are the same.
+ kEqual,
+
+ // First node is after the second one.
+ kAfter,
+ kLast = kAfter,
+};
diff --git a/chromium/ui/accessibility/ax_event_generator.cc b/chromium/ui/accessibility/ax_event_generator.cc
index caa03843531..52747b1632b 100644
--- a/chromium/ui/accessibility/ax_event_generator.cc
+++ b/chromium/ui/accessibility/ax_event_generator.cc
@@ -81,7 +81,7 @@ void AXEventGenerator::ClearEvents() {
void AXEventGenerator::AddEvent(ui::AXNode* node,
AXEventGenerator::Event event) {
- if (node->data().role == AX_ROLE_INLINE_TEXT_BOX)
+ if (node->data().role == ax::mojom::Role::kInlineTextBox)
return;
// A newly created live region or alert should not *also* fire a
@@ -105,7 +105,7 @@ void AXEventGenerator::OnNodeDataWillChange(AXTree* tree,
// We don't expose those to platform APIs, though, so suppress
// CHILDREN_CHANGED events on static text nodes.
if (new_node_data.child_ids != old_node_data.child_ids &&
- new_node_data.role != ui::AX_ROLE_STATIC_TEXT) {
+ new_node_data.role != ax::mojom::Role::kStaticText) {
AXNode* node = tree_->GetFromId(new_node_data.id);
tree_events_[node].insert(Event::CHILDREN_CHANGED);
}
@@ -113,66 +113,86 @@ void AXEventGenerator::OnNodeDataWillChange(AXTree* tree,
void AXEventGenerator::OnRoleChanged(AXTree* tree,
AXNode* node,
- AXRole old_role,
- AXRole new_role) {
+ ax::mojom::Role old_role,
+ ax::mojom::Role new_role) {
DCHECK_EQ(tree_, tree);
AddEvent(node, Event::ROLE_CHANGED);
}
void AXEventGenerator::OnStateChanged(AXTree* tree,
AXNode* node,
- AXState state,
+ ax::mojom::State state,
bool new_value) {
DCHECK_EQ(tree_, tree);
AddEvent(node, Event::STATE_CHANGED);
- if (state == ui::AX_STATE_EXPANDED) {
- AddEvent(node, new_value ? Event::EXPANDED : Event::COLLAPSED);
- if (node->data().role == ui::AX_ROLE_ROW ||
- node->data().role == ui::AX_ROLE_TREE_ITEM) {
+ switch (state) {
+ case ax::mojom::State::kExpanded:
+ AddEvent(node, new_value ? Event::EXPANDED : Event::COLLAPSED);
+
+ // TODO(accessibility): tree in the midst of updates. Disallow access to
+ // |node|.
+ if (node->data().role == ax::mojom::Role::kRow ||
+ node->data().role == ax::mojom::Role::kTreeItem) {
+ ui::AXNode* container = node;
+ while (container && !ui::IsRowContainer(container->data().role))
+ container = container->parent();
+ if (container)
+ AddEvent(container, Event::ROW_COUNT_CHANGED);
+ }
+ break;
+ case ax::mojom::State::kSelected: {
+ AddEvent(node, Event::SELECTED_CHANGED);
ui::AXNode* container = node;
- while (container && !ui::IsRowContainer(container->data().role))
+ while (container &&
+ !ui::IsContainerWithSelectableChildrenRole(container->data().role))
container = container->parent();
if (container)
- AddEvent(container, Event::ROW_COUNT_CHANGED);
+ AddEvent(container, Event::SELECTED_CHILDREN_CHANGED);
+ break;
}
- }
- if (state == ui::AX_STATE_SELECTED) {
- AddEvent(node, Event::SELECTED_CHANGED);
- ui::AXNode* container = node;
- while (container &&
- !ui::IsContainerWithSelectableChildrenRole(container->data().role))
- container = container->parent();
- if (container)
- AddEvent(container, Event::SELECTED_CHILDREN_CHANGED);
+ case ax::mojom::State::kIgnored: {
+ ui::AXNode* unignored_parent = node->GetUnignoredParent();
+ if (unignored_parent)
+ AddEvent(unignored_parent, Event::CHILDREN_CHANGED);
+ break;
+ }
+ default:
+ break;
}
}
void AXEventGenerator::OnStringAttributeChanged(AXTree* tree,
AXNode* node,
- AXStringAttribute attr,
+ ax::mojom::StringAttribute attr,
const std::string& old_value,
const std::string& new_value) {
DCHECK_EQ(tree_, tree);
switch (attr) {
- case ui::AX_ATTR_NAME:
+ case ax::mojom::StringAttribute::kName:
AddEvent(node, Event::NAME_CHANGED);
- if (node->data().HasStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS)) {
+
+ // TODO(accessibility): tree in the midst of updates. Disallow
+ // access to |node|.
+ if (node->data().HasStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus)) {
FireLiveRegionEvents(node);
}
break;
- case ui::AX_ATTR_DESCRIPTION:
+ case ax::mojom::StringAttribute::kDescription:
AddEvent(node, Event::DESCRIPTION_CHANGED);
break;
- case ui::AX_ATTR_VALUE:
+ case ax::mojom::StringAttribute::kValue:
AddEvent(node, Event::VALUE_CHANGED);
break;
- case ui::AX_ATTR_ARIA_INVALID_VALUE:
+ case ax::mojom::StringAttribute::kAriaInvalidValue:
AddEvent(node, Event::INVALID_STATUS_CHANGED);
break;
- case ui::AX_ATTR_LIVE_STATUS:
- if (node->data().role != ui::AX_ROLE_ALERT)
+ case ax::mojom::StringAttribute::kLiveStatus:
+ // TODO(accessibility): tree in the midst of updates. Disallow access to
+ // |node|.
+ if (node->data().role != ax::mojom::Role::kAlert)
AddEvent(node, Event::LIVE_REGION_CREATED);
break;
default:
@@ -183,27 +203,27 @@ void AXEventGenerator::OnStringAttributeChanged(AXTree* tree,
void AXEventGenerator::OnIntAttributeChanged(AXTree* tree,
AXNode* node,
- AXIntAttribute attr,
+ ax::mojom::IntAttribute attr,
int32_t old_value,
int32_t new_value) {
DCHECK_EQ(tree_, tree);
switch (attr) {
- case ui::AX_ATTR_ACTIVEDESCENDANT_ID:
+ case ax::mojom::IntAttribute::kActivedescendantId:
AddEvent(node, Event::ACTIVE_DESCENDANT_CHANGED);
active_descendant_changed_.push_back(node);
break;
- case ui::AX_ATTR_CHECKED_STATE:
+ case ax::mojom::IntAttribute::kCheckedState:
AddEvent(node, Event::CHECKED_STATE_CHANGED);
break;
- case ui::AX_ATTR_INVALID_STATE:
+ case ax::mojom::IntAttribute::kInvalidState:
AddEvent(node, Event::INVALID_STATUS_CHANGED);
break;
- case ui::AX_ATTR_RESTRICTION:
+ case ax::mojom::IntAttribute::kRestriction:
AddEvent(node, Event::STATE_CHANGED);
break;
- case ui::AX_ATTR_SCROLL_X:
- case ui::AX_ATTR_SCROLL_Y:
+ case ax::mojom::IntAttribute::kScrollX:
+ case ax::mojom::IntAttribute::kScrollY:
AddEvent(node, Event::SCROLL_POSITION_CHANGED);
break;
default:
@@ -214,12 +234,12 @@ void AXEventGenerator::OnIntAttributeChanged(AXTree* tree,
void AXEventGenerator::OnFloatAttributeChanged(AXTree* tree,
AXNode* node,
- AXFloatAttribute attr,
+ ax::mojom::FloatAttribute attr,
float old_value,
float new_value) {
DCHECK_EQ(tree_, tree);
- if (attr == ui::AX_ATTR_VALUE_FOR_RANGE)
+ if (attr == ax::mojom::FloatAttribute::kValueForRange)
AddEvent(node, Event::VALUE_CHANGED);
else
AddEvent(node, Event::OTHER_ATTRIBUTE_CHANGED);
@@ -227,7 +247,7 @@ void AXEventGenerator::OnFloatAttributeChanged(AXTree* tree,
void AXEventGenerator::OnBoolAttributeChanged(AXTree* tree,
AXNode* node,
- AXBoolAttribute attr,
+ ax::mojom::BoolAttribute attr,
bool new_value) {
DCHECK_EQ(tree_, tree);
@@ -237,7 +257,7 @@ void AXEventGenerator::OnBoolAttributeChanged(AXTree* tree,
void AXEventGenerator::OnIntListAttributeChanged(
AXTree* tree,
AXNode* node,
- AXIntListAttribute attr,
+ ax::mojom::IntListAttribute attr,
const std::vector<int32_t>& old_value,
const std::vector<int32_t>& new_value) {
DCHECK_EQ(tree_, tree);
@@ -247,7 +267,7 @@ void AXEventGenerator::OnIntListAttributeChanged(
void AXEventGenerator::OnStringListAttributeChanged(
AXTree* tree,
AXNode* node,
- AXStringListAttribute attr,
+ ax::mojom::StringListAttribute attr,
const std::vector<std::string>& old_value,
const std::vector<std::string>& new_value) {
DCHECK_EQ(tree_, tree);
@@ -314,17 +334,22 @@ void AXEventGenerator::OnAtomicUpdateFinished(
for (const auto& change : changes) {
if ((change.type == NODE_CREATED || change.type == SUBTREE_CREATED)) {
- if (change.node->data().HasStringAttribute(ui::AX_ATTR_LIVE_STATUS)) {
- if (change.node->data().role == ui::AX_ROLE_ALERT)
+ if (change.node->data().HasStringAttribute(
+ ax::mojom::StringAttribute::kLiveStatus)) {
+ if (change.node->data().role == ax::mojom::Role::kAlert)
AddEvent(change.node, Event::ALERT);
else
AddEvent(change.node, Event::LIVE_REGION_CREATED);
} else if (change.node->data().HasStringAttribute(
- ui::AX_ATTR_CONTAINER_LIVE_STATUS) &&
- change.node->data().HasStringAttribute(ui::AX_ATTR_NAME)) {
+ ax::mojom::StringAttribute::kContainerLiveStatus) &&
+ change.node->data().HasStringAttribute(
+ ax::mojom::StringAttribute::kName)) {
FireLiveRegionEvents(change.node);
}
}
+
+ if (change.type != NODE_CREATED && change.type != SUBTREE_CREATED)
+ FireRelationSourceEvents(tree, change.node);
}
FireActiveDescendantEvents();
@@ -332,13 +357,16 @@ void AXEventGenerator::OnAtomicUpdateFinished(
void AXEventGenerator::FireLiveRegionEvents(AXNode* node) {
ui::AXNode* live_root = node;
- while (live_root &&
- !live_root->data().HasStringAttribute(ui::AX_ATTR_LIVE_STATUS))
+ while (live_root && !live_root->data().HasStringAttribute(
+ ax::mojom::StringAttribute::kLiveStatus))
live_root = live_root->parent();
- if (live_root && !live_root->data().GetBoolAttribute(ui::AX_ATTR_BUSY)) {
+ if (live_root &&
+ !live_root->data().GetBoolAttribute(ax::mojom::BoolAttribute::kBusy)) {
// Fire LIVE_REGION_NODE_CHANGED on each node that changed.
- if (!node->data().GetStringAttribute(ui::AX_ATTR_NAME).empty())
+ if (!node->data()
+ .GetStringAttribute(ax::mojom::StringAttribute::kName)
+ .empty())
AddEvent(node, Event::LIVE_REGION_NODE_CHANGED);
// Fire LIVE_REGION_NODE_CHANGED on the root of the live region.
AddEvent(live_root, Event::LIVE_REGION_CHANGED);
@@ -347,15 +375,15 @@ void AXEventGenerator::FireLiveRegionEvents(AXNode* node) {
void AXEventGenerator::FireActiveDescendantEvents() {
for (AXNode* node : active_descendant_changed_) {
- AXNode* descendant = tree_->GetFromId(
- node->data().GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID));
+ AXNode* descendant = tree_->GetFromId(node->data().GetIntAttribute(
+ ax::mojom::IntAttribute::kActivedescendantId));
if (!descendant)
continue;
switch (descendant->data().role) {
- case ui::AX_ROLE_MENU_ITEM:
- case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
- case ui::AX_ROLE_MENU_ITEM_RADIO:
- case ui::AX_ROLE_MENU_LIST_OPTION:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kMenuListOption:
AddEvent(descendant, Event::MENU_ITEM_SELECTED);
break;
default:
@@ -365,4 +393,32 @@ void AXEventGenerator::FireActiveDescendantEvents() {
active_descendant_changed_.clear();
}
+void AXEventGenerator::FireRelationSourceEvents(AXTree* tree,
+ AXNode* target_node) {
+ int32_t target_id = target_node->id();
+ std::set<AXNode*> source_nodes;
+ auto callback = [&](const auto& entry) {
+ const auto& target_to_sources = entry.second;
+ auto sources_it = target_to_sources.find(target_id);
+ if (sources_it == target_to_sources.end())
+ return;
+
+ auto sources = sources_it->second;
+ std::for_each(sources.begin(), sources.end(), [&](int32_t source_id) {
+ AXNode* source_node = tree->GetFromId(source_id);
+
+ if (!source_node || source_nodes.count(source_node) > 0)
+ return;
+
+ source_nodes.insert(source_node);
+ AddEvent(source_node, Event::RELATED_NODE_CHANGED);
+ });
+ };
+
+ std::for_each(tree->int_reverse_relations().begin(),
+ tree->int_reverse_relations().end(), callback);
+ std::for_each(tree->intlist_reverse_relations().begin(),
+ tree->intlist_reverse_relations().end(), callback);
+}
+
} // namespace ui
diff --git a/chromium/ui/accessibility/ax_event_generator.h b/chromium/ui/accessibility/ax_event_generator.h
index f4d9c26efb5..2b9d57b3edf 100644
--- a/chromium/ui/accessibility/ax_event_generator.h
+++ b/chromium/ui/accessibility/ax_event_generator.h
@@ -38,6 +38,7 @@ class AX_EXPORT AXEventGenerator : public AXTreeDelegate {
MENU_ITEM_SELECTED,
NAME_CHANGED,
OTHER_ATTRIBUTE_CHANGED,
+ RELATED_NODE_CHANGED,
ROLE_CHANGED,
ROW_COUNT_CHANGED,
SCROLL_POSITION_CHANGED,
@@ -115,41 +116,41 @@ class AX_EXPORT AXEventGenerator : public AXTreeDelegate {
const AXNodeData& new_node_data) override;
void OnRoleChanged(AXTree* tree,
AXNode* node,
- AXRole old_role,
- AXRole new_role) override;
+ ax::mojom::Role old_role,
+ ax::mojom::Role new_role) override;
void OnStateChanged(AXTree* tree,
AXNode* node,
- AXState state,
+ ax::mojom::State state,
bool new_value) override;
void OnStringAttributeChanged(AXTree* tree,
AXNode* node,
- AXStringAttribute attr,
+ ax::mojom::StringAttribute attr,
const std::string& old_value,
const std::string& new_value) override;
void OnIntAttributeChanged(AXTree* tree,
AXNode* node,
- AXIntAttribute attr,
+ ax::mojom::IntAttribute attr,
int32_t old_value,
int32_t new_value) override;
void OnFloatAttributeChanged(AXTree* tree,
AXNode* node,
- AXFloatAttribute attr,
+ ax::mojom::FloatAttribute attr,
float old_value,
float new_value) override;
void OnBoolAttributeChanged(AXTree* tree,
AXNode* node,
- AXBoolAttribute attr,
+ ax::mojom::BoolAttribute attr,
bool new_value) override;
void OnIntListAttributeChanged(
AXTree* tree,
AXNode* node,
- AXIntListAttribute attr,
+ ax::mojom::IntListAttribute attr,
const std::vector<int32_t>& old_value,
const std::vector<int32_t>& new_value) override;
void OnStringListAttributeChanged(
AXTree* tree,
AXNode* node,
- AXStringListAttribute attr,
+ ax::mojom::StringListAttribute attr,
const std::vector<std::string>& old_value,
const std::vector<std::string>& new_value) override;
void OnTreeDataChanged(AXTree* tree,
@@ -169,6 +170,7 @@ class AX_EXPORT AXEventGenerator : public AXTreeDelegate {
private:
void FireLiveRegionEvents(AXNode* node);
void FireActiveDescendantEvents();
+ void FireRelationSourceEvents(AXTree* tree, AXNode* target_node);
AXTree* tree_ = nullptr; // Not owned.
std::map<AXNode*, std::set<Event>> tree_events_;
diff --git a/chromium/ui/accessibility/ax_event_generator_unittest.cc b/chromium/ui/accessibility/ax_event_generator_unittest.cc
index a9b9ce56889..2d3f192568f 100644
--- a/chromium/ui/accessibility/ax_event_generator_unittest.cc
+++ b/chromium/ui/accessibility/ax_event_generator_unittest.cc
@@ -71,6 +71,9 @@ std::string DumpEvents(AXEventGenerator* generator) {
case AXEventGenerator::Event::OTHER_ATTRIBUTE_CHANGED:
event_name = "OTHER_ATTRIBUTE_CHANGED";
break;
+ case AXEventGenerator::Event::RELATED_NODE_CHANGED:
+ event_name = "RELATED_NODE_CHANGED";
+ break;
case AXEventGenerator::Event::ROLE_CHANGED:
event_name = "ROLE_CHANGED";
break;
@@ -183,22 +186,22 @@ TEST(AXEventGeneratorTest, ExpandedAndRowCount) {
initial_state.root_id = 1;
initial_state.nodes.resize(4);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].role = ui::AX_ROLE_ROOT_WEB_AREA;
+ initial_state.nodes[0].role = ax::mojom::Role::kRootWebArea;
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[0].child_ids.push_back(4);
initial_state.nodes[1].id = 2;
- initial_state.nodes[1].role = ui::AX_ROLE_TABLE;
+ initial_state.nodes[1].role = ax::mojom::Role::kTable;
initial_state.nodes[1].child_ids.push_back(3);
initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ui::AX_ROLE_ROW;
+ initial_state.nodes[2].role = ax::mojom::Role::kRow;
initial_state.nodes[3].id = 4;
- initial_state.nodes[3].role = ui::AX_ROLE_POP_UP_BUTTON;
- initial_state.nodes[3].AddState(ui::AX_STATE_EXPANDED);
+ initial_state.nodes[3].role = ax::mojom::Role::kPopUpButton;
+ initial_state.nodes[3].AddState(ax::mojom::State::kExpanded);
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[2].AddState(ui::AX_STATE_EXPANDED);
+ update.nodes[2].AddState(ax::mojom::State::kExpanded);
update.nodes[3].state = 0;
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ(
@@ -215,22 +218,22 @@ TEST(AXEventGeneratorTest, SelectedAndSelectedChildren) {
initial_state.root_id = 1;
initial_state.nodes.resize(4);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].role = ui::AX_ROLE_ROOT_WEB_AREA;
+ initial_state.nodes[0].role = ax::mojom::Role::kRootWebArea;
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[0].child_ids.push_back(4);
initial_state.nodes[1].id = 2;
- initial_state.nodes[1].role = ui::AX_ROLE_MENU;
+ initial_state.nodes[1].role = ax::mojom::Role::kMenu;
initial_state.nodes[1].child_ids.push_back(3);
initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ui::AX_ROLE_MENU_ITEM;
+ initial_state.nodes[2].role = ax::mojom::Role::kMenuItem;
initial_state.nodes[3].id = 4;
- initial_state.nodes[3].role = ui::AX_ROLE_LIST_BOX_OPTION;
- initial_state.nodes[3].AddState(ui::AX_STATE_SELECTED);
+ initial_state.nodes[3].role = ax::mojom::Role::kListBoxOption;
+ initial_state.nodes[3].AddState(ax::mojom::State::kSelected);
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[2].AddState(ui::AX_STATE_SELECTED);
+ update.nodes[2].AddState(ax::mojom::State::kSelected);
update.nodes[3].state = 0;
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ(
@@ -247,14 +250,16 @@ TEST(AXEventGeneratorTest, StringValueChanged) {
initial_state.root_id = 1;
initial_state.nodes.resize(1);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].role = ui::AX_ROLE_TEXT_FIELD;
- initial_state.nodes[0].AddStringAttribute(ui::AX_ATTR_VALUE, "Before");
+ initial_state.nodes[0].role = ax::mojom::Role::kTextField;
+ initial_state.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kValue,
+ "Before");
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
update.nodes[0].string_attributes.clear();
- update.nodes[0].AddStringAttribute(ui::AX_ATTR_VALUE, "After");
+ update.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kValue,
+ "After");
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ("VALUE_CHANGED on 1", DumpEvents(&event_generator));
}
@@ -264,14 +269,16 @@ TEST(AXEventGeneratorTest, FloatValueChanged) {
initial_state.root_id = 1;
initial_state.nodes.resize(1);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].role = ui::AX_ROLE_SLIDER;
- initial_state.nodes[0].AddFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, 1.0);
+ initial_state.nodes[0].role = ax::mojom::Role::kSlider;
+ initial_state.nodes[0].AddFloatAttribute(
+ ax::mojom::FloatAttribute::kValueForRange, 1.0);
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
update.nodes[0].float_attributes.clear();
- update.nodes[0].AddFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE, 2.0);
+ update.nodes[0].AddFloatAttribute(ax::mojom::FloatAttribute::kValueForRange,
+ 2.0);
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ("VALUE_CHANGED on 1", DumpEvents(&event_generator));
}
@@ -281,14 +288,14 @@ TEST(AXEventGeneratorTest, InvalidStatusChanged) {
initial_state.root_id = 1;
initial_state.nodes.resize(1);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].role = ui::AX_ROLE_TEXT_FIELD;
- initial_state.nodes[0].AddStringAttribute(ui::AX_ATTR_VALUE, "Text");
+ initial_state.nodes[0].role = ax::mojom::Role::kTextField;
+ initial_state.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kValue,
+ "Text");
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[0].AddIntAttribute(ui::AX_ATTR_INVALID_STATE,
- ui::AX_INVALID_STATE_SPELLING);
+ update.nodes[0].SetInvalidState(ax::mojom::InvalidState::kSpelling);
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ("INVALID_STATUS_CHANGED on 1", DumpEvents(&event_generator));
}
@@ -302,7 +309,8 @@ TEST(AXEventGeneratorTest, AddLiveRegionAttribute) {
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[0].AddStringAttribute(ui::AX_ATTR_LIVE_STATUS, "polite");
+ update.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kLiveStatus,
+ "polite");
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ("LIVE_REGION_CREATED on 1", DumpEvents(&event_generator));
}
@@ -312,13 +320,12 @@ TEST(AXEventGeneratorTest, CheckedStateChanged) {
initial_state.root_id = 1;
initial_state.nodes.resize(1);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].role = ui::AX_ROLE_CHECK_BOX;
+ initial_state.nodes[0].role = ax::mojom::Role::kCheckBox;
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[0].AddIntAttribute(ui::AX_ATTR_CHECKED_STATE,
- ui::AX_CHECKED_STATE_TRUE);
+ update.nodes[0].SetCheckedState(ax::mojom::CheckedState::kTrue);
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ("CHECKED_STATE_CHANGED on 1", DumpEvents(&event_generator));
}
@@ -328,22 +335,27 @@ TEST(AXEventGeneratorTest, ActiveDescendantChanged) {
initial_state.root_id = 1;
initial_state.nodes.resize(3);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].role = ui::AX_ROLE_LIST_BOX;
+ initial_state.nodes[0].role = ax::mojom::Role::kListBox;
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[0].child_ids.push_back(3);
- initial_state.nodes[0].AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 2);
+ initial_state.nodes[0].AddIntAttribute(
+ ax::mojom::IntAttribute::kActivedescendantId, 2);
initial_state.nodes[1].id = 2;
- initial_state.nodes[1].role = ui::AX_ROLE_LIST_BOX_OPTION;
+ initial_state.nodes[1].role = ax::mojom::Role::kListBoxOption;
initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ui::AX_ROLE_LIST_BOX_OPTION;
+ initial_state.nodes[2].role = ax::mojom::Role::kListBoxOption;
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
update.nodes[0].int_attributes.clear();
- update.nodes[0].AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 3);
+ update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
+ 3);
EXPECT_TRUE(tree.Unserialize(update));
- EXPECT_EQ("ACTIVE_DESCENDANT_CHANGED on 1", DumpEvents(&event_generator));
+ EXPECT_EQ(
+ "ACTIVE_DESCENDANT_CHANGED on 1, "
+ "RELATED_NODE_CHANGED on 1",
+ DumpEvents(&event_generator));
}
TEST(AXEventGeneratorTest, CreateAlertAndLiveRegion) {
@@ -359,10 +371,12 @@ TEST(AXEventGeneratorTest, CreateAlertAndLiveRegion) {
update.nodes[0].child_ids.push_back(2);
update.nodes[0].child_ids.push_back(3);
update.nodes[1].id = 2;
- update.nodes[1].AddStringAttribute(ui::AX_ATTR_LIVE_STATUS, "polite");
+ update.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kLiveStatus,
+ "polite");
update.nodes[2].id = 3;
- update.nodes[2].role = ui::AX_ROLE_ALERT;
- update.nodes[2].AddStringAttribute(ui::AX_ATTR_LIVE_STATUS, "polite");
+ update.nodes[2].role = ax::mojom::Role::kAlert;
+ update.nodes[2].AddStringAttribute(ax::mojom::StringAttribute::kLiveStatus,
+ "polite");
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ(
@@ -377,33 +391,38 @@ TEST(AXEventGeneratorTest, LiveRegionChanged) {
initial_state.root_id = 1;
initial_state.nodes.resize(3);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].AddStringAttribute(ui::AX_ATTR_LIVE_STATUS, "polite");
- initial_state.nodes[0].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
+ initial_state.nodes[0].AddStringAttribute(
+ ax::mojom::StringAttribute::kLiveStatus, "polite");
+ initial_state.nodes[0].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[0].child_ids.push_back(3);
initial_state.nodes[1].id = 2;
- initial_state.nodes[1].role = ui::AX_ROLE_STATIC_TEXT;
- initial_state.nodes[1].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- initial_state.nodes[1].AddStringAttribute(ui::AX_ATTR_NAME, "Before 1");
+ initial_state.nodes[1].role = ax::mojom::Role::kStaticText;
+ initial_state.nodes[1].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ initial_state.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "Before 1");
initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ui::AX_ROLE_STATIC_TEXT;
- initial_state.nodes[2].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- initial_state.nodes[2].AddStringAttribute(ui::AX_ATTR_NAME, "Before 2");
+ initial_state.nodes[2].role = ax::mojom::Role::kStaticText;
+ initial_state.nodes[2].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ initial_state.nodes[2].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "Before 2");
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
update.nodes[1].string_attributes.clear();
- update.nodes[1].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- update.nodes[1].AddStringAttribute(ui::AX_ATTR_NAME, "After 1");
+ update.nodes[1].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ update.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "After 1");
update.nodes[2].string_attributes.clear();
- update.nodes[2].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- update.nodes[2].AddStringAttribute(ui::AX_ATTR_NAME, "After 2");
+ update.nodes[2].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ update.nodes[2].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "After 2");
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ(
@@ -420,28 +439,31 @@ TEST(AXEventGeneratorTest, LiveRegionOnlyTextChanges) {
initial_state.root_id = 1;
initial_state.nodes.resize(3);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].AddStringAttribute(ui::AX_ATTR_LIVE_STATUS, "polite");
- initial_state.nodes[0].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
+ initial_state.nodes[0].AddStringAttribute(
+ ax::mojom::StringAttribute::kLiveStatus, "polite");
+ initial_state.nodes[0].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[0].child_ids.push_back(3);
initial_state.nodes[1].id = 2;
- initial_state.nodes[1].role = ui::AX_ROLE_STATIC_TEXT;
- initial_state.nodes[1].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- initial_state.nodes[1].AddStringAttribute(ui::AX_ATTR_NAME, "Before 1");
+ initial_state.nodes[1].role = ax::mojom::Role::kStaticText;
+ initial_state.nodes[1].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ initial_state.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "Before 1");
initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ui::AX_ROLE_STATIC_TEXT;
- initial_state.nodes[2].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- initial_state.nodes[2].AddStringAttribute(ui::AX_ATTR_NAME, "Before 2");
+ initial_state.nodes[2].role = ax::mojom::Role::kStaticText;
+ initial_state.nodes[2].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ initial_state.nodes[2].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "Before 2");
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[1].AddStringAttribute(ui::AX_ATTR_DESCRIPTION, "Description 1");
- update.nodes[2].AddIntAttribute(ui::AX_ATTR_CHECKED_STATE,
- ui::AX_CHECKED_STATE_TRUE);
+ update.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kDescription,
+ "Description 1");
+ update.nodes[2].SetCheckedState(ax::mojom::CheckedState::kTrue);
// Note that we do NOT expect a LIVE_REGION_CHANGED event here, because
// the name did not change.
@@ -457,34 +479,40 @@ TEST(AXEventGeneratorTest, BusyLiveRegionChanged) {
initial_state.root_id = 1;
initial_state.nodes.resize(3);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].AddStringAttribute(ui::AX_ATTR_LIVE_STATUS, "polite");
- initial_state.nodes[0].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- initial_state.nodes[0].AddBoolAttribute(ui::AX_ATTR_BUSY, true);
+ initial_state.nodes[0].AddStringAttribute(
+ ax::mojom::StringAttribute::kLiveStatus, "polite");
+ initial_state.nodes[0].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ initial_state.nodes[0].AddBoolAttribute(ax::mojom::BoolAttribute::kBusy,
+ true);
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[0].child_ids.push_back(3);
initial_state.nodes[1].id = 2;
- initial_state.nodes[1].role = ui::AX_ROLE_STATIC_TEXT;
- initial_state.nodes[1].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- initial_state.nodes[1].AddStringAttribute(ui::AX_ATTR_NAME, "Before 1");
+ initial_state.nodes[1].role = ax::mojom::Role::kStaticText;
+ initial_state.nodes[1].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ initial_state.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "Before 1");
initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ui::AX_ROLE_STATIC_TEXT;
- initial_state.nodes[2].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- initial_state.nodes[2].AddStringAttribute(ui::AX_ATTR_NAME, "Before 2");
+ initial_state.nodes[2].role = ax::mojom::Role::kStaticText;
+ initial_state.nodes[2].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ initial_state.nodes[2].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "Before 2");
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
update.nodes[1].string_attributes.clear();
- update.nodes[1].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- update.nodes[1].AddStringAttribute(ui::AX_ATTR_NAME, "After 1");
+ update.nodes[1].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ update.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "After 1");
update.nodes[2].string_attributes.clear();
- update.nodes[2].AddStringAttribute(ui::AX_ATTR_CONTAINER_LIVE_STATUS,
- "polite");
- update.nodes[2].AddStringAttribute(ui::AX_ATTR_NAME, "After 2");
+ update.nodes[2].AddStringAttribute(
+ ax::mojom::StringAttribute::kContainerLiveStatus, "polite");
+ update.nodes[2].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "After 2");
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ(
@@ -563,7 +591,7 @@ TEST(AXEventGeneratorTest, ScrollPositionChanged) {
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[0].AddIntAttribute(ui::AX_ATTR_SCROLL_Y, 10);
+ update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kScrollY, 10);
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ("SCROLL_POSITION_CHANGED on 1", DumpEvents(&event_generator));
}
@@ -587,19 +615,24 @@ TEST(AXEventGeneratorTest, OtherAttributeChanged) {
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[1].AddStringAttribute(ui::AX_ATTR_LANGUAGE, "de");
- update.nodes[2].AddIntAttribute(ui::AX_ATTR_ARIA_CELL_COLUMN_INDEX, 7);
- update.nodes[3].AddFloatAttribute(ui::AX_ATTR_FONT_SIZE, 12.0f);
- update.nodes[4].AddBoolAttribute(ui::AX_ATTR_MODAL, true);
+ update.nodes[1].AddStringAttribute(ax::mojom::StringAttribute::kLanguage,
+ "de");
+ update.nodes[2].AddIntAttribute(ax::mojom::IntAttribute::kAriaCellColumnIndex,
+ 7);
+ update.nodes[3].AddFloatAttribute(ax::mojom::FloatAttribute::kFontSize,
+ 12.0f);
+ update.nodes[4].AddBoolAttribute(ax::mojom::BoolAttribute::kModal, true);
std::vector<int> ids = {2};
- update.nodes[5].AddIntListAttribute(ui::AX_ATTR_CONTROLS_IDS, ids);
+ update.nodes[5].AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds,
+ ids);
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ(
"OTHER_ATTRIBUTE_CHANGED on 2, "
"OTHER_ATTRIBUTE_CHANGED on 3, "
"OTHER_ATTRIBUTE_CHANGED on 4, "
"OTHER_ATTRIBUTE_CHANGED on 5, "
- "OTHER_ATTRIBUTE_CHANGED on 6",
+ "OTHER_ATTRIBUTE_CHANGED on 6, "
+ "RELATED_NODE_CHANGED on 6",
DumpEvents(&event_generator));
}
@@ -612,7 +645,8 @@ TEST(AXEventGeneratorTest, NameChanged) {
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[0].AddStringAttribute(ui::AX_ATTR_NAME, "Hello");
+ update.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "Hello");
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ("NAME_CHANGED on 1", DumpEvents(&event_generator));
}
@@ -626,7 +660,8 @@ TEST(AXEventGeneratorTest, DescriptionChanged) {
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[0].AddStringAttribute(ui::AX_ATTR_DESCRIPTION, "Hello");
+ update.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kDescription,
+ "Hello");
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ("DESCRIPTION_CHANGED on 1", DumpEvents(&event_generator));
}
@@ -640,7 +675,7 @@ TEST(AXEventGeneratorTest, RoleChanged) {
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
- update.nodes[0].role = ui::AX_ROLE_CHECK_BOX;
+ update.nodes[0].role = ax::mojom::Role::kCheckBox;
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ("ROLE_CHANGED on 1", DumpEvents(&event_generator));
}
@@ -650,24 +685,92 @@ TEST(AXEventGeneratorTest, MenuItemSelected) {
initial_state.root_id = 1;
initial_state.nodes.resize(3);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].role = ui::AX_ROLE_MENU;
+ initial_state.nodes[0].role = ax::mojom::Role::kMenu;
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[0].child_ids.push_back(3);
- initial_state.nodes[0].AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 2);
+ initial_state.nodes[0].AddIntAttribute(
+ ax::mojom::IntAttribute::kActivedescendantId, 2);
initial_state.nodes[1].id = 2;
- initial_state.nodes[1].role = ui::AX_ROLE_MENU_LIST_OPTION;
+ initial_state.nodes[1].role = ax::mojom::Role::kMenuListOption;
initial_state.nodes[2].id = 3;
- initial_state.nodes[2].role = ui::AX_ROLE_MENU_LIST_OPTION;
+ initial_state.nodes[2].role = ax::mojom::Role::kMenuListOption;
AXTree tree(initial_state);
AXEventGenerator event_generator(&tree);
AXTreeUpdate update = initial_state;
update.nodes[0].int_attributes.clear();
- update.nodes[0].AddIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 3);
+ update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
+ 3);
EXPECT_TRUE(tree.Unserialize(update));
EXPECT_EQ(
"ACTIVE_DESCENDANT_CHANGED on 1, "
- "MENU_ITEM_SELECTED on 3",
+ "MENU_ITEM_SELECTED on 3, "
+ "RELATED_NODE_CHANGED on 1",
+ DumpEvents(&event_generator));
+}
+
+TEST(AXEventGeneratorTest, NodeBecomesIgnored) {
+ AXTreeUpdate initial_state;
+ initial_state.root_id = 1;
+ initial_state.nodes.resize(5);
+ initial_state.nodes[0].id = 1;
+ initial_state.nodes[0].role = ax::mojom::Role::kRootWebArea;
+ initial_state.nodes[0].child_ids.push_back(2);
+ initial_state.nodes[1].id = 2;
+ initial_state.nodes[1].role = ax::mojom::Role::kArticle;
+ initial_state.nodes[1].child_ids.push_back(3);
+ initial_state.nodes[2].id = 3;
+ initial_state.nodes[2].role = ax::mojom::Role::kGroup;
+ initial_state.nodes[2].AddState(ax::mojom::State::kIgnored);
+ initial_state.nodes[2].child_ids.push_back(4);
+ initial_state.nodes[3].id = 4;
+ initial_state.nodes[3].role = ax::mojom::Role::kGroup;
+ initial_state.nodes[3].child_ids.push_back(5);
+ initial_state.nodes[4].id = 5;
+ initial_state.nodes[4].role = ax::mojom::Role::kStaticText;
+
+ AXTree tree(initial_state);
+
+ AXEventGenerator event_generator(&tree);
+ AXTreeUpdate update = initial_state;
+ update.nodes[3].AddState(ax::mojom::State::kIgnored);
+ EXPECT_TRUE(tree.Unserialize(update));
+ EXPECT_EQ(
+ "CHILDREN_CHANGED on 2, "
+ "STATE_CHANGED on 4",
+ DumpEvents(&event_generator));
+}
+
+TEST(AXEventGeneratorTest, NodeBecomesUnignored) {
+ AXTreeUpdate initial_state;
+ initial_state.root_id = 1;
+ initial_state.nodes.resize(5);
+ initial_state.nodes[0].id = 1;
+ initial_state.nodes[0].role = ax::mojom::Role::kRootWebArea;
+ initial_state.nodes[0].child_ids.push_back(2);
+ initial_state.nodes[1].id = 2;
+ initial_state.nodes[1].role = ax::mojom::Role::kArticle;
+ initial_state.nodes[1].child_ids.push_back(3);
+ initial_state.nodes[2].id = 3;
+ initial_state.nodes[2].role = ax::mojom::Role::kGroup;
+ initial_state.nodes[2].AddState(ax::mojom::State::kIgnored);
+ initial_state.nodes[2].child_ids.push_back(4);
+ initial_state.nodes[3].id = 4;
+ initial_state.nodes[3].role = ax::mojom::Role::kGroup;
+ initial_state.nodes[3].AddState(ax::mojom::State::kIgnored);
+ initial_state.nodes[3].child_ids.push_back(5);
+ initial_state.nodes[4].id = 5;
+ initial_state.nodes[4].role = ax::mojom::Role::kStaticText;
+
+ AXTree tree(initial_state);
+
+ AXEventGenerator event_generator(&tree);
+ AXTreeUpdate update = initial_state;
+ update.nodes[3].state = 0;
+ EXPECT_TRUE(tree.Unserialize(update));
+ EXPECT_EQ(
+ "CHILDREN_CHANGED on 2, "
+ "STATE_CHANGED on 4",
DumpEvents(&event_generator));
}
diff --git a/chromium/ui/accessibility/ax_node.cc b/chromium/ui/accessibility/ax_node.cc
index 8327ccd786e..130d47eeb6c 100644
--- a/chromium/ui/accessibility/ax_node.cc
+++ b/chromium/ui/accessibility/ax_node.cc
@@ -7,7 +7,8 @@
#include <algorithm>
#include "base/strings/string16.h"
-#include "ui/accessibility/ax_enums.h"
+#include "base/strings/utf_string_conversions.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/gfx/transform.h"
namespace ui {
@@ -20,10 +21,62 @@ AXNode::AXNode(AXNode* parent, int32_t id, int32_t index_in_parent)
AXNode::~AXNode() {
}
+int AXNode::GetUnignoredChildCount() const {
+ int count = 0;
+ for (int i = 0; i < child_count(); i++) {
+ AXNode* child = children_[i];
+ if (child->data().HasState(ax::mojom::State::kIgnored))
+ count += child->GetUnignoredChildCount();
+ else
+ count++;
+ }
+ return count;
+}
+
+AXNode* AXNode::GetUnignoredChildAtIndex(int index) const {
+ int count = 0;
+ for (int i = 0; i < child_count(); i++) {
+ AXNode* child = children_[i];
+ if (child->data().HasState(ax::mojom::State::kIgnored)) {
+ int nested_child_count = child->GetUnignoredChildCount();
+ if (index < count + nested_child_count)
+ return child->GetUnignoredChildAtIndex(index - count);
+ else
+ count += nested_child_count;
+ } else {
+ if (count == index)
+ return child;
+ else
+ count++;
+ }
+ }
+
+ return nullptr;
+}
+
+AXNode* AXNode::GetUnignoredParent() const {
+ AXNode* result = parent();
+ while (result && result->data().HasState(ax::mojom::State::kIgnored))
+ result = result->parent();
+ return result;
+}
+
+int AXNode::GetUnignoredIndexInParent() const {
+ AXNode* parent = GetUnignoredParent();
+ if (parent) {
+ for (int i = 0; i < parent->GetUnignoredChildCount(); ++i) {
+ if (parent->GetUnignoredChildAtIndex(i) == this)
+ return i;
+ }
+ }
+
+ return 0;
+}
+
bool AXNode::IsTextNode() const {
- return data().role == AX_ROLE_STATIC_TEXT ||
- data().role == AX_ROLE_LINE_BREAK ||
- data().role == AX_ROLE_INLINE_TEXT_BOX;
+ return data().role == ax::mojom::Role::kStaticText ||
+ data().role == ax::mojom::Role::kLineBreak ||
+ data().role == ax::mojom::Role::kInlineTextBox;
}
void AXNode::SetData(const AXNodeData& src) {
@@ -64,12 +117,14 @@ bool AXNode::IsDescendantOf(AXNode* ancestor) {
std::vector<int> AXNode::GetOrComputeLineStartOffsets() {
std::vector<int> line_offsets;
- if (data().GetIntListAttribute(AX_ATTR_CACHED_LINE_STARTS, &line_offsets))
+ if (data().GetIntListAttribute(ax::mojom::IntListAttribute::kCachedLineStarts,
+ &line_offsets))
return line_offsets;
int start_offset = 0;
ComputeLineStartOffsets(&line_offsets, &start_offset);
- data_.AddIntListAttribute(AX_ATTR_CACHED_LINE_STARTS, line_offsets);
+ data_.AddIntListAttribute(ax::mojom::IntListAttribute::kCachedLineStarts,
+ line_offsets);
return line_offsets;
}
@@ -85,17 +140,34 @@ void AXNode::ComputeLineStartOffsets(std::vector<int>* line_offsets,
}
// Don't report if the first piece of text starts a new line or not.
- if (*start_offset &&
- !child->data().HasIntAttribute(ui::AX_ATTR_PREVIOUS_ON_LINE_ID)) {
+ if (*start_offset && !child->data().HasIntAttribute(
+ ax::mojom::IntAttribute::kPreviousOnLineId)) {
// If there are multiple objects with an empty accessible label at the
// start of a line, only include a single line start offset.
if (line_offsets->empty() || line_offsets->back() != *start_offset)
line_offsets->push_back(*start_offset);
}
- base::string16 text = child->data().GetString16Attribute(ui::AX_ATTR_NAME);
+ base::string16 text =
+ child->data().GetString16Attribute(ax::mojom::StringAttribute::kName);
*start_offset += static_cast<int>(text.length());
}
}
+const std::string& AXNode::GetInheritedStringAttribute(
+ ax::mojom::StringAttribute attribute) const {
+ const AXNode* current_node = this;
+ do {
+ if (current_node->data().HasStringAttribute(attribute))
+ return current_node->data().GetStringAttribute(attribute);
+ current_node = current_node->parent();
+ } while (current_node);
+ return base::EmptyString();
+}
+
+base::string16 AXNode::GetInheritedString16Attribute(
+ ax::mojom::StringAttribute attribute) const {
+ return base::UTF8ToUTF16(GetInheritedStringAttribute(attribute));
+}
+
} // namespace ui
diff --git a/chromium/ui/accessibility/ax_node.h b/chromium/ui/accessibility/ax_node.h
index 6dd907f5a3f..c832a6aadf3 100644
--- a/chromium/ui/accessibility/ax_node.h
+++ b/chromium/ui/accessibility/ax_node.h
@@ -33,6 +33,12 @@ class AX_EXPORT AXNode {
// Get the child at the given index.
AXNode* ChildAtIndex(int index) const { return children_[index]; }
+ // Walking the tree skipping ignored nodes.
+ int GetUnignoredChildCount() const;
+ AXNode* GetUnignoredChildAtIndex(int index) const;
+ AXNode* GetUnignoredParent() const;
+ int GetUnignoredIndexInParent() const;
+
// Returns true if the node has any of the text related roles.
bool IsTextNode() const;
@@ -72,6 +78,11 @@ class AX_EXPORT AXNode {
// by computing them and caching the result.
std::vector<int> GetOrComputeLineStartOffsets();
+ const std::string& GetInheritedStringAttribute(
+ ax::mojom::StringAttribute attribute) const;
+ base::string16 GetInheritedString16Attribute(
+ ax::mojom::StringAttribute attribute) const;
+
private:
// Computes the text offset where each line starts by traversing all child
// leaf nodes.
diff --git a/chromium/ui/accessibility/ax_node_data.cc b/chromium/ui/accessibility/ax_node_data.cc
index ec4ef8b6167..5f8967f3698 100644
--- a/chromium/ui/accessibility/ax_node_data.cc
+++ b/chromium/ui/accessibility/ax_node_data.cc
@@ -13,6 +13,7 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "ui/accessibility/ax_enum_util.h"
#include "ui/accessibility/ax_text_utils.h"
#include "ui/gfx/transform.h"
@@ -30,18 +31,21 @@ uint32_t ModifyFlag(uint32_t bitfield, uint32_t flag, bool set) {
std::string StateBitfieldToString(uint32_t state) {
std::string str;
- for (uint32_t i = AX_STATE_NONE + 1; i <= AX_STATE_LAST; ++i) {
+ for (uint32_t i = static_cast<uint32_t>(ax::mojom::State::kNone) + 1;
+ i <= static_cast<uint32_t>(ax::mojom::State::kLast); ++i) {
if (IsFlagSet(state, i))
- str += " " + base::ToUpperASCII(ui::ToString(static_cast<AXState>(i)));
+ str += " " +
+ base::ToUpperASCII(ui::ToString(static_cast<ax::mojom::State>(i)));
}
return str;
}
std::string ActionsBitfieldToString(uint32_t actions) {
std::string str;
- for (uint32_t i = AX_ACTION_NONE + 1; i <= AX_ACTION_LAST; ++i) {
+ for (uint32_t i = static_cast<uint32_t>(ax::mojom::Action::kNone) + 1;
+ i <= static_cast<uint32_t>(ax::mojom::Action::kLast); ++i) {
if (IsFlagSet(actions, i)) {
- str += ui::ToString(static_cast<AXAction>(i));
+ str += ui::ToString(static_cast<ax::mojom::Action>(i));
actions = ModifyFlag(actions, i, false);
str += actions ? "," : "";
}
@@ -86,64 +90,64 @@ typename std::vector<std::pair<FirstType, SecondType>>::const_iterator
// Return true if |attr| is a node ID that would need to be mapped when
// renumbering the ids in a combined tree.
-bool IsNodeIdIntAttribute(AXIntAttribute attr) {
+bool IsNodeIdIntAttribute(ax::mojom::IntAttribute attr) {
switch (attr) {
- case AX_ATTR_ACTIVEDESCENDANT_ID:
- case AX_ATTR_DETAILS_ID:
- case AX_ATTR_ERRORMESSAGE_ID:
- case AX_ATTR_IN_PAGE_LINK_TARGET_ID:
- case AX_ATTR_MEMBER_OF_ID:
- case AX_ATTR_NEXT_ON_LINE_ID:
- case AX_ATTR_PREVIOUS_ON_LINE_ID:
- case AX_ATTR_TABLE_HEADER_ID:
- case AX_ATTR_TABLE_COLUMN_HEADER_ID:
- case AX_ATTR_TABLE_ROW_HEADER_ID:
- case AX_ATTR_NEXT_FOCUS_ID:
- case AX_ATTR_PREVIOUS_FOCUS_ID:
+ case ax::mojom::IntAttribute::kActivedescendantId:
+ case ax::mojom::IntAttribute::kDetailsId:
+ case ax::mojom::IntAttribute::kErrormessageId:
+ case ax::mojom::IntAttribute::kInPageLinkTargetId:
+ case ax::mojom::IntAttribute::kMemberOfId:
+ case ax::mojom::IntAttribute::kNextOnLineId:
+ case ax::mojom::IntAttribute::kPreviousOnLineId:
+ case ax::mojom::IntAttribute::kTableHeaderId:
+ case ax::mojom::IntAttribute::kTableColumnHeaderId:
+ case ax::mojom::IntAttribute::kTableRowHeaderId:
+ case ax::mojom::IntAttribute::kNextFocusId:
+ case ax::mojom::IntAttribute::kPreviousFocusId:
return true;
// Note: all of the attributes are included here explicitly,
// rather than using "default:", so that it's a compiler error to
// add a new attribute without explicitly considering whether it's
// a node id attribute or not.
- case AX_INT_ATTRIBUTE_NONE:
- case AX_ATTR_DEFAULT_ACTION_VERB:
- case AX_ATTR_SCROLL_X:
- case AX_ATTR_SCROLL_X_MIN:
- case AX_ATTR_SCROLL_X_MAX:
- case AX_ATTR_SCROLL_Y:
- case AX_ATTR_SCROLL_Y_MIN:
- case AX_ATTR_SCROLL_Y_MAX:
- case AX_ATTR_TEXT_SEL_START:
- case AX_ATTR_TEXT_SEL_END:
- case AX_ATTR_TABLE_ROW_COUNT:
- case AX_ATTR_TABLE_COLUMN_COUNT:
- case AX_ATTR_TABLE_ROW_INDEX:
- case AX_ATTR_TABLE_COLUMN_INDEX:
- case AX_ATTR_TABLE_CELL_COLUMN_INDEX:
- case AX_ATTR_TABLE_CELL_COLUMN_SPAN:
- case AX_ATTR_TABLE_CELL_ROW_INDEX:
- case AX_ATTR_TABLE_CELL_ROW_SPAN:
- case AX_ATTR_SORT_DIRECTION:
- case AX_ATTR_HIERARCHICAL_LEVEL:
- case AX_ATTR_NAME_FROM:
- case AX_ATTR_DESCRIPTION_FROM:
- case AX_ATTR_CHILD_TREE_ID:
- case AX_ATTR_SET_SIZE:
- case AX_ATTR_POS_IN_SET:
- case AX_ATTR_COLOR_VALUE:
- case AX_ATTR_ARIA_CURRENT_STATE:
- case AX_ATTR_BACKGROUND_COLOR:
- case AX_ATTR_COLOR:
- case AX_ATTR_INVALID_STATE:
- case AX_ATTR_CHECKED_STATE:
- case AX_ATTR_RESTRICTION:
- case AX_ATTR_TEXT_DIRECTION:
- case AX_ATTR_TEXT_STYLE:
- case AX_ATTR_ARIA_COLUMN_COUNT:
- case AX_ATTR_ARIA_CELL_COLUMN_INDEX:
- case AX_ATTR_ARIA_ROW_COUNT:
- case AX_ATTR_ARIA_CELL_ROW_INDEX:
+ case ax::mojom::IntAttribute::kNone:
+ case ax::mojom::IntAttribute::kDefaultActionVerb:
+ case ax::mojom::IntAttribute::kScrollX:
+ case ax::mojom::IntAttribute::kScrollXMin:
+ case ax::mojom::IntAttribute::kScrollXMax:
+ case ax::mojom::IntAttribute::kScrollY:
+ case ax::mojom::IntAttribute::kScrollYMin:
+ case ax::mojom::IntAttribute::kScrollYMax:
+ case ax::mojom::IntAttribute::kTextSelStart:
+ case ax::mojom::IntAttribute::kTextSelEnd:
+ case ax::mojom::IntAttribute::kTableRowCount:
+ case ax::mojom::IntAttribute::kTableColumnCount:
+ case ax::mojom::IntAttribute::kTableRowIndex:
+ case ax::mojom::IntAttribute::kTableColumnIndex:
+ case ax::mojom::IntAttribute::kTableCellColumnIndex:
+ case ax::mojom::IntAttribute::kTableCellColumnSpan:
+ case ax::mojom::IntAttribute::kTableCellRowIndex:
+ case ax::mojom::IntAttribute::kTableCellRowSpan:
+ case ax::mojom::IntAttribute::kSortDirection:
+ case ax::mojom::IntAttribute::kHierarchicalLevel:
+ case ax::mojom::IntAttribute::kNameFrom:
+ case ax::mojom::IntAttribute::kDescriptionFrom:
+ case ax::mojom::IntAttribute::kChildTreeId:
+ case ax::mojom::IntAttribute::kSetSize:
+ case ax::mojom::IntAttribute::kPosInSet:
+ case ax::mojom::IntAttribute::kColorValue:
+ case ax::mojom::IntAttribute::kAriaCurrentState:
+ case ax::mojom::IntAttribute::kBackgroundColor:
+ case ax::mojom::IntAttribute::kColor:
+ case ax::mojom::IntAttribute::kInvalidState:
+ case ax::mojom::IntAttribute::kCheckedState:
+ case ax::mojom::IntAttribute::kRestriction:
+ case ax::mojom::IntAttribute::kTextDirection:
+ case ax::mojom::IntAttribute::kTextStyle:
+ case ax::mojom::IntAttribute::kAriaColumnCount:
+ case ax::mojom::IntAttribute::kAriaCellColumnIndex:
+ case ax::mojom::IntAttribute::kAriaRowCount:
+ case ax::mojom::IntAttribute::kAriaCellRowIndex:
return false;
}
@@ -153,32 +157,32 @@ bool IsNodeIdIntAttribute(AXIntAttribute attr) {
// Return true if |attr| contains a vector of node ids that would need
// to be mapped when renumbering the ids in a combined tree.
-bool IsNodeIdIntListAttribute(AXIntListAttribute attr) {
+bool IsNodeIdIntListAttribute(ax::mojom::IntListAttribute attr) {
switch (attr) {
- case AX_ATTR_CELL_IDS:
- case AX_ATTR_CONTROLS_IDS:
- case AX_ATTR_DESCRIBEDBY_IDS:
- case AX_ATTR_FLOWTO_IDS:
- case AX_ATTR_INDIRECT_CHILD_IDS:
- case AX_ATTR_LABELLEDBY_IDS:
- case AX_ATTR_RADIO_GROUP_IDS:
- case AX_ATTR_UNIQUE_CELL_IDS:
+ case ax::mojom::IntListAttribute::kCellIds:
+ case ax::mojom::IntListAttribute::kControlsIds:
+ case ax::mojom::IntListAttribute::kDescribedbyIds:
+ case ax::mojom::IntListAttribute::kFlowtoIds:
+ case ax::mojom::IntListAttribute::kIndirectChildIds:
+ case ax::mojom::IntListAttribute::kLabelledbyIds:
+ case ax::mojom::IntListAttribute::kRadioGroupIds:
+ case ax::mojom::IntListAttribute::kUniqueCellIds:
return true;
// Note: all of the attributes are included here explicitly,
// rather than using "default:", so that it's a compiler error to
// add a new attribute without explicitly considering whether it's
// a node id attribute or not.
- case AX_INT_LIST_ATTRIBUTE_NONE:
- case AX_ATTR_LINE_BREAKS:
- case AX_ATTR_MARKER_TYPES:
- case AX_ATTR_MARKER_STARTS:
- case AX_ATTR_MARKER_ENDS:
- case AX_ATTR_CHARACTER_OFFSETS:
- case AX_ATTR_CACHED_LINE_STARTS:
- case AX_ATTR_WORD_STARTS:
- case AX_ATTR_WORD_ENDS:
- case AX_ATTR_CUSTOM_ACTION_IDS:
+ case ax::mojom::IntListAttribute::kNone:
+ case ax::mojom::IntListAttribute::kLineBreaks:
+ case ax::mojom::IntListAttribute::kMarkerTypes:
+ case ax::mojom::IntListAttribute::kMarkerStarts:
+ case ax::mojom::IntListAttribute::kMarkerEnds:
+ case ax::mojom::IntListAttribute::kCharacterOffsets:
+ case ax::mojom::IntListAttribute::kCachedLineStarts:
+ case ax::mojom::IntListAttribute::kWordStarts:
+ case ax::mojom::IntListAttribute::kWordEnds:
+ case ax::mojom::IntListAttribute::kCustomActionIds:
return false;
}
@@ -230,20 +234,20 @@ AXNodeData& AXNodeData::operator=(AXNodeData other) {
return *this;
}
-bool AXNodeData::HasBoolAttribute(AXBoolAttribute attribute) const {
+bool AXNodeData::HasBoolAttribute(ax::mojom::BoolAttribute attribute) const {
auto iter = FindInVectorOfPairs(attribute, bool_attributes);
return iter != bool_attributes.end();
}
-bool AXNodeData::GetBoolAttribute(AXBoolAttribute attribute) const {
+bool AXNodeData::GetBoolAttribute(ax::mojom::BoolAttribute attribute) const {
bool result;
if (GetBoolAttribute(attribute, &result))
return result;
return false;
}
-bool AXNodeData::GetBoolAttribute(
- AXBoolAttribute attribute, bool* value) const {
+bool AXNodeData::GetBoolAttribute(ax::mojom::BoolAttribute attribute,
+ bool* value) const {
auto iter = FindInVectorOfPairs(attribute, bool_attributes);
if (iter != bool_attributes.end()) {
*value = iter->second;
@@ -253,20 +257,20 @@ bool AXNodeData::GetBoolAttribute(
return false;
}
-bool AXNodeData::HasFloatAttribute(AXFloatAttribute attribute) const {
+bool AXNodeData::HasFloatAttribute(ax::mojom::FloatAttribute attribute) const {
auto iter = FindInVectorOfPairs(attribute, float_attributes);
return iter != float_attributes.end();
}
-float AXNodeData::GetFloatAttribute(AXFloatAttribute attribute) const {
+float AXNodeData::GetFloatAttribute(ax::mojom::FloatAttribute attribute) const {
float result;
if (GetFloatAttribute(attribute, &result))
return result;
return 0.0;
}
-bool AXNodeData::GetFloatAttribute(
- AXFloatAttribute attribute, float* value) const {
+bool AXNodeData::GetFloatAttribute(ax::mojom::FloatAttribute attribute,
+ float* value) const {
auto iter = FindInVectorOfPairs(attribute, float_attributes);
if (iter != float_attributes.end()) {
*value = iter->second;
@@ -276,20 +280,20 @@ bool AXNodeData::GetFloatAttribute(
return false;
}
-bool AXNodeData::HasIntAttribute(AXIntAttribute attribute) const {
+bool AXNodeData::HasIntAttribute(ax::mojom::IntAttribute attribute) const {
auto iter = FindInVectorOfPairs(attribute, int_attributes);
return iter != int_attributes.end();
}
-int AXNodeData::GetIntAttribute(AXIntAttribute attribute) const {
+int AXNodeData::GetIntAttribute(ax::mojom::IntAttribute attribute) const {
int result;
if (GetIntAttribute(attribute, &result))
return result;
return 0;
}
-bool AXNodeData::GetIntAttribute(
- AXIntAttribute attribute, int* value) const {
+bool AXNodeData::GetIntAttribute(ax::mojom::IntAttribute attribute,
+ int* value) const {
auto iter = FindInVectorOfPairs(attribute, int_attributes);
if (iter != int_attributes.end()) {
*value = iter->second;
@@ -299,20 +303,21 @@ bool AXNodeData::GetIntAttribute(
return false;
}
-bool AXNodeData::HasStringAttribute(AXStringAttribute attribute) const {
+bool AXNodeData::HasStringAttribute(
+ ax::mojom::StringAttribute attribute) const {
auto iter = FindInVectorOfPairs(attribute, string_attributes);
return iter != string_attributes.end();
}
const std::string& AXNodeData::GetStringAttribute(
- AXStringAttribute attribute) const {
+ ax::mojom::StringAttribute attribute) const {
CR_DEFINE_STATIC_LOCAL(std::string, empty_string, ());
auto iter = FindInVectorOfPairs(attribute, string_attributes);
return iter != string_attributes.end() ? iter->second : empty_string;
}
-bool AXNodeData::GetStringAttribute(
- AXStringAttribute attribute, std::string* value) const {
+bool AXNodeData::GetStringAttribute(ax::mojom::StringAttribute attribute,
+ std::string* value) const {
auto iter = FindInVectorOfPairs(attribute, string_attributes);
if (iter != string_attributes.end()) {
*value = iter->second;
@@ -323,16 +328,15 @@ bool AXNodeData::GetStringAttribute(
}
base::string16 AXNodeData::GetString16Attribute(
- AXStringAttribute attribute) const {
+ ax::mojom::StringAttribute attribute) const {
std::string value_utf8;
if (!GetStringAttribute(attribute, &value_utf8))
return base::string16();
return base::UTF8ToUTF16(value_utf8);
}
-bool AXNodeData::GetString16Attribute(
- AXStringAttribute attribute,
- base::string16* value) const {
+bool AXNodeData::GetString16Attribute(ax::mojom::StringAttribute attribute,
+ base::string16* value) const {
std::string value_utf8;
if (!GetStringAttribute(attribute, &value_utf8))
return false;
@@ -340,13 +344,14 @@ bool AXNodeData::GetString16Attribute(
return true;
}
-bool AXNodeData::HasIntListAttribute(AXIntListAttribute attribute) const {
+bool AXNodeData::HasIntListAttribute(
+ ax::mojom::IntListAttribute attribute) const {
auto iter = FindInVectorOfPairs(attribute, intlist_attributes);
return iter != intlist_attributes.end();
}
const std::vector<int32_t>& AXNodeData::GetIntListAttribute(
- AXIntListAttribute attribute) const {
+ ax::mojom::IntListAttribute attribute) const {
CR_DEFINE_STATIC_LOCAL(std::vector<int32_t>, empty_vector, ());
auto iter = FindInVectorOfPairs(attribute, intlist_attributes);
if (iter != intlist_attributes.end())
@@ -354,7 +359,7 @@ const std::vector<int32_t>& AXNodeData::GetIntListAttribute(
return empty_vector;
}
-bool AXNodeData::GetIntListAttribute(AXIntListAttribute attribute,
+bool AXNodeData::GetIntListAttribute(ax::mojom::IntListAttribute attribute,
std::vector<int32_t>* value) const {
auto iter = FindInVectorOfPairs(attribute, intlist_attributes);
if (iter != intlist_attributes.end()) {
@@ -365,13 +370,14 @@ bool AXNodeData::GetIntListAttribute(AXIntListAttribute attribute,
return false;
}
-bool AXNodeData::HasStringListAttribute(AXStringListAttribute attribute) const {
+bool AXNodeData::HasStringListAttribute(
+ ax::mojom::StringListAttribute attribute) const {
auto iter = FindInVectorOfPairs(attribute, stringlist_attributes);
return iter != stringlist_attributes.end();
}
const std::vector<std::string>& AXNodeData::GetStringListAttribute(
- AXStringListAttribute attribute) const {
+ ax::mojom::StringListAttribute attribute) const {
CR_DEFINE_STATIC_LOCAL(std::vector<std::string>, empty_vector, ());
auto iter = FindInVectorOfPairs(attribute, stringlist_attributes);
if (iter != stringlist_attributes.end())
@@ -379,8 +385,9 @@ const std::vector<std::string>& AXNodeData::GetStringListAttribute(
return empty_vector;
}
-bool AXNodeData::GetStringListAttribute(AXStringListAttribute attribute,
- std::vector<std::string>* value) const {
+bool AXNodeData::GetStringListAttribute(
+ ax::mojom::StringListAttribute attribute,
+ std::vector<std::string>* value) const {
auto iter = FindInVectorOfPairs(attribute, stringlist_attributes);
if (iter != stringlist_attributes.end()) {
*value = iter->second;
@@ -392,10 +399,11 @@ bool AXNodeData::GetStringListAttribute(AXStringListAttribute attribute,
bool AXNodeData::GetHtmlAttribute(
const char* html_attr, std::string* value) const {
- for (size_t i = 0; i < html_attributes.size(); ++i) {
- const std::string& attr = html_attributes[i].first;
+ for (const std::pair<std::string, std::string>& html_attribute :
+ html_attributes) {
+ const std::string& attr = html_attribute.first;
if (base::LowerCaseEqualsASCII(attr, html_attr)) {
- *value = html_attributes[i].second;
+ *value = html_attribute.second;
return true;
}
}
@@ -412,82 +420,110 @@ bool AXNodeData::GetHtmlAttribute(
return true;
}
-void AXNodeData::AddStringAttribute(
- AXStringAttribute attribute, const std::string& value) {
+void AXNodeData::AddStringAttribute(ax::mojom::StringAttribute attribute,
+ const std::string& value) {
string_attributes.push_back(std::make_pair(attribute, value));
}
-void AXNodeData::AddIntAttribute(
- AXIntAttribute attribute, int value) {
+void AXNodeData::AddIntAttribute(ax::mojom::IntAttribute attribute, int value) {
int_attributes.push_back(std::make_pair(attribute, value));
}
-void AXNodeData::AddFloatAttribute(
- AXFloatAttribute attribute, float value) {
+void AXNodeData::AddFloatAttribute(ax::mojom::FloatAttribute attribute,
+ float value) {
float_attributes.push_back(std::make_pair(attribute, value));
}
-void AXNodeData::AddBoolAttribute(
- AXBoolAttribute attribute, bool value) {
+void AXNodeData::AddBoolAttribute(ax::mojom::BoolAttribute attribute,
+ bool value) {
bool_attributes.push_back(std::make_pair(attribute, value));
}
-void AXNodeData::AddIntListAttribute(AXIntListAttribute attribute,
+void AXNodeData::AddIntListAttribute(ax::mojom::IntListAttribute attribute,
const std::vector<int32_t>& value) {
intlist_attributes.push_back(std::make_pair(attribute, value));
}
-void AXNodeData::AddStringListAttribute(AXStringListAttribute attribute,
- const std::vector<std::string>& value) {
+void AXNodeData::AddStringListAttribute(
+ ax::mojom::StringListAttribute attribute,
+ const std::vector<std::string>& value) {
stringlist_attributes.push_back(std::make_pair(attribute, value));
}
void AXNodeData::SetName(const std::string& name) {
- for (size_t i = 0; i < string_attributes.size(); ++i) {
- if (string_attributes[i].first == AX_ATTR_NAME) {
- string_attributes[i].second = name;
- return;
- }
+ auto iter = std::find_if(string_attributes.begin(), string_attributes.end(),
+ [](const auto& string_attribute) {
+ return string_attribute.first ==
+ ax::mojom::StringAttribute::kName;
+ });
+ if (iter == string_attributes.end()) {
+ string_attributes.push_back(
+ std::make_pair(ax::mojom::StringAttribute::kName, name));
+ } else {
+ iter->second = name;
}
-
- string_attributes.push_back(std::make_pair(AX_ATTR_NAME, name));
}
void AXNodeData::SetName(const base::string16& name) {
SetName(base::UTF16ToUTF8(name));
}
-void AXNodeData::SetValue(const std::string& value) {
- for (size_t i = 0; i < string_attributes.size(); ++i) {
- if (string_attributes[i].first == AX_ATTR_VALUE) {
- string_attributes[i].second = value;
- return;
- }
+void AXNodeData::SetNameExplicitlyEmpty() {
+ SetNameFrom(ax::mojom::NameFrom::kAttributeExplicitlyEmpty);
+}
+
+void AXNodeData::SetDescription(const std::string& description) {
+ auto iter = std::find_if(string_attributes.begin(), string_attributes.end(),
+ [](const auto& string_attribute) {
+ return string_attribute.first ==
+ ax::mojom::StringAttribute::kDescription;
+ });
+ if (iter == string_attributes.end()) {
+ string_attributes.push_back(
+ std::make_pair(ax::mojom::StringAttribute::kDescription, description));
+ } else {
+ iter->second = description;
}
+}
+
+void AXNodeData::SetDescription(const base::string16& description) {
+ SetDescription(base::UTF16ToUTF8(description));
+}
- string_attributes.push_back(std::make_pair(AX_ATTR_VALUE, value));
+void AXNodeData::SetValue(const std::string& value) {
+ auto iter = std::find_if(string_attributes.begin(), string_attributes.end(),
+ [](const auto& string_attribute) {
+ return string_attribute.first ==
+ ax::mojom::StringAttribute::kValue;
+ });
+ if (iter == string_attributes.end()) {
+ string_attributes.push_back(
+ std::make_pair(ax::mojom::StringAttribute::kValue, value));
+ } else {
+ iter->second = value;
+ }
}
void AXNodeData::SetValue(const base::string16& value) {
SetValue(base::UTF16ToUTF8(value));
}
-bool AXNodeData::HasState(AXState state_enum) const {
- return IsFlagSet(state, state_enum);
+bool AXNodeData::HasState(ax::mojom::State state_enum) const {
+ return IsFlagSet(state, static_cast<uint32_t>(state_enum));
}
-bool AXNodeData::HasAction(AXAction action_enum) const {
- return IsFlagSet(actions, action_enum);
+bool AXNodeData::HasAction(ax::mojom::Action action_enum) const {
+ return IsFlagSet(actions, static_cast<uint32_t>(action_enum));
}
-void AXNodeData::AddState(AXState state_enum) {
- DCHECK_NE(state_enum, AX_STATE_NONE);
- state = ModifyFlag(state, state_enum, true);
+void AXNodeData::AddState(ax::mojom::State state_enum) {
+ DCHECK_NE(state_enum, ax::mojom::State::kNone);
+ state = ModifyFlag(state, static_cast<uint32_t>(state_enum), true);
}
-void AXNodeData::AddAction(AXAction action_enum) {
+void AXNodeData::AddAction(ax::mojom::Action action_enum) {
switch (action_enum) {
- case AX_ACTION_NONE:
+ case ax::mojom::Action::kNone:
NOTREACHED();
break;
@@ -495,37 +531,38 @@ void AXNodeData::AddAction(AXAction action_enum) {
// using "default:", so that it's a compiler error to add a new action
// without explicitly considering whether there are mutually exclusive
// actions that can be performed on a UI control at the same time.
- case AX_ACTION_BLUR:
- case AX_ACTION_FOCUS: {
- AXAction excluded_action =
- (action_enum == AX_ACTION_BLUR) ? AX_ACTION_FOCUS : AX_ACTION_BLUR;
+ case ax::mojom::Action::kBlur:
+ case ax::mojom::Action::kFocus: {
+ ax::mojom::Action excluded_action =
+ (action_enum == ax::mojom::Action::kBlur) ? ax::mojom::Action::kFocus
+ : ax::mojom::Action::kBlur;
DCHECK(HasAction(excluded_action));
} break;
- case AX_ACTION_CUSTOM_ACTION:
- case AX_ACTION_DECREMENT:
- case AX_ACTION_DO_DEFAULT:
- case AX_ACTION_GET_IMAGE_DATA:
- case AX_ACTION_HIT_TEST:
- case AX_ACTION_INCREMENT:
- case AX_ACTION_LOAD_INLINE_TEXT_BOXES:
- case AX_ACTION_REPLACE_SELECTED_TEXT:
- case AX_ACTION_SCROLL_TO_MAKE_VISIBLE:
- case AX_ACTION_SCROLL_TO_POINT:
- case AX_ACTION_SET_SCROLL_OFFSET:
- case AX_ACTION_SET_SELECTION:
- case AX_ACTION_SET_SEQUENTIAL_FOCUS_NAVIGATION_STARTING_POINT:
- case AX_ACTION_SET_VALUE:
- case AX_ACTION_SHOW_CONTEXT_MENU:
- case AX_ACTION_SCROLL_BACKWARD:
- case AX_ACTION_SCROLL_FORWARD:
- case AX_ACTION_SCROLL_UP:
- case AX_ACTION_SCROLL_DOWN:
- case AX_ACTION_SCROLL_LEFT:
- case AX_ACTION_SCROLL_RIGHT:
+ case ax::mojom::Action::kCustomAction:
+ case ax::mojom::Action::kDecrement:
+ case ax::mojom::Action::kDoDefault:
+ case ax::mojom::Action::kGetImageData:
+ case ax::mojom::Action::kHitTest:
+ case ax::mojom::Action::kIncrement:
+ case ax::mojom::Action::kLoadInlineTextBoxes:
+ case ax::mojom::Action::kReplaceSelectedText:
+ case ax::mojom::Action::kScrollToMakeVisible:
+ case ax::mojom::Action::kScrollToPoint:
+ case ax::mojom::Action::kSetScrollOffset:
+ case ax::mojom::Action::kSetSelection:
+ case ax::mojom::Action::kSetSequentialFocusNavigationStartingPoint:
+ case ax::mojom::Action::kSetValue:
+ case ax::mojom::Action::kShowContextMenu:
+ case ax::mojom::Action::kScrollBackward:
+ case ax::mojom::Action::kScrollForward:
+ case ax::mojom::Action::kScrollUp:
+ case ax::mojom::Action::kScrollDown:
+ case ax::mojom::Action::kScrollLeft:
+ case ax::mojom::Action::kScrollRight:
break;
}
- actions = ModifyFlag(actions, action_enum, true);
+ actions = ModifyFlag(actions, static_cast<uint32_t>(action_enum), true);
}
std::string AXNodeData::ToString() const {
@@ -549,450 +586,471 @@ std::string AXNodeData::ToString() const {
if (transform && !transform->IsIdentity())
result += " transform=" + transform->ToString();
- for (size_t i = 0; i < int_attributes.size(); ++i) {
- std::string value = base::NumberToString(int_attributes[i].second);
- switch (int_attributes[i].first) {
- case AX_ATTR_DEFAULT_ACTION_VERB:
- result +=
- " action=" +
- base::UTF16ToUTF8(ActionVerbToUnlocalizedString(
- static_cast<AXDefaultActionVerb>(int_attributes[i].second)));
+ for (const std::pair<ax::mojom::IntAttribute, int32_t>& int_attribute :
+ int_attributes) {
+ std::string value = base::NumberToString(int_attribute.second);
+ switch (int_attribute.first) {
+ case ax::mojom::IntAttribute::kDefaultActionVerb:
+ result += " action=" + base::UTF16ToUTF8(ActionVerbToUnlocalizedString(
+ static_cast<ax::mojom::DefaultActionVerb>(
+ int_attribute.second)));
break;
- case AX_ATTR_SCROLL_X:
+ case ax::mojom::IntAttribute::kScrollX:
result += " scroll_x=" + value;
break;
- case AX_ATTR_SCROLL_X_MIN:
+ case ax::mojom::IntAttribute::kScrollXMin:
result += " scroll_x_min=" + value;
break;
- case AX_ATTR_SCROLL_X_MAX:
+ case ax::mojom::IntAttribute::kScrollXMax:
result += " scroll_x_max=" + value;
break;
- case AX_ATTR_SCROLL_Y:
+ case ax::mojom::IntAttribute::kScrollY:
result += " scroll_y=" + value;
break;
- case AX_ATTR_SCROLL_Y_MIN:
+ case ax::mojom::IntAttribute::kScrollYMin:
result += " scroll_y_min=" + value;
break;
- case AX_ATTR_SCROLL_Y_MAX:
+ case ax::mojom::IntAttribute::kScrollYMax:
result += " scroll_y_max=" + value;
break;
- case AX_ATTR_HIERARCHICAL_LEVEL:
+ case ax::mojom::IntAttribute::kHierarchicalLevel:
result += " level=" + value;
break;
- case AX_ATTR_TEXT_SEL_START:
+ case ax::mojom::IntAttribute::kTextSelStart:
result += " sel_start=" + value;
break;
- case AX_ATTR_TEXT_SEL_END:
+ case ax::mojom::IntAttribute::kTextSelEnd:
result += " sel_end=" + value;
break;
- case AX_ATTR_ARIA_COLUMN_COUNT:
+ case ax::mojom::IntAttribute::kAriaColumnCount:
result += " aria_column_count=" + value;
break;
- case AX_ATTR_ARIA_CELL_COLUMN_INDEX:
+ case ax::mojom::IntAttribute::kAriaCellColumnIndex:
result += " aria_cell_column_index=" + value;
break;
- case AX_ATTR_ARIA_ROW_COUNT:
+ case ax::mojom::IntAttribute::kAriaRowCount:
result += " aria_row_count=" + value;
break;
- case AX_ATTR_ARIA_CELL_ROW_INDEX:
+ case ax::mojom::IntAttribute::kAriaCellRowIndex:
result += " aria_cell_row_index=" + value;
break;
- case AX_ATTR_TABLE_ROW_COUNT:
+ case ax::mojom::IntAttribute::kTableRowCount:
result += " rows=" + value;
break;
- case AX_ATTR_TABLE_COLUMN_COUNT:
+ case ax::mojom::IntAttribute::kTableColumnCount:
result += " cols=" + value;
break;
- case AX_ATTR_TABLE_CELL_COLUMN_INDEX:
+ case ax::mojom::IntAttribute::kTableCellColumnIndex:
result += " col=" + value;
break;
- case AX_ATTR_TABLE_CELL_ROW_INDEX:
+ case ax::mojom::IntAttribute::kTableCellRowIndex:
result += " row=" + value;
break;
- case AX_ATTR_TABLE_CELL_COLUMN_SPAN:
+ case ax::mojom::IntAttribute::kTableCellColumnSpan:
result += " colspan=" + value;
break;
- case AX_ATTR_TABLE_CELL_ROW_SPAN:
+ case ax::mojom::IntAttribute::kTableCellRowSpan:
result += " rowspan=" + value;
break;
- case AX_ATTR_TABLE_COLUMN_HEADER_ID:
+ case ax::mojom::IntAttribute::kTableColumnHeaderId:
result += " column_header_id=" + value;
break;
- case AX_ATTR_TABLE_COLUMN_INDEX:
+ case ax::mojom::IntAttribute::kTableColumnIndex:
result += " column_index=" + value;
break;
- case AX_ATTR_TABLE_HEADER_ID:
+ case ax::mojom::IntAttribute::kTableHeaderId:
result += " header_id=" + value;
break;
- case AX_ATTR_TABLE_ROW_HEADER_ID:
+ case ax::mojom::IntAttribute::kTableRowHeaderId:
result += " row_header_id=" + value;
break;
- case AX_ATTR_TABLE_ROW_INDEX:
+ case ax::mojom::IntAttribute::kTableRowIndex:
result += " row_index=" + value;
break;
- case AX_ATTR_SORT_DIRECTION:
- switch (int_attributes[i].second) {
- case AX_SORT_DIRECTION_UNSORTED:
+ case ax::mojom::IntAttribute::kSortDirection:
+ switch (static_cast<ax::mojom::SortDirection>(int_attribute.second)) {
+ case ax::mojom::SortDirection::kUnsorted:
result += " sort_direction=none";
break;
- case AX_SORT_DIRECTION_ASCENDING:
+ case ax::mojom::SortDirection::kAscending:
result += " sort_direction=ascending";
break;
- case AX_SORT_DIRECTION_DESCENDING:
+ case ax::mojom::SortDirection::kDescending:
result += " sort_direction=descending";
break;
- case AX_SORT_DIRECTION_OTHER:
+ case ax::mojom::SortDirection::kOther:
result += " sort_direction=other";
break;
+ default:
+ break;
}
break;
- case AX_ATTR_NAME_FROM:
+ case ax::mojom::IntAttribute::kNameFrom:
result += " name_from=";
- result +=
- ui::ToString(static_cast<AXNameFrom>(int_attributes[i].second));
+ result += ui::ToString(
+ static_cast<ax::mojom::NameFrom>(int_attribute.second));
break;
- case AX_ATTR_DESCRIPTION_FROM:
+ case ax::mojom::IntAttribute::kDescriptionFrom:
result += " description_from=";
result += ui::ToString(
- static_cast<AXDescriptionFrom>(int_attributes[i].second));
+ static_cast<ax::mojom::DescriptionFrom>(int_attribute.second));
break;
- case AX_ATTR_ACTIVEDESCENDANT_ID:
+ case ax::mojom::IntAttribute::kActivedescendantId:
result += " activedescendant=" + value;
break;
- case AX_ATTR_DETAILS_ID:
+ case ax::mojom::IntAttribute::kDetailsId:
result += " details=" + value;
break;
- case AX_ATTR_ERRORMESSAGE_ID:
+ case ax::mojom::IntAttribute::kErrormessageId:
result += " errormessage=" + value;
break;
- case AX_ATTR_IN_PAGE_LINK_TARGET_ID:
+ case ax::mojom::IntAttribute::kInPageLinkTargetId:
result += " in_page_link_target_id=" + value;
break;
- case AX_ATTR_MEMBER_OF_ID:
+ case ax::mojom::IntAttribute::kMemberOfId:
result += " member_of_id=" + value;
break;
- case AX_ATTR_NEXT_ON_LINE_ID:
+ case ax::mojom::IntAttribute::kNextOnLineId:
result += " next_on_line_id=" + value;
break;
- case AX_ATTR_PREVIOUS_ON_LINE_ID:
+ case ax::mojom::IntAttribute::kPreviousOnLineId:
result += " previous_on_line_id=" + value;
break;
- case AX_ATTR_CHILD_TREE_ID:
+ case ax::mojom::IntAttribute::kChildTreeId:
result += " child_tree_id=" + value;
break;
- case AX_ATTR_COLOR_VALUE:
- result += base::StringPrintf(" color_value=&%X",
- int_attributes[i].second);
+ case ax::mojom::IntAttribute::kColorValue:
+ result += base::StringPrintf(" color_value=&%X", int_attribute.second);
break;
- case AX_ATTR_ARIA_CURRENT_STATE:
- switch (int_attributes[i].second) {
- case AX_ARIA_CURRENT_STATE_FALSE:
+ case ax::mojom::IntAttribute::kAriaCurrentState:
+ switch (
+ static_cast<ax::mojom::AriaCurrentState>(int_attribute.second)) {
+ case ax::mojom::AriaCurrentState::kFalse:
result += " aria_current_state=false";
break;
- case AX_ARIA_CURRENT_STATE_TRUE:
+ case ax::mojom::AriaCurrentState::kTrue:
result += " aria_current_state=true";
break;
- case AX_ARIA_CURRENT_STATE_PAGE:
+ case ax::mojom::AriaCurrentState::kPage:
result += " aria_current_state=page";
break;
- case AX_ARIA_CURRENT_STATE_STEP:
+ case ax::mojom::AriaCurrentState::kStep:
result += " aria_current_state=step";
break;
- case AX_ARIA_CURRENT_STATE_LOCATION:
+ case ax::mojom::AriaCurrentState::kLocation:
result += " aria_current_state=location";
break;
- case AX_ARIA_CURRENT_STATE_DATE:
+ case ax::mojom::AriaCurrentState::kDate:
result += " aria_current_state=date";
break;
- case AX_ARIA_CURRENT_STATE_TIME:
+ case ax::mojom::AriaCurrentState::kTime:
result += " aria_current_state=time";
break;
+ default:
+ break;
}
break;
- case AX_ATTR_BACKGROUND_COLOR:
- result += base::StringPrintf(" background_color=&%X",
- int_attributes[i].second);
+ case ax::mojom::IntAttribute::kBackgroundColor:
+ result +=
+ base::StringPrintf(" background_color=&%X", int_attribute.second);
break;
- case AX_ATTR_COLOR:
- result += base::StringPrintf(" color=&%X", int_attributes[i].second);
+ case ax::mojom::IntAttribute::kColor:
+ result += base::StringPrintf(" color=&%X", int_attribute.second);
break;
- case AX_ATTR_TEXT_DIRECTION:
- switch (int_attributes[i].second) {
- case AX_TEXT_DIRECTION_LTR:
+ case ax::mojom::IntAttribute::kTextDirection:
+ switch (static_cast<ax::mojom::TextDirection>(int_attribute.second)) {
+ case ax::mojom::TextDirection::kLtr:
result += " text_direction=ltr";
break;
- case AX_TEXT_DIRECTION_RTL:
+ case ax::mojom::TextDirection::kRtl:
result += " text_direction=rtl";
break;
- case AX_TEXT_DIRECTION_TTB:
+ case ax::mojom::TextDirection::kTtb:
result += " text_direction=ttb";
break;
- case AX_TEXT_DIRECTION_BTT:
+ case ax::mojom::TextDirection::kBtt:
result += " text_direction=btt";
break;
+ default:
+ break;
}
break;
- case AX_ATTR_TEXT_STYLE: {
- auto text_style = static_cast<AXTextStyle>(int_attributes[i].second);
- if (text_style == AX_TEXT_STYLE_NONE)
+ case ax::mojom::IntAttribute::kTextStyle: {
+ int32_t text_style = int_attribute.second;
+ if (text_style == static_cast<int32_t>(ax::mojom::TextStyle::kNone))
break;
std::string text_style_value(" text_style=");
- if (text_style & AX_TEXT_STYLE_BOLD)
+ if (text_style &
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleBold))
text_style_value += "bold,";
- if (text_style & AX_TEXT_STYLE_ITALIC)
+ if (text_style &
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleItalic))
text_style_value += "italic,";
- if (text_style & AX_TEXT_STYLE_UNDERLINE)
+ if (text_style &
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleUnderline))
text_style_value += "underline,";
- if (text_style & AX_TEXT_STYLE_LINE_THROUGH)
+ if (text_style &
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleLineThrough))
text_style_value += "line-through,";
result += text_style_value.substr(0, text_style_value.size() - 1);
break;
}
- case AX_ATTR_SET_SIZE:
+ case ax::mojom::IntAttribute::kSetSize:
result += " setsize=" + value;
break;
- case AX_ATTR_POS_IN_SET:
+ case ax::mojom::IntAttribute::kPosInSet:
result += " posinset=" + value;
break;
- case AX_ATTR_INVALID_STATE:
- switch (int_attributes[i].second) {
- case AX_INVALID_STATE_FALSE:
+ case ax::mojom::IntAttribute::kInvalidState:
+ switch (static_cast<ax::mojom::InvalidState>(int_attribute.second)) {
+ case ax::mojom::InvalidState::kFalse:
result += " invalid_state=false";
break;
- case AX_INVALID_STATE_TRUE:
+ case ax::mojom::InvalidState::kTrue:
result += " invalid_state=true";
break;
- case AX_INVALID_STATE_SPELLING:
+ case ax::mojom::InvalidState::kSpelling:
result += " invalid_state=spelling";
break;
- case AX_INVALID_STATE_GRAMMAR:
+ case ax::mojom::InvalidState::kGrammar:
result += " invalid_state=grammar";
break;
- case AX_INVALID_STATE_OTHER:
+ case ax::mojom::InvalidState::kOther:
result += " invalid_state=other";
break;
+ default:
+ break;
}
break;
- case AX_ATTR_CHECKED_STATE:
- switch (int_attributes[i].second) {
- case AX_CHECKED_STATE_FALSE:
+ case ax::mojom::IntAttribute::kCheckedState:
+ switch (static_cast<ax::mojom::CheckedState>(int_attribute.second)) {
+ case ax::mojom::CheckedState::kFalse:
result += " checked_state=false";
break;
- case AX_CHECKED_STATE_TRUE:
+ case ax::mojom::CheckedState::kTrue:
result += " checked_state=true";
break;
- case AX_CHECKED_STATE_MIXED:
+ case ax::mojom::CheckedState::kMixed:
result += " checked_state=mixed";
break;
+ default:
+ break;
}
break;
- case AX_ATTR_RESTRICTION:
- switch (int_attributes[i].second) {
- case AX_RESTRICTION_READ_ONLY:
+ case ax::mojom::IntAttribute::kRestriction:
+ switch (static_cast<ax::mojom::Restriction>(int_attribute.second)) {
+ case ax::mojom::Restriction::kReadOnly:
result += " restriction=readonly";
break;
- case AX_RESTRICTION_DISABLED:
+ case ax::mojom::Restriction::kDisabled:
result += " restriction=disabled";
break;
+ default:
+ break;
}
break;
- case AX_ATTR_NEXT_FOCUS_ID:
+ case ax::mojom::IntAttribute::kNextFocusId:
result += " next_focus_id=" + value;
break;
- case AX_ATTR_PREVIOUS_FOCUS_ID:
+ case ax::mojom::IntAttribute::kPreviousFocusId:
result += " previous_focus_id=" + value;
break;
- case AX_INT_ATTRIBUTE_NONE:
+ case ax::mojom::IntAttribute::kNone:
break;
}
}
- for (size_t i = 0; i < string_attributes.size(); ++i) {
- std::string value = string_attributes[i].second;
- switch (string_attributes[i].first) {
- case AX_ATTR_ACCESS_KEY:
+ for (const std::pair<ax::mojom::StringAttribute, std::string>&
+ string_attribute : string_attributes) {
+ std::string value = string_attribute.second;
+ switch (string_attribute.first) {
+ case ax::mojom::StringAttribute::kAccessKey:
result += " access_key=" + value;
break;
- case AX_ATTR_ARIA_INVALID_VALUE:
+ case ax::mojom::StringAttribute::kAriaInvalidValue:
result += " aria_invalid_value=" + value;
break;
- case AX_ATTR_AUTO_COMPLETE:
+ case ax::mojom::StringAttribute::kAutoComplete:
result += " autocomplete=" + value;
break;
- case AX_ATTR_CHROME_CHANNEL:
+ case ax::mojom::StringAttribute::kChromeChannel:
result += " chrome_channel=" + value;
break;
- case AX_ATTR_CLASS_NAME:
+ case ax::mojom::StringAttribute::kClassName:
result += " class_name=" + value;
break;
- case AX_ATTR_DESCRIPTION:
+ case ax::mojom::StringAttribute::kDescription:
result += " description=" + value;
break;
- case AX_ATTR_DISPLAY:
+ case ax::mojom::StringAttribute::kDisplay:
result += " display=" + value;
break;
- case AX_ATTR_FONT_FAMILY:
+ case ax::mojom::StringAttribute::kFontFamily:
result += " font-family=" + value;
break;
- case AX_ATTR_HTML_TAG:
+ case ax::mojom::StringAttribute::kHtmlTag:
result += " html_tag=" + value;
break;
- case AX_ATTR_IMAGE_DATA_URL:
+ case ax::mojom::StringAttribute::kImageDataUrl:
result += " image_data_url=(" +
base::NumberToString(static_cast<int>(value.size())) +
" bytes)";
break;
- case AX_ATTR_INNER_HTML:
+ case ax::mojom::StringAttribute::kInnerHtml:
result += " inner_html=" + value;
break;
- case AX_ATTR_KEY_SHORTCUTS:
+ case ax::mojom::StringAttribute::kKeyShortcuts:
result += " key_shortcuts=" + value;
break;
- case AX_ATTR_LANGUAGE:
+ case ax::mojom::StringAttribute::kLanguage:
result += " language=" + value;
break;
- case AX_ATTR_LIVE_RELEVANT:
+ case ax::mojom::StringAttribute::kLiveRelevant:
result += " relevant=" + value;
break;
- case AX_ATTR_LIVE_STATUS:
+ case ax::mojom::StringAttribute::kLiveStatus:
result += " live=" + value;
break;
- case AX_ATTR_CONTAINER_LIVE_RELEVANT:
+ case ax::mojom::StringAttribute::kContainerLiveRelevant:
result += " container_relevant=" + value;
break;
- case AX_ATTR_CONTAINER_LIVE_STATUS:
+ case ax::mojom::StringAttribute::kContainerLiveStatus:
result += " container_live=" + value;
break;
- case AX_ATTR_PLACEHOLDER:
+ case ax::mojom::StringAttribute::kPlaceholder:
result += " placeholder=" + value;
break;
- case AX_ATTR_ROLE:
+ case ax::mojom::StringAttribute::kRole:
result += " role=" + value;
break;
- case AX_ATTR_ROLE_DESCRIPTION:
+ case ax::mojom::StringAttribute::kRoleDescription:
result += " role_description=" + value;
break;
- case AX_ATTR_URL:
+ case ax::mojom::StringAttribute::kUrl:
result += " url=" + value;
break;
- case AX_ATTR_NAME:
+ case ax::mojom::StringAttribute::kName:
result += " name=" + value;
break;
- case AX_ATTR_VALUE:
+ case ax::mojom::StringAttribute::kValue:
result += " value=" + value;
break;
- case AX_STRING_ATTRIBUTE_NONE:
+ case ax::mojom::StringAttribute::kNone:
break;
}
}
- for (size_t i = 0; i < float_attributes.size(); ++i) {
- std::string value = base::NumberToString(float_attributes[i].second);
- switch (float_attributes[i].first) {
- case AX_ATTR_VALUE_FOR_RANGE:
+ for (const std::pair<ax::mojom::FloatAttribute, float>& float_attribute :
+ float_attributes) {
+ std::string value = base::NumberToString(float_attribute.second);
+ switch (float_attribute.first) {
+ case ax::mojom::FloatAttribute::kValueForRange:
result += " value_for_range=" + value;
break;
- case AX_ATTR_MAX_VALUE_FOR_RANGE:
+ case ax::mojom::FloatAttribute::kMaxValueForRange:
result += " max_value=" + value;
break;
- case AX_ATTR_MIN_VALUE_FOR_RANGE:
+ case ax::mojom::FloatAttribute::kMinValueForRange:
result += " min_value=" + value;
break;
- case AX_ATTR_STEP_VALUE_FOR_RANGE:
+ case ax::mojom::FloatAttribute::kStepValueForRange:
result += " step_value=" + value;
break;
- case AX_ATTR_FONT_SIZE:
+ case ax::mojom::FloatAttribute::kFontSize:
result += " font_size=" + value;
break;
- case AX_FLOAT_ATTRIBUTE_NONE:
+ case ax::mojom::FloatAttribute::kNone:
break;
}
}
- for (size_t i = 0; i < bool_attributes.size(); ++i) {
- std::string value = bool_attributes[i].second ? "true" : "false";
- switch (bool_attributes[i].first) {
- case AX_ATTR_EDITABLE_ROOT:
+ for (const std::pair<ax::mojom::BoolAttribute, bool>& bool_attribute :
+ bool_attributes) {
+ std::string value = bool_attribute.second ? "true" : "false";
+ switch (bool_attribute.first) {
+ case ax::mojom::BoolAttribute::kEditableRoot:
result += " editable_root=" + value;
break;
- case AX_ATTR_LIVE_ATOMIC:
+ case ax::mojom::BoolAttribute::kLiveAtomic:
result += " atomic=" + value;
break;
- case AX_ATTR_BUSY:
+ case ax::mojom::BoolAttribute::kBusy:
result += " busy=" + value;
break;
- case AX_ATTR_CONTAINER_LIVE_ATOMIC:
+ case ax::mojom::BoolAttribute::kContainerLiveAtomic:
result += " container_atomic=" + value;
break;
- case AX_ATTR_CONTAINER_LIVE_BUSY:
+ case ax::mojom::BoolAttribute::kContainerLiveBusy:
result += " container_busy=" + value;
break;
- case AX_ATTR_UPDATE_LOCATION_ONLY:
+ case ax::mojom::BoolAttribute::kUpdateLocationOnly:
result += " update_location_only=" + value;
break;
- case AX_ATTR_CANVAS_HAS_FALLBACK:
+ case ax::mojom::BoolAttribute::kCanvasHasFallback:
result += " has_fallback=" + value;
break;
- case AX_ATTR_MODAL:
+ case ax::mojom::BoolAttribute::kModal:
result += " modal=" + value;
break;
- case AX_ATTR_SCROLLABLE:
+ case ax::mojom::BoolAttribute::kScrollable:
result += " scrollable=" + value;
break;
- case AX_ATTR_CLICKABLE:
+ case ax::mojom::BoolAttribute::kClickable:
result += " clickable=" + value;
break;
- case AX_ATTR_CLIPS_CHILDREN:
+ case ax::mojom::BoolAttribute::kClipsChildren:
result += " clips_children=" + value;
break;
- case AX_BOOL_ATTRIBUTE_NONE:
+ case ax::mojom::BoolAttribute::kNone:
break;
}
}
- for (size_t i = 0; i < intlist_attributes.size(); ++i) {
- const std::vector<int32_t>& values = intlist_attributes[i].second;
- switch (intlist_attributes[i].first) {
- case AX_ATTR_INDIRECT_CHILD_IDS:
+ for (const std::pair<ax::mojom::IntListAttribute, std::vector<int32_t>>&
+ intlist_attribute : intlist_attributes) {
+ const std::vector<int32_t>& values = intlist_attribute.second;
+ switch (intlist_attribute.first) {
+ case ax::mojom::IntListAttribute::kIndirectChildIds:
result += " indirect_child_ids=" + IntVectorToString(values);
break;
- case AX_ATTR_CONTROLS_IDS:
+ case ax::mojom::IntListAttribute::kControlsIds:
result += " controls_ids=" + IntVectorToString(values);
break;
- case AX_ATTR_DESCRIBEDBY_IDS:
+ case ax::mojom::IntListAttribute::kDescribedbyIds:
result += " describedby_ids=" + IntVectorToString(values);
break;
- case AX_ATTR_FLOWTO_IDS:
+ case ax::mojom::IntListAttribute::kFlowtoIds:
result += " flowto_ids=" + IntVectorToString(values);
break;
- case AX_ATTR_LABELLEDBY_IDS:
+ case ax::mojom::IntListAttribute::kLabelledbyIds:
result += " labelledby_ids=" + IntVectorToString(values);
break;
- case AX_ATTR_RADIO_GROUP_IDS:
+ case ax::mojom::IntListAttribute::kRadioGroupIds:
result += " radio_group_ids=" + IntVectorToString(values);
break;
- case AX_ATTR_LINE_BREAKS:
+ case ax::mojom::IntListAttribute::kLineBreaks:
result += " line_breaks=" + IntVectorToString(values);
break;
- case AX_ATTR_MARKER_TYPES: {
+ case ax::mojom::IntListAttribute::kMarkerTypes: {
std::string types_str;
for (size_t i = 0; i < values.size(); ++i) {
- auto type = static_cast<AXMarkerType>(values[i]);
- if (type == AX_MARKER_TYPE_NONE)
+ int32_t type = values[i];
+ if (type == static_cast<int32_t>(ax::mojom::MarkerType::kNone))
continue;
if (i > 0)
types_str += ',';
- if (type & AX_MARKER_TYPE_SPELLING)
+ if (type & static_cast<int32_t>(ax::mojom::MarkerType::kSpelling))
types_str += "spelling&";
- if (type & AX_MARKER_TYPE_GRAMMAR)
+ if (type & static_cast<int32_t>(ax::mojom::MarkerType::kGrammar))
types_str += "grammar&";
- if (type & AX_MARKER_TYPE_TEXT_MATCH)
+ if (type & static_cast<int32_t>(ax::mojom::MarkerType::kTextMatch))
types_str += "text_match&";
- if (type & AX_MARKER_TYPE_ACTIVE_SUGGESTION)
+ if (type &
+ static_cast<int32_t>(ax::mojom::MarkerType::kActiveSuggestion))
types_str += "active_suggestion&";
- if (type & AX_MARKER_TYPE_SUGGESTION)
+ if (type & static_cast<int32_t>(ax::mojom::MarkerType::kSuggestion))
types_str += "suggestion&";
if (!types_str.empty())
@@ -1003,46 +1061,48 @@ std::string AXNodeData::ToString() const {
result += " marker_types=" + types_str;
break;
}
- case AX_ATTR_MARKER_STARTS:
+ case ax::mojom::IntListAttribute::kMarkerStarts:
result += " marker_starts=" + IntVectorToString(values);
break;
- case AX_ATTR_MARKER_ENDS:
+ case ax::mojom::IntListAttribute::kMarkerEnds:
result += " marker_ends=" + IntVectorToString(values);
break;
- case AX_ATTR_CELL_IDS:
+ case ax::mojom::IntListAttribute::kCellIds:
result += " cell_ids=" + IntVectorToString(values);
break;
- case AX_ATTR_UNIQUE_CELL_IDS:
+ case ax::mojom::IntListAttribute::kUniqueCellIds:
result += " unique_cell_ids=" + IntVectorToString(values);
break;
- case AX_ATTR_CHARACTER_OFFSETS:
+ case ax::mojom::IntListAttribute::kCharacterOffsets:
result += " character_offsets=" + IntVectorToString(values);
break;
- case AX_ATTR_CACHED_LINE_STARTS:
+ case ax::mojom::IntListAttribute::kCachedLineStarts:
result += " cached_line_start_offsets=" + IntVectorToString(values);
break;
- case AX_ATTR_WORD_STARTS:
+ case ax::mojom::IntListAttribute::kWordStarts:
result += " word_starts=" + IntVectorToString(values);
break;
- case AX_ATTR_WORD_ENDS:
+ case ax::mojom::IntListAttribute::kWordEnds:
result += " word_ends=" + IntVectorToString(values);
break;
- case AX_ATTR_CUSTOM_ACTION_IDS:
+ case ax::mojom::IntListAttribute::kCustomActionIds:
result += " custom_action_ids=" + IntVectorToString(values);
break;
- case AX_INT_LIST_ATTRIBUTE_NONE:
+ case ax::mojom::IntListAttribute::kNone:
break;
}
}
- for (size_t i = 0; i < stringlist_attributes.size(); ++i) {
- const std::vector<std::string>& values = stringlist_attributes[i].second;
- switch (stringlist_attributes[i].first) {
- case AX_ATTR_CUSTOM_ACTION_DESCRIPTIONS:
+ for (const std::pair<ax::mojom::StringListAttribute,
+ std::vector<std::string>>& stringlist_attribute :
+ stringlist_attributes) {
+ const std::vector<std::string>& values = stringlist_attribute.second;
+ switch (stringlist_attribute.first) {
+ case ax::mojom::StringListAttribute::kCustomActionDescriptions:
result +=
" custom_action_descriptions: " + base::JoinString(values, ",");
break;
- case AX_STRING_LIST_ATTRIBUTE_NONE:
+ case ax::mojom::StringListAttribute::kNone:
break;
}
}
diff --git a/chromium/ui/accessibility/ax_node_data.h b/chromium/ui/accessibility/ax_node_data.h
index 0f2194e421d..5741f15c40b 100644
--- a/chromium/ui/accessibility/ax_node_data.h
+++ b/chromium/ui/accessibility/ax_node_data.h
@@ -14,7 +14,7 @@
#include "base/strings/string16.h"
#include "base/strings/string_split.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_export.h"
#include "ui/gfx/geometry/rect_f.h"
@@ -26,11 +26,11 @@ namespace ui {
// Return true if |attr| should be interpreted as the id of another node
// in the same tree.
-AX_EXPORT bool IsNodeIdIntAttribute(AXIntAttribute attr);
+AX_EXPORT bool IsNodeIdIntAttribute(ax::mojom::IntAttribute attr);
// Return true if |attr| should be interpreted as a list of ids of
// nodes in the same tree.
-AX_EXPORT bool IsNodeIdIntListAttribute(AXIntListAttribute attr);
+AX_EXPORT bool IsNodeIdIntListAttribute(ax::mojom::IntListAttribute attr);
// A compact representation of the accessibility information for a
// single accessible object, in a form that can be serialized and sent from
@@ -57,70 +57,134 @@ struct AX_EXPORT AXNodeData {
// attribute is not present. In addition, strings can be returned as
// either std::string or base::string16, for convenience.
- bool HasBoolAttribute(AXBoolAttribute attr) const;
- bool GetBoolAttribute(AXBoolAttribute attr) const;
- bool GetBoolAttribute(AXBoolAttribute attr, bool* value) const;
+ bool HasBoolAttribute(ax::mojom::BoolAttribute attr) const;
+ bool GetBoolAttribute(ax::mojom::BoolAttribute attr) const;
+ bool GetBoolAttribute(ax::mojom::BoolAttribute attr, bool* value) const;
- bool HasFloatAttribute(AXFloatAttribute attr) const;
- float GetFloatAttribute(AXFloatAttribute attr) const;
- bool GetFloatAttribute(AXFloatAttribute attr, float* value) const;
+ bool HasFloatAttribute(ax::mojom::FloatAttribute attr) const;
+ float GetFloatAttribute(ax::mojom::FloatAttribute attr) const;
+ bool GetFloatAttribute(ax::mojom::FloatAttribute attr, float* value) const;
- bool HasIntAttribute(AXIntAttribute attribute) const;
- int GetIntAttribute(AXIntAttribute attribute) const;
- bool GetIntAttribute(AXIntAttribute attribute, int* value) const;
+ bool HasIntAttribute(ax::mojom::IntAttribute attribute) const;
+ int32_t GetIntAttribute(ax::mojom::IntAttribute attribute) const;
+ bool GetIntAttribute(ax::mojom::IntAttribute attribute, int* value) const;
- bool HasStringAttribute(
- AXStringAttribute attribute) const;
- const std::string& GetStringAttribute(AXStringAttribute attribute) const;
- bool GetStringAttribute(AXStringAttribute attribute,
+ bool HasStringAttribute(ax::mojom::StringAttribute attribute) const;
+ const std::string& GetStringAttribute(
+ ax::mojom::StringAttribute attribute) const;
+ bool GetStringAttribute(ax::mojom::StringAttribute attribute,
std::string* value) const;
- bool GetString16Attribute(AXStringAttribute attribute,
+ bool GetString16Attribute(ax::mojom::StringAttribute attribute,
base::string16* value) const;
base::string16 GetString16Attribute(
- AXStringAttribute attribute) const;
+ ax::mojom::StringAttribute attribute) const;
- bool HasIntListAttribute(AXIntListAttribute attribute) const;
+ bool HasIntListAttribute(ax::mojom::IntListAttribute attribute) const;
const std::vector<int32_t>& GetIntListAttribute(
- AXIntListAttribute attribute) const;
- bool GetIntListAttribute(AXIntListAttribute attribute,
+ ax::mojom::IntListAttribute attribute) const;
+ bool GetIntListAttribute(ax::mojom::IntListAttribute attribute,
std::vector<int32_t>* value) const;
- bool HasStringListAttribute(AXStringListAttribute attribute) const;
+ bool HasStringListAttribute(ax::mojom::StringListAttribute attribute) const;
const std::vector<std::string>& GetStringListAttribute(
- AXStringListAttribute attribute) const;
- bool GetStringListAttribute(AXStringListAttribute attribute,
+ ax::mojom::StringListAttribute attribute) const;
+ bool GetStringListAttribute(ax::mojom::StringListAttribute attribute,
std::vector<std::string>* value) const;
bool GetHtmlAttribute(const char* attr, base::string16* value) const;
bool GetHtmlAttribute(const char* attr, std::string* value) const;
// Setting accessibility attributes.
- void AddStringAttribute(AXStringAttribute attribute,
+ void AddStringAttribute(ax::mojom::StringAttribute attribute,
const std::string& value);
- void AddIntAttribute(AXIntAttribute attribute, int value);
- void AddFloatAttribute(AXFloatAttribute attribute, float value);
- void AddBoolAttribute(AXBoolAttribute attribute, bool value);
- void AddIntListAttribute(AXIntListAttribute attribute,
+ void AddIntAttribute(ax::mojom::IntAttribute attribute, int32_t value);
+ void AddFloatAttribute(ax::mojom::FloatAttribute attribute, float value);
+ void AddBoolAttribute(ax::mojom::BoolAttribute attribute, bool value);
+ void AddIntListAttribute(ax::mojom::IntListAttribute attribute,
const std::vector<int32_t>& value);
- void AddStringListAttribute(AXStringListAttribute attribute,
+ void AddStringListAttribute(ax::mojom::StringListAttribute attribute,
const std::vector<std::string>& value);
- // Convenience functions, mainly for writing unit tests.
- // Equivalent to AddStringAttribute(ATTR_NAME, name).
+ //
+ // Convenience functions.
+ //
+
+ // Adds the name attribute or replaces it if already present.
void SetName(const std::string& name);
void SetName(const base::string16& name);
- // Equivalent to AddStringAttribute(ATTR_VALUE, value).
+
+ // Allows nameless objects to pass accessibility checks.
+ void SetNameExplicitlyEmpty();
+
+ // Adds the description attribute or replaces it if already present.
+ void SetDescription(const std::string& description);
+ void SetDescription(const base::string16& description);
+
+ // Adds the value attribute or replaces it if already present.
void SetValue(const std::string& value);
void SetValue(const base::string16& value);
// Returns true if the given enum bit is 1.
- bool HasState(ui::AXState state_enum) const;
- bool HasAction(ui::AXAction state_enum) const;
+ bool HasState(ax::mojom::State state_enum) const;
+ bool HasAction(ax::mojom::Action state_enum) const;
// Set bits in the given enum's corresponding bitfield.
- void AddState(ui::AXState state_enum);
- void AddAction(ui::AXAction action_enum);
+ void AddState(ax::mojom::State state_enum);
+ void AddAction(ax::mojom::Action action_enum);
+
+ // Helper functions to get some common int attributes with some specific
+ // enum types:
+ ax::mojom::CheckedState GetCheckedState() const {
+ return static_cast<ax::mojom::CheckedState>(
+ GetIntAttribute(ax::mojom::IntAttribute::kCheckedState));
+ }
+ ax::mojom::DefaultActionVerb GetDefaultActionVerb() const {
+ return static_cast<ax::mojom::DefaultActionVerb>(
+ GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb));
+ }
+ ax::mojom::InvalidState GetInvalidState() const {
+ return static_cast<ax::mojom::InvalidState>(
+ GetIntAttribute(ax::mojom::IntAttribute::kInvalidState));
+ }
+ ax::mojom::NameFrom GetNameFrom() const {
+ return static_cast<ax::mojom::NameFrom>(
+ GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
+ }
+ ax::mojom::Restriction GetRestriction() const {
+ return static_cast<ax::mojom::Restriction>(
+ GetIntAttribute(ax::mojom::IntAttribute::kRestriction));
+ }
+ ax::mojom::TextDirection GetTextDirection() const {
+ return static_cast<ax::mojom::TextDirection>(
+ GetIntAttribute(ax::mojom::IntAttribute::kTextDirection));
+ }
+
+ // Helper functions to set some common int attributes.
+ void SetCheckedState(ax::mojom::CheckedState checked_state) {
+ AddIntAttribute(ax::mojom::IntAttribute::kCheckedState,
+ static_cast<int32_t>(checked_state));
+ }
+ void SetDefaultActionVerb(ax::mojom::DefaultActionVerb default_action_verb) {
+ AddIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb,
+ static_cast<int32_t>(default_action_verb));
+ }
+ void SetInvalidState(ax::mojom::InvalidState invalid_state) {
+ AddIntAttribute(ax::mojom::IntAttribute::kInvalidState,
+ static_cast<int32_t>(invalid_state));
+ }
+ void SetNameFrom(ax::mojom::NameFrom name_from) {
+ AddIntAttribute(ax::mojom::IntAttribute::kNameFrom,
+ static_cast<int32_t>(name_from));
+ }
+ void SetRestriction(ax::mojom::Restriction restriction) {
+ AddIntAttribute(ax::mojom::IntAttribute::kRestriction,
+ static_cast<int32_t>(restriction));
+ }
+ void SetTextDirection(ax::mojom::TextDirection text_direction) {
+ AddIntAttribute(ax::mojom::IntAttribute::kTextDirection,
+ static_cast<int32_t>(text_direction));
+ }
// Return a string representation of this data, for debugging.
virtual std::string ToString() const;
@@ -128,16 +192,18 @@ struct AX_EXPORT AXNodeData {
// As much as possible this should behave as a simple, serializable,
// copyable struct.
int32_t id = -1;
- AXRole role = AX_ROLE_UNKNOWN;
- uint32_t state = AX_STATE_NONE;
- uint32_t actions = AX_ACTION_NONE;
- std::vector<std::pair<AXStringAttribute, std::string>> string_attributes;
- std::vector<std::pair<AXIntAttribute, int32_t>> int_attributes;
- std::vector<std::pair<AXFloatAttribute, float>> float_attributes;
- std::vector<std::pair<AXBoolAttribute, bool>> bool_attributes;
- std::vector<std::pair<AXIntListAttribute, std::vector<int32_t>>>
+ ax::mojom::Role role = ax::mojom::Role::kUnknown;
+ uint32_t state = static_cast<uint32_t>(ax::mojom::State::kNone);
+ uint32_t actions = static_cast<uint32_t>(ax::mojom::Action::kNone);
+ std::vector<std::pair<ax::mojom::StringAttribute, std::string>>
+ string_attributes;
+ std::vector<std::pair<ax::mojom::IntAttribute, int32_t>> int_attributes;
+ std::vector<std::pair<ax::mojom::FloatAttribute, float>> float_attributes;
+ std::vector<std::pair<ax::mojom::BoolAttribute, bool>> bool_attributes;
+ std::vector<std::pair<ax::mojom::IntListAttribute, std::vector<int32_t>>>
intlist_attributes;
- std::vector<std::pair<AXStringListAttribute, std::vector<std::string>>>
+ std::vector<
+ std::pair<ax::mojom::StringListAttribute, std::vector<std::string>>>
stringlist_attributes;
base::StringPairs html_attributes;
std::vector<int32_t> child_ids;
diff --git a/chromium/ui/accessibility/ax_node_position.cc b/chromium/ui/accessibility/ax_node_position.cc
index 95318cc7fb6..9711f344677 100644
--- a/chromium/ui/accessibility/ax_node_position.cc
+++ b/chromium/ui/accessibility/ax_node_position.cc
@@ -5,7 +5,7 @@
#include "ui/accessibility/ax_node_position.h"
#include "base/strings/string_util.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
namespace ui {
@@ -24,11 +24,12 @@ base::string16 AXNodePosition::GetInnerText() const {
return base::string16();
DCHECK(GetAnchor());
- base::string16 value =
- GetAnchor()->data().GetString16Attribute(AX_ATTR_VALUE);
+ base::string16 value = GetAnchor()->data().GetString16Attribute(
+ ax::mojom::StringAttribute::kValue);
if (!value.empty())
return value;
- return GetAnchor()->data().GetString16Attribute(AX_ATTR_NAME);
+ return GetAnchor()->data().GetString16Attribute(
+ ax::mojom::StringAttribute::kName);
}
void AXNodePosition::AnchorChild(int child_index,
@@ -100,14 +101,16 @@ std::vector<int32_t> AXNodePosition::GetWordStartOffsets() const {
if (IsNullPosition())
return std::vector<int32_t>();
DCHECK(GetAnchor());
- return GetAnchor()->data().GetIntListAttribute(ui::AX_ATTR_WORD_STARTS);
+ return GetAnchor()->data().GetIntListAttribute(
+ ax::mojom::IntListAttribute::kWordStarts);
}
std::vector<int32_t> AXNodePosition::GetWordEndOffsets() const {
if (IsNullPosition())
return std::vector<int32_t>();
DCHECK(GetAnchor());
- return GetAnchor()->data().GetIntListAttribute(ui::AX_ATTR_WORD_ENDS);
+ return GetAnchor()->data().GetIntListAttribute(
+ ax::mojom::IntListAttribute::kWordEnds);
}
int32_t AXNodePosition::GetNextOnLineID(int32_t node_id) const {
@@ -115,9 +118,8 @@ int32_t AXNodePosition::GetNextOnLineID(int32_t node_id) const {
return INVALID_ANCHOR_ID;
AXNode* node = GetNodeInTree(tree_id(), node_id);
int next_on_line_id;
- if (!node ||
- !node->data().GetIntAttribute(AX_ATTR_NEXT_ON_LINE_ID,
- &next_on_line_id)) {
+ if (!node || !node->data().GetIntAttribute(
+ ax::mojom::IntAttribute::kNextOnLineId, &next_on_line_id)) {
return INVALID_ANCHOR_ID;
}
return static_cast<int32_t>(next_on_line_id);
@@ -129,7 +131,7 @@ int32_t AXNodePosition::GetPreviousOnLineID(int32_t node_id) const {
AXNode* node = GetNodeInTree(tree_id(), node_id);
int previous_on_line_id;
if (!node ||
- !node->data().GetIntAttribute(AX_ATTR_PREVIOUS_ON_LINE_ID,
+ !node->data().GetIntAttribute(ax::mojom::IntAttribute::kPreviousOnLineId,
&previous_on_line_id)) {
return INVALID_ANCHOR_ID;
}
diff --git a/chromium/ui/accessibility/ax_node_position.h b/chromium/ui/accessibility/ax_node_position.h
index a7640bfcfcb..ec8d7715b3e 100644
--- a/chromium/ui/accessibility/ax_node_position.h
+++ b/chromium/ui/accessibility/ax_node_position.h
@@ -10,6 +10,7 @@
#include <vector>
#include "base/strings/string16.h"
+#include "ui/accessibility/ax_enum_util.h"
#include "ui/accessibility/ax_export.h"
#include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_position.h"
diff --git a/chromium/ui/accessibility/ax_node_position_unittest.cc b/chromium/ui/accessibility/ax_node_position_unittest.cc
index 326c7ce5191..243e7f883f7 100644
--- a/chromium/ui/accessibility/ax_node_position_unittest.cc
+++ b/chromium/ui/accessibility/ax_node_position_unittest.cc
@@ -14,7 +14,7 @@
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_node_position.h"
@@ -115,71 +115,78 @@ void AXPositionTest::SetUp() {
static_text2_.id = STATIC_TEXT2_ID;
inline_box2_.id = INLINE_BOX2_ID;
- root_.role = AX_ROLE_DIALOG;
- root_.AddState(AX_STATE_FOCUSABLE);
+ root_.role = ax::mojom::Role::kDialog;
+ root_.AddState(ax::mojom::State::kFocusable);
root_.SetName(std::string("ButtonCheck box") + TEXT_VALUE);
root_.location = gfx::RectF(0, 0, 800, 600);
- button_.role = AX_ROLE_BUTTON;
- button_.AddState(AX_STATE_HASPOPUP);
+ button_.role = ax::mojom::Role::kButton;
+ button_.AddState(ax::mojom::State::kHaspopup);
button_.SetName("Button");
button_.location = gfx::RectF(20, 20, 200, 30);
- button_.AddIntListAttribute(AX_ATTR_WORD_STARTS, std::vector<int32_t>{0});
- button_.AddIntListAttribute(AX_ATTR_WORD_ENDS, std::vector<int32_t>{6});
- button_.AddIntAttribute(AX_ATTR_NEXT_ON_LINE_ID, check_box_.id);
+ button_.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
+ std::vector<int32_t>{0});
+ button_.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
+ std::vector<int32_t>{6});
+ button_.AddIntAttribute(ax::mojom::IntAttribute::kNextOnLineId,
+ check_box_.id);
root_.child_ids.push_back(button_.id);
- check_box_.role = AX_ROLE_CHECK_BOX;
- check_box_.AddIntAttribute(ui::AX_ATTR_CHECKED_STATE,
- ui::AX_CHECKED_STATE_TRUE);
+ check_box_.role = ax::mojom::Role::kCheckBox;
+ check_box_.SetCheckedState(ax::mojom::CheckedState::kTrue);
check_box_.SetName("Check box");
check_box_.location = gfx::RectF(20, 50, 200, 30);
- check_box_.AddIntListAttribute(AX_ATTR_WORD_STARTS,
+ check_box_.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
std::vector<int32_t>{0, 6});
- check_box_.AddIntListAttribute(AX_ATTR_WORD_ENDS, std::vector<int32_t>{5, 9});
- check_box_.AddIntAttribute(AX_ATTR_PREVIOUS_ON_LINE_ID, button_.id);
+ check_box_.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
+ std::vector<int32_t>{5, 9});
+ check_box_.AddIntAttribute(ax::mojom::IntAttribute::kPreviousOnLineId,
+ button_.id);
root_.child_ids.push_back(check_box_.id);
- text_field_.role = AX_ROLE_TEXT_FIELD;
- text_field_.AddState(AX_STATE_EDITABLE);
+ text_field_.role = ax::mojom::Role::kTextField;
+ text_field_.AddState(ax::mojom::State::kEditable);
text_field_.SetValue(TEXT_VALUE);
- text_field_.AddIntListAttribute(AX_ATTR_CACHED_LINE_STARTS,
- std::vector<int32_t>{0, 7});
+ text_field_.AddIntListAttribute(
+ ax::mojom::IntListAttribute::kCachedLineStarts,
+ std::vector<int32_t>{0, 7});
text_field_.child_ids.push_back(static_text1_.id);
text_field_.child_ids.push_back(line_break_.id);
text_field_.child_ids.push_back(static_text2_.id);
root_.child_ids.push_back(text_field_.id);
- static_text1_.role = AX_ROLE_STATIC_TEXT;
- static_text1_.AddState(AX_STATE_EDITABLE);
+ static_text1_.role = ax::mojom::Role::kStaticText;
+ static_text1_.AddState(ax::mojom::State::kEditable);
static_text1_.SetName("Line 1");
static_text1_.child_ids.push_back(inline_box1_.id);
- inline_box1_.role = AX_ROLE_INLINE_TEXT_BOX;
- inline_box1_.AddState(AX_STATE_EDITABLE);
+ inline_box1_.role = ax::mojom::Role::kInlineTextBox;
+ inline_box1_.AddState(ax::mojom::State::kEditable);
inline_box1_.SetName("Line 1");
- inline_box1_.AddIntListAttribute(AX_ATTR_WORD_STARTS,
+ inline_box1_.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
std::vector<int32_t>{0, 5});
- inline_box1_.AddIntListAttribute(AX_ATTR_WORD_ENDS,
+ inline_box1_.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
std::vector<int32_t>{4, 6});
- inline_box1_.AddIntAttribute(AX_ATTR_NEXT_ON_LINE_ID, line_break_.id);
+ inline_box1_.AddIntAttribute(ax::mojom::IntAttribute::kNextOnLineId,
+ line_break_.id);
- line_break_.role = AX_ROLE_LINE_BREAK;
- line_break_.AddState(AX_STATE_EDITABLE);
+ line_break_.role = ax::mojom::Role::kLineBreak;
+ line_break_.AddState(ax::mojom::State::kEditable);
line_break_.SetName("\n");
- line_break_.AddIntAttribute(AX_ATTR_PREVIOUS_ON_LINE_ID, inline_box1_.id);
+ line_break_.AddIntAttribute(ax::mojom::IntAttribute::kPreviousOnLineId,
+ inline_box1_.id);
- static_text2_.role = AX_ROLE_STATIC_TEXT;
- static_text2_.AddState(AX_STATE_EDITABLE);
+ static_text2_.role = ax::mojom::Role::kStaticText;
+ static_text2_.AddState(ax::mojom::State::kEditable);
static_text2_.SetName("Line 2");
static_text2_.child_ids.push_back(inline_box2_.id);
- inline_box2_.role = AX_ROLE_INLINE_TEXT_BOX;
- inline_box2_.AddState(AX_STATE_EDITABLE);
+ inline_box2_.role = ax::mojom::Role::kInlineTextBox;
+ inline_box2_.AddState(ax::mojom::State::kEditable);
inline_box2_.SetName("Line 2");
- inline_box2_.AddIntListAttribute(AX_ATTR_WORD_STARTS,
+ inline_box2_.AddIntListAttribute(ax::mojom::IntListAttribute::kWordStarts,
std::vector<int32_t>{0, 5});
- inline_box2_.AddIntListAttribute(AX_ATTR_WORD_ENDS,
+ inline_box2_.AddIntListAttribute(ax::mojom::IntListAttribute::kWordEnds,
std::vector<int32_t>{4, 6});
AXTreeUpdate initial_state;
@@ -243,25 +250,25 @@ TEST_F(AXPositionTest, Clone) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
copy_position = text_position->Clone();
ASSERT_NE(nullptr, copy_position);
EXPECT_TRUE(copy_position->IsTextPosition());
EXPECT_EQ(text_field_.id, copy_position->anchor_id());
EXPECT_EQ(1, copy_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_UPSTREAM, copy_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kUpstream, copy_position->affinity());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
copy_position = text_position->Clone();
ASSERT_NE(nullptr, copy_position);
EXPECT_TRUE(copy_position->IsTextPosition());
EXPECT_EQ(text_field_.id, copy_position->anchor_id());
EXPECT_EQ(1, copy_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, copy_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, copy_position->affinity());
EXPECT_EQ(AXNodePosition::INVALID_INDEX, copy_position->child_index());
}
@@ -303,19 +310,19 @@ TEST_F(AXPositionTest, AtStartOfAnchorWithTreePosition) {
TEST_F(AXPositionTest, AtStartOfAnchorWithTextPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
EXPECT_TRUE(text_position->AtStartOfAnchor());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtStartOfAnchor());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtStartOfAnchor());
}
@@ -346,19 +353,19 @@ TEST_F(AXPositionTest, AtEndOfAnchorWithTreePosition) {
TEST_F(AXPositionTest, AtEndOfAnchorWithTextPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_TRUE(text_position->AtEndOfAnchor());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtEndOfAnchor());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtEndOfAnchor());
}
@@ -368,19 +375,19 @@ TEST_F(AXPositionTest, AtStartOfLineWithTextPosition) {
// line break.
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
EXPECT_TRUE(text_position->AtStartOfLine());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtStartOfLine());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, line_break_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtStartOfLine());
@@ -388,7 +395,7 @@ TEST_F(AXPositionTest, AtStartOfLineWithTextPosition) {
// as a text position at the start of the next line.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, line_break_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtStartOfLine());
@@ -396,13 +403,13 @@ TEST_F(AXPositionTest, AtStartOfLineWithTextPosition) {
// line break.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
EXPECT_TRUE(text_position->AtStartOfLine());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtStartOfLine());
}
@@ -410,13 +417,13 @@ TEST_F(AXPositionTest, AtStartOfLineWithTextPosition) {
TEST_F(AXPositionTest, AtEndOfLineWithTextPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtEndOfLine());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_TRUE(text_position->AtEndOfLine());
@@ -424,7 +431,7 @@ TEST_F(AXPositionTest, AtEndOfLineWithTextPosition) {
// same as a text position at the end of the previous line.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, line_break_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_TRUE(text_position->AtEndOfLine());
@@ -432,19 +439,19 @@ TEST_F(AXPositionTest, AtEndOfLineWithTextPosition) {
// marked as the end of the line.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, line_break_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtEndOfLine());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_FALSE(text_position->AtEndOfLine());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
EXPECT_TRUE(text_position->AtEndOfLine());
}
@@ -471,11 +478,11 @@ TEST_F(AXPositionTest, LowestCommonAncestor) {
ASSERT_NE(nullptr, static_text2_position);
TestPositionType inline_box1_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, inline_box1_position);
TestPositionType inline_box2_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, inline_box2_position);
TestPositionType test_position =
@@ -556,7 +563,7 @@ TEST_F(AXPositionTest, AsTreePositionWithTextPosition) {
// Create a text position pointing to the last character in the text field.
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 12 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position = text_position->AsTreePosition();
ASSERT_NE(nullptr, test_position);
@@ -572,7 +579,7 @@ TEST_F(AXPositionTest, AsTreePositionWithTextPosition) {
// Test for a "before text" position.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->AsTreePosition();
ASSERT_NE(nullptr, test_position);
@@ -585,7 +592,7 @@ TEST_F(AXPositionTest, AsTreePositionWithTextPosition) {
// Test for an "after text" position.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->AsTreePosition();
ASSERT_NE(nullptr, test_position);
@@ -649,7 +656,7 @@ TEST_F(AXPositionTest, AsTextPositionWithTreePosition) {
TEST_F(AXPositionTest, AsTextPositionWithTextPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position = text_position->AsTextPosition();
ASSERT_NE(nullptr, test_position);
@@ -657,7 +664,7 @@ TEST_F(AXPositionTest, AsTextPositionWithTextPosition) {
EXPECT_EQ(tree_.data().tree_id, test_position->tree_id());
EXPECT_EQ(text_field_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
EXPECT_EQ(AXNodePosition::INVALID_INDEX, test_position->child_index());
}
@@ -681,7 +688,7 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTreePosition) {
EXPECT_EQ(tree_.data().tree_id, test_position->tree_id());
EXPECT_EQ(inline_box1_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
// Create a tree position pointing to the line break node inside the text
// field.
@@ -694,7 +701,7 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTreePosition) {
EXPECT_EQ(tree_.data().tree_id, test_position->tree_id());
EXPECT_EQ(line_break_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
// Create a text position pointing to the second static text node inside the
// text field.
@@ -707,7 +714,7 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTreePosition) {
EXPECT_EQ(tree_.data().tree_id, test_position->tree_id());
EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
}
TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
@@ -715,7 +722,7 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
// position).
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, root_.id, 28 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position = text_position->AsLeafTextPosition();
ASSERT_NE(nullptr, test_position);
@@ -723,11 +730,11 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
EXPECT_EQ(tree_.data().tree_id, test_position->tree_id());
EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
EXPECT_EQ(6, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->AsLeafTextPosition();
ASSERT_NE(nullptr, test_position);
@@ -735,11 +742,11 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
EXPECT_EQ(tree_.data().tree_id, test_position->tree_id());
EXPECT_EQ(inline_box1_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->AsLeafTextPosition();
ASSERT_NE(nullptr, test_position);
@@ -749,7 +756,7 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
EXPECT_EQ(1, test_position->text_offset());
// Even though upstream affinity doesn't make sense on a leaf node, there is
// no need to reset it to downstream.
- EXPECT_EQ(AX_TEXT_AFFINITY_UPSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kUpstream, test_position->affinity());
// Create a text position on the root, pointing to the line break character
// inside the text field but with an upstream affinity which will cause the
@@ -757,7 +764,7 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
// box.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, root_.id, 21 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->AsLeafTextPosition();
ASSERT_NE(nullptr, test_position);
@@ -767,14 +774,14 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
EXPECT_EQ(6, test_position->text_offset());
// Even though upstream affinity doesn't make sense on a leaf node, there is
// no need to reset it to downstream.
- EXPECT_EQ(AX_TEXT_AFFINITY_UPSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kUpstream, test_position->affinity());
// Create a text position pointing to the line break character inside the text
// field but with an upstream affinity which will cause the leaf text position
// to be placed after the text of the first inline text box.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->AsLeafTextPosition();
ASSERT_NE(nullptr, test_position);
@@ -784,13 +791,13 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
EXPECT_EQ(6, test_position->text_offset());
// Even though upstream affinity doesn't make sense on a leaf node, there is
// no need to reset it to downstream.
- EXPECT_EQ(AX_TEXT_AFFINITY_UPSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kUpstream, test_position->affinity());
// Create a text position on the root, pointing to the line break character
// inside the text field.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, root_.id, 21 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->AsLeafTextPosition();
ASSERT_NE(nullptr, test_position);
@@ -798,13 +805,13 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
EXPECT_EQ(tree_.data().tree_id, test_position->tree_id());
EXPECT_EQ(line_break_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
// Create a text position pointing to the line break character inside the text
// field.
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->AsLeafTextPosition();
ASSERT_NE(nullptr, test_position);
@@ -812,13 +819,13 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
EXPECT_EQ(tree_.data().tree_id, test_position->tree_id());
EXPECT_EQ(line_break_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
// Create a text position pointing to the offset after the last character in
// the text field, (an "after text" position).
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 13 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->AsLeafTextPosition();
ASSERT_NE(nullptr, test_position);
@@ -826,7 +833,7 @@ TEST_F(AXPositionTest, AsLeafTextPositionWithTextPosition) {
EXPECT_EQ(tree_.data().tree_id, test_position->tree_id());
EXPECT_EQ(inline_box2_.id, test_position->anchor_id());
EXPECT_EQ(6, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
}
TEST_F(AXPositionTest, CreatePositionAtStartOfAnchorWithNullPosition) {
@@ -872,7 +879,7 @@ TEST_F(AXPositionTest, CreatePositionAtStartOfAnchorWithTreePosition) {
TEST_F(AXPositionTest, CreatePositionAtStartOfAnchorWithTextPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position =
text_position->CreatePositionAtStartOfAnchor();
@@ -880,11 +887,11 @@ TEST_F(AXPositionTest, CreatePositionAtStartOfAnchorWithTextPosition) {
EXPECT_TRUE(test_position->IsTextPosition());
EXPECT_EQ(inline_box1_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->CreatePositionAtStartOfAnchor();
EXPECT_NE(nullptr, test_position);
@@ -892,7 +899,7 @@ TEST_F(AXPositionTest, CreatePositionAtStartOfAnchorWithTextPosition) {
EXPECT_EQ(inline_box1_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
// Affinity should have been reset to the default value.
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
}
TEST_F(AXPositionTest, CreatePositionAtEndOfAnchorWithNullPosition) {
@@ -926,18 +933,18 @@ TEST_F(AXPositionTest, CreatePositionAtEndOfAnchorWithTreePosition) {
TEST_F(AXPositionTest, CreatePositionAtEndOfAnchorWithTextPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position = text_position->CreatePositionAtEndOfAnchor();
EXPECT_NE(nullptr, test_position);
EXPECT_TRUE(test_position->IsTextPosition());
EXPECT_EQ(inline_box1_.id, test_position->anchor_id());
EXPECT_EQ(6, test_position->text_offset());
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->CreatePositionAtEndOfAnchor();
EXPECT_NE(nullptr, test_position);
@@ -945,7 +952,7 @@ TEST_F(AXPositionTest, CreatePositionAtEndOfAnchorWithTextPosition) {
EXPECT_EQ(inline_box1_.id, test_position->anchor_id());
EXPECT_EQ(6, test_position->text_offset());
// Affinity should have been reset to the default value.
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
}
TEST_F(AXPositionTest, CreateChildPositionAtWithNullPosition) {
@@ -979,7 +986,7 @@ TEST_F(AXPositionTest, CreateChildPositionAtWithTreePosition) {
TEST_F(AXPositionTest, CreateChildPositionAtWithTextPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, static_text1_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position = text_position->CreateChildPositionAt(0);
EXPECT_NE(nullptr, test_position);
@@ -989,7 +996,7 @@ TEST_F(AXPositionTest, CreateChildPositionAtWithTextPosition) {
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, static_text2_.id, 4 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->CreateChildPositionAt(1);
EXPECT_NE(nullptr, test_position);
@@ -1026,7 +1033,7 @@ TEST_F(AXPositionTest, CreateParentPositionWithTreePosition) {
TEST_F(AXPositionTest, CreateParentPositionWithTextPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position = text_position->CreateParentPosition();
EXPECT_NE(nullptr, test_position);
@@ -1072,7 +1079,7 @@ TEST_F(AXPositionTest, CreateNextTextAnchorPosition) {
// box.
check_box_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, root_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, check_box_position);
test_position = check_box_position->CreateNextTextAnchorPosition();
EXPECT_NE(nullptr, test_position);
@@ -1083,7 +1090,7 @@ TEST_F(AXPositionTest, CreateNextTextAnchorPosition) {
TestPositionType button_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, button_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, button_position);
test_position = button_position->CreateNextTextAnchorPosition();
EXPECT_NE(nullptr, test_position);
@@ -1131,7 +1138,7 @@ TEST_F(AXPositionTest, CreateNextTextAnchorPosition) {
TEST_F(AXPositionTest, CreatePreviousTextAnchorPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position =
text_position->CreatePreviousTextAnchorPosition();
@@ -1191,7 +1198,7 @@ TEST_F(AXPositionTest, CreatePreviousTextAnchorPosition) {
// box.
TestPositionType check_box_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, check_box_.id, 6 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, check_box_position);
test_position = check_box_position->CreatePreviousTextAnchorPosition();
EXPECT_NE(nullptr, test_position);
@@ -1217,7 +1224,7 @@ TEST_F(AXPositionTest, CreateNextAndPreviousCharacterPositionWithNullPosition) {
TEST_F(AXPositionTest, CreateNextCharacterPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 4 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position = text_position->CreateNextCharacterPosition(
AXBoundaryBehavior::CrossBoundary);
@@ -1228,7 +1235,7 @@ TEST_F(AXPositionTest, CreateNextCharacterPosition) {
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->CreateNextCharacterPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
@@ -1265,7 +1272,7 @@ TEST_F(AXPositionTest, CreateNextCharacterPosition) {
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, check_box_.id, 9 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->CreateNextCharacterPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
@@ -1282,7 +1289,7 @@ TEST_F(AXPositionTest, CreateNextCharacterPosition) {
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->CreateNextCharacterPosition(
AXBoundaryBehavior::CrossBoundary);
@@ -1291,13 +1298,13 @@ TEST_F(AXPositionTest, CreateNextCharacterPosition) {
EXPECT_EQ(text_field_.id, test_position->anchor_id());
EXPECT_EQ(1, test_position->text_offset());
// Affinity should have been reset to downstream.
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
}
TEST_F(AXPositionTest, CreatePreviousCharacterPosition) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
TestPositionType test_position =
text_position->CreatePreviousCharacterPosition(
@@ -1309,7 +1316,7 @@ TEST_F(AXPositionTest, CreatePreviousCharacterPosition) {
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box2_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->CreatePreviousCharacterPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
@@ -1346,7 +1353,7 @@ TEST_F(AXPositionTest, CreatePreviousCharacterPosition) {
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->CreatePreviousCharacterPosition(
AXBoundaryBehavior::StopAtAnchorBoundary);
@@ -1363,7 +1370,7 @@ TEST_F(AXPositionTest, CreatePreviousCharacterPosition) {
text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position);
test_position = text_position->CreatePreviousCharacterPosition(
AXBoundaryBehavior::CrossBoundary);
@@ -1372,7 +1379,7 @@ TEST_F(AXPositionTest, CreatePreviousCharacterPosition) {
EXPECT_EQ(text_field_.id, test_position->anchor_id());
EXPECT_EQ(0, test_position->text_offset());
// Affinity should have been reset to downstream.
- EXPECT_EQ(AX_TEXT_AFFINITY_DOWNSTREAM, test_position->affinity());
+ EXPECT_EQ(ax::mojom::TextAffinity::kDownstream, test_position->affinity());
}
TEST_F(AXPositionTest, CreateNextAndPreviousWordStartPositionWithNullPosition) {
@@ -1459,46 +1466,46 @@ TEST_F(AXPositionTest, OperatorEquals) {
// positions.
TestPositionType text_position1 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 15 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position1);
TestPositionType text_position2 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, text_field_.id, -1 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position2);
EXPECT_EQ(*text_position1, *text_position2);
text_position1 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position1);
text_position2 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position2);
EXPECT_EQ(*text_position1, *text_position2);
// Affinities should match.
text_position2 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position2);
EXPECT_NE(*text_position1, *text_position2);
// Text offsets should match.
text_position1 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 5 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position1);
EXPECT_NE(*text_position1, *text_position2);
// Two "after text" positions on the same node should be equivalent.
text_position1 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, line_break_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position1);
text_position2 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, line_break_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position2);
EXPECT_EQ(*text_position1, *text_position2);
}
@@ -1543,11 +1550,11 @@ TEST_F(AXPositionTest, OperatorsLessThanAndGreaterThan) {
TestPositionType text_position1 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 2 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position1);
TestPositionType text_position2 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
ASSERT_NE(nullptr, text_position2);
EXPECT_GT(*text_position1, *text_position2);
EXPECT_LT(*text_position2, *text_position1);
@@ -1555,7 +1562,7 @@ TEST_F(AXPositionTest, OperatorsLessThanAndGreaterThan) {
// Affinities should not matter.
text_position2 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, inline_box1_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position2);
EXPECT_GT(*text_position1, *text_position2);
EXPECT_LT(*text_position2, *text_position1);
@@ -1563,12 +1570,12 @@ TEST_F(AXPositionTest, OperatorsLessThanAndGreaterThan) {
// An "after text" position.
text_position1 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, line_break_.id, 1 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position1);
// A "before text" position.
text_position2 = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, line_break_.id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
ASSERT_NE(nullptr, text_position2);
EXPECT_GT(*text_position1, *text_position2);
EXPECT_LT(*text_position2, *text_position1);
@@ -1581,7 +1588,7 @@ TEST_F(AXPositionTest, OperatorsLessThanAndGreaterThan) {
TEST_P(AXPositionTestWithParam, TraverseTreeStartingWithAffinityDownstream) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, GetParam().start_node_id_, GetParam().start_offset_,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
for (const std::string& expectation : GetParam().expectations) {
text_position = GetParam().TestMethod.Run(text_position);
EXPECT_NE(nullptr, text_position);
@@ -1592,7 +1599,7 @@ TEST_P(AXPositionTestWithParam, TraverseTreeStartingWithAffinityDownstream) {
TEST_P(AXPositionTestWithParam, TraverseTreeStartingWithAffinityUpstream) {
TestPositionType text_position = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, GetParam().start_node_id_, GetParam().start_offset_,
- AX_TEXT_AFFINITY_UPSTREAM);
+ ax::mojom::TextAffinity::kUpstream);
for (const std::string& expectation : GetParam().expectations) {
text_position = GetParam().TestMethod.Run(text_position);
EXPECT_NE(nullptr, text_position);
@@ -3015,7 +3022,7 @@ TEST_F(AXPositionTest, AXRangeGetTextWithWholeObjects) {
tree_.data().tree_id, root_.id, 0 /* child_index */);
TestPositionType end = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, root_.id, 28 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
AXRange<AXPosition<AXNodePosition, AXNode>> forward_range(start->Clone(),
end->Clone());
EXPECT_EQ(all_text, forward_range.GetText());
@@ -3030,10 +3037,10 @@ TEST_F(AXPositionTest, AXRangeGetTextWithTextOffsets) {
// ending two characters before the end of the root.
TestPositionType start = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, button_.id, 3 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
TestPositionType end = AXNodePosition::CreateTextPosition(
tree_.data().tree_id, static_text2_.id, 4 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
AXRange<AXPosition<AXNodePosition, AXNode>> forward_range(start->Clone(),
end->Clone());
EXPECT_EQ(most_text, forward_range.GetText());
diff --git a/chromium/ui/accessibility/ax_position.h b/chromium/ui/accessibility/ax_position.h
index 8c263dff3b3..e3ed7ee6a46 100644
--- a/chromium/ui/accessibility/ax_position.h
+++ b/chromium/ui/accessibility/ax_position.h
@@ -17,7 +17,8 @@
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enum_util.h"
+#include "ui/accessibility/ax_enums.mojom.h"
namespace ui {
@@ -94,7 +95,7 @@ class AXPosition {
AXPositionInstance new_position(new AXPositionType());
new_position->Initialize(AXPositionKind::NULL_POSITION, INVALID_TREE_ID,
INVALID_ANCHOR_ID, INVALID_INDEX, INVALID_OFFSET,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
return new_position;
}
@@ -104,14 +105,15 @@ class AXPosition {
AXPositionInstance new_position(new AXPositionType());
new_position->Initialize(AXPositionKind::TREE_POSITION, tree_id, anchor_id,
child_index, INVALID_OFFSET,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
return new_position;
}
- static AXPositionInstance CreateTextPosition(int tree_id,
- int32_t anchor_id,
- int text_offset,
- AXTextAffinity affinity) {
+ static AXPositionInstance CreateTextPosition(
+ int tree_id,
+ int32_t anchor_id,
+ int text_offset,
+ ax::mojom::TextAffinity affinity) {
AXPositionInstance new_position(new AXPositionType());
new_position->Initialize(AXPositionKind::TEXT_POSITION, tree_id, anchor_id,
INVALID_INDEX, text_offset, affinity);
@@ -150,9 +152,9 @@ class AXPosition {
str_text_offset = base::IntToString(text_offset_);
}
str = "TextPosition tree_id=" + base::IntToString(tree_id_) +
- " anchor_id=" + base::IntToString(anchor_id_) + " text_offset=" +
- str_text_offset + " affinity=" +
- ui::ToString(static_cast<AXTextAffinity>(affinity_));
+ " anchor_id=" + base::IntToString(anchor_id_) +
+ " text_offset=" + str_text_offset + " affinity=" +
+ ui::ToString(static_cast<ax::mojom::TextAffinity>(affinity_));
break;
}
}
@@ -188,7 +190,7 @@ class AXPosition {
AXPositionKind kind() const { return kind_; }
int child_index() const { return child_index_; }
int text_offset() const { return text_offset_; }
- AXTextAffinity affinity() const { return affinity_; }
+ ax::mojom::TextAffinity affinity() const { return affinity_; }
bool IsNullPosition() const {
return kind_ == AXPositionKind::NULL_POSITION || !GetAnchor();
@@ -376,7 +378,7 @@ class AXPosition {
int child_length = child->MaxTextOffsetInParent();
if (copy->text_offset_ >= current_offset &&
(copy->text_offset_ < (current_offset + child_length) ||
- (copy->affinity_ == AX_TEXT_AFFINITY_UPSTREAM &&
+ (copy->affinity_ == ax::mojom::TextAffinity::kUpstream &&
copy->text_offset_ == (current_offset + child_length)))) {
copy->child_index_ = i;
break;
@@ -474,7 +476,7 @@ class AXPosition {
return CreateTreePosition(tree_id_, anchor_id_, 0 /* child_index */);
case AXPositionKind::TEXT_POSITION:
return CreateTextPosition(tree_id_, anchor_id_, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
}
return CreateNullPosition();
}
@@ -487,7 +489,7 @@ class AXPosition {
return CreateTreePosition(tree_id_, anchor_id_, AnchorChildCount());
case AXPositionKind::TEXT_POSITION:
return CreateTextPosition(tree_id_, anchor_id_, MaxTextOffset(),
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
}
return CreateNullPosition();
}
@@ -519,7 +521,7 @@ class AXPosition {
}
case AXPositionKind::TEXT_POSITION:
return CreateTextPosition(tree_id, child_id, 0 /* text_offset */,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
}
return CreateNullPosition();
@@ -547,12 +549,12 @@ class AXPosition {
// before or after the child and we don't maintain the affinity when the
// position is after the child.
int parent_offset = AnchorTextOffsetInParent();
- AXTextAffinity parent_affinity = affinity_;
+ ax::mojom::TextAffinity parent_affinity = affinity_;
if (MaxTextOffset() == MaxTextOffsetInParent()) {
parent_offset += text_offset_;
} else if (text_offset_ > 0) {
parent_offset += MaxTextOffsetInParent();
- parent_affinity = AX_TEXT_AFFINITY_DOWNSTREAM;
+ parent_affinity = ax::mojom::TextAffinity::kDownstream;
}
return CreateTextPosition(tree_id, parent_id, parent_offset,
parent_affinity);
@@ -606,7 +608,7 @@ class AXPosition {
text_position->text_offset_ += 1;
// Even if our affinity was upstream, moving to the next character should
// inevitably reset it to downstream.
- text_position->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
} else {
// Moving to the end of the current anchor first is essential. Otherwise
// |CreateNextAnchorPosition| might return our deepest left-most child
@@ -639,7 +641,7 @@ class AXPosition {
text_position->text_offset_ -= 1;
// Even if the new position is at the beginning of the line, the affinity
// is defaulted to downstream for simplicity.
- text_position->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
} else {
text_position = text_position->CreatePreviousTextAnchorPosition();
text_position = text_position->CreatePositionAtEndOfAnchor();
@@ -661,7 +663,7 @@ class AXPosition {
if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary &&
text_position->AtStartOfWord()) {
AXPositionInstance clone = Clone();
- clone->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
return clone;
}
@@ -689,7 +691,7 @@ class AXPosition {
text_position->text_offset_ = static_cast<int>(updated_word_starts[0]);
} else {
text_position->text_offset_ = static_cast<int>(*iterator);
- text_position->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
}
// If the word boundary is in the same subtree, return a position rooted
@@ -716,7 +718,7 @@ class AXPosition {
if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary &&
text_position->AtStartOfWord()) {
AXPositionInstance clone = Clone();
- clone->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
return clone;
}
@@ -755,7 +757,7 @@ class AXPosition {
static_cast<int>(*(updated_word_starts.end() - 1));
} else {
text_position->text_offset_ = static_cast<int>(*(--iterator));
- text_position->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
}
// If the word boundary is in the same subtree, return a position rooted
@@ -783,7 +785,7 @@ class AXPosition {
if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary &&
text_position->AtEndOfWord()) {
AXPositionInstance clone = Clone();
- clone->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
return clone;
}
@@ -818,7 +820,7 @@ class AXPosition {
text_position->text_offset_ = static_cast<int>(updated_word_ends[0]);
} else {
text_position->text_offset_ = static_cast<int>(*iterator);
- text_position->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
}
// If the word boundary is in the same subtree, return a position rooted
@@ -846,7 +848,7 @@ class AXPosition {
if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary &&
text_position->AtEndOfWord()) {
AXPositionInstance clone = Clone();
- clone->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
return clone;
}
@@ -884,7 +886,7 @@ class AXPosition {
static_cast<int>(*(updated_word_ends.end() - 1));
} else {
text_position->text_offset_ = static_cast<int>(*(--iterator));
- text_position->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ text_position->affinity_ = ax::mojom::TextAffinity::kDownstream;
}
// If the word boundary is in the same subtree, return a position rooted
@@ -913,7 +915,7 @@ class AXPosition {
if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary &&
text_position->AtStartOfLine()) {
AXPositionInstance clone = Clone();
- clone->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
return clone;
}
@@ -951,7 +953,7 @@ class AXPosition {
if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary &&
text_position->AtStartOfLine()) {
AXPositionInstance clone = Clone();
- clone->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
return clone;
}
@@ -997,7 +999,7 @@ class AXPosition {
if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary &&
text_position->AtEndOfLine()) {
AXPositionInstance clone = Clone();
- clone->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
return clone;
}
@@ -1048,7 +1050,7 @@ class AXPosition {
if (boundary_behavior == AXBoundaryBehavior::StopIfAlreadyAtBoundary &&
text_position->AtEndOfLine()) {
AXPositionInstance clone = Clone();
- clone->affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ clone->affinity_ = ax::mojom::TextAffinity::kDownstream;
return clone;
}
@@ -1100,7 +1102,7 @@ class AXPosition {
int32_t anchor_id,
int child_index,
int text_offset,
- AXTextAffinity affinity) {
+ ax::mojom::TextAffinity affinity) {
kind_ = kind;
tree_id_ = tree_id;
anchor_id_ = anchor_id;
@@ -1120,7 +1122,7 @@ class AXPosition {
anchor_id_ = INVALID_ANCHOR_ID;
child_index_ = INVALID_INDEX;
text_offset_ = INVALID_OFFSET;
- affinity_ = AX_TEXT_AFFINITY_DOWNSTREAM;
+ affinity_ = ax::mojom::TextAffinity::kDownstream;
}
}
@@ -1241,7 +1243,7 @@ class AXPosition {
// TODO(nektar): Get rid of affinity and make Blink handle affinity
// internally since inline text objects don't span lines.
- AXTextAffinity affinity_;
+ ax::mojom::TextAffinity affinity_;
};
template <class AXPositionType, class AXNodeType>
diff --git a/chromium/ui/accessibility/ax_role_properties.cc b/chromium/ui/accessibility/ax_role_properties.cc
index 7540c674cb6..02235b33af3 100644
--- a/chromium/ui/accessibility/ax_role_properties.cc
+++ b/chromium/ui/accessibility/ax_role_properties.cc
@@ -3,141 +3,167 @@
// found in the LICENSE file.
#include "ui/accessibility/ax_role_properties.h"
+#include "build/build_config.h"
namespace ui {
-bool IsRoleClickable(AXRole role) {
+namespace {
+#if defined(OS_WIN)
+static bool kExposeLayoutTableAsDataTable = true;
+#else
+static bool kExposeLayoutTableAsDataTable = false;
+#endif
+} // namespace
+
+bool IsRoleClickable(ax::mojom::Role role) {
+ switch (role) {
+ case ax::mojom::Role::kButton:
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kColorWell:
+ case ax::mojom::Role::kDisclosureTriangle:
+ case ax::mojom::Role::kLink:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kMenuButton:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kMenuListPopup:
+ case ax::mojom::Role::kPopUpButton:
+ case ax::mojom::Role::kRadioButton:
+ case ax::mojom::Role::kSwitch:
+ case ax::mojom::Role::kTab:
+ case ax::mojom::Role::kToggleButton:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsDocument(ax::mojom::Role role) {
switch (role) {
- case AX_ROLE_BUTTON:
- case AX_ROLE_CHECK_BOX:
- case AX_ROLE_COLOR_WELL:
- case AX_ROLE_DISCLOSURE_TRIANGLE:
- case AX_ROLE_LINK:
- case AX_ROLE_LIST_BOX_OPTION:
- case AX_ROLE_MENU_BUTTON:
- case AX_ROLE_MENU_ITEM:
- case AX_ROLE_MENU_ITEM_CHECK_BOX:
- case AX_ROLE_MENU_ITEM_RADIO:
- case AX_ROLE_MENU_LIST_OPTION:
- case AX_ROLE_MENU_LIST_POPUP:
- case AX_ROLE_POP_UP_BUTTON:
- case AX_ROLE_RADIO_BUTTON:
- case AX_ROLE_SWITCH:
- case AX_ROLE_TAB:
- case AX_ROLE_TOGGLE_BUTTON:
+ case ax::mojom::Role::kRootWebArea:
+ case ax::mojom::Role::kWebArea:
return true;
default:
return false;
}
}
-bool IsDocument(ui::AXRole role) {
+bool IsCellOrTableHeaderRole(ax::mojom::Role role) {
switch (role) {
- case ui::AX_ROLE_ROOT_WEB_AREA:
- case ui::AX_ROLE_WEB_AREA:
+ case ax::mojom::Role::kCell:
+ case ax::mojom::Role::kColumnHeader:
+ case ax::mojom::Role::kRowHeader:
return true;
+ case ax::mojom::Role::kLayoutTableCell:
+ return kExposeLayoutTableAsDataTable;
default:
return false;
}
}
-bool IsCellOrTableHeaderRole(ui::AXRole role) {
+bool IsTableLikeRole(ax::mojom::Role role) {
switch (role) {
- case ui::AX_ROLE_CELL:
- case ui::AX_ROLE_COLUMN_HEADER:
- case ui::AX_ROLE_ROW_HEADER:
+ case ax::mojom::Role::kTable:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kTreeGrid:
return true;
+ case ax::mojom::Role::kLayoutTable:
+ return kExposeLayoutTableAsDataTable;
default:
return false;
}
}
-bool IsTableLikeRole(ui::AXRole role) {
+bool IsContainerWithSelectableChildrenRole(ax::mojom::Role role) {
switch (role) {
- case ui::AX_ROLE_TABLE:
- case ui::AX_ROLE_GRID:
- case ui::AX_ROLE_TREE_GRID:
+ case ax::mojom::Role::kComboBoxGrouping:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kMenu:
+ case ax::mojom::Role::kMenuBar:
+ case ax::mojom::Role::kRadioGroup:
+ case ax::mojom::Role::kTabList:
+ case ax::mojom::Role::kToolbar:
+ case ax::mojom::Role::kTree:
+ case ax::mojom::Role::kTreeGrid:
return true;
default:
return false;
}
}
-bool IsContainerWithSelectableChildrenRole(ui::AXRole role) {
+bool IsRowContainer(ax::mojom::Role role) {
switch (role) {
- case ui::AX_ROLE_COMBO_BOX_GROUPING:
- case ui::AX_ROLE_COMBO_BOX_MENU_BUTTON:
- case ui::AX_ROLE_GRID:
- case ui::AX_ROLE_LIST_BOX:
- case ui::AX_ROLE_MENU:
- case ui::AX_ROLE_MENU_BAR:
- case ui::AX_ROLE_RADIO_GROUP:
- case ui::AX_ROLE_TAB_LIST:
- case ui::AX_ROLE_TOOLBAR:
- case ui::AX_ROLE_TREE:
- case ui::AX_ROLE_TREE_GRID:
+ case ax::mojom::Role::kTree:
+ case ax::mojom::Role::kTreeGrid:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kTable:
return true;
default:
return false;
}
}
-bool IsRowContainer(ui::AXRole role) {
+bool IsControl(ax::mojom::Role role) {
switch (role) {
- case ui::AX_ROLE_TREE:
- case ui::AX_ROLE_TREE_GRID:
- case ui::AX_ROLE_GRID:
- case ui::AX_ROLE_TABLE:
+ case ax::mojom::Role::kButton:
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kColorWell:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kDisclosureTriangle:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kMenu:
+ case ax::mojom::Role::kMenuBar:
+ case ax::mojom::Role::kMenuButton:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kMenuListPopup:
+ case ax::mojom::Role::kPopUpButton:
+ case ax::mojom::Role::kRadioButton:
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kSearchBox:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSpinButton:
+ case ax::mojom::Role::kSwitch:
+ case ax::mojom::Role::kTab:
+ case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kTextFieldWithComboBox:
+ case ax::mojom::Role::kToggleButton:
+ case ax::mojom::Role::kTree:
return true;
default:
return false;
}
}
-bool IsControl(ui::AXRole role) {
+bool IsMenuRelated(ax::mojom::Role role) {
switch (role) {
- case ui::AX_ROLE_BUTTON:
- case ui::AX_ROLE_CHECK_BOX:
- case ui::AX_ROLE_COLOR_WELL:
- case ui::AX_ROLE_COMBO_BOX_MENU_BUTTON:
- case ui::AX_ROLE_DISCLOSURE_TRIANGLE:
- case ui::AX_ROLE_LIST_BOX:
- case ui::AX_ROLE_MENU:
- case ui::AX_ROLE_MENU_BAR:
- case ui::AX_ROLE_MENU_BUTTON:
- case ui::AX_ROLE_MENU_ITEM:
- case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
- case ui::AX_ROLE_MENU_ITEM_RADIO:
- case ui::AX_ROLE_MENU_LIST_OPTION:
- case ui::AX_ROLE_MENU_LIST_POPUP:
- case ui::AX_ROLE_POP_UP_BUTTON:
- case ui::AX_ROLE_RADIO_BUTTON:
- case ui::AX_ROLE_SCROLL_BAR:
- case ui::AX_ROLE_SEARCH_BOX:
- case ui::AX_ROLE_SLIDER:
- case ui::AX_ROLE_SPIN_BUTTON:
- case ui::AX_ROLE_SWITCH:
- case ui::AX_ROLE_TAB:
- case ui::AX_ROLE_TEXT_FIELD:
- case ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX:
- case ui::AX_ROLE_TOGGLE_BUTTON:
- case ui::AX_ROLE_TREE:
+ case ax::mojom::Role::kMenu:
+ case ax::mojom::Role::kMenuBar:
+ case ax::mojom::Role::kMenuButton:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kMenuListPopup:
return true;
default:
return false;
}
}
-bool IsMenuRelated(ui::AXRole role) {
+bool IsImage(ax::mojom::Role role) {
switch (role) {
- case ui::AX_ROLE_MENU:
- case ui::AX_ROLE_MENU_BAR:
- case ui::AX_ROLE_MENU_BUTTON:
- case ui::AX_ROLE_MENU_ITEM:
- case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
- case ui::AX_ROLE_MENU_ITEM_RADIO:
- case ui::AX_ROLE_MENU_LIST_OPTION:
- case ui::AX_ROLE_MENU_LIST_POPUP:
+ case ax::mojom::Role::kCanvas:
+ case ax::mojom::Role::kImageMap:
+ case ax::mojom::Role::kImage:
+ case ax::mojom::Role::kSvgRoot:
+ case ax::mojom::Role::kVideo:
return true;
default:
return false;
diff --git a/chromium/ui/accessibility/ax_role_properties.h b/chromium/ui/accessibility/ax_role_properties.h
index 81893bcf87c..9b1793eeda6 100644
--- a/chromium/ui/accessibility/ax_role_properties.h
+++ b/chromium/ui/accessibility/ax_role_properties.h
@@ -5,35 +5,38 @@
#ifndef UI_ACCESSIBILITY_AX_ROLE_PROPERTIES_H_
#define UI_ACCESSIBILITY_AX_ROLE_PROPERTIES_H_
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_export.h"
namespace ui {
// Checks if the given role should belong to a control that can respond to
// clicks.
-AX_EXPORT bool IsRoleClickable(AXRole role);
+AX_EXPORT bool IsRoleClickable(ax::mojom::Role role);
// Returns true if this node is a document
-AX_EXPORT bool IsDocument(ui::AXRole role);
+AX_EXPORT bool IsDocument(ax::mojom::Role role);
// Returns true if this node is a cell or a table header.
-AX_EXPORT bool IsCellOrTableHeaderRole(AXRole role);
+AX_EXPORT bool IsCellOrTableHeaderRole(ax::mojom::Role role);
// Returns true if this node is a table, a grid or a treegrid.
-AX_EXPORT bool IsTableLikeRole(AXRole role);
+AX_EXPORT bool IsTableLikeRole(ax::mojom::Role role);
// Returns true if this node is a container with selectable children.
-AX_EXPORT bool IsContainerWithSelectableChildrenRole(ui::AXRole role);
+AX_EXPORT bool IsContainerWithSelectableChildrenRole(ax::mojom::Role role);
// Returns true if this node is a row container.
-AX_EXPORT bool IsRowContainer(ui::AXRole role);
+AX_EXPORT bool IsRowContainer(ax::mojom::Role role);
// Returns true if this node is a control.
-AX_EXPORT bool IsControl(ui::AXRole role);
+AX_EXPORT bool IsControl(ax::mojom::Role role);
// Returns true if this node is a menu or related role.
-AX_EXPORT bool IsMenuRelated(ui::AXRole role);
+AX_EXPORT bool IsMenuRelated(ax::mojom::Role role);
+
+// Returns true if it's an image, graphic, canvas, etc.
+AX_EXPORT bool IsImage(ax::mojom::Role role);
} // namespace ui
diff --git a/chromium/ui/accessibility/ax_text_utils.cc b/chromium/ui/accessibility/ax_text_utils.cc
index fd0457763f4..d2d9ffef3ad 100644
--- a/chromium/ui/accessibility/ax_text_utils.cc
+++ b/chromium/ui/accessibility/ax_text_utils.cc
@@ -21,7 +21,7 @@ size_t FindAccessibleTextBoundary(const base::string16& text,
TextBoundaryType boundary,
size_t start_offset,
TextBoundaryDirection direction,
- AXTextAffinity affinity) {
+ ax::mojom::TextAffinity affinity) {
size_t text_size = text.size();
DCHECK_LE(start_offset, text_size);
@@ -43,20 +43,20 @@ size_t FindAccessibleTextBoundary(const base::string16& text,
if (direction == FORWARDS_DIRECTION) {
for (size_t j = 0; j < line_breaks.size(); ++j) {
size_t line_break = line_breaks[j] >= 0 ? line_breaks[j] : 0;
- if ((affinity == AX_TEXT_AFFINITY_DOWNSTREAM &&
- line_break > start_offset) ||
- (affinity == AX_TEXT_AFFINITY_UPSTREAM &&
- line_break >= start_offset)) {
- return line_break;
+ if ((affinity == ax::mojom::TextAffinity::kDownstream &&
+ line_break > start_offset) ||
+ (affinity == ax::mojom::TextAffinity::kUpstream &&
+ line_break >= start_offset)) {
+ return line_break;
}
}
return text_size;
} else {
for (size_t j = line_breaks.size(); j != 0; --j) {
size_t line_break = line_breaks[j - 1] >= 0 ? line_breaks[j - 1] : 0;
- if ((affinity == AX_TEXT_AFFINITY_DOWNSTREAM &&
+ if ((affinity == ax::mojom::TextAffinity::kDownstream &&
line_break <= start_offset) ||
- (affinity == AX_TEXT_AFFINITY_UPSTREAM &&
+ (affinity == ax::mojom::TextAffinity::kUpstream &&
line_break < start_offset)) {
return line_break;
}
@@ -116,27 +116,27 @@ size_t FindAccessibleTextBoundary(const base::string16& text,
}
base::string16 ActionVerbToLocalizedString(
- const AXDefaultActionVerb action_verb) {
+ const ax::mojom::DefaultActionVerb action_verb) {
switch (action_verb) {
- case AX_DEFAULT_ACTION_VERB_NONE:
+ case ax::mojom::DefaultActionVerb::kNone:
return base::string16();
- case AX_DEFAULT_ACTION_VERB_ACTIVATE:
+ case ax::mojom::DefaultActionVerb::kActivate:
return l10n_util::GetStringUTF16(IDS_AX_ACTIVATE_ACTION_VERB);
- case AX_DEFAULT_ACTION_VERB_CHECK:
+ case ax::mojom::DefaultActionVerb::kCheck:
return l10n_util::GetStringUTF16(IDS_AX_CHECK_ACTION_VERB);
- case AX_DEFAULT_ACTION_VERB_CLICK:
+ case ax::mojom::DefaultActionVerb::kClick:
return l10n_util::GetStringUTF16(IDS_AX_CLICK_ACTION_VERB);
- case AX_DEFAULT_ACTION_VERB_CLICK_ANCESTOR:
+ case ax::mojom::DefaultActionVerb::kClickAncestor:
return l10n_util::GetStringUTF16(IDS_AX_CLICK_ANCESTOR_ACTION_VERB);
- case AX_DEFAULT_ACTION_VERB_JUMP:
+ case ax::mojom::DefaultActionVerb::kJump:
return l10n_util::GetStringUTF16(IDS_AX_JUMP_ACTION_VERB);
- case AX_DEFAULT_ACTION_VERB_OPEN:
+ case ax::mojom::DefaultActionVerb::kOpen:
return l10n_util::GetStringUTF16(IDS_AX_OPEN_ACTION_VERB);
- case AX_DEFAULT_ACTION_VERB_PRESS:
+ case ax::mojom::DefaultActionVerb::kPress:
return l10n_util::GetStringUTF16(IDS_AX_PRESS_ACTION_VERB);
- case AX_DEFAULT_ACTION_VERB_SELECT:
+ case ax::mojom::DefaultActionVerb::kSelect:
return l10n_util::GetStringUTF16(IDS_AX_SELECT_ACTION_VERB);
- case AX_DEFAULT_ACTION_VERB_UNCHECK:
+ case ax::mojom::DefaultActionVerb::kUncheck:
return l10n_util::GetStringUTF16(IDS_AX_UNCHECK_ACTION_VERB);
}
NOTREACHED();
@@ -145,27 +145,27 @@ base::string16 ActionVerbToLocalizedString(
// Some APIs on Linux and Windows need to return non-localized action names.
base::string16 ActionVerbToUnlocalizedString(
- const AXDefaultActionVerb action_verb) {
+ const ax::mojom::DefaultActionVerb action_verb) {
switch (action_verb) {
- case ui::AX_DEFAULT_ACTION_VERB_NONE:
+ case ax::mojom::DefaultActionVerb::kNone:
return base::UTF8ToUTF16("none");
- case ui::AX_DEFAULT_ACTION_VERB_ACTIVATE:
+ case ax::mojom::DefaultActionVerb::kActivate:
return base::UTF8ToUTF16("activate");
- case ui::AX_DEFAULT_ACTION_VERB_CHECK:
+ case ax::mojom::DefaultActionVerb::kCheck:
return base::UTF8ToUTF16("check");
- case ui::AX_DEFAULT_ACTION_VERB_CLICK:
+ case ax::mojom::DefaultActionVerb::kClick:
return base::UTF8ToUTF16("click");
- case ui::AX_DEFAULT_ACTION_VERB_CLICK_ANCESTOR:
+ case ax::mojom::DefaultActionVerb::kClickAncestor:
return base::UTF8ToUTF16("click-ancestor");
- case ui::AX_DEFAULT_ACTION_VERB_JUMP:
+ case ax::mojom::DefaultActionVerb::kJump:
return base::UTF8ToUTF16("jump");
- case ui::AX_DEFAULT_ACTION_VERB_OPEN:
+ case ax::mojom::DefaultActionVerb::kOpen:
return base::UTF8ToUTF16("open");
- case ui::AX_DEFAULT_ACTION_VERB_PRESS:
+ case ax::mojom::DefaultActionVerb::kPress:
return base::UTF8ToUTF16("press");
- case ui::AX_DEFAULT_ACTION_VERB_SELECT:
+ case ax::mojom::DefaultActionVerb::kSelect:
return base::UTF8ToUTF16("select");
- case ui::AX_DEFAULT_ACTION_VERB_UNCHECK:
+ case ax::mojom::DefaultActionVerb::kUncheck:
return base::UTF8ToUTF16("uncheck");
}
NOTREACHED();
diff --git a/chromium/ui/accessibility/ax_text_utils.h b/chromium/ui/accessibility/ax_text_utils.h
index 5a4c0717870..3b9a78fdcf8 100644
--- a/chromium/ui/accessibility/ax_text_utils.h
+++ b/chromium/ui/accessibility/ax_text_utils.h
@@ -10,7 +10,7 @@
#include <vector>
#include "base/strings/string16.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_export.h"
namespace ui {
@@ -44,22 +44,21 @@ enum TextBoundaryDirection {
// (depending on |direction|) from the given |start_offset| until the
// given boundary is found, and return the offset of that boundary,
// using the vector of line break character offsets in |line_breaks|.
-size_t AX_EXPORT
- FindAccessibleTextBoundary(const base::string16& text,
- const std::vector<int>& line_breaks,
- TextBoundaryType boundary,
- size_t start_offset,
- TextBoundaryDirection direction,
- AXTextAffinity affinity);
+size_t AX_EXPORT FindAccessibleTextBoundary(const base::string16& text,
+ const std::vector<int>& line_breaks,
+ TextBoundaryType boundary,
+ size_t start_offset,
+ TextBoundaryDirection direction,
+ ax::mojom::TextAffinity affinity);
// Returns a string ID that corresponds to the name of the given action.
base::string16 AX_EXPORT
-ActionVerbToLocalizedString(const AXDefaultActionVerb action_verb);
+ActionVerbToLocalizedString(const ax::mojom::DefaultActionVerb action_verb);
// Returns the non-localized string representation of a supported action.
// Some APIs on Linux and Windows need to return non-localized action names.
base::string16 AX_EXPORT
-ActionVerbToUnlocalizedString(const AXDefaultActionVerb action_verb);
+ActionVerbToUnlocalizedString(const ax::mojom::DefaultActionVerb action_verb);
} // namespace ui
diff --git a/chromium/ui/accessibility/ax_text_utils_unittest.cc b/chromium/ui/accessibility/ax_text_utils_unittest.cc
index 0f1ad1de714..7915cdd24cc 100644
--- a/chromium/ui/accessibility/ax_text_utils_unittest.cc
+++ b/chromium/ui/accessibility/ax_text_utils_unittest.cc
@@ -6,7 +6,7 @@
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_text_utils.h"
namespace ui {
@@ -21,47 +21,47 @@ TEST(AXTextUtils, FindAccessibleTextBoundaryWord) {
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
0, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(6UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
5, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(0UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
6, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(12UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
11, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(6UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
12, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(12UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
15, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(17UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
15, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(12UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
16, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(17UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
17, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(20UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
20, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(text_length, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, WORD_BOUNDARY,
text_length, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(20UL, result);
}
@@ -76,56 +76,56 @@ TEST(AXTextUtils, FindAccessibleTextBoundaryLine) {
// Basic cases.
result = FindAccessibleTextBoundary(text, line_start_offsets, LINE_BOUNDARY,
5, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(8UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, LINE_BOUNDARY,
9, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(8UL, result);
result = FindAccessibleTextBoundary(text, line_start_offsets, LINE_BOUNDARY,
10, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(15UL, result);
// Edge cases.
result = FindAccessibleTextBoundary(text, line_start_offsets, LINE_BOUNDARY,
text_length, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(15UL, result);
// When the start_offset is at the start of the next line and we are searching
// backwards, it should not move.
result = FindAccessibleTextBoundary(text, line_start_offsets, LINE_BOUNDARY,
15, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(15UL, result);
// When the start_offset is at a hard line break and we are searching
// backwards, it should return the start of the previous line.
result = FindAccessibleTextBoundary(text, line_start_offsets, LINE_BOUNDARY,
14, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(8UL, result);
// When the start_offset is at the start of a line and we are searching
// forwards, it should return the start of the next line.
result = FindAccessibleTextBoundary(text, line_start_offsets, LINE_BOUNDARY,
8, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(15UL, result);
// When there is no previous line break and we are searching backwards,
// it should return 0.
result = FindAccessibleTextBoundary(text, line_start_offsets, LINE_BOUNDARY,
4, BACKWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(0UL, result);
// When we are at the start of the last line and we are searching forwards.
// it should return the text length.
result = FindAccessibleTextBoundary(text, line_start_offsets, LINE_BOUNDARY,
15, FORWARDS_DIRECTION,
- AX_TEXT_AFFINITY_DOWNSTREAM);
+ ax::mojom::TextAffinity::kDownstream);
EXPECT_EQ(text_length, result);
}
diff --git a/chromium/ui/accessibility/ax_tree.cc b/chromium/ui/accessibility/ax_tree.cc
index 3758d0b7a1b..b6fe217c0b0 100644
--- a/chromium/ui/accessibility/ax_tree.cc
+++ b/chromium/ui/accessibility/ax_tree.cc
@@ -219,8 +219,10 @@ gfx::RectF AXTree::RelativeToTreeBounds(const AXNode* node,
int scroll_x = 0;
int scroll_y = 0;
- if (container->data().GetIntAttribute(ui::AX_ATTR_SCROLL_X, &scroll_x) &&
- container->data().GetIntAttribute(ui::AX_ATTR_SCROLL_Y, &scroll_y)) {
+ if (container->data().GetIntAttribute(ax::mojom::IntAttribute::kScrollX,
+ &scroll_x) &&
+ container->data().GetIntAttribute(ax::mojom::IntAttribute::kScrollY,
+ &scroll_y)) {
bounds.Offset(-scroll_x, -scroll_y);
}
@@ -231,7 +233,8 @@ gfx::RectF AXTree::RelativeToTreeBounds(const AXNode* node,
// Calculate the clipped bounds to determine offscreen state.
gfx::RectF clipped = bounds;
// If this is the root web area, make sure we clip the node to fit.
- if (container->data().GetBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN)) {
+ if (container->data().GetBoolAttribute(
+ ax::mojom::BoolAttribute::kClipsChildren)) {
if (!intersection.IsEmpty()) {
// We can simply clip it to the container.
clipped = intersection;
@@ -258,7 +261,8 @@ gfx::RectF AXTree::RelativeToTreeBounds(const AXNode* node,
if (clip_bounds)
bounds = clipped;
- if (container->data().GetBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN) &&
+ if (container->data().GetBoolAttribute(
+ ax::mojom::BoolAttribute::kClipsChildren) &&
intersection.IsEmpty() && !clipped.IsEmpty()) {
// If it is offscreen with respect to its parent, and the node itself is
// not empty, label it offscreen.
@@ -283,7 +287,7 @@ gfx::RectF AXTree::GetTreeBounds(const AXNode* node,
return RelativeToTreeBounds(node, gfx::RectF(), offscreen, clip_bounds);
}
-std::set<int32_t> AXTree::GetReverseRelations(AXIntAttribute attr,
+std::set<int32_t> AXTree::GetReverseRelations(ax::mojom::IntAttribute attr,
int32_t dst_id) const {
DCHECK(IsNodeIdIntAttribute(attr));
@@ -298,7 +302,7 @@ std::set<int32_t> AXTree::GetReverseRelations(AXIntAttribute attr,
return std::set<int32_t>();
}
-std::set<int32_t> AXTree::GetReverseRelations(AXIntListAttribute attr,
+std::set<int32_t> AXTree::GetReverseRelations(ax::mojom::IntListAttribute attr,
int32_t dst_id) const {
DCHECK(IsNodeIdIntListAttribute(attr));
@@ -460,6 +464,10 @@ bool AXTree::UpdateNode(const AXNodeData& src,
AXNode* node = GetFromId(src.id);
if (node) {
update_state->pending_nodes.erase(node);
+
+ // TODO(accessibility): CallNodeChangeCallbacks should not pass |node|,
+ // since the tree and the node data are not yet in a consistent
+ // state. Possibly only pass id.
if (update_state->new_nodes.find(node) == update_state->new_nodes.end())
CallNodeChangeCallbacks(node, src);
UpdateReverseRelations(node, src);
@@ -535,14 +543,15 @@ void AXTree::CallNodeChangeCallbacks(AXNode* node, const AXNodeData& new_data) {
delegate_->OnRoleChanged(this, node, old_data.role, new_data.role);
if (old_data.state != new_data.state) {
- for (int i = AX_STATE_NONE + 1; i <= AX_STATE_LAST; ++i) {
- AXState state = static_cast<AXState>(i);
+ for (int32_t i = static_cast<int32_t>(ax::mojom::State::kNone) + 1;
+ i <= static_cast<int32_t>(ax::mojom::State::kLast); ++i) {
+ ax::mojom::State state = static_cast<ax::mojom::State>(i);
if (old_data.HasState(state) != new_data.HasState(state))
delegate_->OnStateChanged(this, node, state, new_data.HasState(state));
}
}
- auto string_callback = [this, node](AXStringAttribute attr,
+ auto string_callback = [this, node](ax::mojom::StringAttribute attr,
const std::string& old_string,
const std::string& new_string) {
delegate_->OnStringAttributeChanged(this, node, attr, old_string,
@@ -552,14 +561,15 @@ void AXTree::CallNodeChangeCallbacks(AXNode* node, const AXNodeData& new_data) {
new_data.string_attributes, std::string(),
string_callback);
- auto bool_callback = [this, node](AXBoolAttribute attr, const bool& old_bool,
+ auto bool_callback = [this, node](ax::mojom::BoolAttribute attr,
+ const bool& old_bool,
const bool& new_bool) {
delegate_->OnBoolAttributeChanged(this, node, attr, new_bool);
};
CallIfAttributeValuesChanged(old_data.bool_attributes,
new_data.bool_attributes, false, bool_callback);
- auto float_callback = [this, node](AXFloatAttribute attr,
+ auto float_callback = [this, node](ax::mojom::FloatAttribute attr,
const float& old_float,
const float& new_float) {
delegate_->OnFloatAttributeChanged(this, node, attr, old_float, new_float);
@@ -567,15 +577,15 @@ void AXTree::CallNodeChangeCallbacks(AXNode* node, const AXNodeData& new_data) {
CallIfAttributeValuesChanged(old_data.float_attributes,
new_data.float_attributes, 0.0f, float_callback);
- auto int_callback = [this, node](AXIntAttribute attr, const int& old_int,
- const int& new_int) {
+ auto int_callback = [this, node](ax::mojom::IntAttribute attr,
+ const int& old_int, const int& new_int) {
delegate_->OnIntAttributeChanged(this, node, attr, old_int, new_int);
};
CallIfAttributeValuesChanged(old_data.int_attributes, new_data.int_attributes,
0, int_callback);
auto intlist_callback = [this, node](
- AXIntListAttribute attr,
+ ax::mojom::IntListAttribute attr,
const std::vector<int32_t>& old_intlist,
const std::vector<int32_t>& new_intlist) {
delegate_->OnIntListAttributeChanged(this, node, attr, old_intlist,
@@ -586,7 +596,7 @@ void AXTree::CallNodeChangeCallbacks(AXNode* node, const AXNodeData& new_data) {
std::vector<int32_t>(), intlist_callback);
auto stringlist_callback =
- [this, node](AXStringListAttribute attr,
+ [this, node](ax::mojom::StringListAttribute attr,
const std::vector<std::string>& old_stringlist,
const std::vector<std::string>& new_stringlist) {
delegate_->OnStringListAttributeChanged(this, node, attr,
@@ -600,8 +610,8 @@ void AXTree::CallNodeChangeCallbacks(AXNode* node, const AXNodeData& new_data) {
void AXTree::UpdateReverseRelations(AXNode* node, const AXNodeData& new_data) {
const AXNodeData& old_data = node->data();
int id = new_data.id;
- auto int_callback = [this, node, id](AXIntAttribute attr, const int& old_int,
- const int& new_int) {
+ auto int_callback = [this, node, id](ax::mojom::IntAttribute attr,
+ const int& old_int, const int& new_int) {
if (!IsNodeIdIntAttribute(attr))
return;
@@ -612,7 +622,7 @@ void AXTree::UpdateReverseRelations(AXNode* node, const AXNodeData& new_data) {
0, int_callback);
auto intlist_callback = [this, node, id](
- AXIntListAttribute attr,
+ ax::mojom::IntListAttribute attr,
const std::vector<int32_t>& old_intlist,
const std::vector<int32_t>& new_intlist) {
if (!IsNodeIdIntListAttribute(attr))
diff --git a/chromium/ui/accessibility/ax_tree.h b/chromium/ui/accessibility/ax_tree.h
index d733df9fd1d..ac3eeeabe5e 100644
--- a/chromium/ui/accessibility/ax_tree.h
+++ b/chromium/ui/accessibility/ax_tree.h
@@ -52,41 +52,41 @@ class AX_EXPORT AXTreeDelegate {
// Individual callbacks for every attribute of AXNodeData that can change.
virtual void OnRoleChanged(AXTree* tree,
AXNode* node,
- AXRole old_role,
- AXRole new_role) {}
+ ax::mojom::Role old_role,
+ ax::mojom::Role new_role) {}
virtual void OnStateChanged(AXTree* tree,
AXNode* node,
- AXState state,
+ ax::mojom::State state,
bool new_value) {}
virtual void OnStringAttributeChanged(AXTree* tree,
AXNode* node,
- AXStringAttribute attr,
+ ax::mojom::StringAttribute attr,
const std::string& old_value,
const std::string& new_value) {}
virtual void OnIntAttributeChanged(AXTree* tree,
AXNode* node,
- AXIntAttribute attr,
+ ax::mojom::IntAttribute attr,
int32_t old_value,
int32_t new_value) {}
virtual void OnFloatAttributeChanged(AXTree* tree,
AXNode* node,
- AXFloatAttribute attr,
+ ax::mojom::FloatAttribute attr,
float old_value,
float new_value) {}
virtual void OnBoolAttributeChanged(AXTree* tree,
AXNode* node,
- AXBoolAttribute attr,
+ ax::mojom::BoolAttribute attr,
bool new_value) {}
virtual void OnIntListAttributeChanged(
AXTree* tree,
AXNode* node,
- AXIntListAttribute attr,
+ ax::mojom::IntListAttribute attr,
const std::vector<int32_t>& old_value,
const std::vector<int32_t>& new_value) {}
virtual void OnStringListAttributeChanged(
AXTree* tree,
AXNode* node,
- AXStringListAttribute attr,
+ ax::mojom::StringListAttribute attr,
const std::vector<std::string>& old_value,
const std::vector<std::string>& new_value) {}
@@ -158,6 +158,13 @@ class AX_EXPORT AXTreeDelegate {
// accessibility APIs on a specific platform.
class AX_EXPORT AXTree {
public:
+ typedef std::map<ax::mojom::IntAttribute,
+ std::map<int32_t, std::set<int32_t>>>
+ IntReverseRelationMap;
+ typedef std::map<ax::mojom::IntListAttribute,
+ std::map<int32_t, std::set<int32_t>>>
+ IntListReverseRelationMap;
+
AXTree();
explicit AXTree(const AXTreeUpdate& initial_state);
virtual ~AXTree();
@@ -204,16 +211,23 @@ class AX_EXPORT AXTree {
// Given a node ID attribute (one where IsNodeIdIntAttribute is true),
// and a destination node ID, return a set of all source node IDs that
// have that relationship attribute between them and the destination.
- std::set<int32_t> GetReverseRelations(AXIntAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntAttribute attr,
int32_t dst_id) const;
// Given a node ID list attribute (one where
// IsNodeIdIntListAttribute is true), and a destination node ID,
// return a set of all source node IDs that have that relationship
// attribute between them and the destination.
- std::set<int32_t> GetReverseRelations(AXIntListAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntListAttribute attr,
int32_t dst_id) const;
+ // Map from a relation attribute to a map from a target id to source ids.
+ const IntReverseRelationMap& int_reverse_relations() {
+ return int_reverse_relations_;
+ }
+ const IntListReverseRelationMap& intlist_reverse_relations() {
+ return intlist_reverse_relations_;
+ }
// Return a multi-line indented string representation, for logging.
std::string ToString() const;
@@ -273,12 +287,10 @@ class AX_EXPORT AXTree {
// Map from an int attribute (if IsNodeIdIntAttribute is true) to
// a reverse mapping from target nodes to source nodes.
- std::map<AXIntAttribute, std::map<int32_t, std::set<int32_t>>>
- int_reverse_relations_;
+ IntReverseRelationMap int_reverse_relations_;
// Map from an int list attribute (if IsNodeIdIntListAttribute is true) to
// a reverse mapping from target nodes to source nodes.
- std::map<AXIntListAttribute, std::map<int32_t, std::set<int32_t>>>
- intlist_reverse_relations_;
+ IntListReverseRelationMap intlist_reverse_relations_;
};
} // namespace ui
diff --git a/chromium/ui/accessibility/ax_tree_combiner.cc b/chromium/ui/accessibility/ax_tree_combiner.cc
index 68a9c8b22ac..06a6ac15726 100644
--- a/chromium/ui/accessibility/ax_tree_combiner.cc
+++ b/chromium/ui/accessibility/ax_tree_combiner.cc
@@ -80,7 +80,8 @@ void AXTreeCombiner::ProcessTree(const AXTreeUpdate* tree) {
int32_t tree_id = tree->tree_data.tree_id;
for (size_t i = 0; i < tree->nodes.size(); ++i) {
AXNodeData node = tree->nodes[i];
- int32_t child_tree_id = node.GetIntAttribute(AX_ATTR_CHILD_TREE_ID);
+ int32_t child_tree_id =
+ node.GetIntAttribute(ax::mojom::IntAttribute::kChildTreeId);
// Map the node's ID.
node.id = MapId(tree_id, node.id);
@@ -94,13 +95,13 @@ void AXTreeCombiner::ProcessTree(const AXTreeUpdate* tree) {
node.offset_container_id = MapId(tree_id, node.offset_container_id);
// Map other int attributes that refer to node IDs, and remove the
- // AX_ATTR_CHILD_TREE_ID attribute.
+ // ax::mojom::IntAttribute::kChildTreeId attribute.
for (size_t j = 0; j < node.int_attributes.size(); ++j) {
auto& attr = node.int_attributes[j];
if (IsNodeIdIntAttribute(attr.first))
attr.second = MapId(tree_id, attr.second);
- if (attr.first == AX_ATTR_CHILD_TREE_ID) {
- attr.first = AX_INT_ATTRIBUTE_NONE;
+ if (attr.first == ax::mojom::IntAttribute::kChildTreeId) {
+ attr.first = ax::mojom::IntAttribute::kNone;
attr.second = 0;
}
}
diff --git a/chromium/ui/accessibility/ax_tree_combiner_unittest.cc b/chromium/ui/accessibility/ax_tree_combiner_unittest.cc
index 70f861c0966..6e0aaf498fc 100644
--- a/chromium/ui/accessibility/ax_tree_combiner_unittest.cc
+++ b/chromium/ui/accessibility/ax_tree_combiner_unittest.cc
@@ -45,10 +45,11 @@ TEST(CombineAXTreesTest, EmbedChildTree) {
parent_tree.nodes[0].child_ids.push_back(2);
parent_tree.nodes[0].child_ids.push_back(3);
parent_tree.nodes[1].id = 2;
- parent_tree.nodes[1].role = AX_ROLE_BUTTON;
+ parent_tree.nodes[1].role = ax::mojom::Role::kButton;
parent_tree.nodes[2].id = 3;
- parent_tree.nodes[2].role = AX_ROLE_IFRAME;
- parent_tree.nodes[2].AddIntAttribute(AX_ATTR_CHILD_TREE_ID, 2);
+ parent_tree.nodes[2].role = ax::mojom::Role::kIframe;
+ parent_tree.nodes[2].AddIntAttribute(ax::mojom::IntAttribute::kChildTreeId,
+ 2);
AXTreeUpdate child_tree;
child_tree.root_id = 1;
@@ -60,9 +61,9 @@ TEST(CombineAXTreesTest, EmbedChildTree) {
child_tree.nodes[0].child_ids.push_back(2);
child_tree.nodes[0].child_ids.push_back(3);
child_tree.nodes[1].id = 2;
- child_tree.nodes[1].role = AX_ROLE_CHECK_BOX;
+ child_tree.nodes[1].role = ax::mojom::Role::kCheckBox;
child_tree.nodes[2].id = 3;
- child_tree.nodes[2].role = AX_ROLE_RADIO_BUTTON;
+ child_tree.nodes[2].role = ax::mojom::Role::kRadioButton;
AXTreeCombiner combiner;
combiner.AddTree(parent_tree, true);
@@ -78,16 +79,16 @@ TEST(CombineAXTreesTest, EmbedChildTree) {
EXPECT_EQ(2, combined.nodes[0].child_ids[0]);
EXPECT_EQ(3, combined.nodes[0].child_ids[1]);
EXPECT_EQ(2, combined.nodes[1].id);
- EXPECT_EQ(AX_ROLE_BUTTON, combined.nodes[1].role);
+ EXPECT_EQ(ax::mojom::Role::kButton, combined.nodes[1].role);
EXPECT_EQ(3, combined.nodes[2].id);
- EXPECT_EQ(AX_ROLE_IFRAME, combined.nodes[2].role);
+ EXPECT_EQ(ax::mojom::Role::kIframe, combined.nodes[2].role);
EXPECT_EQ(1U, combined.nodes[2].child_ids.size());
EXPECT_EQ(4, combined.nodes[2].child_ids[0]);
EXPECT_EQ(4, combined.nodes[3].id);
EXPECT_EQ(5, combined.nodes[4].id);
- EXPECT_EQ(AX_ROLE_CHECK_BOX, combined.nodes[4].role);
+ EXPECT_EQ(ax::mojom::Role::kCheckBox, combined.nodes[4].role);
EXPECT_EQ(6, combined.nodes[5].id);
- EXPECT_EQ(AX_ROLE_RADIO_BUTTON, combined.nodes[5].role);
+ EXPECT_EQ(ax::mojom::Role::kRadioButton, combined.nodes[5].role);
}
TEST(CombineAXTreesTest, MapAllIdAttributes) {
@@ -101,18 +102,26 @@ TEST(CombineAXTreesTest, MapAllIdAttributes) {
tree.nodes.resize(2);
tree.nodes[0].id = 11;
tree.nodes[0].child_ids.push_back(22);
- tree.nodes[0].AddIntAttribute(AX_ATTR_TABLE_HEADER_ID, 22);
- tree.nodes[0].AddIntAttribute(AX_ATTR_TABLE_ROW_HEADER_ID, 22);
- tree.nodes[0].AddIntAttribute(AX_ATTR_TABLE_COLUMN_HEADER_ID, 22);
- tree.nodes[0].AddIntAttribute(AX_ATTR_ACTIVEDESCENDANT_ID, 22);
+ tree.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kTableHeaderId, 22);
+ tree.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kTableRowHeaderId, 22);
+ tree.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kTableColumnHeaderId,
+ 22);
+ tree.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
+ 22);
std::vector<int32_t> ids { 22 };
- tree.nodes[0].AddIntListAttribute(AX_ATTR_INDIRECT_CHILD_IDS, ids);
- tree.nodes[0].AddIntListAttribute(AX_ATTR_CONTROLS_IDS, ids);
- tree.nodes[0].AddIntListAttribute(AX_ATTR_DESCRIBEDBY_IDS, ids);
- tree.nodes[0].AddIntListAttribute(AX_ATTR_FLOWTO_IDS, ids);
- tree.nodes[0].AddIntListAttribute(AX_ATTR_LABELLEDBY_IDS, ids);
- tree.nodes[0].AddIntListAttribute(AX_ATTR_CELL_IDS, ids);
- tree.nodes[0].AddIntListAttribute(AX_ATTR_UNIQUE_CELL_IDS, ids);
+ tree.nodes[0].AddIntListAttribute(
+ ax::mojom::IntListAttribute::kIndirectChildIds, ids);
+ tree.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kControlsIds,
+ ids);
+ tree.nodes[0].AddIntListAttribute(
+ ax::mojom::IntListAttribute::kDescribedbyIds, ids);
+ tree.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kFlowtoIds,
+ ids);
+ tree.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
+ ids);
+ tree.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kCellIds, ids);
+ tree.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kUniqueCellIds,
+ ids);
tree.nodes[1].id = 22;
AXTreeCombiner combiner;
@@ -128,25 +137,28 @@ TEST(CombineAXTreesTest, MapAllIdAttributes) {
EXPECT_EQ(2, combined.nodes[0].child_ids[0]);
EXPECT_EQ(2, combined.nodes[1].id);
- EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(AX_ATTR_TABLE_HEADER_ID));
- EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(AX_ATTR_TABLE_ROW_HEADER_ID));
EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(
- AX_ATTR_TABLE_COLUMN_HEADER_ID));
- EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(AX_ATTR_ACTIVEDESCENDANT_ID));
+ ax::mojom::IntAttribute::kTableHeaderId));
+ EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(
+ ax::mojom::IntAttribute::kTableRowHeaderId));
+ EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(
+ ax::mojom::IntAttribute::kTableColumnHeaderId));
+ EXPECT_EQ(2, combined.nodes[0].GetIntAttribute(
+ ax::mojom::IntAttribute::kActivedescendantId));
EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- AX_ATTR_INDIRECT_CHILD_IDS)[0]);
+ ax::mojom::IntListAttribute::kIndirectChildIds)[0]);
EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- AX_ATTR_CONTROLS_IDS)[0]);
+ ax::mojom::IntListAttribute::kControlsIds)[0]);
EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- AX_ATTR_DESCRIBEDBY_IDS)[0]);
+ ax::mojom::IntListAttribute::kDescribedbyIds)[0]);
EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- AX_ATTR_FLOWTO_IDS)[0]);
+ ax::mojom::IntListAttribute::kFlowtoIds)[0]);
EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- AX_ATTR_LABELLEDBY_IDS)[0]);
+ ax::mojom::IntListAttribute::kLabelledbyIds)[0]);
EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- AX_ATTR_CELL_IDS)[0]);
+ ax::mojom::IntListAttribute::kCellIds)[0]);
EXPECT_EQ(2, combined.nodes[0].GetIntListAttribute(
- AX_ATTR_UNIQUE_CELL_IDS)[0]);
+ ax::mojom::IntListAttribute::kUniqueCellIds)[0]);
}
TEST(CombineAXTreesTest, FocusedTree) {
@@ -161,10 +173,11 @@ TEST(CombineAXTreesTest, FocusedTree) {
parent_tree.nodes[0].child_ids.push_back(2);
parent_tree.nodes[0].child_ids.push_back(3);
parent_tree.nodes[1].id = 2;
- parent_tree.nodes[1].role = AX_ROLE_BUTTON;
+ parent_tree.nodes[1].role = ax::mojom::Role::kButton;
parent_tree.nodes[2].id = 3;
- parent_tree.nodes[2].role = AX_ROLE_IFRAME;
- parent_tree.nodes[2].AddIntAttribute(AX_ATTR_CHILD_TREE_ID, 2);
+ parent_tree.nodes[2].role = ax::mojom::Role::kIframe;
+ parent_tree.nodes[2].AddIntAttribute(ax::mojom::IntAttribute::kChildTreeId,
+ 2);
AXTreeUpdate child_tree;
child_tree.has_tree_data = true;
@@ -177,9 +190,9 @@ TEST(CombineAXTreesTest, FocusedTree) {
child_tree.nodes[0].child_ids.push_back(2);
child_tree.nodes[0].child_ids.push_back(3);
child_tree.nodes[1].id = 2;
- child_tree.nodes[1].role = AX_ROLE_CHECK_BOX;
+ child_tree.nodes[1].role = ax::mojom::Role::kCheckBox;
child_tree.nodes[2].id = 3;
- child_tree.nodes[2].role = AX_ROLE_RADIO_BUTTON;
+ child_tree.nodes[2].role = ax::mojom::Role::kRadioButton;
AXTreeCombiner combiner;
combiner.AddTree(parent_tree, true);
diff --git a/chromium/ui/accessibility/ax_tree_data.cc b/chromium/ui/accessibility/ax_tree_data.cc
index 3639b8dbebf..20e5f1ccce8 100644
--- a/chromium/ui/accessibility/ax_tree_data.cc
+++ b/chromium/ui/accessibility/ax_tree_data.cc
@@ -10,6 +10,7 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "ui/accessibility/ax_enum_util.h"
namespace ui {
diff --git a/chromium/ui/accessibility/ax_tree_data.h b/chromium/ui/accessibility/ax_tree_data.h
index d637bf2b45d..0233764b109 100644
--- a/chromium/ui/accessibility/ax_tree_data.h
+++ b/chromium/ui/accessibility/ax_tree_data.h
@@ -13,7 +13,7 @@
#include "base/strings/string16.h"
#include "base/strings/string_split.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_export.h"
#include "ui/gfx/geometry/rect.h"
@@ -61,10 +61,12 @@ struct AX_EXPORT AXTreeData {
// line, otherwise it's on the second line.
int32_t sel_anchor_object_id = -1;
int32_t sel_anchor_offset = -1;
- ui::AXTextAffinity sel_anchor_affinity = AX_TEXT_AFFINITY_UPSTREAM;
+ ax::mojom::TextAffinity sel_anchor_affinity =
+ ax::mojom::TextAffinity::kUpstream;
int32_t sel_focus_object_id = -1;
int32_t sel_focus_offset = -1;
- ui::AXTextAffinity sel_focus_affinity = AX_TEXT_AFFINITY_DOWNSTREAM;
+ ax::mojom::TextAffinity sel_focus_affinity =
+ ax::mojom::TextAffinity::kDownstream;
};
AX_EXPORT bool operator==(const AXTreeData& lhs, const AXTreeData& rhs);
diff --git a/chromium/ui/accessibility/ax_tree_unittest.cc b/chromium/ui/accessibility/ax_tree_unittest.cc
index 5d9b52b33b8..81d8fb536eb 100644
--- a/chromium/ui/accessibility/ax_tree_unittest.cc
+++ b/chromium/ui/accessibility/ax_tree_unittest.cc
@@ -14,6 +14,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/accessibility/ax_enum_util.h"
#include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_serializable_tree.h"
#include "ui/accessibility/ax_tree_serializer.h"
@@ -119,15 +120,15 @@ class FakeAXTreeDelegate : public AXTreeDelegate {
void OnRoleChanged(AXTree* tree,
AXNode* node,
- AXRole old_role,
- AXRole new_role) override {
+ ax::mojom::Role old_role,
+ ax::mojom::Role new_role) override {
attribute_change_log_.push_back(base::StringPrintf(
"Role changed from %s to %s", ToString(old_role), ToString(new_role)));
}
void OnStateChanged(AXTree* tree,
AXNode* node,
- AXState state,
+ ax::mojom::State state,
bool new_value) override {
attribute_change_log_.push_back(base::StringPrintf(
"%s changed to %s", ToString(state), new_value ? "true" : "false"));
@@ -135,7 +136,7 @@ class FakeAXTreeDelegate : public AXTreeDelegate {
void OnStringAttributeChanged(AXTree* tree,
AXNode* node,
- AXStringAttribute attr,
+ ax::mojom::StringAttribute attr,
const std::string& old_value,
const std::string& new_value) override {
attribute_change_log_.push_back(
@@ -145,7 +146,7 @@ class FakeAXTreeDelegate : public AXTreeDelegate {
void OnIntAttributeChanged(AXTree* tree,
AXNode* node,
- AXIntAttribute attr,
+ ax::mojom::IntAttribute attr,
int32_t old_value,
int32_t new_value) override {
attribute_change_log_.push_back(base::StringPrintf(
@@ -154,7 +155,7 @@ class FakeAXTreeDelegate : public AXTreeDelegate {
void OnFloatAttributeChanged(AXTree* tree,
AXNode* node,
- AXFloatAttribute attr,
+ ax::mojom::FloatAttribute attr,
float old_value,
float new_value) override {
attribute_change_log_.push_back(
@@ -165,7 +166,7 @@ class FakeAXTreeDelegate : public AXTreeDelegate {
void OnBoolAttributeChanged(AXTree* tree,
AXNode* node,
- AXBoolAttribute attr,
+ ax::mojom::BoolAttribute attr,
bool new_value) override {
attribute_change_log_.push_back(base::StringPrintf(
"%s changed to %s", ToString(attr), new_value ? "true" : "false"));
@@ -174,7 +175,7 @@ class FakeAXTreeDelegate : public AXTreeDelegate {
void OnIntListAttributeChanged(
AXTree* tree,
AXNode* node,
- AXIntListAttribute attr,
+ ax::mojom::IntListAttribute attr,
const std::vector<int32_t>& old_value,
const std::vector<int32_t>& new_value) override {
attribute_change_log_.push_back(
@@ -229,20 +230,20 @@ class FakeAXTreeDelegate : public AXTreeDelegate {
TEST(AXTreeTest, SerializeSimpleAXTree) {
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_DIALOG;
- root.AddState(AX_STATE_FOCUSABLE);
+ root.role = ax::mojom::Role::kDialog;
+ root.AddState(ax::mojom::State::kFocusable);
root.location = gfx::RectF(0, 0, 800, 600);
root.child_ids.push_back(2);
root.child_ids.push_back(3);
AXNodeData button;
button.id = 2;
- button.role = AX_ROLE_BUTTON;
+ button.role = ax::mojom::Role::kButton;
button.location = gfx::RectF(20, 20, 200, 30);
AXNodeData checkbox;
checkbox.id = 3;
- checkbox.role = AX_ROLE_CHECK_BOX;
+ checkbox.role = ax::mojom::Role::kCheckBox;
checkbox.location = gfx::RectF(20, 50, 200, 30);
AXTreeUpdate initial_state;
@@ -290,22 +291,22 @@ TEST(AXTreeTest, SerializeSimpleAXTree) {
TEST(AXTreeTest, SerializeAXTreeUpdate) {
AXNodeData list;
list.id = 3;
- list.role = AX_ROLE_LIST;
+ list.role = ax::mojom::Role::kList;
list.child_ids.push_back(4);
list.child_ids.push_back(5);
list.child_ids.push_back(6);
AXNodeData list_item_2;
list_item_2.id = 5;
- list_item_2.role = AX_ROLE_LIST_ITEM;
+ list_item_2.role = ax::mojom::Role::kListItem;
AXNodeData list_item_3;
list_item_3.id = 6;
- list_item_3.role = AX_ROLE_LIST_ITEM;
+ list_item_3.role = ax::mojom::Role::kListItem;
AXNodeData button;
button.id = 7;
- button.role = AX_ROLE_BUTTON;
+ button.role = ax::mojom::Role::kButton;
AXTreeUpdate update;
update.root_id = 3;
@@ -742,10 +743,9 @@ TEST(AXTreeTest, RoleAndStateChangeCallbacks) {
initial_state.root_id = 1;
initial_state.nodes.resize(1);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].role = AX_ROLE_BUTTON;
- initial_state.nodes[0].AddIntAttribute(ui::AX_ATTR_CHECKED_STATE,
- ui::AX_CHECKED_STATE_TRUE);
- initial_state.nodes[0].AddState(AX_STATE_FOCUSABLE);
+ initial_state.nodes[0].role = ax::mojom::Role::kButton;
+ initial_state.nodes[0].SetCheckedState(ax::mojom::CheckedState::kTrue);
+ initial_state.nodes[0].AddState(ax::mojom::State::kFocusable);
AXTree tree(initial_state);
FakeAXTreeDelegate fake_delegate;
@@ -756,11 +756,10 @@ TEST(AXTreeTest, RoleAndStateChangeCallbacks) {
update.root_id = 1;
update.nodes.resize(1);
update.nodes[0].id = 1;
- update.nodes[0].role = AX_ROLE_CHECK_BOX;
- update.nodes[0].AddIntAttribute(ui::AX_ATTR_CHECKED_STATE,
- ui::AX_CHECKED_STATE_FALSE);
- update.nodes[0].AddState(AX_STATE_FOCUSABLE);
- update.nodes[0].AddState(AX_STATE_VISITED);
+ update.nodes[0].role = ax::mojom::Role::kCheckBox;
+ update.nodes[0].SetCheckedState(ax::mojom::CheckedState::kFalse);
+ update.nodes[0].AddState(ax::mojom::State::kFocusable);
+ update.nodes[0].AddState(ax::mojom::State::kVisited);
EXPECT_TRUE(tree.Unserialize(update));
const std::vector<std::string>& change_log =
@@ -778,15 +777,23 @@ TEST(AXTreeTest, AttributeChangeCallbacks) {
initial_state.root_id = 1;
initial_state.nodes.resize(1);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].AddStringAttribute(AX_ATTR_NAME, "N1");
- initial_state.nodes[0].AddStringAttribute(AX_ATTR_DESCRIPTION, "D1");
- initial_state.nodes[0].AddBoolAttribute(AX_ATTR_LIVE_ATOMIC, true);
- initial_state.nodes[0].AddBoolAttribute(AX_ATTR_BUSY, false);
- initial_state.nodes[0].AddFloatAttribute(AX_ATTR_MIN_VALUE_FOR_RANGE, 1.0);
- initial_state.nodes[0].AddFloatAttribute(AX_ATTR_MAX_VALUE_FOR_RANGE, 10.0);
- initial_state.nodes[0].AddFloatAttribute(AX_ATTR_STEP_VALUE_FOR_RANGE, 3.0);
- initial_state.nodes[0].AddIntAttribute(AX_ATTR_SCROLL_X, 5);
- initial_state.nodes[0].AddIntAttribute(AX_ATTR_SCROLL_X_MIN, 1);
+ initial_state.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kName,
+ "N1");
+ initial_state.nodes[0].AddStringAttribute(
+ ax::mojom::StringAttribute::kDescription, "D1");
+ initial_state.nodes[0].AddBoolAttribute(ax::mojom::BoolAttribute::kLiveAtomic,
+ true);
+ initial_state.nodes[0].AddBoolAttribute(ax::mojom::BoolAttribute::kBusy,
+ false);
+ initial_state.nodes[0].AddFloatAttribute(
+ ax::mojom::FloatAttribute::kMinValueForRange, 1.0);
+ initial_state.nodes[0].AddFloatAttribute(
+ ax::mojom::FloatAttribute::kMaxValueForRange, 10.0);
+ initial_state.nodes[0].AddFloatAttribute(
+ ax::mojom::FloatAttribute::kStepValueForRange, 3.0);
+ initial_state.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kScrollX, 5);
+ initial_state.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kScrollXMin,
+ 1);
AXTree tree(initial_state);
FakeAXTreeDelegate fake_delegate;
@@ -797,15 +804,20 @@ TEST(AXTreeTest, AttributeChangeCallbacks) {
update0.root_id = 1;
update0.nodes.resize(1);
update0.nodes[0].id = 1;
- update0.nodes[0].AddStringAttribute(AX_ATTR_NAME, "N2");
- update0.nodes[0].AddStringAttribute(AX_ATTR_DESCRIPTION, "D2");
- update0.nodes[0].AddBoolAttribute(AX_ATTR_LIVE_ATOMIC, false);
- update0.nodes[0].AddBoolAttribute(AX_ATTR_BUSY, true);
- update0.nodes[0].AddFloatAttribute(AX_ATTR_MIN_VALUE_FOR_RANGE, 2.0);
- update0.nodes[0].AddFloatAttribute(AX_ATTR_MAX_VALUE_FOR_RANGE, 9.0);
- update0.nodes[0].AddFloatAttribute(AX_ATTR_STEP_VALUE_FOR_RANGE, 0.5);
- update0.nodes[0].AddIntAttribute(AX_ATTR_SCROLL_X, 6);
- update0.nodes[0].AddIntAttribute(AX_ATTR_SCROLL_X_MIN, 2);
+ update0.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kName, "N2");
+ update0.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kDescription,
+ "D2");
+ update0.nodes[0].AddBoolAttribute(ax::mojom::BoolAttribute::kLiveAtomic,
+ false);
+ update0.nodes[0].AddBoolAttribute(ax::mojom::BoolAttribute::kBusy, true);
+ update0.nodes[0].AddFloatAttribute(
+ ax::mojom::FloatAttribute::kMinValueForRange, 2.0);
+ update0.nodes[0].AddFloatAttribute(
+ ax::mojom::FloatAttribute::kMaxValueForRange, 9.0);
+ update0.nodes[0].AddFloatAttribute(
+ ax::mojom::FloatAttribute::kStepValueForRange, 0.5);
+ update0.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kScrollX, 6);
+ update0.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kScrollXMin, 2);
EXPECT_TRUE(tree.Unserialize(update0));
const std::vector<std::string>& change_log =
@@ -829,13 +841,16 @@ TEST(AXTreeTest, AttributeChangeCallbacks) {
update1.root_id = 1;
update1.nodes.resize(1);
update1.nodes[0].id = 1;
- update1.nodes[0].AddStringAttribute(AX_ATTR_DESCRIPTION, "D3");
- update1.nodes[0].AddStringAttribute(AX_ATTR_VALUE, "V3");
- update1.nodes[0].AddBoolAttribute(AX_ATTR_MODAL, true);
- update1.nodes[0].AddFloatAttribute(AX_ATTR_VALUE_FOR_RANGE, 5.0);
- update1.nodes[0].AddFloatAttribute(AX_ATTR_MAX_VALUE_FOR_RANGE, 9.0);
- update1.nodes[0].AddIntAttribute(AX_ATTR_SCROLL_X, 7);
- update1.nodes[0].AddIntAttribute(AX_ATTR_SCROLL_X_MAX, 10);
+ update1.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kDescription,
+ "D3");
+ update1.nodes[0].AddStringAttribute(ax::mojom::StringAttribute::kValue, "V3");
+ update1.nodes[0].AddBoolAttribute(ax::mojom::BoolAttribute::kModal, true);
+ update1.nodes[0].AddFloatAttribute(ax::mojom::FloatAttribute::kValueForRange,
+ 5.0);
+ update1.nodes[0].AddFloatAttribute(
+ ax::mojom::FloatAttribute::kMaxValueForRange, 9.0);
+ update1.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kScrollX, 7);
+ update1.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kScrollXMax, 10);
EXPECT_TRUE(tree.Unserialize(update1));
const std::vector<std::string>& change_log2 =
@@ -871,8 +886,10 @@ TEST(AXTreeTest, IntListChangeCallbacks) {
initial_state.root_id = 1;
initial_state.nodes.resize(1);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].AddIntListAttribute(AX_ATTR_CONTROLS_IDS, one);
- initial_state.nodes[0].AddIntListAttribute(AX_ATTR_RADIO_GROUP_IDS, two);
+ initial_state.nodes[0].AddIntListAttribute(
+ ax::mojom::IntListAttribute::kControlsIds, one);
+ initial_state.nodes[0].AddIntListAttribute(
+ ax::mojom::IntListAttribute::kRadioGroupIds, two);
AXTree tree(initial_state);
FakeAXTreeDelegate fake_delegate;
@@ -883,8 +900,10 @@ TEST(AXTreeTest, IntListChangeCallbacks) {
update0.root_id = 1;
update0.nodes.resize(1);
update0.nodes[0].id = 1;
- update0.nodes[0].AddIntListAttribute(AX_ATTR_CONTROLS_IDS, two);
- update0.nodes[0].AddIntListAttribute(AX_ATTR_RADIO_GROUP_IDS, three);
+ update0.nodes[0].AddIntListAttribute(
+ ax::mojom::IntListAttribute::kControlsIds, two);
+ update0.nodes[0].AddIntListAttribute(
+ ax::mojom::IntListAttribute::kRadioGroupIds, three);
EXPECT_TRUE(tree.Unserialize(update0));
const std::vector<std::string>& change_log =
@@ -901,8 +920,10 @@ TEST(AXTreeTest, IntListChangeCallbacks) {
update1.root_id = 1;
update1.nodes.resize(1);
update1.nodes[0].id = 1;
- update1.nodes[0].AddIntListAttribute(AX_ATTR_RADIO_GROUP_IDS, two);
- update1.nodes[0].AddIntListAttribute(AX_ATTR_FLOWTO_IDS, three);
+ update1.nodes[0].AddIntListAttribute(
+ ax::mojom::IntListAttribute::kRadioGroupIds, two);
+ update1.nodes[0].AddIntListAttribute(ax::mojom::IntListAttribute::kFlowtoIds,
+ three);
EXPECT_TRUE(tree.Unserialize(update1));
const std::vector<std::string>& change_log2 =
@@ -962,8 +983,9 @@ TEST(AXTreeTest, EmptyNodeNotOffscreenEvenIfAllChildrenOffscreen) {
tree_update.nodes.resize(4);
tree_update.nodes[0].id = 1;
tree_update.nodes[0].location = gfx::RectF(0, 0, 800, 600);
- tree_update.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
- tree_update.nodes[0].AddBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN, true);
+ tree_update.nodes[0].role = ax::mojom::Role::kRootWebArea;
+ tree_update.nodes[0].AddBoolAttribute(
+ ax::mojom::BoolAttribute::kClipsChildren, true);
tree_update.nodes[0].child_ids.push_back(2);
tree_update.nodes[1].id = 2;
tree_update.nodes[1].location = gfx::RectF(); // Deliberately empty.
@@ -1040,8 +1062,8 @@ TEST(AXTreeTest, GetBoundsWithScrolling) {
tree_update.nodes[0].child_ids.push_back(2);
tree_update.nodes[1].id = 2;
tree_update.nodes[1].location = gfx::RectF(100, 50, 600, 500);
- tree_update.nodes[1].AddIntAttribute(ui::AX_ATTR_SCROLL_X, 5);
- tree_update.nodes[1].AddIntAttribute(ui::AX_ATTR_SCROLL_Y, 10);
+ tree_update.nodes[1].AddIntAttribute(ax::mojom::IntAttribute::kScrollX, 5);
+ tree_update.nodes[1].AddIntAttribute(ax::mojom::IntAttribute::kScrollY, 10);
tree_update.nodes[1].child_ids.push_back(3);
tree_update.nodes[2].id = 3;
tree_update.nodes[2].offset_container_id = 2;
@@ -1057,7 +1079,8 @@ TEST(AXTreeTest, GetBoundsEmptyBoundsInheritsFromParent) {
tree_update.nodes.resize(3);
tree_update.nodes[0].id = 1;
tree_update.nodes[0].location = gfx::RectF(0, 0, 800, 600);
- tree_update.nodes[1].AddBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN, true);
+ tree_update.nodes[1].AddBoolAttribute(
+ ax::mojom::BoolAttribute::kClipsChildren, true);
tree_update.nodes[0].child_ids.push_back(2);
tree_update.nodes[1].id = 2;
tree_update.nodes[1].location = gfx::RectF(300, 200, 100, 100);
@@ -1083,7 +1106,8 @@ TEST(AXTreeTest, GetBoundsCropsChildToRoot) {
tree_update.nodes.resize(5);
tree_update.nodes[0].id = 1;
tree_update.nodes[0].location = gfx::RectF(0, 0, 800, 600);
- tree_update.nodes[0].AddBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN, true);
+ tree_update.nodes[0].AddBoolAttribute(
+ ax::mojom::BoolAttribute::kClipsChildren, true);
tree_update.nodes[0].child_ids.push_back(2);
tree_update.nodes[0].child_ids.push_back(3);
tree_update.nodes[0].child_ids.push_back(4);
@@ -1121,13 +1145,15 @@ TEST(AXTreeTest, GetBoundsSetsOffscreenIfClipsChildren) {
tree_update.nodes.resize(5);
tree_update.nodes[0].id = 1;
tree_update.nodes[0].location = gfx::RectF(0, 0, 800, 600);
- tree_update.nodes[0].AddBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN, true);
+ tree_update.nodes[0].AddBoolAttribute(
+ ax::mojom::BoolAttribute::kClipsChildren, true);
tree_update.nodes[0].child_ids.push_back(2);
tree_update.nodes[0].child_ids.push_back(3);
tree_update.nodes[1].id = 2;
tree_update.nodes[1].location = gfx::RectF(0, 0, 200, 200);
- tree_update.nodes[1].AddBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN, true);
+ tree_update.nodes[1].AddBoolAttribute(
+ ax::mojom::BoolAttribute::kClipsChildren, true);
tree_update.nodes[1].child_ids.push_back(4);
tree_update.nodes[2].id = 3;
@@ -1156,8 +1182,9 @@ TEST(AXTreeTest, GetBoundsUpdatesOffscreen) {
tree_update.nodes.resize(5);
tree_update.nodes[0].id = 1;
tree_update.nodes[0].location = gfx::RectF(0, 0, 800, 600);
- tree_update.nodes[0].role = AX_ROLE_ROOT_WEB_AREA;
- tree_update.nodes[0].AddBoolAttribute(ui::AX_ATTR_CLIPS_CHILDREN, true);
+ tree_update.nodes[0].role = ax::mojom::Role::kRootWebArea;
+ tree_update.nodes[0].AddBoolAttribute(
+ ax::mojom::BoolAttribute::kClipsChildren, true);
tree_update.nodes[0].child_ids.push_back(2);
tree_update.nodes[0].child_ids.push_back(3);
tree_update.nodes[0].child_ids.push_back(4);
@@ -1187,32 +1214,35 @@ TEST(AXTreeTest, IntReverseRelations) {
initial_state.root_id = 1;
initial_state.nodes.resize(4);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].AddIntAttribute(AX_ATTR_ACTIVEDESCENDANT_ID, 2);
+ initial_state.nodes[0].AddIntAttribute(
+ ax::mojom::IntAttribute::kActivedescendantId, 2);
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[0].child_ids.push_back(3);
initial_state.nodes[0].child_ids.push_back(4);
initial_state.nodes[1].id = 2;
initial_state.nodes[2].id = 3;
- initial_state.nodes[2].AddIntAttribute(AX_ATTR_MEMBER_OF_ID, 1);
+ initial_state.nodes[2].AddIntAttribute(ax::mojom::IntAttribute::kMemberOfId,
+ 1);
initial_state.nodes[3].id = 4;
- initial_state.nodes[3].AddIntAttribute(AX_ATTR_MEMBER_OF_ID, 1);
+ initial_state.nodes[3].AddIntAttribute(ax::mojom::IntAttribute::kMemberOfId,
+ 1);
AXTree tree(initial_state);
auto reverse_active_descendant =
- tree.GetReverseRelations(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 2);
+ tree.GetReverseRelations(ax::mojom::IntAttribute::kActivedescendantId, 2);
ASSERT_EQ(1U, reverse_active_descendant.size());
EXPECT_TRUE(base::ContainsKey(reverse_active_descendant, 1));
reverse_active_descendant =
- tree.GetReverseRelations(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 1);
+ tree.GetReverseRelations(ax::mojom::IntAttribute::kActivedescendantId, 1);
ASSERT_EQ(0U, reverse_active_descendant.size());
auto reverse_errormessage =
- tree.GetReverseRelations(ui::AX_ATTR_ERRORMESSAGE_ID, 1);
+ tree.GetReverseRelations(ax::mojom::IntAttribute::kErrormessageId, 1);
ASSERT_EQ(0U, reverse_errormessage.size());
auto reverse_member_of =
- tree.GetReverseRelations(ui::AX_ATTR_MEMBER_OF_ID, 1);
+ tree.GetReverseRelations(ax::mojom::IntAttribute::kMemberOfId, 1);
ASSERT_EQ(2U, reverse_member_of.size());
EXPECT_TRUE(base::ContainsKey(reverse_member_of, 3));
EXPECT_TRUE(base::ContainsKey(reverse_member_of, 4));
@@ -1220,24 +1250,26 @@ TEST(AXTreeTest, IntReverseRelations) {
AXTreeUpdate update = initial_state;
update.nodes.resize(5);
update.nodes[0].int_attributes.clear();
- update.nodes[0].AddIntAttribute(AX_ATTR_ACTIVEDESCENDANT_ID, 5);
+ update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
+ 5);
update.nodes[0].child_ids.push_back(5);
update.nodes[2].int_attributes.clear();
update.nodes[4].id = 5;
- update.nodes[4].AddIntAttribute(AX_ATTR_MEMBER_OF_ID, 1);
+ update.nodes[4].AddIntAttribute(ax::mojom::IntAttribute::kMemberOfId, 1);
EXPECT_TRUE(tree.Unserialize(update));
reverse_active_descendant =
- tree.GetReverseRelations(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 2);
+ tree.GetReverseRelations(ax::mojom::IntAttribute::kActivedescendantId, 2);
ASSERT_EQ(0U, reverse_active_descendant.size());
reverse_active_descendant =
- tree.GetReverseRelations(ui::AX_ATTR_ACTIVEDESCENDANT_ID, 5);
+ tree.GetReverseRelations(ax::mojom::IntAttribute::kActivedescendantId, 5);
ASSERT_EQ(1U, reverse_active_descendant.size());
EXPECT_TRUE(base::ContainsKey(reverse_active_descendant, 1));
- reverse_member_of = tree.GetReverseRelations(ui::AX_ATTR_MEMBER_OF_ID, 1);
+ reverse_member_of =
+ tree.GetReverseRelations(ax::mojom::IntAttribute::kMemberOfId, 1);
ASSERT_EQ(2U, reverse_member_of.size());
EXPECT_TRUE(base::ContainsKey(reverse_member_of, 4));
EXPECT_TRUE(base::ContainsKey(reverse_member_of, 5));
@@ -1255,7 +1287,8 @@ TEST(AXTreeTest, IntListReverseRelations) {
initial_state.root_id = 1;
initial_state.nodes.resize(3);
initial_state.nodes[0].id = 1;
- initial_state.nodes[0].AddIntListAttribute(AX_ATTR_LABELLEDBY_IDS, node_two);
+ initial_state.nodes[0].AddIntListAttribute(
+ ax::mojom::IntListAttribute::kLabelledbyIds, node_two);
initial_state.nodes[0].child_ids.push_back(2);
initial_state.nodes[0].child_ids.push_back(3);
initial_state.nodes[1].id = 2;
@@ -1264,22 +1297,55 @@ TEST(AXTreeTest, IntListReverseRelations) {
AXTree tree(initial_state);
auto reverse_labelled_by =
- tree.GetReverseRelations(ui::AX_ATTR_LABELLEDBY_IDS, 2);
+ tree.GetReverseRelations(ax::mojom::IntListAttribute::kLabelledbyIds, 2);
ASSERT_EQ(1U, reverse_labelled_by.size());
EXPECT_TRUE(base::ContainsKey(reverse_labelled_by, 1));
- reverse_labelled_by = tree.GetReverseRelations(ui::AX_ATTR_LABELLEDBY_IDS, 3);
+ reverse_labelled_by =
+ tree.GetReverseRelations(ax::mojom::IntListAttribute::kLabelledbyIds, 3);
ASSERT_EQ(0U, reverse_labelled_by.size());
// Change existing attributes.
AXTreeUpdate update = initial_state;
update.nodes[0].intlist_attributes.clear();
- update.nodes[0].AddIntListAttribute(AX_ATTR_LABELLEDBY_IDS, nodes_two_three);
+ update.nodes[0].AddIntListAttribute(
+ ax::mojom::IntListAttribute::kLabelledbyIds, nodes_two_three);
EXPECT_TRUE(tree.Unserialize(update));
- reverse_labelled_by = tree.GetReverseRelations(ui::AX_ATTR_LABELLEDBY_IDS, 3);
+ reverse_labelled_by =
+ tree.GetReverseRelations(ax::mojom::IntListAttribute::kLabelledbyIds, 3);
ASSERT_EQ(1U, reverse_labelled_by.size());
EXPECT_TRUE(base::ContainsKey(reverse_labelled_by, 1));
}
+TEST(AXTreeTest, SkipIgnoredNodes) {
+ AXTreeUpdate tree_update;
+ tree_update.root_id = 1;
+ tree_update.nodes.resize(5);
+ tree_update.nodes[0].id = 1;
+ tree_update.nodes[0].child_ids = {2, 3};
+ tree_update.nodes[1].id = 2;
+ tree_update.nodes[1].AddState(ax::mojom::State::kIgnored);
+ tree_update.nodes[1].child_ids = {4, 5};
+ tree_update.nodes[2].id = 3;
+ tree_update.nodes[3].id = 4;
+ tree_update.nodes[4].id = 5;
+
+ AXTree tree(tree_update);
+ AXNode* root = tree.root();
+ ASSERT_EQ(2, root->child_count());
+ ASSERT_EQ(2, root->ChildAtIndex(0)->id());
+ ASSERT_EQ(3, root->ChildAtIndex(1)->id());
+
+ EXPECT_EQ(3, root->GetUnignoredChildCount());
+ EXPECT_EQ(4, root->GetUnignoredChildAtIndex(0)->id());
+ EXPECT_EQ(5, root->GetUnignoredChildAtIndex(1)->id());
+ EXPECT_EQ(3, root->GetUnignoredChildAtIndex(2)->id());
+ EXPECT_EQ(0, root->GetUnignoredChildAtIndex(0)->GetUnignoredIndexInParent());
+ EXPECT_EQ(1, root->GetUnignoredChildAtIndex(1)->GetUnignoredIndexInParent());
+ EXPECT_EQ(2, root->GetUnignoredChildAtIndex(2)->GetUnignoredIndexInParent());
+
+ EXPECT_EQ(1, root->GetUnignoredChildAtIndex(0)->GetUnignoredParent()->id());
+}
+
} // namespace ui
diff --git a/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_ar.xtb b/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_ar.xtb
index 31de2f8cb75..3443de9d455 100644
--- a/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_ar.xtb
+++ b/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_ar.xtb
@@ -6,7 +6,7 @@
<translation id="145360476452865422">سياسة الصور المتحركة:</translation>
<translation id="1555130319947370107">أزرق</translation>
<translation id="1588438908519853928">عادي</translation>
-<translation id="1591070050619849194">عطّل جميع صور الرسوم المتحركة.</translation>
+<translation id="1591070050619849194">أوقف جميع صور الرسوم المتحركة.</translation>
<translation id="1703735871906654364">التصفح النصي بالمؤشر</translation>
<translation id="1791496371305830581">اسمح بجميع الصور المتحركة.</translation>
<translation id="1996252509865389616">هل تريد التمكين؟</translation>
@@ -21,26 +21,26 @@
<translation id="2965611304828530558">‏&lt;p&gt;عندما تصل إلى رابط أو عنصر تحكم فإنه يتم التركيز عليه تلقائيًا. انقر على &lt;span class='key'&gt;Enter&lt;/span&gt; للنقر على رابط أو زر. &lt;/ P&gt; &lt;p&gt; عندما يقوم عنصر تحكم مُركز عليه بالتقاط مفاتيح الأسهم (مثل مربع نص أو مربع قائمة)، اضغط على &lt;span class='key'&gt;Esc&lt;/span&gt; SPAN&gt; تليها السهم الأيمن أو الأيسر لمواصلة التصفح النصي بالمؤشر &lt;/ P&gt; &lt;P&gt; وبدلاً من ذلك، اضغط &lt;span class='key'&gt;Tab&lt;/span&gt; للانتقال إلى عنصر التحكم التالي القابل للتركيز عليه &lt;/ P&gt;</translation>
<translation id="3252573918265662711">الإعداد</translation>
<translation id="3410969471888629217">نسيان تخصيصات موقع الويب</translation>
-<translation id="3435896845095436175">تمكين الإضافات</translation>
-<translation id="3622586652998721735">تعيين كمخطط افتراضي</translation>
+<translation id="3435896845095436175">تفعيل الإضافات</translation>
+<translation id="3622586652998721735">تعيين كمخطط تلقائي</translation>
<translation id="3812541808639806898">‏عارض النص "Alt" للصورة</translation>
<translation id="381767806621926835">‏انقر بزر الماوس الأيمن على أي شيء يعمل بخاصية "longdesc" أو "aria-describedat" للدخول إلى الوصف المفصل.</translation>
<translation id="4023902424053835668">تصفح نص صفحات الويب باستخدام مفاتيح الأسهم.</translation>
<translation id="4388820049312272371">أبرز موضع المؤشر بومضة سريعة.</translation>
-<translation id="4394049700291259645">تعطيل</translation>
+<translation id="4394049700291259645">إيقاف</translation>
<translation id="4769065380738716500">تم استبدال الصور بواسطة النص البديل</translation>
<translation id="4896660567607030658">لا توجد تعليقات، فقط أعرض المؤشر.</translation>
<translation id="4937901943818762779">السماح بالصور المتحركة، ولكن لمرة واحدة فقط.</translation>
-<translation id="4954450790315188152">عندما يتم تمكين التصفح النصي بالمؤشر.</translation>
+<translation id="4954450790315188152">عندما يتم تفعيل التصفح النصي بالمؤشر.</translation>
<translation id="5041932793799765940">تعديل اللون</translation>
<translation id="5094574508723441140">زيادة التباين</translation>
<translation id="5173942593318174089">أبرز موضع المؤشر بالرسوم المتحركة.</translation>
<translation id="5287723860611749454">‏&lt;p&gt;استخدام مفاتيح الأسهم للتحرك في جميع أنحاء المستند &lt;/ P&gt; &lt;P&gt; انقر في أي مكان لتحريك المؤشر إلى ذلك الموقع. &lt;/ P&gt; &lt;P&gt; اضغط على &lt;span class='key'&gt;Shift&lt;/span&gt; + الأسهم لتحديد النص.&lt;/ P&gt;</translation>
<translation id="5331422999063554397">لون معكوس</translation>
-<translation id="5555153510860501336">التباين العالي مُعطل</translation>
+<translation id="5555153510860501336">التباين العالي غير مفعّل</translation>
<translation id="5558600050691192317">أوامر لوحة المفاتيح</translation>
-<translation id="5594989420907487559">شغّل الصور المتحركة مرة واحدة فقط، أو عطّل الصور المتحركة تمامًا.</translation>
-<translation id="5631241868147802353">مخطط اللون الافتراضي:</translation>
+<translation id="5594989420907487559">شغّل الصور المتحركة مرة واحدة فقط، أو أوقف الصور المتحركة تمامًا.</translation>
+<translation id="5631241868147802353">مخطط اللون التلقائي:</translation>
<translation id="5650358096585648000">التعليقات البصرية</translation>
<translation id="5710185147685935461">تغيير أو عكس نظام الألوان لتسهيل قراءة صفحات الويب.</translation>
<translation id="5939518447894949180">إعادة</translation>
@@ -54,7 +54,7 @@
<translation id="690628312087070417">عندما يقفز مؤشر النص لمسافة كبيرة:</translation>
<translation id="6965382102122355670">موافق</translation>
<translation id="7379645913608427028">درجة</translation>
-<translation id="7384431257964758081">تم تمكين التباين العالي</translation>
+<translation id="7384431257964758081">تم تفعيل التباين العالي</translation>
<translation id="7586636300921797327">الخطوة الثانية: ضبط شريط التمرير؛ حتى تكون جميع النجوم مرئية في
الصف المحدد</translation>
<translation id="7658239707568436148">إلغاء</translation>
@@ -65,5 +65,5 @@
<translation id="8321034316479930120">سياسة الصور المتحركة</translation>
<translation id="8480209185614411573">تباين مرتفع</translation>
<translation id="8609925175482059018">‏لتشغيل التصفح النصي بالمؤشر انقر فوق &lt;span class='key'&gt;F7&lt;/span&gt; ولإيقاف تشغيله انقر فوقه مرة أخرى.</translation>
-<translation id="894241283505723656">وصف مفصل في قائمة السياق</translation>
+<translation id="894241283505723656">وصف مفصل في قائمة السياقات</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_de.xtb b/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_de.xtb
index 2ac6b2b8284..d810acfeeb1 100644
--- a/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_de.xtb
+++ b/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_de.xtb
@@ -35,7 +35,7 @@
<translation id="5041932793799765940">Farbanpassung</translation>
<translation id="5094574508723441140">Kontrasterhöhung</translation>
<translation id="5173942593318174089">Cursorposition mit Animation markieren</translation>
-<translation id="5287723860611749454">&lt;p&gt;Mit den Pfeiltasten können Sie durch das Dokument navigieren. &lt;/p&gt;&lt;p&gt;Klicken Sie an einer Stelle, um den Cursor dort zu platzieren. &lt;/p&gt; &lt;p&gt; Mit &lt;span class='key'&gt;Shift&lt;/span&gt; + Pfeiltaste können Sie Text auswählen.&lt;/p&gt;</translation>
+<translation id="5287723860611749454">&lt;p&gt;Mit den Pfeiltasten können Sie durch das Dokument navigieren. &lt;/p&gt;&lt;p&gt;Klicken Sie an einer Stelle, um den Cursor dort zu platzieren. &lt;/p&gt; &lt;p&gt; Mit &lt;span class='key'&gt;Umschalttaste&lt;/span&gt; + Pfeiltaste können Sie Text auswählen.&lt;/p&gt;</translation>
<translation id="5331422999063554397">Farbumkehrung</translation>
<translation id="5555153510860501336">Hoher Kontrast ist deaktiviert.</translation>
<translation id="5558600050691192317">Tastaturbefehle</translation>
diff --git a/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_es-419.xtb b/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_es-419.xtb
index 39649f27dcf..65569b6c1fc 100644
--- a/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_es-419.xtb
+++ b/chromium/ui/accessibility/extensions/strings/accessibility_extensions_strings_es-419.xtb
@@ -58,7 +58,7 @@
<translation id="7586636300921797327">Paso 2. Ajusta el control deslizante hasta que todas las estrellas sean visibles en la
fila seleccionada.</translation>
<translation id="7658239707568436148">Cancelar</translation>
-<translation id="786423340267544509">Agregar límite a elementos con atributos aria-describedat o longdesc</translation>
+<translation id="786423340267544509">Agregar borde a elementos con atributos aria-describedat o longdesc</translation>
<translation id="7942349550061667556">Rojo</translation>
<translation id="8254860724243898966">Presiona &lt;span class='key'&gt;Alt&lt;/span&gt; + &lt;img src='increase_brightness.png'&gt; (la tecla de Aumentar brillo o F7) para habilitar la navegación por cursor de texto. Vuelve a presionar la misma tecla para inhabilitarla.</translation>
<translation id="8260673944985561857">Opciones de navegación por cursor de texto</translation>
diff --git a/chromium/ui/accessibility/platform/aura_window_properties.cc b/chromium/ui/accessibility/platform/aura_window_properties.cc
index 20775b9ff1a..e72b2d26e9a 100644
--- a/chromium/ui/accessibility/platform/aura_window_properties.cc
+++ b/chromium/ui/accessibility/platform/aura_window_properties.cc
@@ -6,7 +6,7 @@
#include "ui/base/class_property.h"
-DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AX_EXPORT, AXRole)
+DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(AX_EXPORT, ax::mojom::Role)
namespace ui {
@@ -14,6 +14,8 @@ DEFINE_UI_CLASS_PROPERTY_KEY(AXTreeIDRegistry::AXTreeID,
kChildAXTreeID,
AXTreeIDRegistry::kNoAXTreeID);
-DEFINE_UI_CLASS_PROPERTY_KEY(AXRole, kAXRoleOverride, ui::AX_ROLE_NONE);
+DEFINE_UI_CLASS_PROPERTY_KEY(ax::mojom::Role,
+ kAXRoleOverride,
+ ax::mojom::Role::kNone);
} // namespace ui
diff --git a/chromium/ui/accessibility/platform/aura_window_properties.h b/chromium/ui/accessibility/platform/aura_window_properties.h
index 5f25a8e5c18..c78850da22f 100644
--- a/chromium/ui/accessibility/platform/aura_window_properties.h
+++ b/chromium/ui/accessibility/platform/aura_window_properties.h
@@ -5,7 +5,7 @@
#ifndef UI_ACCESSIBILITY_PLATFORM_AURA_WINDOW_PROPERTIES_H_
#define UI_ACCESSIBILITY_PLATFORM_AURA_WINDOW_PROPERTIES_H_
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_export.h"
#include "ui/accessibility/ax_tree_id_registry.h"
#include "ui/aura/window.h"
@@ -15,7 +15,8 @@ namespace ui {
AX_EXPORT extern const aura::WindowProperty<AXTreeIDRegistry::AXTreeID>* const
kChildAXTreeID;
-AX_EXPORT extern const aura::WindowProperty<AXRole>* const kAXRoleOverride;
+AX_EXPORT extern const aura::WindowProperty<ax::mojom::Role>* const
+ kAXRoleOverride;
} // namespace ui
diff --git a/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.cc b/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.cc
index 3a66c1d7141..c13f6dbdf5d 100644
--- a/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.cc
+++ b/chromium/ui/accessibility/platform/ax_platform_atk_hyperlink.cc
@@ -35,7 +35,8 @@ static gchar* ax_platform_atk_hyperlink_get_uri(AtkHyperlink* atk_hyperlink,
if (index != 0)
return nullptr;
- return g_strdup(obj->GetStringAttribute(ui::AX_ATTR_URL).c_str());
+ return g_strdup(
+ obj->GetStringAttribute(ax::mojom::StringAttribute::kUrl).c_str());
}
static AtkObject* ax_platform_atk_hyperlink_get_object(
@@ -155,7 +156,8 @@ static const gchar* ax_platform_atk_hyperlink_get_keybinding(AtkAction* action,
if (!obj)
return nullptr;
- return obj->GetStringAttribute(ui::AX_ATTR_ACCESS_KEY).c_str();
+ return obj->GetStringAttribute(ax::mojom::StringAttribute::kAccessKey)
+ .c_str();
}
static const gchar* ax_platform_atk_hyperlink_get_name(AtkAction* atk_action,
@@ -169,10 +171,11 @@ static const gchar* ax_platform_atk_hyperlink_get_name(AtkAction* atk_action,
return nullptr;
int action;
- if (!obj->GetIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB, &action))
+ if (!obj->GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb,
+ &action))
return nullptr;
base::string16 action_verb = ui::ActionVerbToUnlocalizedString(
- static_cast<ui::AXDefaultActionVerb>(action));
+ static_cast<ax::mojom::DefaultActionVerb>(action));
ATK_AURALINUX_RETURN_STRING(base::UTF16ToUTF8(action_verb));
}
@@ -188,10 +191,11 @@ static const gchar* ax_platform_atk_hyperlink_get_localized_name(
return nullptr;
int action;
- if (!obj->GetIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB, &action))
+ if (!obj->GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb,
+ &action))
return nullptr;
base::string16 action_verb = ui::ActionVerbToLocalizedString(
- static_cast<ui::AXDefaultActionVerb>(action));
+ static_cast<ax::mojom::DefaultActionVerb>(action));
ATK_AURALINUX_RETURN_STRING(base::UTF16ToUTF8(action_verb));
}
diff --git a/chromium/ui/accessibility/platform/ax_platform_node.h b/chromium/ui/accessibility/platform/ax_platform_node.h
index f2e7e7a0556..f723bf064c4 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node.h
+++ b/chromium/ui/accessibility/platform/ax_platform_node.h
@@ -9,7 +9,7 @@
#include "base/lazy_instance.h"
#include "base/observer_list.h"
#include "build/build_config.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_export.h"
#include "ui/accessibility/ax_mode_observer.h"
#include "ui/gfx/native_widget_types.h"
@@ -64,7 +64,7 @@ class AX_EXPORT AXPlatformNode {
// Fire a platform-specific notification that an event has occurred on
// this object.
- virtual void NotifyAccessibilityEvent(AXEvent event_type) = 0;
+ virtual void NotifyAccessibilityEvent(ax::mojom::Event event_type) = 0;
// Return this object's delegate.
virtual AXPlatformNodeDelegate* GetDelegate() const = 0;
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc b/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc
index 06bbf6949fd..b502a6786c6 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc
+++ b/chromium/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -80,12 +80,12 @@ static const gchar* ax_platform_node_auralinux_get_name(AtkObject* atk_object) {
if (!obj)
return nullptr;
- if (obj->GetStringAttribute(ui::AX_ATTR_NAME).empty() &&
- !(obj->GetIntAttribute(ui::AX_ATTR_NAME_FROM) ==
- ui::AX_NAME_FROM_ATTRIBUTE_EXPLICITLY_EMPTY))
+ ax::mojom::NameFrom name_from = obj->GetData().GetNameFrom();
+ if (obj->GetStringAttribute(ax::mojom::StringAttribute::kName).empty() &&
+ name_from != ax::mojom::NameFrom::kAttributeExplicitlyEmpty)
return nullptr;
- return obj->GetStringAttribute(ui::AX_ATTR_NAME).c_str();
+ return obj->GetStringAttribute(ax::mojom::StringAttribute::kName).c_str();
}
static const gchar* ax_platform_node_auralinux_get_description(
@@ -95,8 +95,8 @@ static const gchar* ax_platform_node_auralinux_get_description(
if (!obj)
return nullptr;
- return obj->GetStringAttribute(
- ui::AX_ATTR_DESCRIPTION).c_str();
+ return obj->GetStringAttribute(ax::mojom::StringAttribute::kDescription)
+ .c_str();
}
static gint ax_platform_node_auralinux_get_index_in_parent(
@@ -374,7 +374,8 @@ static const gchar* ax_platform_node_auralinux_get_action_keybinding(
if (!obj)
return nullptr;
- return obj->GetStringAttribute(ui::AX_ATTR_ACCESS_KEY).c_str();
+ return obj->GetStringAttribute(ax::mojom::StringAttribute::kAccessKey)
+ .c_str();
}
void ax_action_interface_base_init(AtkActionIface* iface) {
@@ -459,7 +460,8 @@ static const gchar* ax_platform_node_auralinux_get_image_description(
if (!obj)
return nullptr;
- return obj->GetStringAttribute(ui::AX_ATTR_DESCRIPTION).c_str();
+ return obj->GetStringAttribute(ax::mojom::StringAttribute::kDescription)
+ .c_str();
}
static void ax_platform_node_auralinux_get_image_size(AtkImage* atk_img,
@@ -501,7 +503,8 @@ static void ax_platform_node_auralinux_get_current_value(AtkValue* atk_value,
if (!obj)
return;
- obj->GetFloatAttributeInGValue(ui::AX_ATTR_VALUE_FOR_RANGE, value);
+ obj->GetFloatAttributeInGValue(ax::mojom::FloatAttribute::kValueForRange,
+ value);
}
static void ax_platform_node_auralinux_get_minimum_value(AtkValue* atk_value,
@@ -514,7 +517,8 @@ static void ax_platform_node_auralinux_get_minimum_value(AtkValue* atk_value,
if (!obj)
return;
- obj->GetFloatAttributeInGValue(ui::AX_ATTR_MIN_VALUE_FOR_RANGE, value);
+ obj->GetFloatAttributeInGValue(ax::mojom::FloatAttribute::kMinValueForRange,
+ value);
}
static void ax_platform_node_auralinux_get_maximum_value(AtkValue* atk_value,
@@ -527,7 +531,8 @@ static void ax_platform_node_auralinux_get_maximum_value(AtkValue* atk_value,
if (!obj)
return;
- obj->GetFloatAttributeInGValue(ui::AX_ATTR_MAX_VALUE_FOR_RANGE, value);
+ obj->GetFloatAttributeInGValue(ax::mojom::FloatAttribute::kMaxValueForRange,
+ value);
}
static void ax_platform_node_auralinux_get_minimum_increment(
@@ -541,7 +546,8 @@ static void ax_platform_node_auralinux_get_minimum_increment(
if (!obj)
return;
- obj->GetFloatAttributeInGValue(ui::AX_ATTR_STEP_VALUE_FOR_RANGE, value);
+ obj->GetFloatAttributeInGValue(ax::mojom::FloatAttribute::kStepValueForRange,
+ value);
}
static void ax_value_interface_base_init(AtkValueIface* iface) {
@@ -810,13 +816,13 @@ void AXPlatformNodeAuraLinux::StaticInitialize() {
AtkRole AXPlatformNodeAuraLinux::GetAtkRole() {
switch (GetData().role) {
- case ui::AX_ROLE_ALERT:
+ case ax::mojom::Role::kAlert:
return ATK_ROLE_ALERT;
- case ui::AX_ROLE_ALERT_DIALOG:
+ case ax::mojom::Role::kAlertDialog:
return ATK_ROLE_ALERT;
- case ui::AX_ROLE_APPLICATION:
+ case ax::mojom::Role::kApplication:
return ATK_ROLE_APPLICATION;
- case ui::AX_ROLE_AUDIO:
+ case ax::mojom::Role::kAudio:
#if defined(ATK_CHECK_VERSION)
#if ATK_CHECK_VERSION(2, 12, 0)
return ATK_ROLE_AUDIO;
@@ -826,53 +832,62 @@ AtkRole AXPlatformNodeAuraLinux::GetAtkRole() {
#else
return ATK_ROLE_SECTION;
#endif
- case ui::AX_ROLE_BUTTON:
+ case ax::mojom::Role::kButton:
return ATK_ROLE_PUSH_BUTTON;
- case ui::AX_ROLE_CANVAS:
+ case ax::mojom::Role::kCanvas:
return ATK_ROLE_CANVAS;
- case ui::AX_ROLE_CAPTION:
+ case ax::mojom::Role::kCaption:
return ATK_ROLE_CAPTION;
- case ui::AX_ROLE_CHECK_BOX:
+ case ax::mojom::Role::kCheckBox:
return ATK_ROLE_CHECK_BOX;
- case ui::AX_ROLE_COLOR_WELL:
+ case ax::mojom::Role::kColorWell:
return ATK_ROLE_COLOR_CHOOSER;
- case ui::AX_ROLE_COLUMN_HEADER:
+ case ax::mojom::Role::kColumnHeader:
return ATK_ROLE_COLUMN_HEADER;
- case ui::AX_ROLE_COMBO_BOX_GROUPING:
+ case ax::mojom::Role::kComboBoxGrouping:
return ATK_ROLE_COMBO_BOX;
- case ui::AX_ROLE_COMBO_BOX_MENU_BUTTON:
+ case ax::mojom::Role::kComboBoxMenuButton:
return ATK_ROLE_COMBO_BOX;
- case ui::AX_ROLE_DATE:
+ case ax::mojom::Role::kDate:
return ATK_ROLE_DATE_EDITOR;
- case ui::AX_ROLE_DATE_TIME:
+ case ax::mojom::Role::kDateTime:
return ATK_ROLE_DATE_EDITOR;
- case ui::AX_ROLE_DIALOG:
+ case ax::mojom::Role::kDialog:
return ATK_ROLE_DIALOG;
- case ui::AX_ROLE_DOCUMENT:
+ case ax::mojom::Role::kDocument:
return ATK_ROLE_DOCUMENT_WEB;
- case ui::AX_ROLE_FORM:
+ case ax::mojom::Role::kForm:
return ATK_ROLE_FORM;
- case ui::AX_ROLE_GENERIC_CONTAINER:
+ case ax::mojom::Role::kGenericContainer:
return ATK_ROLE_PANEL;
- case ui::AX_ROLE_GROUP:
+ case ax::mojom::Role::kGroup:
return ATK_ROLE_PANEL;
- case ui::AX_ROLE_IGNORED:
+ case ax::mojom::Role::kIgnored:
return ATK_ROLE_REDUNDANT_OBJECT;
- case ui::AX_ROLE_IMAGE:
+ case ax::mojom::Role::kImage:
return ATK_ROLE_IMAGE;
- case ui::AX_ROLE_IMAGE_MAP:
+ case ax::mojom::Role::kImageMap:
return ATK_ROLE_IMAGE_MAP;
- case ui::AX_ROLE_LABEL_TEXT:
+ case ax::mojom::Role::kLabelText:
return ATK_ROLE_LABEL;
- case ui::AX_ROLE_LINK:
+ // Layout table objects are treated the same as Role::kGenericContainer.
+ case ax::mojom::Role::kLayoutTable:
+ return ATK_ROLE_PANEL;
+ case ax::mojom::Role::kLayoutTableCell:
+ return ATK_ROLE_PANEL;
+ case ax::mojom::Role::kLayoutTableColumn:
+ return ATK_ROLE_PANEL;
+ case ax::mojom::Role::kLayoutTableRow:
+ return ATK_ROLE_PANEL;
+ case ax::mojom::Role::kLink:
return ATK_ROLE_LINK;
- case ui::AX_ROLE_LIST:
+ case ax::mojom::Role::kList:
return ATK_ROLE_LIST;
- case ui::AX_ROLE_LIST_BOX:
+ case ax::mojom::Role::kListBox:
return ATK_ROLE_LIST_BOX;
- case ui::AX_ROLE_LIST_ITEM:
+ case ax::mojom::Role::kListItem:
return ATK_ROLE_LIST_ITEM;
- case ui::AX_ROLE_MATH:
+ case ax::mojom::Role::kMath:
#if defined(ATK_CHECK_VERSION)
#if ATK_CHECK_VERSION(2, 12, 0)
return ATK_ROLE_MATH;
@@ -882,61 +897,61 @@ AtkRole AXPlatformNodeAuraLinux::GetAtkRole() {
#else
return ATK_ROLE_TEXT;
#endif
- case ui::AX_ROLE_MENU:
+ case ax::mojom::Role::kMenu:
return ATK_ROLE_MENU;
- case ui::AX_ROLE_MENU_BAR:
+ case ax::mojom::Role::kMenuBar:
return ATK_ROLE_MENU_BAR;
- case ui::AX_ROLE_MENU_ITEM:
+ case ax::mojom::Role::kMenuItem:
return ATK_ROLE_MENU_ITEM;
- case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
+ case ax::mojom::Role::kMenuItemCheckBox:
return ATK_ROLE_CHECK_MENU_ITEM;
- case ui::AX_ROLE_MENU_ITEM_RADIO:
+ case ax::mojom::Role::kMenuItemRadio:
return ATK_ROLE_RADIO_MENU_ITEM;
- case ui::AX_ROLE_METER:
+ case ax::mojom::Role::kMeter:
return ATK_ROLE_PROGRESS_BAR;
- case ui::AX_ROLE_PARAGRAPH:
+ case ax::mojom::Role::kParagraph:
return ATK_ROLE_PARAGRAPH;
- case ui::AX_ROLE_RADIO_BUTTON:
+ case ax::mojom::Role::kRadioButton:
return ATK_ROLE_RADIO_BUTTON;
- case ui::AX_ROLE_ROW_HEADER:
+ case ax::mojom::Role::kRowHeader:
return ATK_ROLE_ROW_HEADER;
- case ui::AX_ROLE_ROOT_WEB_AREA:
+ case ax::mojom::Role::kRootWebArea:
return ATK_ROLE_DOCUMENT_WEB;
- case ui::AX_ROLE_SCROLL_BAR:
+ case ax::mojom::Role::kScrollBar:
return ATK_ROLE_SCROLL_BAR;
- case ui::AX_ROLE_SLIDER:
+ case ax::mojom::Role::kSlider:
return ATK_ROLE_SLIDER;
- case ui::AX_ROLE_SPIN_BUTTON:
+ case ax::mojom::Role::kSpinButton:
return ATK_ROLE_SPIN_BUTTON;
- case ui::AX_ROLE_SPLITTER:
+ case ax::mojom::Role::kSplitter:
return ATK_ROLE_SEPARATOR;
- case ui::AX_ROLE_STATIC_TEXT:
+ case ax::mojom::Role::kStaticText:
return ATK_ROLE_TEXT;
- case ui::AX_ROLE_STATUS:
+ case ax::mojom::Role::kStatus:
return ATK_ROLE_STATUSBAR;
- case ui::AX_ROLE_TAB:
+ case ax::mojom::Role::kTab:
return ATK_ROLE_PAGE_TAB;
- case ui::AX_ROLE_TABLE:
+ case ax::mojom::Role::kTable:
return ATK_ROLE_TABLE;
- case ui::AX_ROLE_TAB_LIST:
+ case ax::mojom::Role::kTabList:
return ATK_ROLE_PAGE_TAB_LIST;
- case ui::AX_ROLE_TEXT_FIELD:
+ case ax::mojom::Role::kTextField:
return ATK_ROLE_ENTRY;
- case ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX:
+ case ax::mojom::Role::kTextFieldWithComboBox:
return ATK_ROLE_COMBO_BOX;
- case ui::AX_ROLE_TOGGLE_BUTTON:
+ case ax::mojom::Role::kToggleButton:
return ATK_ROLE_TOGGLE_BUTTON;
- case ui::AX_ROLE_TOOLBAR:
+ case ax::mojom::Role::kToolbar:
return ATK_ROLE_TOOL_BAR;
- case ui::AX_ROLE_TOOLTIP:
+ case ax::mojom::Role::kTooltip:
return ATK_ROLE_TOOL_TIP;
- case ui::AX_ROLE_TREE:
+ case ax::mojom::Role::kTree:
return ATK_ROLE_TREE;
- case ui::AX_ROLE_TREE_ITEM:
+ case ax::mojom::Role::kTreeItem:
return ATK_ROLE_TREE_ITEM;
- case ui::AX_ROLE_TREE_GRID:
+ case ax::mojom::Role::kTreeGrid:
return ATK_ROLE_TREE_TABLE;
- case ui::AX_ROLE_VIDEO:
+ case ax::mojom::Role::kVideo:
#if defined(ATK_CHECK_VERSION)
#if ATK_CHECK_VERSION(2, 12, 0)
return ATK_ROLE_VIDEO;
@@ -946,9 +961,9 @@ AtkRole AXPlatformNodeAuraLinux::GetAtkRole() {
#else
return ATK_ROLE_SECTION;
#endif
- case ui::AX_ROLE_WEB_AREA:
+ case ax::mojom::Role::kWebArea:
return ATK_ROLE_DOCUMENT_WEB;
- case ui::AX_ROLE_WINDOW:
+ case ax::mojom::Role::kWindow:
return ATK_ROLE_WINDOW;
default:
return ATK_ROLE_UNKNOWN;
@@ -957,35 +972,34 @@ AtkRole AXPlatformNodeAuraLinux::GetAtkRole() {
void AXPlatformNodeAuraLinux::GetAtkState(AtkStateSet* atk_state_set) {
AXNodeData data = GetData();
- if (data.HasState(ui::AX_STATE_DEFAULT))
+ if (data.HasState(ax::mojom::State::kDefault))
atk_state_set_add_state(atk_state_set, ATK_STATE_DEFAULT);
- if (data.HasState(ui::AX_STATE_EDITABLE))
+ if (data.HasState(ax::mojom::State::kEditable))
atk_state_set_add_state(atk_state_set, ATK_STATE_EDITABLE);
- if (data.HasState(ui::AX_STATE_EXPANDED))
+ if (data.HasState(ax::mojom::State::kExpanded))
atk_state_set_add_state(atk_state_set, ATK_STATE_EXPANDED);
- if (data.HasState(ui::AX_STATE_FOCUSABLE))
+ if (data.HasState(ax::mojom::State::kFocusable))
atk_state_set_add_state(atk_state_set, ATK_STATE_FOCUSABLE);
#if defined(ATK_CHECK_VERSION)
#if ATK_CHECK_VERSION(2, 11, 2)
- if (data.HasState(ui::AX_STATE_HASPOPUP))
+ if (data.HasState(ax::mojom::State::kHaspopup))
atk_state_set_add_state(atk_state_set, ATK_STATE_HAS_POPUP);
#endif
#endif
- if (data.HasState(ui::AX_STATE_SELECTED))
+ if (data.HasState(ax::mojom::State::kSelected))
atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTED);
- if (data.HasState(ui::AX_STATE_SELECTABLE))
+ if (data.HasState(ax::mojom::State::kSelectable))
atk_state_set_add_state(atk_state_set, ATK_STATE_SELECTABLE);
// Checked state
- const auto checked_state = static_cast<ui::AXCheckedState>(
- GetIntAttribute(ui::AX_ATTR_CHECKED_STATE));
+ const auto checked_state = GetData().GetCheckedState();
switch (checked_state) {
- case ui::AX_CHECKED_STATE_MIXED:
+ case ax::mojom::CheckedState::kMixed:
atk_state_set_add_state(atk_state_set, ATK_STATE_INDETERMINATE);
break;
- case ui::AX_CHECKED_STATE_TRUE:
+ case ax::mojom::CheckedState::kTrue:
atk_state_set_add_state(atk_state_set,
- data.role == ui::AX_ROLE_TOGGLE_BUTTON
+ data.role == ax::mojom::Role::kToggleButton
? ATK_STATE_PRESSED
: ATK_STATE_CHECKED);
break;
@@ -993,17 +1007,19 @@ void AXPlatformNodeAuraLinux::GetAtkState(AtkStateSet* atk_state_set) {
break;
}
- switch (GetIntAttribute(ui::AX_ATTR_RESTRICTION)) {
- case ui::AX_RESTRICTION_NONE:
+ switch (GetData().GetRestriction()) {
+ case ax::mojom::Restriction::kNone:
atk_state_set_add_state(atk_state_set, ATK_STATE_ENABLED);
break;
- case ui::AX_RESTRICTION_READ_ONLY:
+ case ax::mojom::Restriction::kReadOnly:
#if defined(ATK_CHECK_VERSION)
#if ATK_CHECK_VERSION(2, 16, 0)
atk_state_set_add_state(atk_state_set, ATK_STATE_READ_ONLY);
#endif
#endif
break;
+ default:
+ break;
}
if (delegate_->GetFocus() == GetNativeViewAccessible())
@@ -1093,9 +1109,10 @@ void AXPlatformNodeAuraLinux::OnFocused() {
true);
}
-void AXPlatformNodeAuraLinux::NotifyAccessibilityEvent(ui::AXEvent event_type) {
+void AXPlatformNodeAuraLinux::NotifyAccessibilityEvent(
+ ax::mojom::Event event_type) {
switch (event_type) {
- case AX_EVENT_FOCUS:
+ case ax::mojom::Event::kFocus:
OnFocused();
break;
default:
@@ -1112,7 +1129,7 @@ int AXPlatformNodeAuraLinux::GetIndexInParent() {
void AXPlatformNodeAuraLinux::SetExtentsRelativeToAtkCoordinateType(
gint* x, gint* y, gint* width, gint* height, AtkCoordType coord_type) {
- gfx::Rect extents = GetBoundsInScreen();
+ gfx::Rect extents = delegate_->GetUnclippedScreenBoundsRect();
if (x)
*x = extents.x();
@@ -1172,23 +1189,23 @@ AXPlatformNodeAuraLinux::HitTestSync(gint x, gint y, AtkCoordType coord_type) {
bool AXPlatformNodeAuraLinux::GrabFocus() {
AXActionData action_data;
- action_data.action = AX_ACTION_FOCUS;
+ action_data.action = ax::mojom::Action::kFocus;
return delegate_->AccessibilityPerformAction(action_data);
}
bool AXPlatformNodeAuraLinux::DoDefaultAction() {
AXActionData action_data;
- action_data.action = AX_ACTION_DO_DEFAULT;
+ action_data.action = ax::mojom::Action::kDoDefault;
return delegate_->AccessibilityPerformAction(action_data);
}
const gchar* AXPlatformNodeAuraLinux::GetDefaultActionName() {
int action;
- if (!GetIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB, &action))
+ if (!GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb, &action))
return nullptr;
base::string16 action_verb = ui::ActionVerbToUnlocalizedString(
- static_cast<ui::AXDefaultActionVerb>(action));
+ static_cast<ax::mojom::DefaultActionVerb>(action));
ATK_AURALINUX_RETURN_STRING(base::UTF16ToUTF8(action_verb));
}
@@ -1250,8 +1267,9 @@ AtkHyperlink* AXPlatformNodeAuraLinux::GetAtkHyperlink() {
// Misc helpers
//
-void AXPlatformNodeAuraLinux::GetFloatAttributeInGValue(AXFloatAttribute attr,
- GValue* value) {
+void AXPlatformNodeAuraLinux::GetFloatAttributeInGValue(
+ ax::mojom::FloatAttribute attr,
+ GValue* value) {
float float_val;
if (GetFloatAttribute(attr, &float_val)) {
memset(value, 0, sizeof(*value));
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_auralinux.h b/chromium/ui/accessibility/platform/ax_platform_node_auralinux.h
index 6eaa14ab84f..e0c31e92000 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_auralinux.h
+++ b/chromium/ui/accessibility/platform/ax_platform_node_auralinux.h
@@ -70,14 +70,14 @@ class AXPlatformNodeAuraLinux : public AXPlatformNodeBase {
AtkHyperlink* GetAtkHyperlink();
// Misc helpers
- void GetFloatAttributeInGValue(AXFloatAttribute attr, GValue* value);
+ void GetFloatAttributeInGValue(ax::mojom::FloatAttribute attr, GValue* value);
// Event helpers
void OnFocused();
// AXPlatformNode overrides.
gfx::NativeViewAccessible GetNativeViewAccessible() override;
- void NotifyAccessibilityEvent(ui::AXEvent event_type) override;
+ void NotifyAccessibilityEvent(ax::mojom::Event event_type) override;
// AXPlatformNodeBase overrides.
void Init(AXPlatformNodeDelegate* delegate) override;
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc b/chromium/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
index e20de0f8cdd..b9714a2b866 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
+++ b/chromium/ui/accessibility/platform/ax_platform_node_auralinux_unittest.cc
@@ -87,7 +87,8 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectName) {
TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectDescription) {
AXNodeData root;
root.id = 1;
- root.AddStringAttribute(AX_ATTR_DESCRIPTION, "Description");
+ root.AddStringAttribute(ax::mojom::StringAttribute::kDescription,
+ "Description");
Init(root);
AtkObject* root_obj(GetRootAtkObject());
@@ -111,7 +112,7 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectRole) {
Init(root, child);
AXNode* child_node = GetRootNode()->children()[0];
- child.role = AX_ROLE_ALERT;
+ child.role = ax::mojom::Role::kAlert;
child_node->SetData(child);
AtkObject* child_obj(AtkObjectFromNode(child_node));
ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
@@ -119,7 +120,7 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectRole) {
EXPECT_EQ(ATK_ROLE_ALERT, atk_object_get_role(child_obj));
g_object_unref(child_obj);
- child.role = AX_ROLE_BUTTON;
+ child.role = ax::mojom::Role::kButton;
child_node->SetData(child);
child_obj = AtkObjectFromNode(child_node);
ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
@@ -127,7 +128,7 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectRole) {
EXPECT_EQ(ATK_ROLE_PUSH_BUTTON, atk_object_get_role(child_obj));
g_object_unref(child_obj);
- child.role = AX_ROLE_CANVAS;
+ child.role = ax::mojom::Role::kCanvas;
child_node->SetData(child);
child_obj = AtkObjectFromNode(child_node);
ASSERT_TRUE(ATK_IS_OBJECT(child_obj));
@@ -139,8 +140,8 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectRole) {
TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectState) {
AXNodeData root;
root.id = 1;
- root.AddState(AX_STATE_DEFAULT);
- root.AddState(AX_STATE_EXPANDED);
+ root.AddState(ax::mojom::State::kDefault);
+ root.AddState(ax::mojom::State::kExpanded);
Init(root);
@@ -165,11 +166,11 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkObjectChildAndParent) {
root.child_ids.push_back(3);
AXNodeData button;
- button.role = AX_ROLE_BUTTON;
+ button.role = ax::mojom::Role::kButton;
button.id = 2;
AXNodeData checkbox;
- checkbox.role = AX_ROLE_CHECK_BOX;
+ checkbox.role = ax::mojom::Role::kCheckBox;
checkbox.id = 3;
Init(root, button, checkbox);
@@ -291,7 +292,7 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkComponentRefAtPoint) {
TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkComponentsGetExtentsPositionSize) {
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_WINDOW;
+ root.role = ax::mojom::Role::kWindow;
root.location = gfx::RectF(10, 40, 800, 600);
root.child_ids.push_back(2);
@@ -380,8 +381,8 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkComponentsGetExtentsPositionSize) {
TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetCurrentValue) {
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_SLIDER;
- root.AddFloatAttribute(AX_ATTR_VALUE_FOR_RANGE, 5.0);
+ root.role = ax::mojom::Role::kSlider;
+ root.AddFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, 5.0);
Init(root);
AtkObject* root_obj(GetRootAtkObject());
@@ -402,8 +403,8 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetCurrentValue) {
TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMaximumValue) {
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_SLIDER;
- root.AddFloatAttribute(AX_ATTR_MAX_VALUE_FOR_RANGE, 5.0);
+ root.role = ax::mojom::Role::kSlider;
+ root.AddFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, 5.0);
Init(root);
AtkObject* root_obj(GetRootAtkObject());
@@ -424,8 +425,8 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMaximumValue) {
TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumValue) {
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_SLIDER;
- root.AddFloatAttribute(AX_ATTR_MIN_VALUE_FOR_RANGE, 5.0);
+ root.role = ax::mojom::Role::kSlider;
+ root.AddFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange, 5.0);
Init(root);
AtkObject* root_obj(GetRootAtkObject());
@@ -446,8 +447,8 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumValue) {
TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumIncrement) {
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_SLIDER;
- root.AddFloatAttribute(AX_ATTR_STEP_VALUE_FOR_RANGE, 5.0);
+ root.role = ax::mojom::Role::kSlider;
+ root.AddFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange, 5.0);
Init(root);
AtkObject* root_obj(GetRootAtkObject());
@@ -472,8 +473,8 @@ TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkValueGetMinimumIncrement) {
TEST_F(AXPlatformNodeAuraLinuxTest, TestAtkHyperlink) {
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_LINK;
- root.AddStringAttribute(AX_ATTR_URL, "http://foo.com");
+ root.role = ax::mojom::Role::kLink;
+ root.AddStringAttribute(ax::mojom::StringAttribute::kUrl, "http://foo.com");
Init(root);
AtkObject* root_obj(GetRootAtkObject());
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_base.cc b/chromium/ui/accessibility/platform/ax_platform_node_base.cc
index 97afb682632..613ade4d498 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_base.cc
+++ b/chromium/ui/accessibility/platform/ax_platform_node_base.cc
@@ -26,12 +26,6 @@ const AXNodeData& AXPlatformNodeBase::GetData() const {
return empty_data;
}
-gfx::Rect AXPlatformNodeBase::GetBoundsInScreen() const {
- if (delegate_)
- return delegate_->GetScreenBoundsRect();
- return gfx::Rect();
-}
-
gfx::NativeViewAccessible AXPlatformNodeBase::GetParent() {
if (delegate_)
return delegate_->GetParent();
@@ -116,107 +110,116 @@ bool AXPlatformNodeBase::IsDescendant(AXPlatformNodeBase* node) {
return IsDescendant(parent);
}
-bool AXPlatformNodeBase::HasBoolAttribute(AXBoolAttribute attribute) const {
+bool AXPlatformNodeBase::HasBoolAttribute(
+ ax::mojom::BoolAttribute attribute) const {
if (!delegate_)
return false;
return GetData().HasBoolAttribute(attribute);
}
-bool AXPlatformNodeBase::GetBoolAttribute(AXBoolAttribute attribute) const {
+bool AXPlatformNodeBase::GetBoolAttribute(
+ ax::mojom::BoolAttribute attribute) const {
if (!delegate_)
return false;
return GetData().GetBoolAttribute(attribute);
}
-bool AXPlatformNodeBase::GetBoolAttribute(AXBoolAttribute attribute,
+bool AXPlatformNodeBase::GetBoolAttribute(ax::mojom::BoolAttribute attribute,
bool* value) const {
if (!delegate_)
return false;
return GetData().GetBoolAttribute(attribute, value);
}
-bool AXPlatformNodeBase::HasFloatAttribute(AXFloatAttribute attribute) const {
+bool AXPlatformNodeBase::HasFloatAttribute(
+ ax::mojom::FloatAttribute attribute) const {
if (!delegate_)
return false;
return GetData().HasFloatAttribute(attribute);
}
-float AXPlatformNodeBase::GetFloatAttribute(AXFloatAttribute attribute) const {
+float AXPlatformNodeBase::GetFloatAttribute(
+ ax::mojom::FloatAttribute attribute) const {
if (!delegate_)
return false;
return GetData().GetFloatAttribute(attribute);
}
-bool AXPlatformNodeBase::GetFloatAttribute(AXFloatAttribute attribute,
+bool AXPlatformNodeBase::GetFloatAttribute(ax::mojom::FloatAttribute attribute,
float* value) const {
if (!delegate_)
return false;
return GetData().GetFloatAttribute(attribute, value);
}
-bool AXPlatformNodeBase::HasIntAttribute(AXIntAttribute attribute) const {
+bool AXPlatformNodeBase::HasIntAttribute(
+ ax::mojom::IntAttribute attribute) const {
if (!delegate_)
return false;
return GetData().HasIntAttribute(attribute);
}
-int AXPlatformNodeBase::GetIntAttribute(AXIntAttribute attribute) const {
+int AXPlatformNodeBase::GetIntAttribute(
+ ax::mojom::IntAttribute attribute) const {
if (!delegate_)
return false;
return GetData().GetIntAttribute(attribute);
}
-bool AXPlatformNodeBase::GetIntAttribute(AXIntAttribute attribute,
+bool AXPlatformNodeBase::GetIntAttribute(ax::mojom::IntAttribute attribute,
int* value) const {
if (!delegate_)
return false;
return GetData().GetIntAttribute(attribute, value);
}
-bool AXPlatformNodeBase::HasStringAttribute(AXStringAttribute attribute) const {
+bool AXPlatformNodeBase::HasStringAttribute(
+ ax::mojom::StringAttribute attribute) const {
if (!delegate_)
return false;
return GetData().HasStringAttribute(attribute);
}
const std::string& AXPlatformNodeBase::GetStringAttribute(
- AXStringAttribute attribute) const {
+ ax::mojom::StringAttribute attribute) const {
CR_DEFINE_STATIC_LOCAL(std::string, empty_data, ());
if (!delegate_)
return empty_data;
return GetData().GetStringAttribute(attribute);
}
-bool AXPlatformNodeBase::GetStringAttribute(AXStringAttribute attribute,
- std::string* value) const {
+bool AXPlatformNodeBase::GetStringAttribute(
+ ax::mojom::StringAttribute attribute,
+ std::string* value) const {
if (!delegate_)
return false;
return GetData().GetStringAttribute(attribute, value);
}
base::string16 AXPlatformNodeBase::GetString16Attribute(
- AXStringAttribute attribute) const {
+ ax::mojom::StringAttribute attribute) const {
if (!delegate_)
return base::string16();
return GetData().GetString16Attribute(attribute);
}
-bool AXPlatformNodeBase::GetString16Attribute(AXStringAttribute attribute,
- base::string16* value) const {
+bool AXPlatformNodeBase::GetString16Attribute(
+ ax::mojom::StringAttribute attribute,
+ base::string16* value) const {
if (!delegate_)
return false;
return GetData().GetString16Attribute(attribute, value);
}
bool AXPlatformNodeBase::HasIntListAttribute(
- AXIntListAttribute attribute) const {
+ ax::mojom::IntListAttribute attribute) const {
if (!delegate_)
return false;
return GetData().HasIntListAttribute(attribute);
}
const std::vector<int32_t>& AXPlatformNodeBase::GetIntListAttribute(
- AXIntListAttribute attribute) const {
+ ax::mojom::IntListAttribute attribute) const {
CR_DEFINE_STATIC_LOCAL(std::vector<int32_t>, empty_data, ());
if (!delegate_)
return empty_data;
@@ -224,7 +227,7 @@ const std::vector<int32_t>& AXPlatformNodeBase::GetIntListAttribute(
}
bool AXPlatformNodeBase::GetIntListAttribute(
- AXIntListAttribute attribute,
+ ax::mojom::IntListAttribute attribute,
std::vector<int32_t>* value) const {
if (!delegate_)
return false;
@@ -246,7 +249,7 @@ AXPlatformNodeBase* AXPlatformNodeBase::FromNativeViewAccessible(
bool AXPlatformNodeBase::SetTextSelection(int start_offset, int end_offset) {
AXActionData action_data;
- action_data.action = AX_ACTION_SET_SELECTION;
+ action_data.action = ax::mojom::Action::kSetSelection;
action_data.anchor_node_id = action_data.focus_node_id = GetData().id;
action_data.anchor_offset = start_offset;
action_data.focus_offset = end_offset;
@@ -257,30 +260,30 @@ bool AXPlatformNodeBase::SetTextSelection(int start_offset, int end_offset) {
}
bool AXPlatformNodeBase::IsTextOnlyObject() const {
- return GetData().role == AX_ROLE_STATIC_TEXT ||
- GetData().role == AX_ROLE_LINE_BREAK ||
- GetData().role == AX_ROLE_INLINE_TEXT_BOX;
+ return GetData().role == ax::mojom::Role::kStaticText ||
+ GetData().role == ax::mojom::Role::kLineBreak ||
+ GetData().role == ax::mojom::Role::kInlineTextBox;
}
bool AXPlatformNodeBase::IsPlainTextField() const {
// We need to check both the role and editable state, because some ARIA text
// fields may in fact not be editable, whilst some editable fields might not
// have the role.
- return !GetData().HasState(AX_STATE_RICHLY_EDITABLE) &&
- (GetData().role == AX_ROLE_TEXT_FIELD ||
- GetData().role == AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX ||
- GetData().role == AX_ROLE_SEARCH_BOX ||
- GetBoolAttribute(AX_ATTR_EDITABLE_ROOT));
+ return !GetData().HasState(ax::mojom::State::kRichlyEditable) &&
+ (GetData().role == ax::mojom::Role::kTextField ||
+ GetData().role == ax::mojom::Role::kTextFieldWithComboBox ||
+ GetData().role == ax::mojom::Role::kSearchBox ||
+ GetBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot));
}
bool AXPlatformNodeBase::IsRichTextField() const {
- return GetBoolAttribute(AX_ATTR_EDITABLE_ROOT) &&
- GetData().HasState(AX_STATE_RICHLY_EDITABLE);
+ return GetBoolAttribute(ax::mojom::BoolAttribute::kEditableRoot) &&
+ GetData().HasState(ax::mojom::State::kRichlyEditable);
}
base::string16 AXPlatformNodeBase::GetInnerText() {
if (IsTextOnlyObject())
- return GetString16Attribute(AX_ATTR_NAME);
+ return GetString16Attribute(ax::mojom::StringAttribute::kName);
base::string16 text;
for (int i = 0; i < GetChildCount(); ++i) {
@@ -296,14 +299,14 @@ base::string16 AXPlatformNodeBase::GetInnerText() {
bool AXPlatformNodeBase::IsRangeValueSupported() const {
switch (GetData().role) {
- case AX_ROLE_METER:
- case AX_ROLE_PROGRESS_INDICATOR:
- case AX_ROLE_SLIDER:
- case AX_ROLE_SPIN_BUTTON:
- case AX_ROLE_SCROLL_BAR:
+ case ax::mojom::Role::kMeter:
+ case ax::mojom::Role::kProgressIndicator:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSpinButton:
+ case ax::mojom::Role::kScrollBar:
return true;
- case AX_ROLE_SPLITTER:
- return GetData().HasState(AX_STATE_FOCUSABLE);
+ case ax::mojom::Role::kSplitter:
+ return GetData().HasState(ax::mojom::State::kFocusable);
default:
return false;
}
@@ -311,9 +314,11 @@ bool AXPlatformNodeBase::IsRangeValueSupported() const {
base::string16 AXPlatformNodeBase::GetRangeValueText() {
float fval;
- base::string16 value = GetString16Attribute(AX_ATTR_VALUE);
+ base::string16 value =
+ GetString16Attribute(ax::mojom::StringAttribute::kValue);
- if (value.empty() && GetFloatAttribute(AX_ATTR_VALUE_FOR_RANGE, &fval)) {
+ if (value.empty() &&
+ GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, &fval)) {
value = base::NumberToString16(fval);
}
return value;
@@ -343,7 +348,7 @@ AXPlatformNodeBase* AXPlatformNodeBase::GetTableCell(int index) const {
if (!table)
return nullptr;
const std::vector<int32_t>& unique_cell_ids =
- table->GetIntListAttribute(AX_ATTR_UNIQUE_CELL_IDS);
+ table->GetIntListAttribute(ax::mojom::IntListAttribute::kUniqueCellIds);
if (index < 0 || index >= static_cast<int>(unique_cell_ids.size()))
return nullptr;
@@ -369,7 +374,7 @@ AXPlatformNodeBase* AXPlatformNodeBase::GetTableCell(int row,
// In contrast to unique cell IDs, these are duplicated whenever a cell spans
// multiple columns or rows.
const std::vector<int32_t>& cell_ids =
- table->GetIntListAttribute(AX_ATTR_CELL_IDS);
+ table->GetIntListAttribute(ax::mojom::IntListAttribute::kCellIds);
DCHECK_EQ(GetTableRowCount() * GetTableColumnCount(),
static_cast<int>(cell_ids.size()));
int position = row * GetTableColumnCount() + column;
@@ -389,7 +394,7 @@ int AXPlatformNodeBase::GetTableCellIndex() const {
return -1;
const std::vector<int32_t>& unique_cell_ids =
- table->GetIntListAttribute(AX_ATTR_UNIQUE_CELL_IDS);
+ table->GetIntListAttribute(ax::mojom::IntListAttribute::kUniqueCellIds);
auto iter =
std::find(unique_cell_ids.begin(), unique_cell_ids.end(), GetData().id);
if (iter == unique_cell_ids.end())
@@ -399,7 +404,7 @@ int AXPlatformNodeBase::GetTableCellIndex() const {
}
int AXPlatformNodeBase::GetTableColumn() const {
- return GetIntAttribute(AX_ATTR_TABLE_CELL_COLUMN_INDEX);
+ return GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex);
}
int AXPlatformNodeBase::GetTableColumnCount() const {
@@ -407,7 +412,7 @@ int AXPlatformNodeBase::GetTableColumnCount() const {
if (!table)
return 0;
- return table->GetIntAttribute(AX_ATTR_TABLE_COLUMN_COUNT);
+ return table->GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount);
}
int AXPlatformNodeBase::GetTableColumnSpan() const {
@@ -415,13 +420,14 @@ int AXPlatformNodeBase::GetTableColumnSpan() const {
return 0;
int column_span;
- if (GetIntAttribute(AX_ATTR_TABLE_CELL_COLUMN_SPAN, &column_span))
+ if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnSpan,
+ &column_span))
return column_span;
return 1;
}
int AXPlatformNodeBase::GetTableRow() const {
- return GetIntAttribute(AX_ATTR_TABLE_CELL_ROW_INDEX);
+ return GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex);
}
int AXPlatformNodeBase::GetTableRowCount() const {
@@ -429,7 +435,7 @@ int AXPlatformNodeBase::GetTableRowCount() const {
if (!table)
return 0;
- return table->GetIntAttribute(AX_ATTR_TABLE_ROW_COUNT);
+ return table->GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount);
}
int AXPlatformNodeBase::GetTableRowSpan() const {
@@ -437,14 +443,15 @@ int AXPlatformNodeBase::GetTableRowSpan() const {
return 0;
int row_span;
- if (GetIntAttribute(AX_ATTR_TABLE_CELL_ROW_SPAN, &row_span))
+ if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowSpan, &row_span))
return row_span;
return 1;
}
bool AXPlatformNodeBase::HasCaret() {
- if (IsPlainTextField() && HasIntAttribute(ui::AX_ATTR_TEXT_SEL_START) &&
- HasIntAttribute(ui::AX_ATTR_TEXT_SEL_END)) {
+ if (IsPlainTextField() &&
+ HasIntAttribute(ax::mojom::IntAttribute::kTextSelStart) &&
+ HasIntAttribute(ax::mojom::IntAttribute::kTextSelEnd)) {
return true;
}
@@ -489,12 +496,12 @@ bool AXPlatformNodeBase::IsLeaf() {
// (Note that whilst ARIA buttons can have only presentational children, HTML5
// buttons are allowed to have content.)
switch (GetData().role) {
- case ui::AX_ROLE_IMAGE:
- case ui::AX_ROLE_METER:
- case ui::AX_ROLE_SCROLL_BAR:
- case ui::AX_ROLE_SLIDER:
- case ui::AX_ROLE_SPLITTER:
- case ui::AX_ROLE_PROGRESS_INDICATOR:
+ case ax::mojom::Role::kImage:
+ case ax::mojom::Role::kMeter:
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kProgressIndicator:
return true;
default:
return false;
@@ -525,7 +532,8 @@ base::string16 AXPlatformNodeBase::GetValue() {
// On Windows, the value of a document should be its URL.
return base::UTF8ToUTF16(delegate_->GetTreeData().url);
}
- base::string16 value = GetString16Attribute(ui::AX_ATTR_VALUE);
+ base::string16 value =
+ GetString16Attribute(ax::mojom::StringAttribute::kValue);
// Some screen readers like Jaws and VoiceOver require a
// value to be set in text fields with rich content, even though the same
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_base.h b/chromium/ui/accessibility/platform/ax_platform_node_base.h
index 7a3a93f7cc5..2525833c6c0 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_base.h
+++ b/chromium/ui/accessibility/platform/ax_platform_node_base.h
@@ -6,7 +6,7 @@
#define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_BASE_H_
#include "base/macros.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/platform/ax_platform_node.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
@@ -22,7 +22,6 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
// These are simple wrappers to our delegate.
const AXNodeData& GetData() const;
- gfx::Rect GetBoundsInScreen() const;
gfx::NativeViewAccessible GetParent();
int GetChildCount();
gfx::NativeViewAccessible ChildAtIndex(int index);
@@ -40,31 +39,33 @@ class AX_EXPORT AXPlatformNodeBase : public AXPlatformNode {
AXPlatformNodeBase* GetNextSibling();
bool IsDescendant(AXPlatformNodeBase* descendant);
- bool HasBoolAttribute(AXBoolAttribute attr) const;
- bool GetBoolAttribute(AXBoolAttribute attr) const;
- bool GetBoolAttribute(AXBoolAttribute attr, bool* value) const;
+ bool HasBoolAttribute(ax::mojom::BoolAttribute attr) const;
+ bool GetBoolAttribute(ax::mojom::BoolAttribute attr) const;
+ bool GetBoolAttribute(ax::mojom::BoolAttribute attr, bool* value) const;
- bool HasFloatAttribute(AXFloatAttribute attr) const;
- float GetFloatAttribute(AXFloatAttribute attr) const;
- bool GetFloatAttribute(AXFloatAttribute attr, float* value) const;
+ bool HasFloatAttribute(ax::mojom::FloatAttribute attr) const;
+ float GetFloatAttribute(ax::mojom::FloatAttribute attr) const;
+ bool GetFloatAttribute(ax::mojom::FloatAttribute attr, float* value) const;
- bool HasIntAttribute(AXIntAttribute attribute) const;
- int GetIntAttribute(AXIntAttribute attribute) const;
- bool GetIntAttribute(AXIntAttribute attribute, int* value) const;
+ bool HasIntAttribute(ax::mojom::IntAttribute attribute) const;
+ int GetIntAttribute(ax::mojom::IntAttribute attribute) const;
+ bool GetIntAttribute(ax::mojom::IntAttribute attribute, int* value) const;
- bool HasStringAttribute(AXStringAttribute attribute) const;
- const std::string& GetStringAttribute(AXStringAttribute attribute) const;
- bool GetStringAttribute(AXStringAttribute attribute,
+ bool HasStringAttribute(ax::mojom::StringAttribute attribute) const;
+ const std::string& GetStringAttribute(
+ ax::mojom::StringAttribute attribute) const;
+ bool GetStringAttribute(ax::mojom::StringAttribute attribute,
std::string* value) const;
- bool GetString16Attribute(AXStringAttribute attribute,
+ bool GetString16Attribute(ax::mojom::StringAttribute attribute,
base::string16* value) const;
- base::string16 GetString16Attribute(AXStringAttribute attribute) const;
+ base::string16 GetString16Attribute(
+ ax::mojom::StringAttribute attribute) const;
- bool HasIntListAttribute(AXIntListAttribute attribute) const;
+ bool HasIntListAttribute(ax::mojom::IntListAttribute attribute) const;
const std::vector<int32_t>& GetIntListAttribute(
- AXIntListAttribute attribute) const;
+ ax::mojom::IntListAttribute attribute) const;
- bool GetIntListAttribute(AXIntListAttribute attribute,
+ bool GetIntListAttribute(ax::mojom::IntListAttribute attribute,
std::vector<int32_t>* value) const;
// Returns the table or ARIA grid if inside one.
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_delegate.h b/chromium/ui/accessibility/platform/ax_platform_node_delegate.h
index 704bc5e9a4c..3b5bc807e65 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_delegate.h
+++ b/chromium/ui/accessibility/platform/ax_platform_node_delegate.h
@@ -7,7 +7,7 @@
#include <set>
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_export.h"
#include "ui/accessibility/platform/ax_unique_id.h"
#include "ui/gfx/geometry/vector2d.h"
@@ -59,8 +59,13 @@ class AX_EXPORT AXPlatformNodeDelegate {
// Get the child of a node given a 0-based index.
virtual gfx::NativeViewAccessible ChildAtIndex(int index) = 0;
- // Get the bounds of this node in screen coordinates.
- virtual gfx::Rect GetScreenBoundsRect() const = 0;
+ // Get the bounds of this node in screen coordinates, applying clipping
+ // to all bounding boxes so that the resulting rect is within the window.
+ virtual gfx::Rect GetClippedScreenBoundsRect() const = 0;
+
+ // Get the bounds of this node in screen coordinates without applying
+ // any clipping; it may be outside of the window or offscreen.
+ virtual gfx::Rect GetUnclippedScreenBoundsRect() const = 0;
// Do a *synchronous* hit test of the given location in global screen
// coordinates, and the node within this node's subtree (inclusive) that's
@@ -87,15 +92,16 @@ class AX_EXPORT AXPlatformNodeDelegate {
// Given a node ID attribute (one where IsNodeIdIntAttribute is true),
// and a destination node ID, return a set of all source node IDs that
// have that relationship attribute between them and the destination.
- virtual std::set<int32_t> GetReverseRelations(AXIntAttribute attr,
+ virtual std::set<int32_t> GetReverseRelations(ax::mojom::IntAttribute attr,
int32_t dst_id) = 0;
// Given a node ID list attribute (one where
// IsNodeIdIntListAttribute is true), and a destination node ID,
// return a set of all source node IDs that have that relationship
// attribute between them and the destination.
- virtual std::set<int32_t> GetReverseRelations(AXIntListAttribute attr,
- int32_t dst_id) = 0;
+ virtual std::set<int32_t> GetReverseRelations(
+ ax::mojom::IntListAttribute attr,
+ int32_t dst_id) = 0;
virtual const AXUniqueId& GetUniqueId() const = 0;
@@ -111,7 +117,7 @@ class AX_EXPORT AXPlatformNodeDelegate {
// Actions.
//
- // Perform an accessibility action, switching on the AXAction
+ // Perform an accessibility action, switching on the ax::mojom::Action
// provided in |data|.
virtual bool AccessibilityPerformAction(const AXActionData& data) = 0;
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_mac.h b/chromium/ui/accessibility/platform/ax_platform_node_mac.h
index 36ee00335e2..0ae797818b0 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_mac.h
+++ b/chromium/ui/accessibility/platform/ax_platform_node_mac.h
@@ -22,7 +22,7 @@ class AXPlatformNodeMac : public AXPlatformNodeBase {
// AXPlatformNode.
gfx::NativeViewAccessible GetNativeViewAccessible() override;
- void NotifyAccessibilityEvent(ui::AXEvent event_type) override;
+ void NotifyAccessibilityEvent(ax::mojom::Event event_type) override;
// AXPlatformNodeBase.
void Destroy() override;
@@ -38,7 +38,7 @@ class AXPlatformNodeMac : public AXPlatformNodeBase {
// Convenience function to determine whether an internal object role should
// expose its accessible name in AXValue (as opposed to AXTitle/AXDescription).
-AX_EXPORT bool IsNameExposedInAXValueForRole(AXRole role);
+AX_EXPORT bool IsNameExposedInAXValueForRole(ax::mojom::Role role);
} // namespace ui
@@ -47,13 +47,13 @@ AX_EXPORT
// Maps AX roles to native roles. Returns NSAccessibilityUnknownRole if not
// found.
-+ (NSString*)nativeRoleFromAXRole:(ui::AXRole)role;
++ (NSString*)nativeRoleFromAXRole:(ax::mojom::Role)role;
// Maps AX roles to native subroles. Returns nil if not found.
-+ (NSString*)nativeSubroleFromAXRole:(ui::AXRole)role;
++ (NSString*)nativeSubroleFromAXRole:(ax::mojom::Role)role;
// Maps AX events to native notifications. Returns nil if not found.
-+ (NSString*)nativeNotificationFromAXEvent:(ui::AXEvent)event;
++ (NSString*)nativeNotificationFromAXEvent:(ax::mojom::Event)event;
- (instancetype)initWithNode:(ui::AXPlatformNodeBase*)node;
- (void)detach;
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_mac.mm b/chromium/ui/accessibility/platform/ax_platform_node_mac.mm
index 4c0b3f9f467..6a439f162f8 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_mac.mm
+++ b/chromium/ui/accessibility/platform/ax_platform_node_mac.mm
@@ -20,133 +20,139 @@
namespace {
-using RoleMap = std::map<ui::AXRole, NSString*>;
-using EventMap = std::map<ui::AXEvent, NSString*>;
-using ActionList = std::vector<std::pair<ui::AXAction, NSString*>>;
+using RoleMap = std::map<ax::mojom::Role, NSString*>;
+using EventMap = std::map<ax::mojom::Event, NSString*>;
+using ActionList = std::vector<std::pair<ax::mojom::Action, NSString*>>;
RoleMap BuildRoleMap() {
const RoleMap::value_type roles[] = {
- {ui::AX_ROLE_ABBR, NSAccessibilityGroupRole},
- {ui::AX_ROLE_ALERT, NSAccessibilityGroupRole},
- {ui::AX_ROLE_ALERT_DIALOG, NSAccessibilityGroupRole},
- {ui::AX_ROLE_ANCHOR, NSAccessibilityGroupRole},
- {ui::AX_ROLE_ANNOTATION, NSAccessibilityUnknownRole},
- {ui::AX_ROLE_APPLICATION, NSAccessibilityGroupRole},
- {ui::AX_ROLE_ARTICLE, NSAccessibilityGroupRole},
- {ui::AX_ROLE_AUDIO, NSAccessibilityGroupRole},
- {ui::AX_ROLE_BANNER, NSAccessibilityGroupRole},
- {ui::AX_ROLE_BLOCKQUOTE, NSAccessibilityGroupRole},
- {ui::AX_ROLE_BUTTON, NSAccessibilityButtonRole},
- {ui::AX_ROLE_CANVAS, NSAccessibilityImageRole},
- {ui::AX_ROLE_CAPTION, NSAccessibilityGroupRole},
- {ui::AX_ROLE_CELL, @"AXCell"},
- {ui::AX_ROLE_CHECK_BOX, NSAccessibilityCheckBoxRole},
- {ui::AX_ROLE_COLOR_WELL, NSAccessibilityColorWellRole},
- {ui::AX_ROLE_COLUMN, NSAccessibilityColumnRole},
- {ui::AX_ROLE_COLUMN_HEADER, @"AXCell"},
- {ui::AX_ROLE_COMBO_BOX_GROUPING, NSAccessibilityGroupRole},
- {ui::AX_ROLE_COMBO_BOX_MENU_BUTTON, NSAccessibilityButtonRole},
- {ui::AX_ROLE_COMPLEMENTARY, NSAccessibilityGroupRole},
- {ui::AX_ROLE_CONTENT_INFO, NSAccessibilityGroupRole},
- {ui::AX_ROLE_DATE, @"AXDateField"},
- {ui::AX_ROLE_DATE_TIME, @"AXDateField"},
- {ui::AX_ROLE_DEFINITION, NSAccessibilityGroupRole},
- {ui::AX_ROLE_DESCRIPTION_LIST_DETAIL, NSAccessibilityGroupRole},
- {ui::AX_ROLE_DESCRIPTION_LIST, NSAccessibilityListRole},
- {ui::AX_ROLE_DESCRIPTION_LIST_TERM, NSAccessibilityGroupRole},
- {ui::AX_ROLE_DIALOG, NSAccessibilityGroupRole},
- {ui::AX_ROLE_DETAILS, NSAccessibilityGroupRole},
- {ui::AX_ROLE_DIRECTORY, NSAccessibilityListRole},
+ {ax::mojom::Role::kAbbr, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kAlert, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kAlertDialog, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kAnchor, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kAnnotation, NSAccessibilityUnknownRole},
+ {ax::mojom::Role::kApplication, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kArticle, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kAudio, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kBanner, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kBlockquote, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kButton, NSAccessibilityButtonRole},
+ {ax::mojom::Role::kCanvas, NSAccessibilityImageRole},
+ {ax::mojom::Role::kCaption, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kCell, @"AXCell"},
+ {ax::mojom::Role::kCheckBox, NSAccessibilityCheckBoxRole},
+ {ax::mojom::Role::kColorWell, NSAccessibilityColorWellRole},
+ {ax::mojom::Role::kColumn, NSAccessibilityColumnRole},
+ {ax::mojom::Role::kColumnHeader, @"AXCell"},
+ {ax::mojom::Role::kComboBoxGrouping, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kComboBoxMenuButton, NSAccessibilityButtonRole},
+ {ax::mojom::Role::kComplementary, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kContentInfo, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kDate, @"AXDateField"},
+ {ax::mojom::Role::kDateTime, @"AXDateField"},
+ {ax::mojom::Role::kDefinition, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kDescriptionListDetail, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kDescriptionList, NSAccessibilityListRole},
+ {ax::mojom::Role::kDescriptionListTerm, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kDialog, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kDetails, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kDirectory, NSAccessibilityListRole},
// If Mac supports AXExpandedChanged event with
// NSAccessibilityDisclosureTriangleRole, We should update
- // AX_ROLE_DISCLOSURE_TRIANGLE mapping to
+ // ax::mojom::Role::kDisclosureTriangle mapping to
// NSAccessibilityDisclosureTriangleRole. http://crbug.com/558324
- {ui::AX_ROLE_DISCLOSURE_TRIANGLE, NSAccessibilityButtonRole},
- {ui::AX_ROLE_DOCUMENT, NSAccessibilityGroupRole},
- {ui::AX_ROLE_EMBEDDED_OBJECT, NSAccessibilityGroupRole},
- {ui::AX_ROLE_FIGCAPTION, NSAccessibilityGroupRole},
- {ui::AX_ROLE_FIGURE, NSAccessibilityGroupRole},
- {ui::AX_ROLE_FOOTER, NSAccessibilityGroupRole},
- {ui::AX_ROLE_FORM, NSAccessibilityGroupRole},
- {ui::AX_ROLE_GENERIC_CONTAINER, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kDisclosureTriangle, NSAccessibilityButtonRole},
+ {ax::mojom::Role::kDocument, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kEmbeddedObject, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kFigcaption, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kFigure, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kFooter, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kForm, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kGenericContainer, NSAccessibilityGroupRole},
// Should be NSAccessibilityGridRole but VoiceOver treating it like
// a list as of 10.12.6, so following WebKit and using table role:
- {ui::AX_ROLE_GRID, NSAccessibilityTableRole}, // crbug.com/753925
- {ui::AX_ROLE_GROUP, NSAccessibilityGroupRole},
- {ui::AX_ROLE_HEADING, @"AXHeading"},
- {ui::AX_ROLE_IFRAME, NSAccessibilityGroupRole},
- {ui::AX_ROLE_IFRAME_PRESENTATIONAL, NSAccessibilityGroupRole},
- {ui::AX_ROLE_IGNORED, NSAccessibilityUnknownRole},
- {ui::AX_ROLE_IMAGE, NSAccessibilityImageRole},
- {ui::AX_ROLE_IMAGE_MAP, NSAccessibilityGroupRole},
- {ui::AX_ROLE_INPUT_TIME, @"AXTimeField"},
- {ui::AX_ROLE_LABEL_TEXT, NSAccessibilityGroupRole},
- {ui::AX_ROLE_LEGEND, NSAccessibilityGroupRole},
- {ui::AX_ROLE_LINE_BREAK, NSAccessibilityGroupRole},
- {ui::AX_ROLE_LINK, NSAccessibilityLinkRole},
- {ui::AX_ROLE_LIST, NSAccessibilityListRole},
- {ui::AX_ROLE_LIST_BOX, NSAccessibilityListRole},
- {ui::AX_ROLE_LIST_BOX_OPTION, NSAccessibilityStaticTextRole},
- {ui::AX_ROLE_LIST_ITEM, NSAccessibilityGroupRole},
- {ui::AX_ROLE_LIST_MARKER, @"AXListMarker"},
- {ui::AX_ROLE_LOG, NSAccessibilityGroupRole},
- {ui::AX_ROLE_MAIN, NSAccessibilityGroupRole},
- {ui::AX_ROLE_MARK, NSAccessibilityGroupRole},
- {ui::AX_ROLE_MARQUEE, NSAccessibilityGroupRole},
- {ui::AX_ROLE_MATH, NSAccessibilityGroupRole},
- {ui::AX_ROLE_MENU, NSAccessibilityMenuRole},
- {ui::AX_ROLE_MENU_BAR, NSAccessibilityMenuBarRole},
- {ui::AX_ROLE_MENU_BUTTON, NSAccessibilityButtonRole},
- {ui::AX_ROLE_MENU_ITEM, NSAccessibilityMenuItemRole},
- {ui::AX_ROLE_MENU_ITEM_CHECK_BOX, NSAccessibilityMenuItemRole},
- {ui::AX_ROLE_MENU_ITEM_RADIO, NSAccessibilityMenuItemRole},
- {ui::AX_ROLE_MENU_LIST_OPTION, NSAccessibilityMenuItemRole},
- {ui::AX_ROLE_MENU_LIST_POPUP, NSAccessibilityUnknownRole},
- {ui::AX_ROLE_METER, NSAccessibilityProgressIndicatorRole},
- {ui::AX_ROLE_NAVIGATION, NSAccessibilityGroupRole},
- {ui::AX_ROLE_NONE, NSAccessibilityGroupRole},
- {ui::AX_ROLE_NOTE, NSAccessibilityGroupRole},
- {ui::AX_ROLE_PARAGRAPH, NSAccessibilityGroupRole},
- {ui::AX_ROLE_POP_UP_BUTTON, NSAccessibilityPopUpButtonRole},
- {ui::AX_ROLE_PRE, NSAccessibilityGroupRole},
- {ui::AX_ROLE_PRESENTATIONAL, NSAccessibilityGroupRole},
- {ui::AX_ROLE_PROGRESS_INDICATOR, NSAccessibilityProgressIndicatorRole},
- {ui::AX_ROLE_RADIO_BUTTON, NSAccessibilityRadioButtonRole},
- {ui::AX_ROLE_RADIO_GROUP, NSAccessibilityRadioGroupRole},
- {ui::AX_ROLE_REGION, NSAccessibilityGroupRole},
- {ui::AX_ROLE_ROOT_WEB_AREA, @"AXWebArea"},
- {ui::AX_ROLE_ROW, NSAccessibilityRowRole},
- {ui::AX_ROLE_ROW_HEADER, @"AXCell"},
- {ui::AX_ROLE_SCROLL_BAR, NSAccessibilityScrollBarRole},
- {ui::AX_ROLE_SEARCH, NSAccessibilityGroupRole},
- {ui::AX_ROLE_SEARCH_BOX, NSAccessibilityTextFieldRole},
- {ui::AX_ROLE_SLIDER, NSAccessibilitySliderRole},
- {ui::AX_ROLE_SLIDER_THUMB, NSAccessibilityValueIndicatorRole},
- {ui::AX_ROLE_SPIN_BUTTON, NSAccessibilityIncrementorRole},
- {ui::AX_ROLE_SPLITTER, NSAccessibilitySplitterRole},
- {ui::AX_ROLE_STATIC_TEXT, NSAccessibilityStaticTextRole},
- {ui::AX_ROLE_STATUS, NSAccessibilityGroupRole},
- {ui::AX_ROLE_SVG_ROOT, NSAccessibilityGroupRole},
- {ui::AX_ROLE_SWITCH, NSAccessibilityCheckBoxRole},
- {ui::AX_ROLE_TAB, NSAccessibilityRadioButtonRole},
- {ui::AX_ROLE_TABLE, NSAccessibilityTableRole},
- {ui::AX_ROLE_TABLE_HEADER_CONTAINER, NSAccessibilityGroupRole},
- {ui::AX_ROLE_TAB_LIST, NSAccessibilityTabGroupRole},
- {ui::AX_ROLE_TAB_PANEL, NSAccessibilityGroupRole},
- {ui::AX_ROLE_TERM, NSAccessibilityGroupRole},
- {ui::AX_ROLE_TEXT_FIELD, NSAccessibilityTextFieldRole},
- {ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX, NSAccessibilityComboBoxRole},
- {ui::AX_ROLE_TIME, NSAccessibilityGroupRole},
- {ui::AX_ROLE_TIMER, NSAccessibilityGroupRole},
- {ui::AX_ROLE_TOGGLE_BUTTON, NSAccessibilityCheckBoxRole},
- {ui::AX_ROLE_TOOLBAR, NSAccessibilityToolbarRole},
- {ui::AX_ROLE_TOOLTIP, NSAccessibilityGroupRole},
- {ui::AX_ROLE_TREE, NSAccessibilityOutlineRole},
- {ui::AX_ROLE_TREE_GRID, NSAccessibilityTableRole},
- {ui::AX_ROLE_TREE_ITEM, NSAccessibilityRowRole},
- {ui::AX_ROLE_VIDEO, NSAccessibilityGroupRole},
- {ui::AX_ROLE_WEB_AREA, @"AXWebArea"},
- {ui::AX_ROLE_WINDOW, NSAccessibilityWindowRole},
+ {ax::mojom::Role::kGrid, NSAccessibilityTableRole}, // crbug.com/753925
+ {ax::mojom::Role::kGroup, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kHeading, @"AXHeading"},
+ {ax::mojom::Role::kIframe, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kIframePresentational, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kIgnored, NSAccessibilityUnknownRole},
+ {ax::mojom::Role::kImage, NSAccessibilityImageRole},
+ {ax::mojom::Role::kImageMap, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kInputTime, @"AXTimeField"},
+ {ax::mojom::Role::kLabelText, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kLayoutTable, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kLayoutTableCell, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kLayoutTableColumn, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kLayoutTableRow, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kLegend, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kLineBreak, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kLink, NSAccessibilityLinkRole},
+ {ax::mojom::Role::kList, NSAccessibilityListRole},
+ {ax::mojom::Role::kListBox, NSAccessibilityListRole},
+ {ax::mojom::Role::kListBoxOption, NSAccessibilityStaticTextRole},
+ {ax::mojom::Role::kListItem, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kListMarker, @"AXListMarker"},
+ {ax::mojom::Role::kLog, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kMain, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kMark, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kMarquee, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kMath, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kMenu, NSAccessibilityMenuRole},
+ {ax::mojom::Role::kMenuBar, NSAccessibilityMenuBarRole},
+ {ax::mojom::Role::kMenuButton, NSAccessibilityButtonRole},
+ {ax::mojom::Role::kMenuItem, NSAccessibilityMenuItemRole},
+ {ax::mojom::Role::kMenuItemCheckBox, NSAccessibilityMenuItemRole},
+ {ax::mojom::Role::kMenuItemRadio, NSAccessibilityMenuItemRole},
+ {ax::mojom::Role::kMenuListOption, NSAccessibilityMenuItemRole},
+ {ax::mojom::Role::kMenuListPopup, NSAccessibilityUnknownRole},
+ {ax::mojom::Role::kMeter, NSAccessibilityProgressIndicatorRole},
+ {ax::mojom::Role::kNavigation, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kNone, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kNote, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kParagraph, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kPopUpButton, NSAccessibilityPopUpButtonRole},
+ {ax::mojom::Role::kPre, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kPresentational, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kProgressIndicator,
+ NSAccessibilityProgressIndicatorRole},
+ {ax::mojom::Role::kRadioButton, NSAccessibilityRadioButtonRole},
+ {ax::mojom::Role::kRadioGroup, NSAccessibilityRadioGroupRole},
+ {ax::mojom::Role::kRegion, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kRootWebArea, @"AXWebArea"},
+ {ax::mojom::Role::kRow, NSAccessibilityRowRole},
+ {ax::mojom::Role::kRowHeader, @"AXCell"},
+ {ax::mojom::Role::kScrollBar, NSAccessibilityScrollBarRole},
+ {ax::mojom::Role::kSearch, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kSearchBox, NSAccessibilityTextFieldRole},
+ {ax::mojom::Role::kSlider, NSAccessibilitySliderRole},
+ {ax::mojom::Role::kSliderThumb, NSAccessibilityValueIndicatorRole},
+ {ax::mojom::Role::kSpinButton, NSAccessibilityIncrementorRole},
+ {ax::mojom::Role::kSplitter, NSAccessibilitySplitterRole},
+ {ax::mojom::Role::kStaticText, NSAccessibilityStaticTextRole},
+ {ax::mojom::Role::kStatus, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kSvgRoot, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kSwitch, NSAccessibilityCheckBoxRole},
+ {ax::mojom::Role::kTab, NSAccessibilityRadioButtonRole},
+ {ax::mojom::Role::kTable, NSAccessibilityTableRole},
+ {ax::mojom::Role::kTableHeaderContainer, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kTabList, NSAccessibilityTabGroupRole},
+ {ax::mojom::Role::kTabPanel, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kTerm, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kTextField, NSAccessibilityTextFieldRole},
+ {ax::mojom::Role::kTextFieldWithComboBox, NSAccessibilityComboBoxRole},
+ {ax::mojom::Role::kTime, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kTimer, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kTitleBar, NSAccessibilityStaticTextRole},
+ {ax::mojom::Role::kToggleButton, NSAccessibilityCheckBoxRole},
+ {ax::mojom::Role::kToolbar, NSAccessibilityToolbarRole},
+ {ax::mojom::Role::kTooltip, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kTree, NSAccessibilityOutlineRole},
+ {ax::mojom::Role::kTreeGrid, NSAccessibilityTableRole},
+ {ax::mojom::Role::kTreeItem, NSAccessibilityRowRole},
+ {ax::mojom::Role::kVideo, NSAccessibilityGroupRole},
+ {ax::mojom::Role::kWebArea, @"AXWebArea"},
+ {ax::mojom::Role::kWindow, NSAccessibilityWindowRole},
};
return RoleMap(begin(roles), end(roles));
@@ -154,37 +160,37 @@ RoleMap BuildRoleMap() {
RoleMap BuildSubroleMap() {
const RoleMap::value_type subroles[] = {
- {ui::AX_ROLE_ALERT, @"AXApplicationAlert"},
- {ui::AX_ROLE_ALERT_DIALOG, @"AXApplicationAlertDialog"},
- {ui::AX_ROLE_APPLICATION, @"AXLandmarkApplication"},
- {ui::AX_ROLE_ARTICLE, @"AXDocumentArticle"},
- {ui::AX_ROLE_BANNER, @"AXLandmarkBanner"},
- {ui::AX_ROLE_COMPLEMENTARY, @"AXLandmarkComplementary"},
- {ui::AX_ROLE_CONTENT_INFO, @"AXLandmarkContentInfo"},
- {ui::AX_ROLE_DEFINITION, @"AXDefinition"},
- {ui::AX_ROLE_DESCRIPTION_LIST_DETAIL, @"AXDefinition"},
- {ui::AX_ROLE_DESCRIPTION_LIST_TERM, @"AXTerm"},
- {ui::AX_ROLE_DIALOG, @"AXApplicationDialog"},
- {ui::AX_ROLE_DOCUMENT, @"AXDocument"},
- {ui::AX_ROLE_FOOTER, @"AXLandmarkContentInfo"},
- {ui::AX_ROLE_FORM, @"AXLandmarkForm"},
- {ui::AX_ROLE_LOG, @"AXApplicationLog"},
- {ui::AX_ROLE_MAIN, @"AXLandmarkMain"},
- {ui::AX_ROLE_MARQUEE, @"AXApplicationMarquee"},
- {ui::AX_ROLE_MATH, @"AXDocumentMath"},
- {ui::AX_ROLE_NAVIGATION, @"AXLandmarkNavigation"},
- {ui::AX_ROLE_NOTE, @"AXDocumentNote"},
- {ui::AX_ROLE_REGION, @"AXDocumentRegion"},
- {ui::AX_ROLE_SEARCH, @"AXLandmarkSearch"},
- {ui::AX_ROLE_SEARCH_BOX, @"AXSearchField"},
- {ui::AX_ROLE_STATUS, @"AXApplicationStatus"},
- {ui::AX_ROLE_SWITCH, @"AXSwitch"},
- {ui::AX_ROLE_TAB_PANEL, @"AXTabPanel"},
- {ui::AX_ROLE_TERM, @"AXTerm"},
- {ui::AX_ROLE_TIMER, @"AXApplicationTimer"},
- {ui::AX_ROLE_TOGGLE_BUTTON, @"AXToggleButton"},
- {ui::AX_ROLE_TOOLTIP, @"AXUserInterfaceTooltip"},
- {ui::AX_ROLE_TREE_ITEM, NSAccessibilityOutlineRowSubrole},
+ {ax::mojom::Role::kAlert, @"AXApplicationAlert"},
+ {ax::mojom::Role::kAlertDialog, @"AXApplicationAlertDialog"},
+ {ax::mojom::Role::kApplication, @"AXLandmarkApplication"},
+ {ax::mojom::Role::kArticle, @"AXDocumentArticle"},
+ {ax::mojom::Role::kBanner, @"AXLandmarkBanner"},
+ {ax::mojom::Role::kComplementary, @"AXLandmarkComplementary"},
+ {ax::mojom::Role::kContentInfo, @"AXLandmarkContentInfo"},
+ {ax::mojom::Role::kDefinition, @"AXDefinition"},
+ {ax::mojom::Role::kDescriptionListDetail, @"AXDefinition"},
+ {ax::mojom::Role::kDescriptionListTerm, @"AXTerm"},
+ {ax::mojom::Role::kDialog, @"AXApplicationDialog"},
+ {ax::mojom::Role::kDocument, @"AXDocument"},
+ {ax::mojom::Role::kFooter, @"AXLandmarkContentInfo"},
+ {ax::mojom::Role::kForm, @"AXLandmarkForm"},
+ {ax::mojom::Role::kLog, @"AXApplicationLog"},
+ {ax::mojom::Role::kMain, @"AXLandmarkMain"},
+ {ax::mojom::Role::kMarquee, @"AXApplicationMarquee"},
+ {ax::mojom::Role::kMath, @"AXDocumentMath"},
+ {ax::mojom::Role::kNavigation, @"AXLandmarkNavigation"},
+ {ax::mojom::Role::kNote, @"AXDocumentNote"},
+ {ax::mojom::Role::kRegion, @"AXDocumentRegion"},
+ {ax::mojom::Role::kSearch, @"AXLandmarkSearch"},
+ {ax::mojom::Role::kSearchBox, @"AXSearchField"},
+ {ax::mojom::Role::kStatus, @"AXApplicationStatus"},
+ {ax::mojom::Role::kSwitch, @"AXSwitch"},
+ {ax::mojom::Role::kTabPanel, @"AXTabPanel"},
+ {ax::mojom::Role::kTerm, @"AXTerm"},
+ {ax::mojom::Role::kTimer, @"AXApplicationTimer"},
+ {ax::mojom::Role::kToggleButton, @"AXToggleButton"},
+ {ax::mojom::Role::kTooltip, @"AXUserInterfaceTooltip"},
+ {ax::mojom::Role::kTreeItem, NSAccessibilityOutlineRowSubrole},
};
return RoleMap(begin(subroles), end(subroles));
@@ -192,10 +198,12 @@ RoleMap BuildSubroleMap() {
EventMap BuildEventMap() {
const EventMap::value_type events[] = {
- {ui::AX_EVENT_FOCUS, NSAccessibilityFocusedUIElementChangedNotification},
- {ui::AX_EVENT_TEXT_CHANGED, NSAccessibilityTitleChangedNotification},
- {ui::AX_EVENT_VALUE_CHANGED, NSAccessibilityValueChangedNotification},
- {ui::AX_EVENT_TEXT_SELECTION_CHANGED,
+ {ax::mojom::Event::kFocus,
+ NSAccessibilityFocusedUIElementChangedNotification},
+ {ax::mojom::Event::kTextChanged, NSAccessibilityTitleChangedNotification},
+ {ax::mojom::Event::kValueChanged,
+ NSAccessibilityValueChangedNotification},
+ {ax::mojom::Event::kTextSelectionChanged,
NSAccessibilitySelectedTextChangedNotification},
// TODO(patricialor): Add more events.
};
@@ -206,11 +214,11 @@ EventMap BuildEventMap() {
ActionList BuildActionList() {
const ActionList::value_type entries[] = {
// NSAccessibilityPressAction must come first in this list.
- {ui::AX_ACTION_DO_DEFAULT, NSAccessibilityPressAction},
+ {ax::mojom::Action::kDoDefault, NSAccessibilityPressAction},
- {ui::AX_ACTION_DECREMENT, NSAccessibilityDecrementAction},
- {ui::AX_ACTION_INCREMENT, NSAccessibilityIncrementAction},
- {ui::AX_ACTION_SHOW_CONTEXT_MENU, NSAccessibilityShowMenuAction},
+ {ax::mojom::Action::kDecrement, NSAccessibilityDecrementAction},
+ {ax::mojom::Action::kIncrement, NSAccessibilityIncrementAction},
+ {ax::mojom::Action::kShowContextMenu, NSAccessibilityShowMenuAction},
};
return ActionList(begin(entries), end(entries));
}
@@ -220,30 +228,31 @@ const ActionList& GetActionList() {
return action_map;
}
-void NotifyMacEvent(AXPlatformNodeCocoa* target, ui::AXEvent event_type) {
+void NotifyMacEvent(AXPlatformNodeCocoa* target, ax::mojom::Event event_type) {
NSAccessibilityPostNotification(
target, [AXPlatformNodeCocoa nativeNotificationFromAXEvent:event_type]);
}
// Returns true if |action| should be added implicitly for |data|.
-bool HasImplicitAction(const ui::AXNodeData& data, ui::AXAction action) {
- return action == ui::AX_ACTION_DO_DEFAULT && ui::IsRoleClickable(data.role);
+bool HasImplicitAction(const ui::AXNodeData& data, ax::mojom::Action action) {
+ return action == ax::mojom::Action::kDoDefault &&
+ ui::IsRoleClickable(data.role);
}
// For roles that show a menu for the default action, ensure "show menu" also
// appears in available actions, but only if that's not already used for a
// context menu. It will be mapped back to the default action when performed.
bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
- return HasImplicitAction(data, ui::AX_ACTION_DO_DEFAULT) &&
- !data.HasAction(ui::AX_ACTION_SHOW_CONTEXT_MENU) &&
- data.role == ui::AX_ROLE_POP_UP_BUTTON;
+ return HasImplicitAction(data, ax::mojom::Action::kDoDefault) &&
+ !data.HasAction(ax::mojom::Action::kShowContextMenu) &&
+ data.role == ax::mojom::Role::kPopUpButton;
}
} // namespace
@interface AXPlatformNodeCocoa ()
// Helper function for string attributes that don't require extra processing.
-- (NSString*)getStringAttribute:(ui::AXStringAttribute)attribute;
+- (NSString*)getStringAttribute:(ax::mojom::StringAttribute)attribute;
// Returns AXValue, or nil if AXValue isn't an NSString.
- (NSString*)getAXValueAsString;
@end
@@ -254,19 +263,19 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
@synthesize node = node_;
-+ (NSString*)nativeRoleFromAXRole:(ui::AXRole)role {
++ (NSString*)nativeRoleFromAXRole:(ax::mojom::Role)role {
CR_DEFINE_STATIC_LOCAL(const RoleMap, role_map, (BuildRoleMap()));
RoleMap::const_iterator it = role_map.find(role);
return it != role_map.end() ? it->second : NSAccessibilityUnknownRole;
}
-+ (NSString*)nativeSubroleFromAXRole:(ui::AXRole)role {
++ (NSString*)nativeSubroleFromAXRole:(ax::mojom::Role)role {
CR_DEFINE_STATIC_LOCAL(const RoleMap, subrole_map, (BuildSubroleMap()));
RoleMap::const_iterator it = subrole_map.find(role);
return it != subrole_map.end() ? it->second : nil;
}
-+ (NSString*)nativeNotificationFromAXEvent:(ui::AXEvent)event {
++ (NSString*)nativeNotificationFromAXEvent:(ax::mojom::Event)event {
CR_DEFINE_STATIC_LOCAL(const EventMap, event_map, (BuildEventMap()));
EventMap::const_iterator it = event_map.find(event);
return it != event_map.end() ? it->second : nil;
@@ -288,12 +297,13 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
}
- (NSRect)boundsInScreen {
- if (!node_)
+ if (!node_ || !node_->GetDelegate())
return NSZeroRect;
- return gfx::ScreenRectToNSRect(node_->GetBoundsInScreen());
+ return gfx::ScreenRectToNSRect(
+ node_->GetDelegate()->GetClippedScreenBoundsRect());
}
-- (NSString*)getStringAttribute:(ui::AXStringAttribute)attribute {
+- (NSString*)getStringAttribute:(ax::mojom::StringAttribute)attribute {
std::string attributeValue;
if (node_->GetStringAttribute(attribute, &attributeValue))
return base::SysUTF8ToNSString(attributeValue);
@@ -312,7 +322,7 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
return YES;
return [[self AXRole] isEqualToString:NSAccessibilityUnknownRole] ||
- node_->GetData().HasState(ui::AX_STATE_INVISIBLE);
+ node_->GetData().HasState(ax::mojom::State::kInvisible);
}
- (id)accessibilityHitTest:(NSPoint)point {
@@ -366,7 +376,7 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
ui::AXActionData data;
if ([action isEqualToString:NSAccessibilityShowMenuAction] &&
AlsoUseShowMenuActionForDefaultAction(node_->GetData())) {
- data.action = ui::AX_ACTION_DO_DEFAULT;
+ data.action = ax::mojom::Action::kDoDefault;
} else {
for (const ActionList::value_type& entry : GetActionList()) {
if ([action isEqualToString:entry.second]) {
@@ -380,7 +390,7 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
// are already implemented in -accessibilitySetValue:forAttribute:, so ignore
// those here.
- if (data.action != ui::AX_ACTION_NONE)
+ if (data.action != ax::mojom::Action::kNone)
node_->GetDelegate()->AccessibilityPerformAction(data);
}
@@ -431,22 +441,22 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
[axAttributes addObjectsFromArray:kAllRoleAttributes];
switch (node_->GetData().role) {
- case ui::AX_ROLE_TEXT_FIELD:
- case ui::AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX:
- case ui::AX_ROLE_STATIC_TEXT:
+ case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kTextFieldWithComboBox:
+ case ax::mojom::Role::kStaticText:
[axAttributes addObject:kTextAttributes];
- if (!node_->GetData().HasState(ui::AX_STATE_PROTECTED))
+ if (!node_->GetData().HasState(ax::mojom::State::kProtected))
[axAttributes addObjectsFromArray:kUnprotectedTextAttributes];
- // Fallthrough.
- case ui::AX_ROLE_CHECK_BOX:
- case ui::AX_ROLE_COMBO_BOX_MENU_BUTTON:
- case ui::AX_ROLE_MENU_ITEM_CHECK_BOX:
- case ui::AX_ROLE_MENU_ITEM_RADIO:
- case ui::AX_ROLE_RADIO_BUTTON:
- case ui::AX_ROLE_SEARCH_BOX:
- case ui::AX_ROLE_SLIDER:
- case ui::AX_ROLE_SLIDER_THUMB:
- case ui::AX_ROLE_TOGGLE_BUTTON:
+ FALLTHROUGH;
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
+ case ax::mojom::Role::kRadioButton:
+ case ax::mojom::Role::kSearchBox:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSliderThumb:
+ case ax::mojom::Role::kToggleButton:
[axAttributes addObjectsFromArray:kValueAttributes];
break;
// TODO(tapted): Add additional attributes based on role.
@@ -473,8 +483,8 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
] retain];
switch (node_->GetData().role) {
- case ui::AX_ROLE_TEXT_FIELD:
- case ui::AX_ROLE_STATIC_TEXT:
+ case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kStaticText:
return kSelectableTextAttributes;
default:
break;
@@ -486,9 +496,8 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
if (!node_)
return NO;
- const int restriction =
- node_->GetData().GetIntAttribute(ui::AX_ATTR_RESTRICTION);
- if (restriction == ui::AX_RESTRICTION_DISABLED)
+ const ax::mojom::Restriction restriction = node_->GetData().GetRestriction();
+ if (restriction == ax::mojom::Restriction::kDisabled)
return NO;
// Allow certain attributes to be written via an accessibility client. A
@@ -504,10 +513,10 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
if ([attributeName isEqualToString:NSAccessibilityValueAttribute]) {
// Since tabs use the Radio Button role on Mac, the standard way to set
// them is via the value attribute rather than the selected attribute.
- if (node_->GetData().role == ui::AX_ROLE_TAB)
- return !node_->GetData().HasState(ui::AX_STATE_SELECTED);
+ if (node_->GetData().role == ax::mojom::Role::kTab)
+ return !node_->GetData().HasState(ax::mojom::State::kSelected);
- return restriction != ui::AX_RESTRICTION_READ_ONLY;
+ return restriction != ax::mojom::Restriction::kReadOnly;
}
// Readonly fields and selected text operations:
@@ -517,10 +526,10 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
// NSAccessibilitySelectedTextAttribute is prevented, which is correct.
if ([attributeName isEqualToString:NSAccessibilitySelectedTextAttribute] ||
[attributeName isEqualToString:NSAccessibilitySelectedTextRangeAttribute])
- return restriction != ui::AX_RESTRICTION_READ_ONLY;
+ return restriction != ax::mojom::Restriction::kReadOnly;
if ([attributeName isEqualToString:NSAccessibilityFocusedAttribute]) {
- return node_->GetData().HasState(ui::AX_STATE_FOCUSABLE);
+ return node_->GetData().HasState(ax::mojom::State::kFocusable);
}
// TODO(patricialor): Add callbacks for updating the above attributes except
@@ -537,32 +546,32 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
// Check for attributes first. Only the |data.action| should be set here - any
// type-specific information, if needed, should be set below.
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
- data.action = node_->GetData().role == ui::AX_ROLE_TAB
- ? ui::AX_ACTION_SET_SELECTION
- : ui::AX_ACTION_SET_VALUE;
+ data.action = node_->GetData().role == ax::mojom::Role::kTab
+ ? ax::mojom::Action::kSetSelection
+ : ax::mojom::Action::kSetValue;
} else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
- data.action = ui::AX_ACTION_REPLACE_SELECTED_TEXT;
+ data.action = ax::mojom::Action::kReplaceSelectedText;
} else if ([attribute
isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
- data.action = ui::AX_ACTION_SET_SELECTION;
+ data.action = ax::mojom::Action::kSetSelection;
} else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
if ([value isKindOfClass:[NSNumber class]]) {
- data.action =
- [value boolValue] ? ui::AX_ACTION_FOCUS : ui::AX_ACTION_BLUR;
+ data.action = [value boolValue] ? ax::mojom::Action::kFocus
+ : ax::mojom::Action::kBlur;
}
}
// Set type-specific information as necessary for actions set above.
if ([value isKindOfClass:[NSString class]]) {
data.value = base::SysNSStringToUTF16(value);
- } else if (data.action == ui::AX_ACTION_SET_SELECTION &&
+ } else if (data.action == ax::mojom::Action::kSetSelection &&
[value isKindOfClass:[NSValue class]]) {
NSRange range = [value rangeValue];
data.anchor_offset = range.location;
data.focus_offset = NSMaxRange(range);
}
- if (data.action != ui::AX_ACTION_NONE)
+ if (data.action != ax::mojom::Action::kNone)
node_->GetDelegate()->AccessibilityPerformAction(data);
// TODO(patricialor): Plumb through all the other writable attributes as
@@ -571,7 +580,7 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
- (id)accessibilityAttributeValue:(NSString*)attribute {
if (!node_)
- return nil; // Return nil when detached. Even for AXRole.
+ return nil; // Return nil when detached. Even for ax::mojom::Role.
SEL selector = NSSelectorFromString(attribute);
if ([self respondsToSelector:selector])
@@ -602,12 +611,12 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
- (NSString*)AXRoleDescription {
switch (node_->GetData().role) {
- case ui::AX_ROLE_TAB:
+ case ax::mojom::Role::kTab:
// There is no NSAccessibilityTabRole or similar (AXRadioButton is used
// instead). Do the same as NSTabView and put "tab" in the description.
return [l10n_util::GetNSStringWithFixup(IDS_ACCNAME_TAB_ROLE_DESCRIPTION)
lowercaseString];
- case ui::AX_ROLE_DISCLOSURE_TRIANGLE:
+ case ax::mojom::Role::kDisclosureTriangle:
return [l10n_util::GetNSStringWithFixup(
IDS_ACCNAME_DISCLOSURE_TRIANGLE_ROLE_DESCRIPTION) lowercaseString];
default:
@@ -617,10 +626,10 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
}
- (NSString*)AXSubrole {
- ui::AXRole role = node_->GetData().role;
+ ax::mojom::Role role = node_->GetData().role;
switch (role) {
- case ui::AX_ROLE_TEXT_FIELD:
- if (node_->GetData().HasState(ui::AX_STATE_PROTECTED))
+ case ax::mojom::Role::kTextField:
+ if (node_->GetData().HasState(ax::mojom::State::kProtected))
return NSAccessibilitySecureTextFieldSubrole;
break;
default:
@@ -633,8 +642,10 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
// TODO(aleventhal) Key shortcuts attribute should eventually get
// its own field. Follow what WebKit does for aria-keyshortcuts, see
// https://bugs.webkit.org/show_bug.cgi?id=159215 (WebKit bug).
- NSString* desc = [self getStringAttribute:ui::AX_ATTR_DESCRIPTION];
- NSString* key = [self getStringAttribute:ui::AX_ATTR_KEY_SHORTCUTS];
+ NSString* desc =
+ [self getStringAttribute:ax::mojom::StringAttribute::kDescription];
+ NSString* key =
+ [self getStringAttribute:ax::mojom::StringAttribute::kKeyShortcuts];
if (!desc.length)
return key.length ? key : @"";
if (!key.length)
@@ -643,23 +654,23 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
}
- (id)AXValue {
- ui::AXRole role = node_->GetData().role;
- if (role == ui::AX_ROLE_TAB)
+ ax::mojom::Role role = node_->GetData().role;
+ if (role == ax::mojom::Role::kTab)
return [self AXSelected];
if (ui::IsNameExposedInAXValueForRole(role))
- return [self getStringAttribute:ui::AX_ATTR_NAME];
+ return [self getStringAttribute:ax::mojom::StringAttribute::kName];
- return [self getStringAttribute:ui::AX_ATTR_VALUE];
+ return [self getStringAttribute:ax::mojom::StringAttribute::kValue];
}
- (NSNumber*)AXEnabled {
- return @(node_->GetData().GetIntAttribute(ui::AX_ATTR_RESTRICTION) !=
- ui::AX_RESTRICTION_DISABLED);
+ return
+ @(node_->GetData().GetRestriction() != ax::mojom::Restriction::kDisabled);
}
- (NSNumber*)AXFocused {
- if (node_->GetData().HasState(ui::AX_STATE_FOCUSABLE))
+ if (node_->GetData().HasState(ax::mojom::State::kFocusable))
return
@(node_->GetDelegate()->GetFocus() == node_->GetNativeViewAccessible());
return @NO;
@@ -702,17 +713,17 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
if (ui::IsNameExposedInAXValueForRole(node_->GetData().role))
return @"";
- return [self getStringAttribute:ui::AX_ATTR_NAME];
+ return [self getStringAttribute:ax::mojom::StringAttribute::kName];
}
// Misc attributes.
- (NSNumber*)AXSelected {
- return @(node_->GetData().HasState(ui::AX_STATE_SELECTED));
+ return @(node_->GetData().HasState(ax::mojom::State::kSelected));
}
- (NSString*)AXPlaceholderValue {
- return [self getStringAttribute:ui::AX_ATTR_PLACEHOLDER];
+ return [self getStringAttribute:ax::mojom::StringAttribute::kPlaceholder];
}
// Text-specific attributes.
@@ -726,8 +737,8 @@ bool AlsoUseShowMenuActionForDefaultAction(const ui::AXNodeData& data) {
- (NSValue*)AXSelectedTextRange {
// Selection might not be supported. Return (NSRange){0,0} in that case.
int start = 0, end = 0;
- node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, &start);
- node_->GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, &end);
+ node_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &start);
+ node_->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &end);
// NSRange cannot represent the direction the text was selected in.
return [NSValue valueWithRange:{std::min(start, end), abs(end - start)}];
@@ -846,15 +857,16 @@ gfx::NativeViewAccessible AXPlatformNodeMac::GetNativeViewAccessible() {
return native_node_.get();
}
-void AXPlatformNodeMac::NotifyAccessibilityEvent(ui::AXEvent event_type) {
+void AXPlatformNodeMac::NotifyAccessibilityEvent(ax::mojom::Event event_type) {
GetNativeViewAccessible();
- // Add mappings between ui::AXEvent and NSAccessibility notifications using
- // the EventMap above. This switch contains exceptions to those mappings.
+ // Add mappings between ax::mojom::Event and NSAccessibility notifications
+ // using the EventMap above. This switch contains exceptions to those
+ // mappings.
switch (event_type) {
- case ui::AX_EVENT_TEXT_CHANGED:
+ case ax::mojom::Event::kTextChanged:
// If the view is a user-editable textfield, this should change the value.
- if (GetData().role == ui::AX_ROLE_TEXT_FIELD) {
- NotifyMacEvent(native_node_, ui::AX_EVENT_VALUE_CHANGED);
+ if (GetData().role == ax::mojom::Role::kTextField) {
+ NotifyMacEvent(native_node_, ax::mojom::Event::kValueChanged);
return;
}
break;
@@ -869,12 +881,13 @@ int AXPlatformNodeMac::GetIndexInParent() {
return -1;
}
-bool IsNameExposedInAXValueForRole(AXRole role) {
+bool IsNameExposedInAXValueForRole(ax::mojom::Role role) {
switch (role) {
- case AX_ROLE_LIST_BOX_OPTION:
- case AX_ROLE_LIST_MARKER:
- case AX_ROLE_MENU_LIST_OPTION:
- case AX_ROLE_STATIC_TEXT:
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kListMarker:
+ case ax::mojom::Role::kMenuListOption:
+ case ax::mojom::Role::kStaticText:
+ case ax::mojom::Role::kTitleBar:
return true;
default:
return false;
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_unittest.cc b/chromium/ui/accessibility/platform/ax_platform_node_unittest.cc
index de424716d22..9cb8b4428a3 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_unittest.cc
+++ b/chromium/ui/accessibility/platform/ax_platform_node_unittest.cc
@@ -57,8 +57,8 @@ void AXPlatformNodeTest::Init(const AXNodeData& node1,
AXTreeUpdate AXPlatformNodeTest::BuildTextField() {
AXNodeData text_field_node;
text_field_node.id = 1;
- text_field_node.role = AX_ROLE_TEXT_FIELD;
- text_field_node.AddState(AX_STATE_EDITABLE);
+ text_field_node.role = ax::mojom::Role::kTextField;
+ text_field_node.AddState(ax::mojom::State::kEditable);
text_field_node.SetValue("How now brown cow.");
AXTreeUpdate update;
@@ -72,11 +72,12 @@ AXTreeUpdate AXPlatformNodeTest::BuildTextFieldWithSelectionRange(
int32_t stop) {
AXNodeData text_field_node;
text_field_node.id = 1;
- text_field_node.role = AX_ROLE_TEXT_FIELD;
- text_field_node.AddState(AX_STATE_EDITABLE);
- text_field_node.AddState(AX_STATE_SELECTED);
- text_field_node.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_START, start);
- text_field_node.AddIntAttribute(ui::AX_ATTR_TEXT_SEL_END, stop);
+ text_field_node.role = ax::mojom::Role::kTextField;
+ text_field_node.AddState(ax::mojom::State::kEditable);
+ text_field_node.AddState(ax::mojom::State::kSelected);
+ text_field_node.AddIntAttribute(ax::mojom::IntAttribute::kTextSelStart,
+ start);
+ text_field_node.AddIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, stop);
text_field_node.SetValue("How now brown cow.");
AXTreeUpdate update;
@@ -88,9 +89,10 @@ AXTreeUpdate AXPlatformNodeTest::BuildTextFieldWithSelectionRange(
AXTreeUpdate AXPlatformNodeTest::BuildContentEditable() {
AXNodeData content_editable_node;
content_editable_node.id = 1;
- content_editable_node.role = AX_ROLE_GROUP;
- content_editable_node.AddState(AX_STATE_RICHLY_EDITABLE);
- content_editable_node.AddBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT, true);
+ content_editable_node.role = ax::mojom::Role::kGroup;
+ content_editable_node.AddState(ax::mojom::State::kRichlyEditable);
+ content_editable_node.AddBoolAttribute(
+ ax::mojom::BoolAttribute::kEditableRoot, true);
content_editable_node.SetValue("How now brown cow.");
AXTreeUpdate update;
@@ -104,10 +106,11 @@ AXTreeUpdate AXPlatformNodeTest::BuildContentEditableWithSelectionRange(
int32_t end) {
AXNodeData content_editable_node;
content_editable_node.id = 1;
- content_editable_node.role = AX_ROLE_GROUP;
- content_editable_node.AddState(AX_STATE_RICHLY_EDITABLE);
- content_editable_node.AddState(AX_STATE_SELECTED);
- content_editable_node.AddBoolAttribute(ui::AX_ATTR_EDITABLE_ROOT, true);
+ content_editable_node.role = ax::mojom::Role::kGroup;
+ content_editable_node.AddState(ax::mojom::State::kRichlyEditable);
+ content_editable_node.AddState(ax::mojom::State::kSelected);
+ content_editable_node.AddBoolAttribute(
+ ax::mojom::BoolAttribute::kEditableRoot, true);
content_editable_node.SetValue("How now brown cow.");
AXTreeUpdate update;
@@ -138,18 +141,18 @@ AXTreeUpdate AXPlatformNodeTest::AXPlatformNodeTest::Build3X3Table() {
AXNodeData table;
table.id = 0;
- table.role = AX_ROLE_TABLE;
+ table.role = ax::mojom::Role::kTable;
- table.AddIntAttribute(AX_ATTR_TABLE_ROW_COUNT, 3);
- table.AddIntAttribute(AX_ATTR_TABLE_COLUMN_COUNT, 3);
+ table.AddIntAttribute(ax::mojom::IntAttribute::kTableRowCount, 3);
+ table.AddIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, 3);
// Ordering in this list matters. It is used in the calculation
// of where cells are by the following:
// int position = row * GetTableColumnCount() + column;
std::vector<int32_t> ids{51, 52, 53, 2, 3, 4, 11, 12, 13};
- table.AddIntListAttribute(AX_ATTR_CELL_IDS, ids);
- table.AddIntListAttribute(AX_ATTR_UNIQUE_CELL_IDS, ids);
+ table.AddIntListAttribute(ax::mojom::IntListAttribute::kCellIds, ids);
+ table.AddIntListAttribute(ax::mojom::IntListAttribute::kUniqueCellIds, ids);
table.child_ids.push_back(50); // Header
table.child_ids.push_back(1); // Row 1
@@ -158,74 +161,75 @@ AXTreeUpdate AXPlatformNodeTest::AXPlatformNodeTest::Build3X3Table() {
// Table column header
AXNodeData table_row_header;
table_row_header.id = 50;
- table_row_header.role = AX_ROLE_ROW;
+ table_row_header.role = ax::mojom::Role::kRow;
table_row_header.child_ids.push_back(51);
table_row_header.child_ids.push_back(52);
table_row_header.child_ids.push_back(53);
AXNodeData table_column_header_1;
table_column_header_1.id = 51;
- table_column_header_1.role = AX_ROLE_COLUMN_HEADER;
+ table_column_header_1.role = ax::mojom::Role::kColumnHeader;
AXNodeData table_column_header_2;
table_column_header_2.id = 52;
- table_column_header_2.role = AX_ROLE_COLUMN_HEADER;
+ table_column_header_2.role = ax::mojom::Role::kColumnHeader;
table_column_header_2.SetName("column header 1");
AXNodeData table_column_header_3;
table_column_header_3.id = 53;
- table_column_header_3.role = AX_ROLE_COLUMN_HEADER;
- // Either AX_ATTR_NAME -or- AX_ATTR_DESCRIPTION is acceptable for a
- // description
- table_column_header_3.AddStringAttribute(AX_ATTR_DESCRIPTION,
- "column header 2");
+ table_column_header_3.role = ax::mojom::Role::kColumnHeader;
+ // Either ax::mojom::StringAttribute::kName -or-
+ // ax::mojom::StringAttribute::kDescription is acceptable for a description
+ table_column_header_3.AddStringAttribute(
+ ax::mojom::StringAttribute::kDescription, "column header 2");
// Row 1
AXNodeData table_row_1;
table_row_1.id = 1;
- table_row_1.role = AX_ROLE_ROW;
+ table_row_1.role = ax::mojom::Role::kRow;
table_row_1.child_ids.push_back(2);
table_row_1.child_ids.push_back(3);
table_row_1.child_ids.push_back(4);
AXNodeData table_row_header_1;
table_row_header_1.id = 2;
- table_row_header_1.role = AX_ROLE_ROW_HEADER;
+ table_row_header_1.role = ax::mojom::Role::kRowHeader;
table_row_header_1.SetName("row header 1");
AXNodeData table_cell_1;
table_cell_1.id = 3;
- table_cell_1.role = AX_ROLE_CELL;
+ table_cell_1.role = ax::mojom::Role::kCell;
table_cell_1.SetName("1");
AXNodeData table_cell_2;
table_cell_2.id = 4;
- table_cell_2.role = AX_ROLE_CELL;
+ table_cell_2.role = ax::mojom::Role::kCell;
table_cell_2.SetName("2");
// Row 2
AXNodeData table_row_2;
table_row_2.id = 10;
- table_row_2.role = AX_ROLE_ROW;
+ table_row_2.role = ax::mojom::Role::kRow;
table_row_2.child_ids.push_back(11);
table_row_2.child_ids.push_back(12);
table_row_2.child_ids.push_back(13);
AXNodeData table_row_header_2;
table_row_header_2.id = 11;
- table_row_header_2.role = AX_ROLE_ROW_HEADER;
- // Either AX_ATTR_NAME -or- AX_ATTR_DESCRIPTION is acceptable for a
- // description
- table_row_header_2.AddStringAttribute(AX_ATTR_DESCRIPTION, "row header 2");
+ table_row_header_2.role = ax::mojom::Role::kRowHeader;
+ // Either ax::mojom::StringAttribute::kName -or-
+ // ax::mojom::StringAttribute::kDescription is acceptable for a description
+ table_row_header_2.AddStringAttribute(
+ ax::mojom::StringAttribute::kDescription, "row header 2");
AXNodeData table_cell_3;
table_cell_3.id = 12;
- table_cell_3.role = AX_ROLE_CELL;
+ table_cell_3.role = ax::mojom::Role::kCell;
table_cell_3.SetName("3");
AXNodeData table_cell_4;
table_cell_4.id = 13;
- table_cell_4.role = AX_ROLE_CELL;
+ table_cell_4.role = ax::mojom::Role::kCell;
table_cell_4.SetName("4");
AXTreeUpdate update;
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_win.cc b/chromium/ui/accessibility/platform/ax_platform_node_win.cc
index 7d3ead2c186..f266a181e11 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/chromium/ui/accessibility/platform/ax_platform_node_win.cc
@@ -283,7 +283,7 @@ void AXPlatformNodeWin::SanitizeStringAttributeForIA2(
void AXPlatformNodeWin::StringAttributeToIA2(
std::vector<base::string16>& attributes,
- AXStringAttribute attribute,
+ ax::mojom::StringAttribute attribute,
const char* ia2_attr) {
base::string16 value;
if (GetString16Attribute(attribute, &value)) {
@@ -294,7 +294,7 @@ void AXPlatformNodeWin::StringAttributeToIA2(
void AXPlatformNodeWin::BoolAttributeToIA2(
std::vector<base::string16>& attributes,
- AXBoolAttribute attribute,
+ ax::mojom::BoolAttribute attribute,
const char* ia2_attr) {
bool value;
if (GetBoolAttribute(attribute, &value)) {
@@ -305,7 +305,7 @@ void AXPlatformNodeWin::BoolAttributeToIA2(
void AXPlatformNodeWin::IntAttributeToIA2(
std::vector<base::string16>& attributes,
- AXIntAttribute attribute,
+ ax::mojom::IntAttribute attribute,
const char* ia2_attr) {
int value;
if (GetIntAttribute(attribute, &value)) {
@@ -340,15 +340,16 @@ gfx::NativeViewAccessible AXPlatformNodeWin::GetNativeViewAccessible() {
return this;
}
-void AXPlatformNodeWin::NotifyAccessibilityEvent(AXEvent event_type) {
+void AXPlatformNodeWin::NotifyAccessibilityEvent(ax::mojom::Event event_type) {
HWND hwnd = delegate_->GetTargetForNativeAccessibilityEvent();
if (!hwnd)
return;
// Menu items fire selection events but Windows screen readers work reliably
// with focus events. Remap here.
- if (event_type == AX_EVENT_SELECTION && GetData().role == AX_ROLE_MENU_ITEM)
- event_type = AX_EVENT_FOCUS;
+ if (event_type == ax::mojom::Event::kSelection &&
+ GetData().role == ax::mojom::Role::kMenuItem)
+ event_type = ax::mojom::Event::kFocus;
int native_event = MSAAEvent(event_type);
if (native_event < EVENT_MIN)
@@ -357,7 +358,7 @@ void AXPlatformNodeWin::NotifyAccessibilityEvent(AXEvent event_type) {
::NotifyWinEvent(native_event, hwnd, OBJID_CLIENT, -GetUniqueId());
// Keep track of objects that are a target of an alert event.
- if (event_type == AX_EVENT_ALERT)
+ if (event_type == ax::mojom::Event::kAlert)
AddAlertTarget();
}
@@ -403,7 +404,7 @@ STDMETHODIMP AXPlatformNodeWin::accHitTest(
COM_OBJECT_VALIDATE_1_ARG(child);
gfx::Point point(x_left, y_top);
- if (!delegate_->GetScreenBoundsRect().Contains(point)) {
+ if (!delegate_->GetClippedScreenBoundsRect().Contains(point)) {
// Return S_FALSE and VT_EMPTY when outside the object's boundaries.
child->vt = VT_EMPTY;
return S_FALSE;
@@ -446,7 +447,7 @@ HRESULT AXPlatformNodeWin::accDoDefaultAction(VARIANT var_id) {
AXPlatformNodeWin* target;
COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target);
AXActionData data;
- data.action = AX_ACTION_DO_DEFAULT;
+ data.action = ax::mojom::Action::kDoDefault;
if (target->delegate_->AccessibilityPerformAction(data))
return S_OK;
@@ -460,7 +461,7 @@ STDMETHODIMP AXPlatformNodeWin::accLocation(
COM_OBJECT_VALIDATE_VAR_ID_4_ARGS_AND_GET_TARGET(var_id, x_left, y_top, width,
height, target);
- gfx::Rect bounds = target->delegate_->GetScreenBoundsRect();
+ gfx::Rect bounds = target->delegate_->GetUnclippedScreenBoundsRect();
*x_left = bounds.x();
*y_top = bounds.y();
*width = bounds.width();
@@ -612,13 +613,14 @@ STDMETHODIMP AXPlatformNodeWin::get_accDefaultAction(
AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
int action;
- if (!target->GetIntAttribute(AX_ATTR_DEFAULT_ACTION_VERB, &action)) {
+ if (!target->GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb,
+ &action)) {
*def_action = nullptr;
return S_FALSE;
}
- base::string16 action_verb =
- ActionVerbToLocalizedString(static_cast<AXDefaultActionVerb>(action));
+ base::string16 action_verb = ActionVerbToLocalizedString(
+ static_cast<ax::mojom::DefaultActionVerb>(action));
if (action_verb.empty()) {
*def_action = nullptr;
return S_FALSE;
@@ -635,7 +637,8 @@ STDMETHODIMP AXPlatformNodeWin::get_accDescription(
AXPlatformNodeWin* target;
COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, desc, target);
- return target->GetStringAttributeAsBstr(AX_ATTR_DESCRIPTION, desc);
+ return target->GetStringAttributeAsBstr(
+ ax::mojom::StringAttribute::kDescription, desc);
}
STDMETHODIMP AXPlatformNodeWin::get_accFocus(VARIANT* focus_child) {
@@ -663,7 +666,8 @@ STDMETHODIMP AXPlatformNodeWin::get_accKeyboardShortcut(
AXPlatformNodeWin* target;
COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, acc_key, target);
- return target->GetStringAttributeAsBstr(AX_ATTR_KEY_SHORTCUTS, acc_key);
+ return target->GetStringAttributeAsBstr(
+ ax::mojom::StringAttribute::kKeyShortcuts, acc_key);
}
STDMETHODIMP AXPlatformNodeWin::get_accName(
@@ -672,7 +676,8 @@ STDMETHODIMP AXPlatformNodeWin::get_accName(
AXPlatformNodeWin* target;
COM_OBJECT_VALIDATE_VAR_ID_1_ARG_AND_GET_TARGET(var_id, name, target);
- HRESULT result = target->GetStringAttributeAsBstr(AX_ATTR_NAME, name);
+ HRESULT result =
+ target->GetStringAttributeAsBstr(ax::mojom::StringAttribute::kName, name);
if (FAILED(result) && MSAARole() == ROLE_SYSTEM_DOCUMENT && GetParent()) {
// Hack: Some versions of JAWS crash if they get an empty name on
// a document that's the child of an iframe, so always return a
@@ -747,19 +752,20 @@ STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) {
// get_accValue() has two sets of special cases depending on the node's role.
// The first set apply without regard for the nodes |value| attribute. That is
// the nodes value attribute isn't consider for the first set of special
- // cases. For example, if the node role is AX_ROLE_COLOR_WELL, we do not care
- // at all about the node's AX_ATTR_VALUE attribute. The second set of special
- // cases only apply if the value attribute for the node is empty. That is, if
- // AX_ATTR_VALUE is empty, we do something special.
+ // cases. For example, if the node role is ax::mojom::Role::kColorWell, we do
+ // not care at all about the node's ax::mojom::StringAttribute::kValue
+ // attribute. The second set of special cases only apply if the value
+ // attribute for the node is empty. That is, if
+ // ax::mojom::StringAttribute::kValue is empty, we do something special.
base::string16 result;
//
- // Color Well special case (Use AX_ATTR_COLOR_VALUE)
+ // Color Well special case (Use ax::mojom::IntAttribute::kColorValue)
//
- if (target->GetData().role == AX_ROLE_COLOR_WELL) {
+ if (target->GetData().role == ax::mojom::Role::kColorWell) {
unsigned int color = static_cast<unsigned int>(target->GetIntAttribute(
- AX_ATTR_COLOR_VALUE)); // todo, why the static cast?
+ ax::mojom::IntAttribute::kColorValue)); // todo, why the static cast?
unsigned int red = SkColorGetR(color);
unsigned int green = SkColorGetG(color);
@@ -776,8 +782,8 @@ STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) {
//
// Document special case (Use the document's URL)
//
- if (target->GetData().role == AX_ROLE_ROOT_WEB_AREA ||
- target->GetData().role == AX_ROLE_WEB_AREA) {
+ if (target->GetData().role == ax::mojom::Role::kRootWebArea ||
+ target->GetData().role == ax::mojom::Role::kWebArea) {
result = base::UTF8ToUTF16(target->delegate_->GetTreeData().url);
*value = SysAllocString(result.c_str());
DCHECK(*value);
@@ -785,10 +791,10 @@ STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) {
}
//
- // Links (Use AX_ATTR_URL)
+ // Links (Use ax::mojom::StringAttribute::kUrl)
//
- if (target->GetData().role == AX_ROLE_LINK) {
- result = target->GetString16Attribute(AX_ATTR_URL);
+ if (target->GetData().role == ax::mojom::Role::kLink) {
+ result = target->GetString16Attribute(ax::mojom::StringAttribute::kUrl);
*value = SysAllocString(result.c_str());
DCHECK(*value);
return S_OK;
@@ -797,11 +803,12 @@ STDMETHODIMP AXPlatformNodeWin::get_accValue(VARIANT var_id, BSTR* value) {
// For range controls, e.g. sliders and spin buttons, |ax_attr_value| holds
// the aria-valuetext if present but not the inner text. The actual value,
// provided either via aria-valuenow or the actual control's value is held in
- // |AX_ATTR_VALUE_FOR_RANGE|.
- result = target->GetString16Attribute(AX_ATTR_VALUE);
+ // |ax::mojom::FloatAttribute::kValueForRange|.
+ result = target->GetString16Attribute(ax::mojom::StringAttribute::kValue);
if (result.empty() && target->IsRangeValueSupported()) {
float fval;
- if (target->GetFloatAttribute(AX_ATTR_VALUE_FOR_RANGE, &fval)) {
+ if (target->GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange,
+ &fval)) {
result = base::NumberToString16(fval);
*value = SysAllocString(result.c_str());
DCHECK(*value);
@@ -823,7 +830,7 @@ STDMETHODIMP AXPlatformNodeWin::put_accValue(VARIANT var_id,
COM_OBJECT_VALIDATE_VAR_ID_AND_GET_TARGET(var_id, target);
AXActionData data;
- data.action = AX_ACTION_SET_VALUE;
+ data.action = ax::mojom::Action::kSetValue;
data.value = new_value;
if (target->delegate_->AccessibilityPerformAction(data))
return S_OK;
@@ -837,7 +844,7 @@ STDMETHODIMP AXPlatformNodeWin::get_accSelection(VARIANT* selected) {
for (int i = 0; i < delegate_->GetChildCount(); ++i) {
auto* node = static_cast<AXPlatformNodeWin*>(
FromNativeViewAccessible(delegate_->ChildAtIndex(i)));
- if (node && node->GetData().HasState(AX_STATE_SELECTED))
+ if (node && node->GetData().HasState(ax::mojom::State::kSelected))
selected_nodes.emplace_back(node);
}
@@ -874,7 +881,7 @@ STDMETHODIMP AXPlatformNodeWin::accSelect(
if (flagsSelect & SELFLAG_TAKEFOCUS) {
AXActionData action_data;
- action_data.action = AX_ACTION_FOCUS;
+ action_data.action = ax::mojom::Action::kFocus;
target->delegate_->AccessibilityPerformAction(action_data);
return S_OK;
}
@@ -1120,9 +1127,9 @@ STDMETHODIMP AXPlatformNodeWin::get_groupPosition(LONG* group_level,
position_in_group);
AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
- *group_level = GetIntAttribute(ui::AX_ATTR_HIERARCHICAL_LEVEL);
- *similar_items_in_group = GetIntAttribute(ui::AX_ATTR_SET_SIZE);
- *position_in_group = GetIntAttribute(ui::AX_ATTR_POS_IN_SET);
+ *group_level = GetIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel);
+ *similar_items_in_group = GetIntAttribute(ax::mojom::IntAttribute::kSetSize);
+ *position_in_group = GetIntAttribute(ax::mojom::IntAttribute::kPosInSet);
if (!*group_level && !*similar_items_in_group && !*position_in_group)
return S_FALSE;
@@ -1135,7 +1142,7 @@ STDMETHODIMP AXPlatformNodeWin::get_localizedExtendedRole(
COM_OBJECT_VALIDATE_1_ARG(localized_extended_role);
AXPlatformNode::NotifyAddAXModeFlags(kScreenReaderAndHTMLAccessibilityModes);
- return GetStringAttributeAsBstr(ui::AX_ATTR_ROLE_DESCRIPTION,
+ return GetStringAttributeAsBstr(ax::mojom::StringAttribute::kRoleDescription,
localized_extended_role);
}
@@ -1154,7 +1161,8 @@ STDMETHODIMP AXPlatformNodeWin::scrollTo(enum IA2ScrollType scroll_type) {
COM_OBJECT_VALIDATE();
WIN_ACCESSIBILITY_API_HISTOGRAM(UMA_API_IA2_SCROLL_TO);
- // AX_ACTION_SCROLL_TO_MAKE_VISIBLE wants a target rect in *local* coords.
+ // ax::mojom::Action::kScrollToMakeVisible wants a target rect in *local*
+ // coords.
gfx::Rect r = gfx::ToEnclosingRect(GetData().location);
r.Offset(-r.OffsetFromOrigin());
switch (scroll_type) {
@@ -1183,7 +1191,7 @@ STDMETHODIMP AXPlatformNodeWin::scrollTo(enum IA2ScrollType scroll_type) {
ui::AXActionData action_data;
action_data.target_node_id = GetData().id;
- action_data.action = ui::AX_ACTION_SCROLL_TO_MAKE_VISIBLE;
+ action_data.action = ax::mojom::Action::kScrollToMakeVisible;
action_data.target_rect = r;
delegate_->AccessibilityPerformAction(action_data);
return S_OK;
@@ -1200,11 +1208,12 @@ STDMETHODIMP AXPlatformNodeWin::scrollToPoint(
gfx::Point scroll_to(x, y);
if (coordinate_type == IA2_COORDTYPE_SCREEN_RELATIVE) {
- scroll_to -= delegate_->GetScreenBoundsRect().OffsetFromOrigin();
+ scroll_to -= delegate_->GetUnclippedScreenBoundsRect().OffsetFromOrigin();
} else if (coordinate_type == IA2_COORDTYPE_PARENT_RELATIVE) {
if (GetParent()) {
AXPlatformNodeBase* base = FromNativeViewAccessible(GetParent());
- scroll_to += base->delegate_->GetScreenBoundsRect().OffsetFromOrigin();
+ scroll_to +=
+ base->delegate_->GetUnclippedScreenBoundsRect().OffsetFromOrigin();
}
} else {
return E_INVALIDARG;
@@ -1212,7 +1221,7 @@ STDMETHODIMP AXPlatformNodeWin::scrollToPoint(
ui::AXActionData action_data;
action_data.target_node_id = GetData().id;
- action_data.action = ui::AX_ACTION_SCROLL_TO_POINT;
+ action_data.action = ax::mojom::Action::kScrollToPoint;
action_data.target_point = scroll_to;
delegate_->AccessibilityPerformAction(action_data);
return S_OK;
@@ -1328,14 +1337,16 @@ STDMETHODIMP AXPlatformNodeWin::get_columnDescription(LONG column,
for (int r = 0; r < rows; ++r) {
AXPlatformNodeBase* cell = GetTableCell(r, column);
- if (cell && cell->GetData().role == AX_ROLE_COLUMN_HEADER) {
- base::string16 cell_name = cell->GetString16Attribute(AX_ATTR_NAME);
+ if (cell && cell->GetData().role == ax::mojom::Role::kColumnHeader) {
+ base::string16 cell_name =
+ cell->GetString16Attribute(ax::mojom::StringAttribute::kName);
if (cell_name.size() > 0) {
*description = SysAllocString(cell_name.c_str());
return S_OK;
}
- cell_name = cell->GetString16Attribute(AX_ATTR_DESCRIPTION);
+ cell_name =
+ cell->GetString16Attribute(ax::mojom::StringAttribute::kDescription);
if (cell_name.size() > 0) {
*description = SysAllocString(cell_name.c_str());
return S_OK;
@@ -1429,7 +1440,7 @@ STDMETHODIMP AXPlatformNodeWin::get_nSelectedChildren(LONG* cell_count) {
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < columns; ++c) {
AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (cell && cell->GetData().HasState(AX_STATE_SELECTED))
+ if (cell && cell->GetData().HasState(ax::mojom::State::kSelected))
result++;
}
}
@@ -1456,7 +1467,7 @@ STDMETHODIMP AXPlatformNodeWin::get_nSelectedColumns(LONG* column_count) {
bool selected = true;
for (int r = 0; r < rows && selected == true; ++r) {
AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (!cell || !(cell->GetData().HasState(AX_STATE_SELECTED)))
+ if (!cell || !(cell->GetData().HasState(ax::mojom::State::kSelected)))
selected = false;
}
if (selected)
@@ -1486,7 +1497,7 @@ STDMETHODIMP AXPlatformNodeWin::get_nSelectedRows(LONG* row_count) {
bool selected = true;
for (int c = 0; c < columns && selected == true; ++c) {
AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (!cell || !(cell->GetData().HasState(AX_STATE_SELECTED)))
+ if (!cell || !(cell->GetData().HasState(ax::mojom::State::kSelected)))
selected = false;
}
if (selected)
@@ -1516,13 +1527,15 @@ STDMETHODIMP AXPlatformNodeWin::get_rowDescription(LONG row,
for (int c = 0; c < columns; ++c) {
AXPlatformNodeBase* cell = GetTableCell(row, c);
- if (cell && cell->GetData().role == AX_ROLE_ROW_HEADER) {
- base::string16 cell_name = cell->GetString16Attribute(AX_ATTR_NAME);
+ if (cell && cell->GetData().role == ax::mojom::Role::kRowHeader) {
+ base::string16 cell_name =
+ cell->GetString16Attribute(ax::mojom::StringAttribute::kName);
if (cell_name.size() > 0) {
*description = SysAllocString(cell_name.c_str());
return S_OK;
}
- cell_name = cell->GetString16Attribute(AX_ATTR_DESCRIPTION);
+ cell_name =
+ cell->GetString16Attribute(ax::mojom::StringAttribute::kDescription);
if (cell_name.size() > 0) {
*description = SysAllocString(cell_name.c_str());
return S_OK;
@@ -1594,7 +1607,7 @@ STDMETHODIMP AXPlatformNodeWin::get_selectedChildren(LONG max_children,
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < columns; ++c) {
AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (cell && cell->GetData().HasState(AX_STATE_SELECTED))
+ if (cell && cell->GetData().HasState(ax::mojom::State::kSelected))
// index is row index * column count + column index.
results.push_back(r * columns + c);
}
@@ -1623,7 +1636,7 @@ STDMETHODIMP AXPlatformNodeWin::get_selectedColumns(LONG max_columns,
bool selected = true;
for (int r = 0; r < row_count && selected == true; ++r) {
AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (!cell || !(cell->GetData().HasState(AX_STATE_SELECTED)))
+ if (!cell || !(cell->GetData().HasState(ax::mojom::State::kSelected)))
selected = false;
}
if (selected)
@@ -1651,7 +1664,7 @@ STDMETHODIMP AXPlatformNodeWin::get_selectedRows(LONG max_rows,
bool selected = true;
for (int c = 0; c < column_count && selected == true; ++c) {
AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (!cell || !(cell->GetData().HasState(AX_STATE_SELECTED)))
+ if (!cell || !(cell->GetData().HasState(ax::mojom::State::kSelected)))
selected = false;
}
if (selected)
@@ -1688,7 +1701,7 @@ STDMETHODIMP AXPlatformNodeWin::get_isColumnSelected(LONG column,
for (int r = 0; r < rows; ++r) {
AXPlatformNodeBase* cell = GetTableCell(r, column);
- if (!cell || !(cell->GetData().HasState(AX_STATE_SELECTED)))
+ if (!cell || !(cell->GetData().HasState(ax::mojom::State::kSelected)))
return S_OK;
}
@@ -1711,7 +1724,7 @@ STDMETHODIMP AXPlatformNodeWin::get_isRowSelected(LONG row,
for (int c = 0; c < columns; ++c) {
AXPlatformNodeBase* cell = GetTableCell(row, c);
- if (!cell || !(cell->GetData().HasState(AX_STATE_SELECTED)))
+ if (!cell || !(cell->GetData().HasState(ax::mojom::State::kSelected)))
return S_OK;
}
@@ -1735,7 +1748,7 @@ STDMETHODIMP AXPlatformNodeWin::get_isSelected(LONG row,
return S_FALSE;
AXPlatformNodeBase* cell = GetTableCell(row, column);
- if (cell && cell->GetData().HasState(AX_STATE_SELECTED))
+ if (cell && cell->GetData().HasState(ax::mojom::State::kSelected))
*is_selected = true;
return S_OK;
@@ -1852,7 +1865,7 @@ STDMETHODIMP AXPlatformNodeWin::get_selectedCells(IUnknown*** cells,
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < columns; ++c) {
AXPlatformNodeBase* cell = GetTableCell(r, c);
- if (cell && cell->GetData().HasState(AX_STATE_SELECTED))
+ if (cell && cell->GetData().HasState(ax::mojom::State::kSelected))
selected.push_back(cell);
}
}
@@ -1901,7 +1914,7 @@ STDMETHODIMP AXPlatformNodeWin::get_columnHeaderCells(
return E_INVALIDARG;
*n_column_header_cells = 0;
- if (GetData().role != AX_ROLE_CELL)
+ if (GetData().role != ax::mojom::Role::kCell)
return S_FALSE;
AXPlatformNodeBase* table = GetTable();
@@ -1917,7 +1930,7 @@ STDMETHODIMP AXPlatformNodeWin::get_columnHeaderCells(
for (int r = 0; r < rows; ++r) {
AXPlatformNodeBase* cell = GetTableCell(r, column);
- if (cell && cell->GetData().role == AX_ROLE_COLUMN_HEADER)
+ if (cell && cell->GetData().role == ax::mojom::Role::kColumnHeader)
(*n_column_header_cells)++;
}
@@ -1926,7 +1939,7 @@ STDMETHODIMP AXPlatformNodeWin::get_columnHeaderCells(
int index = 0;
for (int r = 0; r < rows; ++r) {
AXPlatformNodeBase* cell = GetTableCell(r, column);
- if (cell && cell->GetData().role == AX_ROLE_COLUMN_HEADER) {
+ if (cell && cell->GetData().role == ax::mojom::Role::kColumnHeader) {
auto* node_win = static_cast<AXPlatformNodeWin*>(cell);
node_win->AddRef();
@@ -1969,7 +1982,7 @@ STDMETHODIMP AXPlatformNodeWin::get_rowHeaderCells(IUnknown*** cell_accessibles,
return E_INVALIDARG;
*n_row_header_cells = 0;
- if (GetData().role != AX_ROLE_CELL)
+ if (GetData().role != ax::mojom::Role::kCell)
return S_FALSE;
AXPlatformNodeBase* table = GetTable();
@@ -1985,7 +1998,7 @@ STDMETHODIMP AXPlatformNodeWin::get_rowHeaderCells(IUnknown*** cell_accessibles,
for (int c = 0; c < columns; ++c) {
AXPlatformNodeBase* cell = GetTableCell(row, c);
- if (cell && cell->GetData().role == AX_ROLE_ROW_HEADER)
+ if (cell && cell->GetData().role == ax::mojom::Role::kRowHeader)
(*n_row_header_cells)++;
}
@@ -1994,7 +2007,7 @@ STDMETHODIMP AXPlatformNodeWin::get_rowHeaderCells(IUnknown*** cell_accessibles,
int index = 0;
for (int c = 0; c < columns; ++c) {
AXPlatformNodeBase* cell = GetTableCell(row, c);
- if (cell && cell->GetData().role == AX_ROLE_ROW_HEADER) {
+ if (cell && cell->GetData().role == ax::mojom::Role::kRowHeader) {
auto* node_win = static_cast<AXPlatformNodeWin*>(cell);
node_win->AddRef();
@@ -2284,7 +2297,7 @@ STDMETHODIMP AXPlatformNodeWin::removeSelection(LONG selection_index) {
return E_INVALIDARG;
// Simply collapse the selection to the position of the caret if a caret is
// visible, otherwise set the selection to 0.
- return setCaretOffset(GetIntAttribute(AX_ATTR_TEXT_SEL_END));
+ return setCaretOffset(GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd));
}
STDMETHODIMP AXPlatformNodeWin::setCaretOffset(LONG offset) {
@@ -2394,345 +2407,360 @@ int AXPlatformNodeWin::MSAARole() {
return ROLE_SYSTEM_GROUPING;
switch (GetData().role) {
- case AX_ROLE_ALERT:
+ case ax::mojom::Role::kAlert:
return ROLE_SYSTEM_ALERT;
- case AX_ROLE_ALERT_DIALOG:
+ case ax::mojom::Role::kAlertDialog:
return ROLE_SYSTEM_DIALOG;
- case AX_ROLE_ANCHOR:
+ case ax::mojom::Role::kAnchor:
return ROLE_SYSTEM_LINK;
- case AX_ROLE_APPLICATION:
+ case ax::mojom::Role::kApplication:
return ROLE_SYSTEM_APPLICATION;
- case AX_ROLE_ARTICLE:
+ case ax::mojom::Role::kArticle:
return ROLE_SYSTEM_DOCUMENT;
- case AX_ROLE_AUDIO:
+ case ax::mojom::Role::kAudio:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_BANNER:
+ case ax::mojom::Role::kBanner:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_BUTTON:
+ case ax::mojom::Role::kButton:
return ROLE_SYSTEM_PUSHBUTTON;
- case AX_ROLE_CANVAS:
+ case ax::mojom::Role::kCanvas:
return ROLE_SYSTEM_GRAPHIC;
- case AX_ROLE_CAPTION:
+ case ax::mojom::Role::kCaption:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_CELL:
+ case ax::mojom::Role::kCell:
return ROLE_SYSTEM_CELL;
- case AX_ROLE_CHECK_BOX:
+ case ax::mojom::Role::kCheckBox:
return ROLE_SYSTEM_CHECKBUTTON;
- case AX_ROLE_COLOR_WELL:
+ case ax::mojom::Role::kColorWell:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_COLUMN:
+ case ax::mojom::Role::kColumn:
return ROLE_SYSTEM_COLUMN;
- case AX_ROLE_COLUMN_HEADER:
+ case ax::mojom::Role::kColumnHeader:
return ROLE_SYSTEM_COLUMNHEADER;
- case AX_ROLE_COMBO_BOX_GROUPING:
- case AX_ROLE_COMBO_BOX_MENU_BUTTON:
+ case ax::mojom::Role::kComboBoxGrouping:
+ case ax::mojom::Role::kComboBoxMenuButton:
return ROLE_SYSTEM_COMBOBOX;
- case AX_ROLE_COMPLEMENTARY:
+ case ax::mojom::Role::kComplementary:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_CONTENT_INFO:
+ case ax::mojom::Role::kContentInfo:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_DATE:
- case AX_ROLE_DATE_TIME:
+ case ax::mojom::Role::kDate:
+ case ax::mojom::Role::kDateTime:
return ROLE_SYSTEM_DROPLIST;
- case AX_ROLE_DESCRIPTION_LIST_DETAIL:
+ case ax::mojom::Role::kDescriptionListDetail:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_DESCRIPTION_LIST:
+ case ax::mojom::Role::kDescriptionList:
return ROLE_SYSTEM_LIST;
- case AX_ROLE_DESCRIPTION_LIST_TERM:
+ case ax::mojom::Role::kDescriptionListTerm:
return ROLE_SYSTEM_LISTITEM;
- case AX_ROLE_DETAILS:
+ case ax::mojom::Role::kDetails:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_DIALOG:
+ case ax::mojom::Role::kDialog:
return ROLE_SYSTEM_DIALOG;
- case AX_ROLE_DISCLOSURE_TRIANGLE:
+ case ax::mojom::Role::kDisclosureTriangle:
return ROLE_SYSTEM_PUSHBUTTON;
- case AX_ROLE_DOCUMENT:
- case AX_ROLE_ROOT_WEB_AREA:
- case AX_ROLE_WEB_AREA:
+ case ax::mojom::Role::kDocument:
+ case ax::mojom::Role::kRootWebArea:
+ case ax::mojom::Role::kWebArea:
return ROLE_SYSTEM_DOCUMENT;
- case AX_ROLE_EMBEDDED_OBJECT:
+ case ax::mojom::Role::kEmbeddedObject:
if (delegate_->GetChildCount()) {
return ROLE_SYSTEM_GROUPING;
} else {
return ROLE_SYSTEM_CLIENT;
}
- case AX_ROLE_FIGURE:
+ case ax::mojom::Role::kFigure:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_FEED:
+ case ax::mojom::Role::kFeed:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_GENERIC_CONTAINER:
+ case ax::mojom::Role::kGenericContainer:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_GRID:
+ case ax::mojom::Role::kGrid:
return ROLE_SYSTEM_TABLE;
- case AX_ROLE_GROUP:
+ case ax::mojom::Role::kGroup:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_HEADING:
+ case ax::mojom::Role::kHeading:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_IFRAME:
+ case ax::mojom::Role::kIframe:
return ROLE_SYSTEM_DOCUMENT;
- case AX_ROLE_IFRAME_PRESENTATIONAL:
+ case ax::mojom::Role::kIframePresentational:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_IMAGE:
+ case ax::mojom::Role::kImage:
return ROLE_SYSTEM_GRAPHIC;
- case AX_ROLE_INPUT_TIME:
+ case ax::mojom::Role::kInputTime:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_LABEL_TEXT:
- case AX_ROLE_LEGEND:
+ case ax::mojom::Role::kLabelText:
+ case ax::mojom::Role::kLegend:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_LINK:
+ case ax::mojom::Role::kLayoutTable:
+ return ROLE_SYSTEM_TABLE;
+
+ case ax::mojom::Role::kLayoutTableCell:
+ return ROLE_SYSTEM_CELL;
+
+ case ax::mojom::Role::kLayoutTableColumn:
+ return ROLE_SYSTEM_COLUMN;
+
+ case ax::mojom::Role::kLayoutTableRow:
+ return ROLE_SYSTEM_ROW;
+
+ case ax::mojom::Role::kLink:
return ROLE_SYSTEM_LINK;
- case AX_ROLE_LIST:
+ case ax::mojom::Role::kList:
return ROLE_SYSTEM_LIST;
- case AX_ROLE_LIST_BOX:
+ case ax::mojom::Role::kListBox:
return ROLE_SYSTEM_LIST;
- case AX_ROLE_LIST_BOX_OPTION:
+ case ax::mojom::Role::kListBoxOption:
return ROLE_SYSTEM_LISTITEM;
- case AX_ROLE_LIST_ITEM:
+ case ax::mojom::Role::kListItem:
return ROLE_SYSTEM_LISTITEM;
- case AX_ROLE_MAIN:
+ case ax::mojom::Role::kMain:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_MARK:
+ case ax::mojom::Role::kMark:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_MARQUEE:
+ case ax::mojom::Role::kMarquee:
return ROLE_SYSTEM_ANIMATION;
- case AX_ROLE_MATH:
+ case ax::mojom::Role::kMath:
return ROLE_SYSTEM_EQUATION;
- case AX_ROLE_MENU:
- case AX_ROLE_MENU_BUTTON:
+ case ax::mojom::Role::kMenu:
+ case ax::mojom::Role::kMenuButton:
return ROLE_SYSTEM_MENUPOPUP;
- case AX_ROLE_MENU_BAR:
+ case ax::mojom::Role::kMenuBar:
return ROLE_SYSTEM_MENUBAR;
- case AX_ROLE_MENU_ITEM:
+ case ax::mojom::Role::kMenuItem:
return ROLE_SYSTEM_MENUITEM;
- case AX_ROLE_MENU_ITEM_CHECK_BOX:
+ case ax::mojom::Role::kMenuItemCheckBox:
return ROLE_SYSTEM_MENUITEM;
- case AX_ROLE_MENU_ITEM_RADIO:
+ case ax::mojom::Role::kMenuItemRadio:
return ROLE_SYSTEM_MENUITEM;
- case ui::AX_ROLE_MENU_LIST_POPUP:
+ case ax::mojom::Role::kMenuListPopup:
if (IsAncestorComboBox())
return ROLE_SYSTEM_LIST;
return ROLE_SYSTEM_MENUPOPUP;
- case ui::AX_ROLE_MENU_LIST_OPTION:
+ case ax::mojom::Role::kMenuListOption:
if (IsAncestorComboBox())
return ROLE_SYSTEM_LISTITEM;
return ROLE_SYSTEM_MENUITEM;
- case AX_ROLE_METER:
+ case ax::mojom::Role::kMeter:
return ROLE_SYSTEM_PROGRESSBAR;
- case AX_ROLE_NAVIGATION:
+ case ax::mojom::Role::kNavigation:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_NOTE:
+ case ax::mojom::Role::kNote:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_POP_UP_BUTTON: {
- std::string html_tag = GetData().GetStringAttribute(AX_ATTR_HTML_TAG);
+ case ax::mojom::Role::kPopUpButton: {
+ std::string html_tag =
+ GetData().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
if (html_tag == "select")
return ROLE_SYSTEM_COMBOBOX;
return ROLE_SYSTEM_BUTTONMENU;
}
- case AX_ROLE_PRE:
+ case ax::mojom::Role::kPre:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_PROGRESS_INDICATOR:
+ case ax::mojom::Role::kProgressIndicator:
return ROLE_SYSTEM_PROGRESSBAR;
- case AX_ROLE_RADIO_BUTTON:
+ case ax::mojom::Role::kRadioButton:
return ROLE_SYSTEM_RADIOBUTTON;
- case AX_ROLE_RADIO_GROUP:
+ case ax::mojom::Role::kRadioGroup:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_REGION: {
- std::string html_tag = GetData().GetStringAttribute(AX_ATTR_HTML_TAG);
+ case ax::mojom::Role::kRegion: {
+ std::string html_tag =
+ GetData().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
if (html_tag == "section")
return ROLE_SYSTEM_GROUPING;
return ROLE_SYSTEM_PANE;
}
- case AX_ROLE_ROW: {
+ case ax::mojom::Role::kRow: {
// Role changes depending on whether row is inside a treegrid
// https://www.w3.org/TR/core-aam-1.1/#role-map-row
return IsInTreeGrid() ? ROLE_SYSTEM_OUTLINEITEM : ROLE_SYSTEM_ROW;
}
- case AX_ROLE_ROW_HEADER:
+ case ax::mojom::Role::kRowHeader:
return ROLE_SYSTEM_ROWHEADER;
- case AX_ROLE_RUBY:
+ case ax::mojom::Role::kRuby:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_SCROLL_BAR:
+ case ax::mojom::Role::kScrollBar:
return ROLE_SYSTEM_SCROLLBAR;
- case AX_ROLE_SEARCH:
+ case ax::mojom::Role::kSearch:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_SLIDER:
+ case ax::mojom::Role::kSlider:
return ROLE_SYSTEM_SLIDER;
- case AX_ROLE_SPIN_BUTTON:
+ case ax::mojom::Role::kSpinButton:
return ROLE_SYSTEM_SPINBUTTON;
- case AX_ROLE_SPIN_BUTTON_PART:
+ case ax::mojom::Role::kSpinButtonPart:
return ROLE_SYSTEM_PUSHBUTTON;
- case AX_ROLE_ANNOTATION:
- case AX_ROLE_LIST_MARKER:
- case AX_ROLE_STATIC_TEXT:
+ case ax::mojom::Role::kAnnotation:
+ case ax::mojom::Role::kListMarker:
+ case ax::mojom::Role::kStaticText:
return ROLE_SYSTEM_STATICTEXT;
- case AX_ROLE_STATUS:
+ case ax::mojom::Role::kStatus:
return ROLE_SYSTEM_STATUSBAR;
- case AX_ROLE_SPLITTER:
+ case ax::mojom::Role::kSplitter:
return ROLE_SYSTEM_SEPARATOR;
- case AX_ROLE_SVG_ROOT:
+ case ax::mojom::Role::kSvgRoot:
return ROLE_SYSTEM_GRAPHIC;
- case AX_ROLE_TAB:
+ case ax::mojom::Role::kTab:
return ROLE_SYSTEM_PAGETAB;
- case AX_ROLE_TABLE:
+ case ax::mojom::Role::kTable:
return ROLE_SYSTEM_TABLE;
- case AX_ROLE_TABLE_HEADER_CONTAINER:
+ case ax::mojom::Role::kTableHeaderContainer:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_TAB_LIST:
+ case ax::mojom::Role::kTabList:
return ROLE_SYSTEM_PAGETABLIST;
- case AX_ROLE_TAB_PANEL:
+ case ax::mojom::Role::kTabPanel:
return ROLE_SYSTEM_PROPERTYPAGE;
- case AX_ROLE_TERM:
+ case ax::mojom::Role::kTerm:
return ROLE_SYSTEM_LISTITEM;
- case AX_ROLE_TOGGLE_BUTTON:
+ case ax::mojom::Role::kTitleBar:
+ return ROLE_SYSTEM_TITLEBAR;
+
+ case ax::mojom::Role::kToggleButton:
return ROLE_SYSTEM_PUSHBUTTON;
- case AX_ROLE_TEXT_FIELD:
- case AX_ROLE_SEARCH_BOX:
+ case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kSearchBox:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX:
+ case ax::mojom::Role::kTextFieldWithComboBox:
return ROLE_SYSTEM_COMBOBOX;
- case AX_ROLE_ABBR:
- case AX_ROLE_TIME:
+ case ax::mojom::Role::kAbbr:
+ case ax::mojom::Role::kTime:
return ROLE_SYSTEM_TEXT;
- case AX_ROLE_TIMER:
+ case ax::mojom::Role::kTimer:
return ROLE_SYSTEM_CLOCK;
- case AX_ROLE_TOOLBAR:
+ case ax::mojom::Role::kToolbar:
return ROLE_SYSTEM_TOOLBAR;
- case AX_ROLE_TOOLTIP:
+ case ax::mojom::Role::kTooltip:
return ROLE_SYSTEM_TOOLTIP;
- case AX_ROLE_TREE:
+ case ax::mojom::Role::kTree:
return ROLE_SYSTEM_OUTLINE;
- case AX_ROLE_TREE_GRID:
+ case ax::mojom::Role::kTreeGrid:
return ROLE_SYSTEM_OUTLINE;
- case AX_ROLE_TREE_ITEM:
+ case ax::mojom::Role::kTreeItem:
return ROLE_SYSTEM_OUTLINEITEM;
- case AX_ROLE_LINE_BREAK:
+ case ax::mojom::Role::kLineBreak:
return ROLE_SYSTEM_WHITESPACE;
- case AX_ROLE_VIDEO:
+ case ax::mojom::Role::kVideo:
return ROLE_SYSTEM_GROUPING;
- case AX_ROLE_WINDOW:
+ case ax::mojom::Role::kWindow:
// Do not return ROLE_SYSTEM_WINDOW as that is a special MSAA system role
// used to indicate a real native window object. It is automatically
// created by oleacc.dll as a parent of the root of our hierarchy,
// matching the HWND.
- return ROLE_SYSTEM_APPLICATION;
+ return ROLE_SYSTEM_PANE;
// TODO(dmazzoni): figure out the proper MSAA role for roles listed below.
- case AX_ROLE_BLOCKQUOTE:
- case AX_ROLE_BUTTON_DROP_DOWN:
- case AX_ROLE_CARET:
- case AX_ROLE_CLIENT:
- case AX_ROLE_DEFINITION:
- case AX_ROLE_DESKTOP:
- case AX_ROLE_DIRECTORY:
- case AX_ROLE_FIGCAPTION:
- case AX_ROLE_FOOTER:
- case AX_ROLE_FORM:
- case AX_ROLE_IGNORED:
- case AX_ROLE_IMAGE_MAP:
- case AX_ROLE_INLINE_TEXT_BOX:
- case AX_ROLE_LOCATION_BAR:
- case AX_ROLE_LOG:
- case AX_ROLE_NONE:
- case AX_ROLE_PANE:
- case AX_ROLE_PARAGRAPH:
- case AX_ROLE_PRESENTATIONAL:
- case AX_ROLE_SLIDER_THUMB:
- case AX_ROLE_SWITCH:
- case AX_ROLE_TITLE_BAR:
- case AX_ROLE_UNKNOWN:
- case AX_ROLE_WEB_VIEW:
+ case ax::mojom::Role::kBlockquote:
+ case ax::mojom::Role::kCaret:
+ case ax::mojom::Role::kClient:
+ case ax::mojom::Role::kDefinition:
+ case ax::mojom::Role::kDesktop:
+ case ax::mojom::Role::kDirectory:
+ case ax::mojom::Role::kFigcaption:
+ case ax::mojom::Role::kFooter:
+ case ax::mojom::Role::kForm:
+ case ax::mojom::Role::kIgnored:
+ case ax::mojom::Role::kImageMap:
+ case ax::mojom::Role::kInlineTextBox:
+ case ax::mojom::Role::kLocationBar:
+ case ax::mojom::Role::kLog:
+ case ax::mojom::Role::kNone:
+ case ax::mojom::Role::kPane:
+ case ax::mojom::Role::kParagraph:
+ case ax::mojom::Role::kPresentational:
+ case ax::mojom::Role::kSliderThumb:
+ case ax::mojom::Role::kSwitch:
+ case ax::mojom::Role::kUnknown:
+ case ax::mojom::Role::kWebView:
return ROLE_SYSTEM_CLIENT;
}
@@ -2741,40 +2769,42 @@ int AXPlatformNodeWin::MSAARole() {
}
std::string AXPlatformNodeWin::StringOverrideForMSAARole() {
- std::string html_tag = GetData().GetStringAttribute(AX_ATTR_HTML_TAG);
+ std::string html_tag =
+ GetData().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
switch (GetData().role) {
- case AX_ROLE_BLOCKQUOTE:
- case AX_ROLE_DEFINITION:
- case AX_ROLE_IMAGE_MAP:
+ case ax::mojom::Role::kBlockquote:
+ case ax::mojom::Role::kDefinition:
+ case ax::mojom::Role::kImageMap:
return html_tag;
- case AX_ROLE_CANVAS:
- if (GetData().GetBoolAttribute(AX_ATTR_CANVAS_HAS_FALLBACK)) {
+ case ax::mojom::Role::kCanvas:
+ if (GetData().GetBoolAttribute(
+ ax::mojom::BoolAttribute::kCanvasHasFallback)) {
return html_tag;
}
break;
- case AX_ROLE_FORM:
+ case ax::mojom::Role::kForm:
// This could be a div with the role of form
// so we return just the string "form".
return "form";
- case AX_ROLE_HEADING:
+ case ax::mojom::Role::kHeading:
if (!html_tag.empty())
return html_tag;
break;
- case AX_ROLE_PARAGRAPH:
+ case ax::mojom::Role::kParagraph:
return html_tag;
- case AX_ROLE_GENERIC_CONTAINER:
+ case ax::mojom::Role::kGenericContainer:
// TODO(dougt) why can't we always use div in this case?
if (html_tag.empty())
return "div";
return html_tag;
- case AX_ROLE_SWITCH:
+ case ax::mojom::Role::kSwitch:
return "switch";
default:
@@ -2785,8 +2815,8 @@ std::string AXPlatformNodeWin::StringOverrideForMSAARole() {
}
bool AXPlatformNodeWin::IsWebAreaForPresentationalIframe() {
- if (GetData().role != AX_ROLE_WEB_AREA &&
- GetData().role != AX_ROLE_ROOT_WEB_AREA) {
+ if (GetData().role != ax::mojom::Role::kWebArea &&
+ GetData().role != ax::mojom::Role::kRootWebArea) {
return false;
}
@@ -2794,34 +2824,34 @@ bool AXPlatformNodeWin::IsWebAreaForPresentationalIframe() {
if (!parent)
return false;
- return parent->GetData().role == AX_ROLE_IFRAME_PRESENTATIONAL;
+ return parent->GetData().role == ax::mojom::Role::kIframePresentational;
}
int32_t AXPlatformNodeWin::ComputeIA2State() {
const AXNodeData& data = GetData();
int32_t ia2_state = IA2_STATE_OPAQUE;
- const auto checked_state =
- static_cast<AXCheckedState>(GetIntAttribute(AX_ATTR_CHECKED_STATE));
- if (checked_state) {
+ const auto checked_state = data.GetCheckedState();
+ if (checked_state != ax::mojom::CheckedState::kNone) {
ia2_state |= IA2_STATE_CHECKABLE;
}
- if (HasIntAttribute(AX_ATTR_INVALID_STATE) &&
- GetIntAttribute(AX_ATTR_INVALID_STATE) != AX_INVALID_STATE_FALSE)
+ if (HasIntAttribute(ax::mojom::IntAttribute::kInvalidState) &&
+ GetIntAttribute(ax::mojom::IntAttribute::kInvalidState) !=
+ static_cast<int32_t>(ax::mojom::InvalidState::kFalse))
ia2_state |= IA2_STATE_INVALID_ENTRY;
- if (data.HasState(AX_STATE_REQUIRED))
+ if (data.HasState(ax::mojom::State::kRequired))
ia2_state |= IA2_STATE_REQUIRED;
- if (data.HasState(AX_STATE_VERTICAL))
+ if (data.HasState(ax::mojom::State::kVertical))
ia2_state |= IA2_STATE_VERTICAL;
- if (data.HasState(AX_STATE_HORIZONTAL))
+ if (data.HasState(ax::mojom::State::kHorizontal))
ia2_state |= IA2_STATE_HORIZONTAL;
- if (data.HasState(AX_STATE_EDITABLE))
+ if (data.HasState(ax::mojom::State::kEditable))
ia2_state |= IA2_STATE_EDITABLE;
if (IsPlainTextField() || IsRichTextField()) {
- if (data.HasState(AX_STATE_MULTILINE)) {
+ if (data.HasState(ax::mojom::State::kMultiline)) {
ia2_state |= IA2_STATE_MULTI_LINE;
} else {
ia2_state |= IA2_STATE_SINGLE_LINE;
@@ -2829,15 +2859,15 @@ int32_t AXPlatformNodeWin::ComputeIA2State() {
ia2_state |= IA2_STATE_SELECTABLE_TEXT;
}
- if (!GetStringAttribute(AX_ATTR_AUTO_COMPLETE).empty())
+ if (!GetStringAttribute(ax::mojom::StringAttribute::kAutoComplete).empty())
ia2_state |= IA2_STATE_SUPPORTS_AUTOCOMPLETION;
- if (GetBoolAttribute(AX_ATTR_MODAL))
+ if (GetBoolAttribute(ax::mojom::BoolAttribute::kModal))
ia2_state |= IA2_STATE_MODAL;
switch (data.role) {
- case AX_ROLE_MENU_LIST_POPUP:
- case AX_ROLE_MENU_LIST_OPTION:
+ case ax::mojom::Role::kMenuListPopup:
+ case ax::mojom::Role::kMenuListOption:
ia2_state &= ~(IA2_STATE_EDITABLE);
break;
default:
@@ -2859,117 +2889,118 @@ int32_t AXPlatformNodeWin::ComputeIA2Role() {
int32_t ia2_role = 0;
switch (GetData().role) {
- case AX_ROLE_BANNER:
+ case ax::mojom::Role::kBanner:
ia2_role = IA2_ROLE_HEADER;
break;
- case AX_ROLE_BLOCKQUOTE:
+ case ax::mojom::Role::kBlockquote:
ia2_role = IA2_ROLE_SECTION;
break;
- case AX_ROLE_CANVAS:
- if (GetBoolAttribute(AX_ATTR_CANVAS_HAS_FALLBACK)) {
+ case ax::mojom::Role::kCanvas:
+ if (GetBoolAttribute(ax::mojom::BoolAttribute::kCanvasHasFallback)) {
ia2_role = IA2_ROLE_CANVAS;
}
break;
- case AX_ROLE_CAPTION:
+ case ax::mojom::Role::kCaption:
ia2_role = IA2_ROLE_CAPTION;
break;
- case AX_ROLE_COLOR_WELL:
+ case ax::mojom::Role::kColorWell:
ia2_role = IA2_ROLE_COLOR_CHOOSER;
break;
- case AX_ROLE_COMPLEMENTARY:
+ case ax::mojom::Role::kComplementary:
ia2_role = IA2_ROLE_NOTE;
break;
- case AX_ROLE_CONTENT_INFO:
+ case ax::mojom::Role::kContentInfo:
ia2_role = IA2_ROLE_PARAGRAPH;
break;
- case AX_ROLE_DATE:
- case AX_ROLE_DATE_TIME:
+ case ax::mojom::Role::kDate:
+ case ax::mojom::Role::kDateTime:
ia2_role = IA2_ROLE_DATE_EDITOR;
break;
- case AX_ROLE_DEFINITION:
+ case ax::mojom::Role::kDefinition:
ia2_role = IA2_ROLE_PARAGRAPH;
break;
- case AX_ROLE_DESCRIPTION_LIST_DETAIL:
+ case ax::mojom::Role::kDescriptionListDetail:
ia2_role = IA2_ROLE_PARAGRAPH;
break;
- case AX_ROLE_EMBEDDED_OBJECT:
+ case ax::mojom::Role::kEmbeddedObject:
if (!delegate_->GetChildCount()) {
ia2_role = IA2_ROLE_EMBEDDED_OBJECT;
}
break;
- case AX_ROLE_FIGCAPTION:
+ case ax::mojom::Role::kFigcaption:
ia2_role = IA2_ROLE_CAPTION;
break;
- case AX_ROLE_FORM:
+ case ax::mojom::Role::kForm:
ia2_role = IA2_ROLE_FORM;
break;
- case AX_ROLE_FOOTER:
+ case ax::mojom::Role::kFooter:
ia2_role = IA2_ROLE_FOOTER;
break;
- case AX_ROLE_GENERIC_CONTAINER:
+ case ax::mojom::Role::kGenericContainer:
ia2_role = IA2_ROLE_SECTION;
break;
- case AX_ROLE_HEADING:
+ case ax::mojom::Role::kHeading:
ia2_role = IA2_ROLE_HEADING;
break;
- case AX_ROLE_IFRAME:
+ case ax::mojom::Role::kIframe:
ia2_role = IA2_ROLE_INTERNAL_FRAME;
break;
- case AX_ROLE_IMAGE_MAP:
+ case ax::mojom::Role::kImageMap:
ia2_role = IA2_ROLE_IMAGE_MAP;
break;
- case AX_ROLE_LABEL_TEXT:
- case AX_ROLE_LEGEND:
+ case ax::mojom::Role::kLabelText:
+ case ax::mojom::Role::kLegend:
ia2_role = IA2_ROLE_LABEL;
break;
- case AX_ROLE_MAIN:
+ case ax::mojom::Role::kMain:
ia2_role = IA2_ROLE_PARAGRAPH;
break;
- case AX_ROLE_MARK:
+ case ax::mojom::Role::kMark:
ia2_role = IA2_ROLE_TEXT_FRAME;
break;
- case AX_ROLE_MENU_ITEM_CHECK_BOX:
+ case ax::mojom::Role::kMenuItemCheckBox:
ia2_role = IA2_ROLE_CHECK_MENU_ITEM;
break;
- case AX_ROLE_MENU_ITEM_RADIO:
+ case ax::mojom::Role::kMenuItemRadio:
ia2_role = IA2_ROLE_RADIO_MENU_ITEM;
break;
- case AX_ROLE_NAVIGATION:
+ case ax::mojom::Role::kNavigation:
ia2_role = IA2_ROLE_SECTION;
break;
- case AX_ROLE_NOTE:
+ case ax::mojom::Role::kNote:
ia2_role = IA2_ROLE_NOTE;
break;
- case AX_ROLE_PARAGRAPH:
+ case ax::mojom::Role::kParagraph:
ia2_role = IA2_ROLE_PARAGRAPH;
break;
- case AX_ROLE_PRE:
+ case ax::mojom::Role::kPre:
ia2_role = IA2_ROLE_PARAGRAPH;
break;
- case AX_ROLE_REGION: {
- base::string16 html_tag = GetString16Attribute(AX_ATTR_HTML_TAG);
+ case ax::mojom::Role::kRegion: {
+ base::string16 html_tag =
+ GetString16Attribute(ax::mojom::StringAttribute::kHtmlTag);
if (html_tag == L"section") {
ia2_role = IA2_ROLE_SECTION;
}
} break;
- case AX_ROLE_RUBY:
+ case ax::mojom::Role::kRuby:
ia2_role = IA2_ROLE_TEXT_FRAME;
break;
- case AX_ROLE_SEARCH:
+ case ax::mojom::Role::kSearch:
ia2_role = IA2_ROLE_SECTION;
break;
- case AX_ROLE_SWITCH:
+ case ax::mojom::Role::kSwitch:
ia2_role = IA2_ROLE_TOGGLE_BUTTON;
break;
- case AX_ROLE_TABLE_HEADER_CONTAINER:
+ case ax::mojom::Role::kTableHeaderContainer:
ia2_role = IA2_ROLE_SECTION;
break;
- case AX_ROLE_TOGGLE_BUTTON:
+ case ax::mojom::Role::kToggleButton:
ia2_role = IA2_ROLE_TOGGLE_BUTTON;
break;
- case AX_ROLE_ABBR:
- case AX_ROLE_TIME:
+ case ax::mojom::Role::kAbbr:
+ case ax::mojom::Role::kTime:
ia2_role = IA2_ROLE_TEXT_FRAME;
break;
default:
@@ -2985,71 +3016,82 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() {
// historical reasons. Aside from that virtually every ARIA attribute
// is exposed in a really straightforward way, i.e. "aria-foo" is exposed
// as "foo".
- StringAttributeToIA2(result, AX_ATTR_DISPLAY, "display");
- StringAttributeToIA2(result, AX_ATTR_HTML_TAG, "tag");
- StringAttributeToIA2(result, AX_ATTR_ROLE, "xml-roles");
- StringAttributeToIA2(result, AX_ATTR_PLACEHOLDER, "placeholder");
-
- StringAttributeToIA2(result, AX_ATTR_AUTO_COMPLETE, "autocomplete");
- StringAttributeToIA2(result, AX_ATTR_ROLE_DESCRIPTION, "roledescription");
- StringAttributeToIA2(result, AX_ATTR_KEY_SHORTCUTS, "keyshortcuts");
-
- IntAttributeToIA2(result, AX_ATTR_HIERARCHICAL_LEVEL, "level");
- IntAttributeToIA2(result, AX_ATTR_SET_SIZE, "setsize");
- IntAttributeToIA2(result, AX_ATTR_POS_IN_SET, "posinset");
-
- if (HasIntAttribute(AX_ATTR_CHECKED_STATE))
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kDisplay, "display");
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kHtmlTag, "tag");
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kRole, "xml-roles");
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kPlaceholder,
+ "placeholder");
+
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kAutoComplete,
+ "autocomplete");
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kRoleDescription,
+ "roledescription");
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kKeyShortcuts,
+ "keyshortcuts");
+
+ IntAttributeToIA2(result, ax::mojom::IntAttribute::kHierarchicalLevel,
+ "level");
+ IntAttributeToIA2(result, ax::mojom::IntAttribute::kSetSize, "setsize");
+ IntAttributeToIA2(result, ax::mojom::IntAttribute::kPosInSet, "posinset");
+
+ if (HasIntAttribute(ax::mojom::IntAttribute::kCheckedState))
result.push_back(L"checkable:true");
// Expose live region attributes.
- StringAttributeToIA2(result, AX_ATTR_LIVE_STATUS, "live");
- StringAttributeToIA2(result, AX_ATTR_LIVE_RELEVANT, "relevant");
- BoolAttributeToIA2(result, AX_ATTR_LIVE_ATOMIC, "atomic");
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kLiveStatus, "live");
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kLiveRelevant,
+ "relevant");
+ BoolAttributeToIA2(result, ax::mojom::BoolAttribute::kLiveAtomic, "atomic");
// Busy is usually associated with live regions but can occur anywhere:
- BoolAttributeToIA2(result, AX_ATTR_BUSY, "busy");
+ BoolAttributeToIA2(result, ax::mojom::BoolAttribute::kBusy, "busy");
// Expose container live region attributes.
- StringAttributeToIA2(result, AX_ATTR_CONTAINER_LIVE_STATUS, "container-live");
- StringAttributeToIA2(result, AX_ATTR_CONTAINER_LIVE_RELEVANT,
+ StringAttributeToIA2(result, ax::mojom::StringAttribute::kContainerLiveStatus,
+ "container-live");
+ StringAttributeToIA2(result,
+ ax::mojom::StringAttribute::kContainerLiveRelevant,
"container-relevant");
- BoolAttributeToIA2(result, AX_ATTR_CONTAINER_LIVE_ATOMIC, "container-atomic");
- BoolAttributeToIA2(result, AX_ATTR_CONTAINER_LIVE_BUSY, "container-busy");
+ BoolAttributeToIA2(result, ax::mojom::BoolAttribute::kContainerLiveAtomic,
+ "container-atomic");
+ BoolAttributeToIA2(result, ax::mojom::BoolAttribute::kContainerLiveBusy,
+ "container-busy");
// Expose the non-standard explicit-name IA2 attribute.
int name_from;
- if (GetIntAttribute(AX_ATTR_NAME_FROM, &name_from) &&
- name_from != AX_NAME_FROM_CONTENTS) {
+ if (GetIntAttribute(ax::mojom::IntAttribute::kNameFrom, &name_from) &&
+ name_from != static_cast<int32_t>(ax::mojom::NameFrom::kContents)) {
result.push_back(L"explicit-name:true");
}
// Expose the aria-current attribute.
int32_t aria_current_state;
- if (GetIntAttribute(AX_ATTR_ARIA_CURRENT_STATE, &aria_current_state)) {
- switch (static_cast<AXAriaCurrentState>(aria_current_state)) {
- case AX_ARIA_CURRENT_STATE_NONE:
+ if (GetIntAttribute(ax::mojom::IntAttribute::kAriaCurrentState,
+ &aria_current_state)) {
+ switch (static_cast<ax::mojom::AriaCurrentState>(aria_current_state)) {
+ case ax::mojom::AriaCurrentState::kNone:
break;
- case AX_ARIA_CURRENT_STATE_FALSE:
+ case ax::mojom::AriaCurrentState::kFalse:
result.push_back(L"current:false");
break;
- case AX_ARIA_CURRENT_STATE_TRUE:
+ case ax::mojom::AriaCurrentState::kTrue:
result.push_back(L"current:true");
break;
- case AX_ARIA_CURRENT_STATE_PAGE:
+ case ax::mojom::AriaCurrentState::kPage:
result.push_back(L"current:page");
break;
- case AX_ARIA_CURRENT_STATE_STEP:
+ case ax::mojom::AriaCurrentState::kStep:
result.push_back(L"current:step");
break;
- case AX_ARIA_CURRENT_STATE_LOCATION:
+ case ax::mojom::AriaCurrentState::kLocation:
result.push_back(L"current:location");
break;
- case AX_ARIA_CURRENT_STATE_UNCLIPPED_LOCATION:
+ case ax::mojom::AriaCurrentState::kUnclippedLocation:
result.push_back(L"current:unclippedLocation");
break;
- case AX_ARIA_CURRENT_STATE_DATE:
+ case ax::mojom::AriaCurrentState::kDate:
result.push_back(L"current:date");
break;
- case AX_ARIA_CURRENT_STATE_TIME:
+ case ax::mojom::AriaCurrentState::kTime:
result.push_back(L"current:time");
break;
}
@@ -3063,8 +3105,8 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() {
table = FromNativeViewAccessible(table->GetParent());
if (table) {
- const std::vector<int32_t>& unique_cell_ids =
- table->GetIntListAttribute(AX_ATTR_UNIQUE_CELL_IDS);
+ const std::vector<int32_t>& unique_cell_ids = table->GetIntListAttribute(
+ ax::mojom::IntListAttribute::kUniqueCellIds);
for (size_t i = 0; i < unique_cell_ids.size(); ++i) {
if (unique_cell_ids[i] == GetData().id) {
result.push_back(base::string16(L"table-cell-index:") +
@@ -3073,19 +3115,25 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() {
}
}
}
+ if (GetData().role == ax::mojom::Role::kLayoutTable)
+ result.push_back(base::string16(L"layout-guess:true"));
// Expose aria-colcount and aria-rowcount in a table, grid or treegrid.
if (IsTableLikeRole(GetData().role)) {
- IntAttributeToIA2(result, AX_ATTR_ARIA_COLUMN_COUNT, "colcount");
- IntAttributeToIA2(result, AX_ATTR_ARIA_ROW_COUNT, "rowcount");
+ IntAttributeToIA2(result, ax::mojom::IntAttribute::kAriaColumnCount,
+ "colcount");
+ IntAttributeToIA2(result, ax::mojom::IntAttribute::kAriaRowCount,
+ "rowcount");
}
// Expose aria-colindex and aria-rowindex in a cell or row.
if (IsCellOrTableHeaderRole(GetData().role) ||
- GetData().role == AX_ROLE_ROW) {
- if (GetData().role != AX_ROLE_ROW)
- IntAttributeToIA2(result, AX_ATTR_ARIA_CELL_COLUMN_INDEX, "colindex");
- IntAttributeToIA2(result, AX_ATTR_ARIA_CELL_ROW_INDEX, "rowindex");
+ GetData().role == ax::mojom::Role::kRow) {
+ if (GetData().role != ax::mojom::Role::kRow)
+ IntAttributeToIA2(result, ax::mojom::IntAttribute::kAriaCellColumnIndex,
+ "colindex");
+ IntAttributeToIA2(result, ax::mojom::IntAttribute::kAriaCellRowIndex,
+ "rowindex");
// Experimental: expose aria-rowtext / aria-coltext. Not standardized
// yet, but obscure enough that it's safe to expose.
@@ -3108,20 +3156,21 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() {
int32_t sort_direction;
if ((MSAARole() == ROLE_SYSTEM_COLUMNHEADER ||
MSAARole() == ROLE_SYSTEM_ROWHEADER) &&
- GetIntAttribute(AX_ATTR_SORT_DIRECTION, &sort_direction)) {
- switch (static_cast<AXSortDirection>(sort_direction)) {
- case AX_SORT_DIRECTION_NONE:
+ GetIntAttribute(ax::mojom::IntAttribute::kSortDirection,
+ &sort_direction)) {
+ switch (static_cast<ax::mojom::SortDirection>(sort_direction)) {
+ case ax::mojom::SortDirection::kNone:
break;
- case AX_SORT_DIRECTION_UNSORTED:
+ case ax::mojom::SortDirection::kUnsorted:
result.push_back(L"sort:none");
break;
- case AX_SORT_DIRECTION_ASCENDING:
+ case ax::mojom::SortDirection::kAscending:
result.push_back(L"sort:ascending");
break;
- case AX_SORT_DIRECTION_DESCENDING:
+ case ax::mojom::SortDirection::kDescending:
result.push_back(L"sort:descending");
break;
- case AX_SORT_DIRECTION_OTHER:
+ case ax::mojom::SortDirection::kOther:
result.push_back(L"sort:other");
break;
}
@@ -3166,14 +3215,16 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() {
// Expose class attribute.
base::string16 class_attr;
- if (GetData().GetHtmlAttribute("class", &class_attr)) {
+ if (GetData().GetHtmlAttribute("class", &class_attr) ||
+ GetData().GetString16Attribute(ax::mojom::StringAttribute::kClassName,
+ &class_attr)) {
SanitizeStringAttributeForIA2(class_attr, &class_attr);
result.push_back(L"class:" + class_attr);
}
// Expose datetime attribute.
base::string16 datetime;
- if (GetData().role == AX_ROLE_TIME &&
+ if (GetData().role == ax::mojom::Role::kTime &&
GetData().GetHtmlAttribute("datetime", &datetime)) {
SanitizeStringAttributeForIA2(datetime, &datetime);
result.push_back(L"datetime:" + datetime);
@@ -3188,7 +3239,7 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() {
// Expose src attribute.
base::string16 src;
- if (GetData().role == AX_ROLE_IMAGE &&
+ if (GetData().role == ax::mojom::Role::kImage &&
GetData().GetHtmlAttribute("src", &src)) {
SanitizeStringAttributeForIA2(src, &src);
result.push_back(L"src:" + src);
@@ -3204,7 +3255,8 @@ std::vector<base::string16> AXPlatformNodeWin::ComputeIA2Attributes() {
// Expose input-text type attribute.
base::string16 type;
- base::string16 html_tag = GetString16Attribute(AX_ATTR_HTML_TAG);
+ base::string16 html_tag =
+ GetString16Attribute(ax::mojom::StringAttribute::kHtmlTag);
if (IsPlainTextField() && html_tag == L"input" &&
GetData().GetHtmlAttribute("type", &type)) {
SanitizeStringAttributeForIA2(type, &type);
@@ -3223,7 +3275,7 @@ base::string16 AXPlatformNodeWin::GetValue() {
// TODO(dougt): Look into ensuring that on click handlers correctly provide
// a value here.
if (value.empty() && (MSAAState() & STATE_SYSTEM_LINKED))
- value = GetString16Attribute(ui::AX_ATTR_URL);
+ value = GetString16Attribute(ax::mojom::StringAttribute::kUrl);
return value;
}
@@ -3243,7 +3295,7 @@ AXHypertext AXPlatformNodeWin::ComputeHypertext() {
// We don't want to expose any associated label in IA2 Hypertext.
return result;
}
- result.hypertext = GetString16Attribute(ui::AX_ATTR_NAME);
+ result.hypertext = GetString16Attribute(ax::mojom::StringAttribute::kName);
return result;
}
@@ -3260,7 +3312,8 @@ AXHypertext AXPlatformNodeWin::ComputeHypertext() {
DCHECK(child);
// Similar to Firefox, we don't expose text-only objects in IA2 hypertext.
if (child->IsTextOnlyObject()) {
- hypertext += child->GetString16Attribute(ui::AX_ATTR_NAME);
+ hypertext +=
+ child->GetString16Attribute(ax::mojom::StringAttribute::kName);
} else {
int32_t char_offset = static_cast<int32_t>(hypertext.size());
int32_t child_unique_id = child->GetUniqueId();
@@ -3277,26 +3330,26 @@ AXHypertext AXPlatformNodeWin::ComputeHypertext() {
bool AXPlatformNodeWin::ShouldNodeHaveReadonlyStateByDefault(
const AXNodeData& data) const {
switch (data.role) {
- case AX_ROLE_ARTICLE:
- case AX_ROLE_DEFINITION:
- case AX_ROLE_DESCRIPTION_LIST:
- case AX_ROLE_DESCRIPTION_LIST_TERM:
- case AX_ROLE_DOCUMENT:
- case AX_ROLE_IFRAME:
- case AX_ROLE_IMAGE:
- case AX_ROLE_IMAGE_MAP:
- case AX_ROLE_LIST:
- case AX_ROLE_LIST_ITEM:
- case AX_ROLE_PROGRESS_INDICATOR:
- case AX_ROLE_ROOT_WEB_AREA:
- case AX_ROLE_TERM:
- case AX_ROLE_TIMER:
- case AX_ROLE_TOOLBAR:
- case AX_ROLE_TOOLTIP:
- case AX_ROLE_WEB_AREA:
+ case ax::mojom::Role::kArticle:
+ case ax::mojom::Role::kDefinition:
+ case ax::mojom::Role::kDescriptionList:
+ case ax::mojom::Role::kDescriptionListTerm:
+ case ax::mojom::Role::kDocument:
+ case ax::mojom::Role::kIframe:
+ case ax::mojom::Role::kImage:
+ case ax::mojom::Role::kImageMap:
+ case ax::mojom::Role::kList:
+ case ax::mojom::Role::kListItem:
+ case ax::mojom::Role::kProgressIndicator:
+ case ax::mojom::Role::kRootWebArea:
+ case ax::mojom::Role::kTerm:
+ case ax::mojom::Role::kTimer:
+ case ax::mojom::Role::kToolbar:
+ case ax::mojom::Role::kTooltip:
+ case ax::mojom::Role::kWebArea:
return true;
- case AX_ROLE_GRID:
+ case ax::mojom::Role::kGrid:
// TODO(aleventhal) this changed between ARIA 1.0 and 1.1,
// need to determine whether grids/treegrids should really be readonly
// or editable by default
@@ -3312,56 +3365,57 @@ bool AXPlatformNodeWin::ShouldNodeHaveReadonlyStateByDefault(
bool AXPlatformNodeWin::ShouldNodeHaveFocusableState(
const AXNodeData& data) const {
switch (data.role) {
- case AX_ROLE_DOCUMENT:
- case AX_ROLE_ROOT_WEB_AREA:
- case AX_ROLE_WEB_AREA:
+ case ax::mojom::Role::kDocument:
+ case ax::mojom::Role::kRootWebArea:
+ case ax::mojom::Role::kWebArea:
return true;
- case AX_ROLE_IFRAME:
+ case ax::mojom::Role::kIframe:
return false;
- case AX_ROLE_LIST_BOX_OPTION:
- case AX_ROLE_MENU_LIST_OPTION:
- if (data.HasState(AX_STATE_SELECTABLE))
+ case ax::mojom::Role::kListBoxOption:
+ case ax::mojom::Role::kMenuListOption:
+ if (data.HasState(ax::mojom::State::kSelectable))
return true;
+ break;
default:
break;
}
- return data.HasState(AX_STATE_FOCUSABLE);
+ return data.HasState(ax::mojom::State::kFocusable);
}
int AXPlatformNodeWin::MSAAState() {
const AXNodeData& data = GetData();
int msaa_state = 0;
- // Map the AXState to MSAA state. Note that some of the states are not
- // currently handled.
+ // Map the ax::mojom::State to MSAA state. Note that some of the states are
+ // not currently handled.
- if (data.GetBoolAttribute(AX_ATTR_BUSY))
+ if (data.GetBoolAttribute(ax::mojom::BoolAttribute::kBusy))
msaa_state |= STATE_SYSTEM_BUSY;
- if (data.HasState(AX_STATE_COLLAPSED))
+ if (data.HasState(ax::mojom::State::kCollapsed))
msaa_state |= STATE_SYSTEM_COLLAPSED;
- if (data.HasState(AX_STATE_DEFAULT))
+ if (data.HasState(ax::mojom::State::kDefault))
msaa_state |= STATE_SYSTEM_DEFAULT;
- // TODO(dougt) unhandled ux::AX_STATE_EDITABLE
+ // TODO(dougt) unhandled ux::ax::mojom::State::kEditable
- if (data.HasState(AX_STATE_EXPANDED))
+ if (data.HasState(ax::mojom::State::kExpanded))
msaa_state |= STATE_SYSTEM_EXPANDED;
if (ShouldNodeHaveFocusableState(data))
msaa_state |= STATE_SYSTEM_FOCUSABLE;
- if (data.HasState(AX_STATE_HASPOPUP))
+ if (data.HasState(ax::mojom::State::kHaspopup))
msaa_state |= STATE_SYSTEM_HASPOPUP;
- // TODO(dougt) unhandled ux::AX_STATE_HORIZONTAL
+ // TODO(dougt) unhandled ux::ax::mojom::State::kHorizontal
- if (data.HasState(AX_STATE_HOVERED)) {
+ if (data.HasState(ax::mojom::State::kHovered)) {
// Expose whether or not the mouse is over an element, but suppress
// this for tests because it can make the test results flaky depending
// on the position of the mouse.
@@ -3371,15 +3425,16 @@ int AXPlatformNodeWin::MSAAState() {
// If the role is IGNORED, we want these elements to be invisible so that
// these nodes are hidden from the screen reader.
- if (data.HasState(AX_STATE_INVISIBLE) || GetData().role == AX_ROLE_IGNORED) {
+ if (data.HasState(ax::mojom::State::kInvisible) ||
+ GetData().role == ax::mojom::Role::kIgnored) {
msaa_state |= STATE_SYSTEM_INVISIBLE;
}
- if (data.HasState(AX_STATE_LINKED))
+ if (data.HasState(ax::mojom::State::kLinked))
msaa_state |= STATE_SYSTEM_LINKED;
- // TODO(dougt) unhandled ux::AX_STATE_MULTILINE
+ // TODO(dougt) unhandled ux::ax::mojom::State::kMultiline
- if (data.HasState(AX_STATE_MULTISELECTABLE)) {
+ if (data.HasState(ax::mojom::State::kMultiselectable)) {
msaa_state |= STATE_SYSTEM_EXTSELECTABLE;
msaa_state |= STATE_SYSTEM_MULTISELECTABLE;
}
@@ -3387,47 +3442,48 @@ int AXPlatformNodeWin::MSAAState() {
if (delegate_->IsOffscreen())
msaa_state |= STATE_SYSTEM_OFFSCREEN;
- if (data.HasState(AX_STATE_PROTECTED))
+ if (data.HasState(ax::mojom::State::kProtected))
msaa_state |= STATE_SYSTEM_PROTECTED;
- // TODO(dougt) unhandled ux::AX_STATE_REQUIRED
- // TODO(dougt) unhandled ux::AX_STATE_RICHLY_EDITABLE
+ // TODO(dougt) unhandled ux::ax::mojom::State::kRequired
+ // TODO(dougt) unhandled ux::ax::mojom::State::kRichlyEditable
- if (data.HasState(AX_STATE_SELECTABLE))
+ if (data.HasState(ax::mojom::State::kSelectable))
msaa_state |= STATE_SYSTEM_SELECTABLE;
- if (data.HasState(AX_STATE_SELECTED))
+ if (data.HasState(ax::mojom::State::kSelected))
msaa_state |= STATE_SYSTEM_SELECTED;
// TODO(dougt) unhandled VERTICAL
- if (data.HasState(AX_STATE_VISITED))
+ if (data.HasState(ax::mojom::State::kVisited))
msaa_state |= STATE_SYSTEM_TRAVERSED;
//
// Checked state
//
- const auto checked_state =
- static_cast<AXCheckedState>(GetIntAttribute(AX_ATTR_CHECKED_STATE));
+ const auto checked_state = static_cast<ax::mojom::CheckedState>(
+ GetIntAttribute(ax::mojom::IntAttribute::kCheckedState));
switch (checked_state) {
- case AX_CHECKED_STATE_TRUE:
- msaa_state |= data.role == AX_ROLE_TOGGLE_BUTTON ? STATE_SYSTEM_PRESSED
- : STATE_SYSTEM_CHECKED;
+ case ax::mojom::CheckedState::kTrue:
+ msaa_state |= data.role == ax::mojom::Role::kToggleButton
+ ? STATE_SYSTEM_PRESSED
+ : STATE_SYSTEM_CHECKED;
break;
- case AX_CHECKED_STATE_MIXED:
+ case ax::mojom::CheckedState::kMixed:
msaa_state |= STATE_SYSTEM_MIXED;
break;
default:
break;
}
- const auto restriction =
- static_cast<AXRestriction>(GetIntAttribute(AX_ATTR_RESTRICTION));
+ const auto restriction = static_cast<ax::mojom::Restriction>(
+ GetIntAttribute(ax::mojom::IntAttribute::kRestriction));
switch (restriction) {
- case AX_RESTRICTION_DISABLED:
+ case ax::mojom::Restriction::kDisabled:
msaa_state |= STATE_SYSTEM_UNAVAILABLE;
break;
- case AX_RESTRICTION_READ_ONLY:
+ case ax::mojom::Restriction::kReadOnly:
msaa_state |= STATE_SYSTEM_READONLY;
break;
default:
@@ -3435,7 +3491,7 @@ int AXPlatformNodeWin::MSAAState() {
// on *some* document structure roles such as paragraph, heading or list
// even if the node data isn't marked as read only, as long as the
// node is not editable.
- if (!data.HasState(AX_STATE_RICHLY_EDITABLE) &&
+ if (!data.HasState(ax::mojom::State::kRichlyEditable) &&
ShouldNodeHaveReadonlyStateByDefault(data))
msaa_state |= STATE_SYSTEM_READONLY;
break;
@@ -3454,55 +3510,59 @@ int AXPlatformNodeWin::MSAAState() {
// TODO(dmazzoni): this should probably check if focus is actually inside
// the menu bar, but we don't currently track focus inside menu pop-ups,
// and Chrome only has one menu visible at a time so this works for now.
- if (data.role == AX_ROLE_MENU_BAR && !(data.HasState(AX_STATE_INVISIBLE))) {
+ if (data.role == ax::mojom::Role::kMenuBar &&
+ !(data.HasState(ax::mojom::State::kInvisible))) {
msaa_state |= STATE_SYSTEM_FOCUSED;
}
// Handle STATE_SYSTEM_LINKED
- if (GetData().role == AX_ROLE_LINK)
+ if (GetData().role == ax::mojom::Role::kLink)
msaa_state |= STATE_SYSTEM_LINKED;
// Special case for indeterminate progressbar.
- if (GetData().role == AX_ROLE_PROGRESS_INDICATOR &&
- !HasFloatAttribute(ui::AX_ATTR_VALUE_FOR_RANGE))
+ if (GetData().role == ax::mojom::Role::kProgressIndicator &&
+ !HasFloatAttribute(ax::mojom::FloatAttribute::kValueForRange))
msaa_state |= STATE_SYSTEM_MIXED;
return msaa_state;
}
-int AXPlatformNodeWin::MSAAEvent(AXEvent event) {
+int AXPlatformNodeWin::MSAAEvent(ax::mojom::Event event) {
switch (event) {
- case AX_EVENT_ALERT:
+ case ax::mojom::Event::kAlert:
return EVENT_SYSTEM_ALERT;
- case AX_EVENT_FOCUS:
+ case ax::mojom::Event::kExpandedChanged:
+ return EVENT_OBJECT_STATECHANGE;
+ case ax::mojom::Event::kFocus:
return EVENT_OBJECT_FOCUS;
- case AX_EVENT_MENU_START:
+ case ax::mojom::Event::kMenuStart:
return EVENT_SYSTEM_MENUSTART;
- case AX_EVENT_MENU_END:
+ case ax::mojom::Event::kMenuEnd:
return EVENT_SYSTEM_MENUEND;
- case AX_EVENT_MENU_POPUP_START:
+ case ax::mojom::Event::kMenuPopupStart:
return EVENT_SYSTEM_MENUPOPUPSTART;
- case AX_EVENT_MENU_POPUP_END:
+ case ax::mojom::Event::kMenuPopupEnd:
return EVENT_SYSTEM_MENUPOPUPEND;
- case AX_EVENT_SELECTION:
+ case ax::mojom::Event::kSelection:
return EVENT_OBJECT_SELECTION;
- case AX_EVENT_SELECTION_ADD:
+ case ax::mojom::Event::kSelectionAdd:
return EVENT_OBJECT_SELECTIONADD;
- case AX_EVENT_SELECTION_REMOVE:
+ case ax::mojom::Event::kSelectionRemove:
return EVENT_OBJECT_SELECTIONREMOVE;
- case AX_EVENT_TEXT_CHANGED:
+ case ax::mojom::Event::kTextChanged:
return EVENT_OBJECT_NAMECHANGE;
- case AX_EVENT_TEXT_SELECTION_CHANGED:
+ case ax::mojom::Event::kTextSelectionChanged:
return IA2_EVENT_TEXT_CARET_MOVED;
- case AX_EVENT_VALUE_CHANGED:
+ case ax::mojom::Event::kValueChanged:
return EVENT_OBJECT_VALUECHANGE;
default:
return -1;
}
}
-HRESULT AXPlatformNodeWin::GetStringAttributeAsBstr(AXStringAttribute attribute,
- BSTR* value_bstr) const {
+HRESULT AXPlatformNodeWin::GetStringAttributeAsBstr(
+ ax::mojom::StringAttribute attribute,
+ BSTR* value_bstr) const {
base::string16 str;
if (!GetString16Attribute(attribute, &str))
@@ -3526,7 +3586,7 @@ void AXPlatformNodeWin::RemoveAlertTarget() {
base::string16 AXPlatformNodeWin::TextForIAccessibleText() {
// Special case allows us to get text even in non-HTML case, e.g. browser UI.
if (IsPlainTextField())
- return GetString16Attribute(AX_ATTR_VALUE);
+ return GetString16Attribute(ax::mojom::StringAttribute::kValue);
return GetText();
}
@@ -3536,9 +3596,12 @@ void AXPlatformNodeWin::HandleSpecialTextOffset(LONG* offset) {
} else if (*offset == IA2_TEXT_OFFSET_CARET) {
int selection_start, selection_end;
GetSelectionOffsets(&selection_start, &selection_end);
+ // TODO(nektar): Deprecate selection_start and selection_end in favor of
+ // sel_anchor_offset/sel_focus_offset. See https://crbug.com/645596.
if (selection_end < 0)
*offset = 0;
- *offset = static_cast<LONG>(selection_end);
+ else
+ *offset = static_cast<LONG>(selection_end);
}
}
@@ -3570,9 +3633,9 @@ LONG AXPlatformNodeWin::FindBoundary(const base::string16& text,
HandleSpecialTextOffset(&start_offset);
TextBoundaryType boundary = IA2TextBoundaryToTextBoundary(ia2_boundary);
std::vector<int32_t> line_breaks;
- return static_cast<LONG>(
- FindAccessibleTextBoundary(text, line_breaks, boundary, start_offset,
- direction, AX_TEXT_AFFINITY_DOWNSTREAM));
+ return static_cast<LONG>(FindAccessibleTextBoundary(
+ text, line_breaks, boundary, start_offset, direction,
+ ax::mojom::TextAffinity::kDownstream));
}
AXPlatformNodeWin* AXPlatformNodeWin::GetTargetFromChildID(
@@ -3612,13 +3675,13 @@ bool AXPlatformNodeWin::IsInTreeGrid() {
AXPlatformNodeBase* container = FromNativeViewAccessible(GetParent());
// If parent was a rowgroup, we need to look at the grandparent
- if (container && container->GetData().role == AX_ROLE_GROUP)
+ if (container && container->GetData().role == ax::mojom::Role::kGroup)
container = FromNativeViewAccessible(container->GetParent());
if (!container)
return false;
- return container->GetData().role == AX_ROLE_TREE_GRID;
+ return container->GetData().role == ax::mojom::Role::kTreeGrid;
}
HRESULT AXPlatformNodeWin::AllocateComArrayFromVector(
@@ -3923,8 +3986,9 @@ void AXPlatformNodeWin::GetSelectionOffsets(int* selection_start,
DCHECK(selection_start && selection_end);
if (IsPlainTextField() &&
- GetIntAttribute(ui::AX_ATTR_TEXT_SEL_START, selection_start) &&
- GetIntAttribute(ui::AX_ATTR_TEXT_SEL_END, selection_end)) {
+ GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart,
+ selection_start) &&
+ GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, selection_end)) {
return;
}
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_win.h b/chromium/ui/accessibility/platform/ax_platform_node_win.h
index 7b49fa9b316..4efab44077a 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_win.h
+++ b/chromium/ui/accessibility/platform/ax_platform_node_win.h
@@ -270,7 +270,7 @@ class AX_EXPORT __declspec(uuid("26f5641a-246d-457b-a96d-07f3fae6acf2"))
// AXPlatformNode overrides.
gfx::NativeViewAccessible GetNativeViewAccessible() override;
- void NotifyAccessibilityEvent(AXEvent event_type) override;
+ void NotifyAccessibilityEvent(ax::mojom::Event event_type) override;
// AXPlatformNodeBase overrides.
void Destroy() override;
@@ -708,12 +708,12 @@ class AX_EXPORT __declspec(uuid("26f5641a-246d-457b-a96d-07f3fae6acf2"))
TextBoundaryType IA2TextBoundaryToTextBoundary(IA2TextBoundaryType type);
private:
- int MSAAEvent(AXEvent event);
+ int MSAAEvent(ax::mojom::Event event);
bool IsWebAreaForPresentationalIframe();
bool ShouldNodeHaveReadonlyStateByDefault(const AXNodeData& data) const;
bool ShouldNodeHaveFocusableState(const AXNodeData& data) const;
- HRESULT GetStringAttributeAsBstr(AXStringAttribute attribute,
+ HRESULT GetStringAttributeAsBstr(ax::mojom::StringAttribute attribute,
BSTR* value_bstr) const;
// Escapes characters in string attributes as required by the IA2 Spec.
@@ -727,19 +727,19 @@ class AX_EXPORT __declspec(uuid("26f5641a-246d-457b-a96d-07f3fae6acf2"))
// If the string attribute |attribute| is present, add its value as an
// IAccessible2 attribute with the name |ia2_attr|.
void StringAttributeToIA2(std::vector<base::string16>& attributes,
- AXStringAttribute attribute,
+ ax::mojom::StringAttribute attribute,
const char* ia2_attr);
// If the bool attribute |attribute| is present, add its value as an
// IAccessible2 attribute with the name |ia2_attr|.
void BoolAttributeToIA2(std::vector<base::string16>& attributes,
- AXBoolAttribute attribute,
+ ax::mojom::BoolAttribute attribute,
const char* ia2_attr);
// If the int attribute |attribute| is present, add its value as an
// IAccessible2 attribute with the name |ia2_attr|.
void IntAttributeToIA2(std::vector<base::string16>& attributes,
- AXIntAttribute attribute,
+ ax::mojom::IntAttribute attribute,
const char* ia2_attr);
void AddAlertTarget();
diff --git a/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc b/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc
index 7a7ea0db3e1..20de83957ca 100644
--- a/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc
+++ b/chromium/ui/accessibility/platform/ax_platform_node_win_unittest.cc
@@ -206,7 +206,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleName) {
TEST_F(AXPlatformNodeWinTest, TestIAccessibleDescription) {
AXNodeData root;
root.id = 1;
- root.AddStringAttribute(AX_ATTR_DESCRIPTION, "Description");
+ root.AddStringAttribute(ax::mojom::StringAttribute::kDescription,
+ "Description");
Init(root);
ComPtr<IAccessible> root_obj(GetRootIAccessible());
@@ -223,7 +224,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleDescription) {
TEST_F(AXPlatformNodeWinTest, TestIAccessibleValue) {
AXNodeData root;
root.id = 1;
- root.AddStringAttribute(AX_ATTR_VALUE, "Value");
+ root.AddStringAttribute(ax::mojom::StringAttribute::kValue, "Value");
Init(root);
ComPtr<IAccessible> root_obj(GetRootIAccessible());
@@ -240,7 +241,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleValue) {
TEST_F(AXPlatformNodeWinTest, TestIAccessibleShortcut) {
AXNodeData root;
root.id = 1;
- root.AddStringAttribute(AX_ATTR_KEY_SHORTCUTS, "Shortcut");
+ root.AddStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts,
+ "Shortcut");
Init(root);
ComPtr<IAccessible> root_obj(GetRootIAccessible());
@@ -259,16 +261,16 @@ TEST_F(AXPlatformNodeWinTest,
TestIAccessibleSelectionListBoxOptionNothingSelected) {
AXNodeData list;
list.id = 0;
- list.role = AX_ROLE_LIST_BOX;
+ list.role = ax::mojom::Role::kListBox;
AXNodeData list_item_1;
list_item_1.id = 1;
- list_item_1.role = AX_ROLE_LIST_BOX_OPTION;
+ list_item_1.role = ax::mojom::Role::kListBoxOption;
list_item_1.SetName("Name1");
AXNodeData list_item_2;
list_item_2.id = 2;
- list_item_2.role = AX_ROLE_LIST_BOX_OPTION;
+ list_item_2.role = ax::mojom::Role::kListBoxOption;
list_item_2.SetName("Name2");
list.child_ids.push_back(list_item_1.id);
@@ -288,17 +290,17 @@ TEST_F(AXPlatformNodeWinTest,
TestIAccessibleSelectionListBoxOptionOneSelected) {
AXNodeData list;
list.id = 0;
- list.role = AX_ROLE_LIST_BOX;
+ list.role = ax::mojom::Role::kListBox;
AXNodeData list_item_1;
list_item_1.id = 1;
- list_item_1.role = AX_ROLE_LIST_BOX_OPTION;
- list_item_1.AddState(AX_STATE_SELECTED);
+ list_item_1.role = ax::mojom::Role::kListBoxOption;
+ list_item_1.AddState(ax::mojom::State::kSelected);
list_item_1.SetName("Name1");
AXNodeData list_item_2;
list_item_2.id = 2;
- list_item_2.role = AX_ROLE_LIST_BOX_OPTION;
+ list_item_2.role = ax::mojom::Role::kListBoxOption;
list_item_2.SetName("Name2");
list.child_ids.push_back(list_item_1.id);
@@ -320,23 +322,23 @@ TEST_F(AXPlatformNodeWinTest,
TestIAccessibleSelectionListBoxOptionMultipleSelected) {
AXNodeData list;
list.id = 0;
- list.role = AX_ROLE_LIST_BOX;
+ list.role = ax::mojom::Role::kListBox;
AXNodeData list_item_1;
list_item_1.id = 1;
- list_item_1.role = AX_ROLE_LIST_BOX_OPTION;
- list_item_1.AddState(AX_STATE_SELECTED);
+ list_item_1.role = ax::mojom::Role::kListBoxOption;
+ list_item_1.AddState(ax::mojom::State::kSelected);
list_item_1.SetName("Name1");
AXNodeData list_item_2;
list_item_2.id = 2;
- list_item_2.role = AX_ROLE_LIST_BOX_OPTION;
- list_item_2.AddState(AX_STATE_SELECTED);
+ list_item_2.role = ax::mojom::Role::kListBoxOption;
+ list_item_2.AddState(ax::mojom::State::kSelected);
list_item_2.SetName("Name2");
AXNodeData list_item_3;
list_item_3.id = 3;
- list_item_3.role = AX_ROLE_LIST_BOX_OPTION;
+ list_item_3.role = ax::mojom::Role::kListBoxOption;
list_item_3.SetName("Name3");
list.child_ids.push_back(list_item_1.id);
@@ -413,7 +415,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleSelectionTableRowOneSelected) {
AXTreeUpdate update = Build3X3Table();
// 5 == table_row_1
- update.nodes[5].AddState(AX_STATE_SELECTED);
+ update.nodes[5].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -441,8 +443,8 @@ TEST_F(AXPlatformNodeWinTest,
// 5 == table_row_1
// 9 == table_row_2
- update.nodes[5].AddState(AX_STATE_SELECTED);
- update.nodes[9].AddState(AX_STATE_SELECTED);
+ update.nodes[5].AddState(ax::mojom::State::kSelected);
+ update.nodes[9].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -503,7 +505,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleSelectionTableCellOneSelected) {
AXTreeUpdate update = Build3X3Table();
// 7 == table_cell_1
- update.nodes[7].AddState(AX_STATE_SELECTED);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -541,8 +543,8 @@ TEST_F(AXPlatformNodeWinTest,
// 11 == table_cell_3
// 12 == table_cell_4
- update.nodes[11].AddState(AX_STATE_SELECTED);
- update.nodes[12].AddState(AX_STATE_SELECTED);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
+ update.nodes[12].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -619,17 +621,17 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleRole) {
ScopedVariant role;
- child.role = AX_ROLE_ALERT;
+ child.role = ax::mojom::Role::kAlert;
child_node->SetData(child);
EXPECT_EQ(S_OK, child_iaccessible->get_accRole(SELF, role.Receive()));
EXPECT_EQ(ROLE_SYSTEM_ALERT, V_I4(role.ptr()));
- child.role = AX_ROLE_BUTTON;
+ child.role = ax::mojom::Role::kButton;
child_node->SetData(child);
EXPECT_EQ(S_OK, child_iaccessible->get_accRole(SELF, role.Receive()));
EXPECT_EQ(ROLE_SYSTEM_PUSHBUTTON, V_I4(role.ptr()));
- child.role = AX_ROLE_POP_UP_BUTTON;
+ child.role = ax::mojom::Role::kPopUpButton;
child_node->SetData(child);
EXPECT_EQ(S_OK, child_iaccessible->get_accRole(SELF, role.Receive()));
EXPECT_EQ(ROLE_SYSTEM_BUTTONMENU, V_I4(role.ptr()));
@@ -676,11 +678,11 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleChildAndParent) {
root.child_ids.push_back(3);
AXNodeData button;
- button.role = AX_ROLE_BUTTON;
+ button.role = ax::mojom::Role::kButton;
button.id = 2;
AXNodeData checkbox;
- checkbox.role = AX_ROLE_CHECK_BOX;
+ checkbox.role = ax::mojom::Role::kCheckBox;
checkbox.id = 3;
Init(root, button, checkbox);
@@ -809,16 +811,16 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2IndexInParent) {
TEST_F(AXPlatformNodeWinTest, TestAccNavigate) {
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_ROOT_WEB_AREA;
+ root.role = ax::mojom::Role::kRootWebArea;
AXNodeData child1;
child1.id = 2;
- child1.role = AX_ROLE_STATIC_TEXT;
+ child1.role = ax::mojom::Role::kStaticText;
root.child_ids.push_back(2);
AXNodeData child2;
child2.id = 3;
- child2.role = AX_ROLE_STATIC_TEXT;
+ child2.role = ax::mojom::Role::kStaticText;
root.child_ids.push_back(3);
Init(root, child1, child2);
@@ -1003,12 +1005,12 @@ TEST_F(AXPlatformNodeWinTest,
TEST_F(AXPlatformNodeWinTest, TestIAccessible2ScrollToPoint) {
AXNodeData root;
root.id = 1;
- root.role = ui::AX_ROLE_ROOT_WEB_AREA;
+ root.role = ax::mojom::Role::kRootWebArea;
root.location = gfx::RectF(0, 0, 2000, 2000);
AXNodeData child1;
child1.id = 2;
- child1.role = AX_ROLE_STATIC_TEXT;
+ child1.role = ax::mojom::Role::kStaticText;
child1.location = gfx::RectF(10, 10, 10, 10);
root.child_ids.push_back(2);
@@ -1055,12 +1057,12 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2ScrollToPoint) {
TEST_F(AXPlatformNodeWinTest, TestIAccessible2ScrollTo) {
AXNodeData root;
root.id = 1;
- root.role = ui::AX_ROLE_ROOT_WEB_AREA;
+ root.role = ax::mojom::Role::kRootWebArea;
root.location = gfx::RectF(0, 0, 2000, 2000);
AXNodeData child1;
child1.id = 2;
- child1.role = AX_ROLE_STATIC_TEXT;
+ child1.role = ax::mojom::Role::kStaticText;
child1.location = gfx::RectF(10, 10, 10, 10);
root.child_ids.push_back(2);
@@ -1373,8 +1375,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableCellGetRowHeaderCells) {
long number_cells;
EXPECT_EQ(S_OK, cell->get_rowHeaderCells(&cell_accessibles, &number_cells));
- // Since we do not have AX_ATTR_TABLE_CELL_ROW_INDEX set, the evaluated row
- // will be 0. In this case, we do not expect any row headers.
+ // Since we do not have ax::mojom::IntAttribute::kTableCellRowIndex set, the
+ // evaluated row will be 0. In this case, we do not expect any row headers.
EXPECT_EQ(number_cells, 0);
}
@@ -1430,20 +1432,21 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetNRelations) {
// specific COM/BrowserAccessibility knowledge.
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_ROOT_WEB_AREA;
+ root.role = ax::mojom::Role::kRootWebArea;
std::vector<int32_t> describedby_ids = {1, 2, 3};
- root.AddIntListAttribute(AX_ATTR_DESCRIBEDBY_IDS, describedby_ids);
+ root.AddIntListAttribute(ax::mojom::IntListAttribute::kDescribedbyIds,
+ describedby_ids);
AXNodeData child1;
child1.id = 2;
- child1.role = AX_ROLE_STATIC_TEXT;
+ child1.role = ax::mojom::Role::kStaticText;
root.child_ids.push_back(2);
AXNodeData child2;
child2.id = 3;
- child2.role = AX_ROLE_STATIC_TEXT;
+ child2.role = ax::mojom::Role::kStaticText;
root.child_ids.push_back(3);
@@ -1538,27 +1541,28 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetNRelations) {
TEST_F(AXPlatformNodeWinTest, TestRelationTargetsOfType) {
AXNodeData root;
root.id = 1;
- root.role = AX_ROLE_ROOT_WEB_AREA;
- root.AddIntAttribute(AX_ATTR_DETAILS_ID, 2);
+ root.role = ax::mojom::Role::kRootWebArea;
+ root.AddIntAttribute(ax::mojom::IntAttribute::kDetailsId, 2);
AXNodeData child1;
child1.id = 2;
- child1.role = AX_ROLE_STATIC_TEXT;
+ child1.role = ax::mojom::Role::kStaticText;
root.child_ids.push_back(2);
AXNodeData child2;
child2.id = 3;
- child2.role = AX_ROLE_STATIC_TEXT;
+ child2.role = ax::mojom::Role::kStaticText;
std::vector<int32_t> labelledby_ids = {1, 4};
- child2.AddIntListAttribute(AX_ATTR_LABELLEDBY_IDS, labelledby_ids);
+ child2.AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
+ labelledby_ids);
root.child_ids.push_back(3);
AXNodeData child3;
child3.id = 4;
- child3.role = AX_ROLE_STATIC_TEXT;
- child3.AddIntAttribute(AX_ATTR_DETAILS_ID, 2);
+ child3.role = ax::mojom::Role::kStaticText;
+ child3.AddIntAttribute(ax::mojom::IntAttribute::kDetailsId, 2);
root.child_ids.push_back(4);
@@ -1643,7 +1647,7 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedChildrenOne) {
AXTreeUpdate update = Build3X3Table();
// 7 == table_cell_1
- update.nodes[7].AddState(AX_STATE_SELECTED);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
Init(update);
ComPtr<IAccessibleTableCell> cell = GetCellInTable();
@@ -1668,10 +1672,10 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedChildrenMany) {
// 8 == table_cell_2
// 11 == table_cell_3
// 12 == table_cell_4
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[8].AddState(AX_STATE_SELECTED);
- update.nodes[11].AddState(AX_STATE_SELECTED);
- update.nodes[12].AddState(AX_STATE_SELECTED);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[8].AddState(ax::mojom::State::kSelected);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
+ update.nodes[12].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -1714,9 +1718,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedColumnsOne) {
// 3 == table_column_header_2
// 7 == table_cell_1
// 11 == table_cell_3
- update.nodes[3].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[11].AddState(AX_STATE_SELECTED);
+ update.nodes[3].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -1741,16 +1745,16 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedColumnsMany) {
// 3 == table_column_header_2
// 7 == table_cell_1
// 11 == table_cell_3
- update.nodes[3].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[11].AddState(AX_STATE_SELECTED);
+ update.nodes[3].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
// 4 == table_column_header_3
// 8 == table_cell_2
// 12 == table_cell_4
- update.nodes[4].AddState(AX_STATE_SELECTED);
- update.nodes[8].AddState(AX_STATE_SELECTED);
- update.nodes[12].AddState(AX_STATE_SELECTED);
+ update.nodes[4].AddState(ax::mojom::State::kSelected);
+ update.nodes[8].AddState(ax::mojom::State::kSelected);
+ update.nodes[12].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -1793,9 +1797,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedRowsOne) {
// 6 == table_row_header_1
// 7 == table_cell_1
// 8 == table_cell_2
- update.nodes[6].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[8].AddState(AX_STATE_SELECTED);
+ update.nodes[6].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[8].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -1820,16 +1824,16 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetNSelectedRowsMany) {
// 6 == table_row_header_3
// 7 == table_cell_1
// 8 == table_cell_2
- update.nodes[6].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[8].AddState(AX_STATE_SELECTED);
+ update.nodes[6].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[8].AddState(ax::mojom::State::kSelected);
// 10 == table_row_header_3
// 11 == table_cell_1
// 12 == table_cell_2
- update.nodes[10].AddState(AX_STATE_SELECTED);
- update.nodes[11].AddState(AX_STATE_SELECTED);
- update.nodes[12].AddState(AX_STATE_SELECTED);
+ update.nodes[10].AddState(ax::mojom::State::kSelected);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
+ update.nodes[12].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -1853,8 +1857,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedChildren) {
// 7 == table_cell_1
// 12 == table_cell_4
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[12].AddState(AX_STATE_SELECTED);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[12].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -1882,8 +1886,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedChildrenZeroMax) {
// 7 == table_cell_1
// 12 == table_cell_4
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[12].AddState(AX_STATE_SELECTED);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[12].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -1907,8 +1911,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedColumnsZero) {
// 7 == table_cell_1
// 11 == table_cell_3
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[11].AddState(AX_STATE_SELECTED);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -1936,9 +1940,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedColumnsOne) {
// 3 == table_column_header_2
// 7 == table_cell_1
// 11 == table_cell_3
- update.nodes[3].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[11].AddState(AX_STATE_SELECTED);
+ update.nodes[3].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -1967,16 +1971,16 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedColumnsMany) {
// 3 == table_column_header_2
// 7 == table_cell_1
// 11 == table_cell_3
- update.nodes[3].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[11].AddState(AX_STATE_SELECTED);
+ update.nodes[3].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
// 4 == table_column_header_3
// 8 == table_cell_2
// 12 == table_cell_4
- update.nodes[4].AddState(AX_STATE_SELECTED);
- update.nodes[8].AddState(AX_STATE_SELECTED);
- update.nodes[12].AddState(AX_STATE_SELECTED);
+ update.nodes[4].AddState(ax::mojom::State::kSelected);
+ update.nodes[8].AddState(ax::mojom::State::kSelected);
+ update.nodes[12].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -2026,9 +2030,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedRowsOne) {
// 6 == table_row_header_1
// 7 == table_cell_1
// 8 == table_cell_2
- update.nodes[6].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[8].AddState(AX_STATE_SELECTED);
+ update.nodes[6].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[8].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -2056,16 +2060,16 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableGetSelectedRowsMany) {
// 6 == table_row_header_3
// 7 == table_cell_1
// 8 == table_cell_2
- update.nodes[6].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[8].AddState(AX_STATE_SELECTED);
+ update.nodes[6].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[8].AddState(ax::mojom::State::kSelected);
// 10 == table_row_header_3
// 11 == table_cell_1
// 12 == table_cell_2
- update.nodes[10].AddState(AX_STATE_SELECTED);
- update.nodes[11].AddState(AX_STATE_SELECTED);
- update.nodes[12].AddState(AX_STATE_SELECTED);
+ update.nodes[10].AddState(ax::mojom::State::kSelected);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
+ update.nodes[12].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -2094,9 +2098,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableIsColumnSelected) {
// 3 == table_column_header_2
// 7 == table_cell_1
// 11 == table_cell_3
- update.nodes[3].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[11].AddState(AX_STATE_SELECTED);
+ update.nodes[3].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[11].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -2130,9 +2134,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableIsRowSelected) {
// 6 == table_row_header_3
// 7 == table_cell_1
// 8 == table_cell_2
- update.nodes[6].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[8].AddState(AX_STATE_SELECTED);
+ update.nodes[6].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[8].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -2166,9 +2170,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTableIsSelected) {
// 6 == table_row_header_3
// 7 == table_cell_1
// 8 == table_cell_2
- update.nodes[6].AddState(AX_STATE_SELECTED);
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[8].AddState(AX_STATE_SELECTED);
+ update.nodes[6].AddState(ax::mojom::State::kSelected);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[8].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -2231,8 +2235,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTable2GetSelectedChildren) {
// 7 == table_cell_1
// 12 == table_cell_4
- update.nodes[7].AddState(AX_STATE_SELECTED);
- update.nodes[12].AddState(AX_STATE_SELECTED);
+ update.nodes[7].AddState(ax::mojom::State::kSelected);
+ update.nodes[12].AddState(ax::mojom::State::kSelected);
Init(update);
@@ -2261,9 +2265,9 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessibleTable2GetSelectedChildren) {
TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetGroupPosition) {
AXNodeData root;
root.id = 1;
- root.AddIntAttribute(AX_ATTR_HIERARCHICAL_LEVEL, 1);
- root.AddIntAttribute(AX_ATTR_SET_SIZE, 1);
- root.AddIntAttribute(AX_ATTR_POS_IN_SET, 1);
+ root.AddIntAttribute(ax::mojom::IntAttribute::kHierarchicalLevel, 1);
+ root.AddIntAttribute(ax::mojom::IntAttribute::kSetSize, 1);
+ root.AddIntAttribute(ax::mojom::IntAttribute::kPosInSet, 1);
Init(root);
ComPtr<IAccessible> root_obj(GetRootIAccessible());
@@ -2281,7 +2285,8 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetGroupPosition) {
TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetLocalizedExtendedRole) {
AXNodeData root;
root.id = 1;
- root.AddStringAttribute(AX_ATTR_ROLE_DESCRIPTION, "extended role");
+ root.AddStringAttribute(ax::mojom::StringAttribute::kRoleDescription,
+ "extended role");
Init(root);
ComPtr<IAccessible> root_obj(GetRootIAccessible());
@@ -2294,12 +2299,12 @@ TEST_F(AXPlatformNodeWinTest, TestIAccessible2GetLocalizedExtendedRole) {
TEST_F(AXPlatformNodeWinTest, TestIAccessibleTextGetNCharacters) {
AXNodeData root;
root.id = 0;
- root.role = AX_ROLE_STATIC_TEXT;
+ root.role = ax::mojom::Role::kStaticText;
root.child_ids.push_back(1);
AXNodeData node;
node.id = 1;
- node.role = AX_ROLE_STATIC_TEXT;
+ node.role = ax::mojom::Role::kStaticText;
node.SetName("Name");
Init(root, node);
diff --git a/chromium/ui/accessibility/platform/ax_platform_relation_win.cc b/chromium/ui/accessibility/platform/ax_platform_relation_win.cc
index 83480eba1d1..803fc97e4d8 100644
--- a/chromium/ui/accessibility/platform/ax_platform_relation_win.cc
+++ b/chromium/ui/accessibility/platform/ax_platform_relation_win.cc
@@ -41,13 +41,13 @@ AXPlatformRelationWin::AXPlatformRelationWin() {
AXPlatformRelationWin::~AXPlatformRelationWin() {}
-base::string16 GetIA2RelationFromIntAttr(ui::AXIntAttribute attribute) {
+base::string16 GetIA2RelationFromIntAttr(ax::mojom::IntAttribute attribute) {
switch (attribute) {
- case AX_ATTR_DETAILS_ID:
+ case ax::mojom::IntAttribute::kDetailsId:
return IA2_RELATION_DETAILS;
- case AX_ATTR_MEMBER_OF_ID:
+ case ax::mojom::IntAttribute::kMemberOfId:
return IA2_RELATION_MEMBER_OF;
- case AX_ATTR_ERRORMESSAGE_ID:
+ case ax::mojom::IntAttribute::kErrormessageId:
return IA2_RELATION_ERROR_MESSAGE;
default:
break;
@@ -55,15 +55,16 @@ base::string16 GetIA2RelationFromIntAttr(ui::AXIntAttribute attribute) {
return base::string16();
}
-base::string16 GetIA2RelationFromIntListAttr(ui::AXIntListAttribute attribute) {
+base::string16 GetIA2RelationFromIntListAttr(
+ ax::mojom::IntListAttribute attribute) {
switch (attribute) {
- case AX_ATTR_CONTROLS_IDS:
+ case ax::mojom::IntListAttribute::kControlsIds:
return IA2_RELATION_CONTROLLER_FOR;
- case AX_ATTR_DESCRIBEDBY_IDS:
+ case ax::mojom::IntListAttribute::kDescribedbyIds:
return IA2_RELATION_DESCRIBED_BY;
- case AX_ATTR_FLOWTO_IDS:
+ case ax::mojom::IntListAttribute::kFlowtoIds:
return IA2_RELATION_FLOWS_TO;
- case AX_ATTR_LABELLEDBY_IDS:
+ case ax::mojom::IntListAttribute::kLabelledbyIds:
return IA2_RELATION_LABELLED_BY;
default:
break;
@@ -71,9 +72,10 @@ base::string16 GetIA2RelationFromIntListAttr(ui::AXIntListAttribute attribute) {
return base::string16();
}
-base::string16 GetIA2ReverseRelationFromIntAttr(ui::AXIntAttribute attribute) {
+base::string16 GetIA2ReverseRelationFromIntAttr(
+ ax::mojom::IntAttribute attribute) {
switch (attribute) {
- case AX_ATTR_DETAILS_ID:
+ case ax::mojom::IntAttribute::kDetailsId:
return IA2_RELATION_DETAILS_FOR;
default:
break;
@@ -82,15 +84,15 @@ base::string16 GetIA2ReverseRelationFromIntAttr(ui::AXIntAttribute attribute) {
}
base::string16 GetIA2ReverseRelationFromIntListAttr(
- ui::AXIntListAttribute attribute) {
+ ax::mojom::IntListAttribute attribute) {
switch (attribute) {
- case AX_ATTR_CONTROLS_IDS:
+ case ax::mojom::IntListAttribute::kControlsIds:
return IA2_RELATION_CONTROLLED_BY;
- case AX_ATTR_DESCRIBEDBY_IDS:
+ case ax::mojom::IntListAttribute::kDescribedbyIds:
return IA2_RELATION_DESCRIPTION_FOR;
- case AX_ATTR_FLOWTO_IDS:
+ case ax::mojom::IntListAttribute::kFlowtoIds:
return IA2_RELATION_FLOWS_FROM;
- case AX_ATTR_LABELLEDBY_IDS:
+ case ax::mojom::IntListAttribute::kLabelledbyIds:
return IA2_RELATION_LABEL_FOR;
default:
break;
@@ -112,20 +114,25 @@ int AXPlatformRelationWin::EnumerateRelationships(
// GetIA2ReverseRelationFrom{Int|IntList}Attr on every possible attribute
// simplifies the work needed to support an additional relation
// attribute in the future.
- static std::vector<AXIntAttribute> int_attributes_with_reverse_relations;
- static std::vector<AXIntListAttribute>
+ static std::vector<ax::mojom::IntAttribute>
+ int_attributes_with_reverse_relations;
+ static std::vector<ax::mojom::IntListAttribute>
intlist_attributes_with_reverse_relations;
static bool first_time = true;
if (first_time) {
- for (int attr_index = AX_INT_ATTRIBUTE_NONE;
- attr_index <= AX_INT_ATTRIBUTE_LAST; ++attr_index) {
- auto attr = static_cast<AXIntAttribute>(attr_index);
+ for (int32_t attr_index =
+ static_cast<int32_t>(ax::mojom::IntAttribute::kNone);
+ attr_index <= static_cast<int32_t>(ax::mojom::IntAttribute::kLast);
+ ++attr_index) {
+ auto attr = static_cast<ax::mojom::IntAttribute>(attr_index);
if (!GetIA2ReverseRelationFromIntAttr(attr).empty())
int_attributes_with_reverse_relations.push_back(attr);
}
- for (int attr_index = AX_INT_LIST_ATTRIBUTE_NONE;
- attr_index <= AX_INT_LIST_ATTRIBUTE_LAST; ++attr_index) {
- auto attr = static_cast<AXIntListAttribute>(attr_index);
+ for (int32_t attr_index =
+ static_cast<int32_t>(ax::mojom::IntListAttribute::kNone);
+ attr_index <= static_cast<int32_t>(ax::mojom::IntListAttribute::kLast);
+ ++attr_index) {
+ auto attr = static_cast<ax::mojom::IntListAttribute>(attr_index);
if (!GetIA2ReverseRelationFromIntListAttr(attr).empty())
intlist_attributes_with_reverse_relations.push_back(attr);
}
@@ -142,7 +149,7 @@ int AXPlatformRelationWin::EnumerateRelationships(
// Iterate over all int attributes on this node to check the ones
// that correspond to IAccessible2 relations.
for (size_t i = 0; i < node_data.int_attributes.size(); ++i) {
- AXIntAttribute int_attribute = node_data.int_attributes[i].first;
+ ax::mojom::IntAttribute int_attribute = node_data.int_attributes[i].first;
base::string16 relation = GetIA2RelationFromIntAttr(int_attribute);
if (!relation.empty() &&
(desired_ia2_relation.empty() || desired_ia2_relation == relation)) {
@@ -160,7 +167,8 @@ int AXPlatformRelationWin::EnumerateRelationships(
// Iterate over all of the int attributes that have reverse relations
// in IAccessible2, and query AXTree to see if the reverse relation exists.
- for (AXIntAttribute int_attribute : int_attributes_with_reverse_relations) {
+ for (ax::mojom::IntAttribute int_attribute :
+ int_attributes_with_reverse_relations) {
base::string16 relation = GetIA2ReverseRelationFromIntAttr(int_attribute);
std::set<int32_t> targets =
delegate->GetReverseRelations(int_attribute, node_data.id);
@@ -182,7 +190,7 @@ int AXPlatformRelationWin::EnumerateRelationships(
// Iterate over all intlist attributes on this node to check the ones
// that correspond to IAccessible2 relations.
for (size_t i = 0; i < node_data.intlist_attributes.size(); ++i) {
- AXIntListAttribute intlist_attribute =
+ ax::mojom::IntListAttribute intlist_attribute =
node_data.intlist_attributes[i].first;
base::string16 relation = GetIA2RelationFromIntListAttr(intlist_attribute);
if (!relation.empty() &&
@@ -205,7 +213,7 @@ int AXPlatformRelationWin::EnumerateRelationships(
// Iterate over all of the intlist attributes that have reverse relations
// in IAccessible2, and query AXTree to see if the reverse relation exists.
- for (AXIntListAttribute intlist_attribute :
+ for (ax::mojom::IntListAttribute intlist_attribute :
intlist_attributes_with_reverse_relations) {
base::string16 relation =
GetIA2ReverseRelationFromIntListAttr(intlist_attribute);
diff --git a/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.cc b/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.cc
index 83e083901df..998ae65757c 100644
--- a/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.cc
+++ b/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.cc
@@ -10,7 +10,7 @@
#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node.h"
#include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/ax_serializable_tree.h"
@@ -24,7 +24,7 @@ namespace {
bool HasFocusableChild(const AXNode* node) {
for (auto* child : node->children()) {
- if (child->data().HasState(AX_STATE_FOCUSABLE) ||
+ if (child->data().HasState(ax::mojom::State::kFocusable) ||
HasFocusableChild(child)) {
return true;
}
@@ -42,22 +42,24 @@ bool HasOnlyTextChildren(const AXNode* node) {
// TODO(muyuanli): share with BrowserAccessibility.
bool IsSimpleTextControl(const AXNode* node, uint32_t state) {
- return (node->data().role == AX_ROLE_TEXT_FIELD ||
- node->data().role == AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX ||
- node->data().role == AX_ROLE_SEARCH_BOX ||
- node->data().HasBoolAttribute(AX_ATTR_EDITABLE_ROOT)) &&
- !node->data().HasState(AX_STATE_RICHLY_EDITABLE);
+ return (node->data().role == ax::mojom::Role::kTextField ||
+ node->data().role == ax::mojom::Role::kTextFieldWithComboBox ||
+ node->data().role == ax::mojom::Role::kSearchBox ||
+ node->data().HasBoolAttribute(
+ ax::mojom::BoolAttribute::kEditableRoot)) &&
+ !node->data().HasState(ax::mojom::State::kRichlyEditable);
}
bool IsRichTextEditable(const AXNode* node) {
const AXNode* parent = node->parent();
- return node->data().HasState(AX_STATE_RICHLY_EDITABLE) &&
- (!parent || !parent->data().HasState(AX_STATE_RICHLY_EDITABLE));
+ return node->data().HasState(ax::mojom::State::kRichlyEditable) &&
+ (!parent ||
+ !parent->data().HasState(ax::mojom::State::kRichlyEditable));
}
bool IsNativeTextControl(const AXNode* node) {
const std::string& html_tag =
- node->data().GetStringAttribute(AX_ATTR_HTML_TAG);
+ node->data().GetStringAttribute(ax::mojom::StringAttribute::kHtmlTag);
if (html_tag == "input") {
std::string input_type;
if (!node->data().GetHtmlAttribute("type", &input_type))
@@ -79,15 +81,15 @@ bool IsLeaf(const AXNode* node) {
}
switch (node->data().role) {
- case AX_ROLE_IMAGE:
- case AX_ROLE_METER:
- case AX_ROLE_SCROLL_BAR:
- case AX_ROLE_SLIDER:
- case AX_ROLE_SPLITTER:
- case AX_ROLE_PROGRESS_INDICATOR:
- case AX_ROLE_DATE:
- case AX_ROLE_DATE_TIME:
- case AX_ROLE_INPUT_TIME:
+ case ax::mojom::Role::kImage:
+ case ax::mojom::Role::kMeter:
+ case ax::mojom::Role::kScrollBar:
+ case ax::mojom::Role::kSlider:
+ case ax::mojom::Role::kSplitter:
+ case ax::mojom::Role::kProgressIndicator:
+ case ax::mojom::Role::kDate:
+ case ax::mojom::Role::kDateTime:
+ case ax::mojom::Role::kInputTime:
return true;
default:
return false;
@@ -96,7 +98,7 @@ bool IsLeaf(const AXNode* node) {
base::string16 GetInnerText(const AXNode* node) {
if (node->IsTextNode()) {
- return node->data().GetString16Attribute(AX_ATTR_NAME);
+ return node->data().GetString16Attribute(ax::mojom::StringAttribute::kName);
}
base::string16 text;
for (auto* child : node->children()) {
@@ -106,7 +108,8 @@ base::string16 GetInnerText(const AXNode* node) {
}
base::string16 GetValue(const AXNode* node, bool show_password) {
- base::string16 value = node->data().GetString16Attribute(AX_ATTR_VALUE);
+ base::string16 value =
+ node->data().GetString16Attribute(ax::mojom::StringAttribute::kValue);
if (value.empty() &&
(IsSimpleTextControl(node, node->data().state) ||
@@ -115,7 +118,7 @@ base::string16 GetValue(const AXNode* node, bool show_password) {
value = GetInnerText(node);
}
- if (node->data().HasState(AX_STATE_PROTECTED)) {
+ if (node->data().HasState(ax::mojom::State::kProtected)) {
if (!show_password) {
value = base::string16(value.size(), kSecurePasswordBullet);
}
@@ -126,8 +129,8 @@ base::string16 GetValue(const AXNode* node, bool show_password) {
bool HasOnlyTextAndImageChildren(const AXNode* node) {
for (auto* child : node->children()) {
- if (child->data().role != AX_ROLE_STATIC_TEXT &&
- child->data().role != AX_ROLE_IMAGE) {
+ if (child->data().role != ax::mojom::Role::kStaticText &&
+ child->data().role != ax::mojom::Role::kImage) {
return false;
}
}
@@ -135,24 +138,25 @@ bool HasOnlyTextAndImageChildren(const AXNode* node) {
}
bool IsFocusable(const AXNode* node) {
- if (node->data().role == AX_ROLE_IFRAME ||
- node->data().role == AX_ROLE_IFRAME_PRESENTATIONAL ||
- (node->data().role == AX_ROLE_ROOT_WEB_AREA && node->parent())) {
- return node->data().HasStringAttribute(AX_ATTR_NAME);
+ if (node->data().role == ax::mojom::Role::kIframe ||
+ node->data().role == ax::mojom::Role::kIframePresentational ||
+ (node->data().role == ax::mojom::Role::kRootWebArea && node->parent())) {
+ return node->data().HasStringAttribute(ax::mojom::StringAttribute::kName);
}
- return node->data().HasState(AX_STATE_FOCUSABLE);
+ return node->data().HasState(ax::mojom::State::kFocusable);
}
base::string16 GetText(const AXNode* node, bool show_password) {
- if (node->data().role == AX_ROLE_WEB_AREA ||
- node->data().role == AX_ROLE_IFRAME ||
- node->data().role == AX_ROLE_IFRAME_PRESENTATIONAL) {
+ if (node->data().role == ax::mojom::Role::kWebArea ||
+ node->data().role == ax::mojom::Role::kIframe ||
+ node->data().role == ax::mojom::Role::kIframePresentational) {
return base::string16();
}
- if (node->data().role == AX_ROLE_LIST_ITEM &&
- node->data().GetIntAttribute(AX_ATTR_NAME_FROM) ==
- AX_NAME_FROM_CONTENTS) {
+ ax::mojom::NameFrom name_from = static_cast<ax::mojom::NameFrom>(
+ node->data().GetIntAttribute(ax::mojom::IntAttribute::kNameFrom));
+ if (node->data().role == ax::mojom::Role::kListItem &&
+ name_from == ax::mojom::NameFrom::kContents) {
if (node->child_count() > 0 && !HasOnlyTextChildren(node))
return base::string16();
}
@@ -160,23 +164,23 @@ base::string16 GetText(const AXNode* node, bool show_password) {
base::string16 value = GetValue(node, show_password);
if (!value.empty()) {
- if (node->data().HasState(AX_STATE_EDITABLE))
+ if (node->data().HasState(ax::mojom::State::kEditable))
return value;
switch (node->data().role) {
- case AX_ROLE_COMBO_BOX_MENU_BUTTON:
- case AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX:
- case AX_ROLE_POP_UP_BUTTON:
- case AX_ROLE_TEXT_FIELD:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kTextFieldWithComboBox:
+ case ax::mojom::Role::kPopUpButton:
+ case ax::mojom::Role::kTextField:
return value;
default:
break;
}
}
- if (node->data().role == AX_ROLE_COLOR_WELL) {
+ if (node->data().role == ax::mojom::Role::kColorWell) {
unsigned int color = static_cast<unsigned int>(
- node->data().GetIntAttribute(AX_ATTR_COLOR_VALUE));
+ node->data().GetIntAttribute(ax::mojom::IntAttribute::kColorValue));
unsigned int red = color >> 16 & 0xFF;
unsigned int green = color >> 8 & 0xFF;
unsigned int blue = color >> 0 & 0xFF;
@@ -184,9 +188,10 @@ base::string16 GetText(const AXNode* node, bool show_password) {
base::StringPrintf("#%02X%02X%02X", red, green, blue));
}
- base::string16 text = node->data().GetString16Attribute(AX_ATTR_NAME);
- base::string16 description =
- node->data().GetString16Attribute(AX_ATTR_DESCRIPTION);
+ base::string16 text =
+ node->data().GetString16Attribute(ax::mojom::StringAttribute::kName);
+ base::string16 description = node->data().GetString16Attribute(
+ ax::mojom::StringAttribute::kDescription);
if (!description.empty()) {
if (!text.empty())
text += base::ASCIIToUTF16(" ");
@@ -196,7 +201,7 @@ base::string16 GetText(const AXNode* node, bool show_password) {
if (text.empty())
text = value;
- if (node->data().role == AX_ROLE_ROOT_WEB_AREA)
+ if (node->data().role == ax::mojom::Role::kRootWebArea)
return text;
if (text.empty() &&
@@ -208,51 +213,52 @@ base::string16 GetText(const AXNode* node, bool show_password) {
}
if (text.empty() && (AXSnapshotNodeAndroid::AXRoleIsLink(node->data().role) ||
- node->data().role == AX_ROLE_IMAGE)) {
- base::string16 url = node->data().GetString16Attribute(AX_ATTR_URL);
+ node->data().role == ax::mojom::Role::kImage)) {
+ base::string16 url =
+ node->data().GetString16Attribute(ax::mojom::StringAttribute::kUrl);
text = AXSnapshotNodeAndroid::AXUrlBaseText(url);
}
return text;
}
-// Get string representation of AXRole. We are not using ToString() in
+// Get string representation of ax::mojom::Role. We are not using ToString() in
// ax_enums.h since the names are subject to change in the future and
// we are only interested in a subset of the roles.
-base::Optional<std::string> AXRoleToString(AXRole role) {
+base::Optional<std::string> AXRoleToString(ax::mojom::Role role) {
switch (role) {
- case AX_ROLE_ARTICLE:
+ case ax::mojom::Role::kArticle:
return base::Optional<std::string>("article");
- case AX_ROLE_BANNER:
+ case ax::mojom::Role::kBanner:
return base::Optional<std::string>("banner");
- case AX_ROLE_CAPTION:
+ case ax::mojom::Role::kCaption:
return base::Optional<std::string>("caption");
- case AX_ROLE_COMPLEMENTARY:
+ case ax::mojom::Role::kComplementary:
return base::Optional<std::string>("complementary");
- case AX_ROLE_DATE:
+ case ax::mojom::Role::kDate:
return base::Optional<std::string>("date");
- case AX_ROLE_DATE_TIME:
+ case ax::mojom::Role::kDateTime:
return base::Optional<std::string>("date_time");
- case AX_ROLE_DEFINITION:
+ case ax::mojom::Role::kDefinition:
return base::Optional<std::string>("definition");
- case AX_ROLE_DETAILS:
+ case ax::mojom::Role::kDetails:
return base::Optional<std::string>("details");
- case AX_ROLE_DOCUMENT:
+ case ax::mojom::Role::kDocument:
return base::Optional<std::string>("document");
- case AX_ROLE_FEED:
+ case ax::mojom::Role::kFeed:
return base::Optional<std::string>("feed");
- case AX_ROLE_HEADING:
+ case ax::mojom::Role::kHeading:
return base::Optional<std::string>("heading");
- case AX_ROLE_IFRAME:
+ case ax::mojom::Role::kIframe:
return base::Optional<std::string>("iframe");
- case AX_ROLE_IFRAME_PRESENTATIONAL:
+ case ax::mojom::Role::kIframePresentational:
return base::Optional<std::string>("iframe_presentational");
- case AX_ROLE_LIST:
+ case ax::mojom::Role::kList:
return base::Optional<std::string>("list");
- case AX_ROLE_LIST_ITEM:
+ case ax::mojom::Role::kListItem:
return base::Optional<std::string>("list_item");
- case AX_ROLE_MAIN:
+ case ax::mojom::Role::kMain:
return base::Optional<std::string>("main");
- case AX_ROLE_PARAGRAPH:
+ case ax::mojom::Role::kParagraph:
return base::Optional<std::string>("paragraph");
default:
return base::Optional<std::string>();
@@ -282,8 +288,8 @@ AX_EXPORT std::unique_ptr<AXSnapshotNodeAndroid> AXSnapshotNodeAndroid::Create(
}
// static
-AX_EXPORT bool AXSnapshotNodeAndroid::AXRoleIsLink(AXRole role) {
- return role == AX_ROLE_LINK;
+AX_EXPORT bool AXSnapshotNodeAndroid::AXRoleIsLink(ax::mojom::Role role) {
+ return role == ax::mojom::Role::kLink;
}
// static
@@ -309,56 +315,56 @@ AX_EXPORT base::string16 AXSnapshotNodeAndroid::AXUrlBaseText(
// static
AX_EXPORT const char* AXSnapshotNodeAndroid::AXRoleToAndroidClassName(
- AXRole role,
+ ax::mojom::Role role,
bool has_parent) {
switch (role) {
- case AX_ROLE_SEARCH_BOX:
- case AX_ROLE_SPIN_BUTTON:
- case AX_ROLE_TEXT_FIELD:
- case AX_ROLE_TEXT_FIELD_WITH_COMBO_BOX:
+ case ax::mojom::Role::kSearchBox:
+ case ax::mojom::Role::kSpinButton:
+ case ax::mojom::Role::kTextField:
+ case ax::mojom::Role::kTextFieldWithComboBox:
return kAXEditTextClassname;
- case AX_ROLE_SLIDER:
+ case ax::mojom::Role::kSlider:
return kAXSeekBarClassname;
- case AX_ROLE_COLOR_WELL:
- case AX_ROLE_COMBO_BOX_MENU_BUTTON:
- case AX_ROLE_DATE:
- case AX_ROLE_POP_UP_BUTTON:
- case AX_ROLE_INPUT_TIME:
+ case ax::mojom::Role::kColorWell:
+ case ax::mojom::Role::kComboBoxMenuButton:
+ case ax::mojom::Role::kDate:
+ case ax::mojom::Role::kPopUpButton:
+ case ax::mojom::Role::kInputTime:
return kAXSpinnerClassname;
- case AX_ROLE_BUTTON:
- case AX_ROLE_MENU_BUTTON:
+ case ax::mojom::Role::kButton:
+ case ax::mojom::Role::kMenuButton:
return kAXButtonClassname;
- case AX_ROLE_CHECK_BOX:
- case AX_ROLE_SWITCH:
+ case ax::mojom::Role::kCheckBox:
+ case ax::mojom::Role::kSwitch:
return kAXCheckBoxClassname;
- case AX_ROLE_RADIO_BUTTON:
+ case ax::mojom::Role::kRadioButton:
return kAXRadioButtonClassname;
- case AX_ROLE_TOGGLE_BUTTON:
+ case ax::mojom::Role::kToggleButton:
return kAXToggleButtonClassname;
- case AX_ROLE_CANVAS:
- case AX_ROLE_IMAGE:
- case AX_ROLE_SVG_ROOT:
+ case ax::mojom::Role::kCanvas:
+ case ax::mojom::Role::kImage:
+ case ax::mojom::Role::kSvgRoot:
return kAXImageClassname;
- case AX_ROLE_METER:
- case AX_ROLE_PROGRESS_INDICATOR:
+ case ax::mojom::Role::kMeter:
+ case ax::mojom::Role::kProgressIndicator:
return kAXProgressBarClassname;
- case AX_ROLE_TAB_LIST:
+ case ax::mojom::Role::kTabList:
return kAXTabWidgetClassname;
- case AX_ROLE_GRID:
- case AX_ROLE_TREE_GRID:
- case AX_ROLE_TABLE:
+ case ax::mojom::Role::kGrid:
+ case ax::mojom::Role::kTreeGrid:
+ case ax::mojom::Role::kTable:
return kAXGridViewClassname;
- case AX_ROLE_LIST:
- case AX_ROLE_LIST_BOX:
- case AX_ROLE_DESCRIPTION_LIST:
+ case ax::mojom::Role::kList:
+ case ax::mojom::Role::kListBox:
+ case ax::mojom::Role::kDescriptionList:
return kAXListViewClassname;
- case AX_ROLE_DIALOG:
+ case ax::mojom::Role::kDialog:
return kAXDialogClassname;
- case AX_ROLE_ROOT_WEB_AREA:
+ case ax::mojom::Role::kRootWebArea:
return has_parent ? kAXViewClassname : kAXWebViewClassname;
- case AX_ROLE_MENU_ITEM:
- case AX_ROLE_MENU_ITEM_CHECK_BOX:
- case AX_ROLE_MENU_ITEM_RADIO:
+ case ax::mojom::Role::kMenuItem:
+ case ax::mojom::Role::kMenuItemCheckBox:
+ case ax::mojom::Role::kMenuItemRadio:
return kAXMenuItemClassname;
default:
return kAXViewClassname;
@@ -388,20 +394,32 @@ AXSnapshotNodeAndroid::WalkAXTreeDepthFirst(
result->line_through = 0;
result->underline = 0;
- if (node->data().HasFloatAttribute(AX_ATTR_FONT_SIZE)) {
+ if (node->data().HasFloatAttribute(ax::mojom::FloatAttribute::kFontSize)) {
gfx::RectF text_size_rect(
- 0, 0, 1, node->data().GetFloatAttribute(AX_ATTR_FONT_SIZE));
+ 0, 0, 1,
+ node->data().GetFloatAttribute(ax::mojom::FloatAttribute::kFontSize));
gfx::Rect scaled_text_size_rect =
gfx::ToEnclosingRect(tree->RelativeToTreeBounds(node, text_size_rect));
result->text_size = scaled_text_size_rect.height();
- const int text_style = node->data().GetIntAttribute(AX_ATTR_TEXT_STYLE);
- result->color = node->data().GetIntAttribute(AX_ATTR_COLOR);
- result->bgcolor = node->data().GetIntAttribute(AX_ATTR_BACKGROUND_COLOR);
- result->bold = (text_style & AX_TEXT_STYLE_BOLD) != 0;
- result->italic = (text_style & AX_TEXT_STYLE_ITALIC) != 0;
- result->line_through = (text_style & AX_TEXT_STYLE_LINE_THROUGH) != 0;
- result->underline = (text_style & AX_TEXT_STYLE_UNDERLINE) != 0;
+ const int32_t text_style =
+ node->data().GetIntAttribute(ax::mojom::IntAttribute::kTextStyle);
+ result->color =
+ node->data().GetIntAttribute(ax::mojom::IntAttribute::kColor);
+ result->bgcolor =
+ node->data().GetIntAttribute(ax::mojom::IntAttribute::kBackgroundColor);
+ result->bold =
+ (text_style &
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleBold)) != 0;
+ result->italic =
+ (text_style &
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleItalic)) != 0;
+ result->line_through =
+ (text_style & static_cast<int32_t>(
+ ax::mojom::TextStyle::kTextStyleLineThrough)) != 0;
+ result->underline =
+ (text_style &
+ static_cast<int32_t>(ax::mojom::TextStyle::kTextStyleUnderline)) != 0;
}
const gfx::Rect& absolute_rect =
diff --git a/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.h b/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.h
index be01b51bcee..f5502219fd5 100644
--- a/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.h
+++ b/chromium/ui/accessibility/platform/ax_snapshot_node_android_platform.h
@@ -11,7 +11,7 @@
#include "base/optional.h"
#include "base/strings/string16.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_export.h"
#include "ui/accessibility/ax_tree_update.h"
#include "ui/gfx/geometry/rect.h"
@@ -32,11 +32,11 @@ struct AXSnapshotNodeAndroid {
bool show_password);
// Returns a fake Android view class that is a closest
- // approximation of the AXRole.
- AX_EXPORT static const char* AXRoleToAndroidClassName(AXRole role,
+ // approximation of the ax::mojom::Role.
+ AX_EXPORT static const char* AXRoleToAndroidClassName(ax::mojom::Role role,
bool has_parent);
- AX_EXPORT static bool AXRoleIsLink(AXRole role);
+ AX_EXPORT static bool AXRoleIsLink(ax::mojom::Role role);
AX_EXPORT static base::string16 AXUrlBaseText(base::string16 url);
diff --git a/chromium/ui/accessibility/platform/ax_system_caret_win.cc b/chromium/ui/accessibility/platform/ax_system_caret_win.cc
index 7547cd669a9..d173583715a 100644
--- a/chromium/ui/accessibility/platform/ax_system_caret_win.cc
+++ b/chromium/ui/accessibility/platform/ax_system_caret_win.cc
@@ -7,7 +7,7 @@
#include <windows.h>
#include "base/logging.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gfx/geometry/rect_f.h"
@@ -21,7 +21,7 @@ AXSystemCaretWin::AXSystemCaretWin(gfx::AcceleratedWidget event_target)
// a node ID. A globally unique ID is used when firing Win events, retrieved
// via |unique_id|.
data_.id = -1;
- data_.role = AX_ROLE_CARET;
+ data_.role = ax::mojom::Role::kCaret;
// |get_accState| should return 0 which means that the caret is visible.
data_.state = 0;
// According to MSDN, "Edit" should be the name of the caret object.
@@ -95,9 +95,13 @@ gfx::NativeViewAccessible AXSystemCaretWin::ChildAtIndex(int index) {
return nullptr;
}
-gfx::Rect AXSystemCaretWin::GetScreenBoundsRect() const {
- gfx::Rect bounds = ToEnclosingRect(data_.location);
- return bounds;
+gfx::Rect AXSystemCaretWin::GetClippedScreenBoundsRect() const {
+ // We could optionally add clipping here if ever needed.
+ return ToEnclosingRect(data_.location);
+}
+
+gfx::Rect AXSystemCaretWin::GetUnclippedScreenBoundsRect() const {
+ return ToEnclosingRect(data_.location);
}
gfx::NativeViewAccessible AXSystemCaretWin::HitTestSync(int x, int y) {
@@ -133,13 +137,15 @@ bool AXSystemCaretWin::IsOffscreen() const {
return false;
}
-std::set<int32_t> AXSystemCaretWin::GetReverseRelations(AXIntAttribute attr,
- int32_t dst_id) {
+std::set<int32_t> AXSystemCaretWin::GetReverseRelations(
+ ax::mojom::IntAttribute attr,
+ int32_t dst_id) {
return std::set<int32_t>();
}
-std::set<int32_t> AXSystemCaretWin::GetReverseRelations(AXIntListAttribute attr,
- int32_t dst_id) {
+std::set<int32_t> AXSystemCaretWin::GetReverseRelations(
+ ax::mojom::IntListAttribute attr,
+ int32_t dst_id) {
return std::set<int32_t>();
}
diff --git a/chromium/ui/accessibility/platform/ax_system_caret_win.h b/chromium/ui/accessibility/platform/ax_system_caret_win.h
index 6a4ec9686ee..56e26854f47 100644
--- a/chromium/ui/accessibility/platform/ax_system_caret_win.h
+++ b/chromium/ui/accessibility/platform/ax_system_caret_win.h
@@ -40,7 +40,8 @@ class AX_EXPORT AXSystemCaretWin : private AXPlatformNodeDelegate {
gfx::NativeViewAccessible GetParent() override;
int GetChildCount() override;
gfx::NativeViewAccessible ChildAtIndex(int index) override;
- gfx::Rect GetScreenBoundsRect() const override;
+ gfx::Rect GetClippedScreenBoundsRect() const override;
+ gfx::Rect GetUnclippedScreenBoundsRect() const override;
gfx::NativeViewAccessible HitTestSync(int x, int y) override;
gfx::NativeViewAccessible GetFocus() override;
AXPlatformNode* GetFromNodeID(int32_t id) override;
@@ -50,9 +51,9 @@ class AX_EXPORT AXSystemCaretWin : private AXPlatformNodeDelegate {
bool ShouldIgnoreHoveredStateForTesting() override;
bool IsOffscreen() const override;
const ui::AXUniqueId& GetUniqueId() const override;
- std::set<int32_t> GetReverseRelations(AXIntAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntAttribute attr,
int32_t dst_id) override;
- std::set<int32_t> GetReverseRelations(AXIntListAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntListAttribute attr,
int32_t dst_id) override;
AXPlatformNodeWin* caret_;
diff --git a/chromium/ui/accessibility/platform/test_ax_node_wrapper.cc b/chromium/ui/accessibility/platform/test_ax_node_wrapper.cc
index 045e04cef2b..bba0ceb1da3 100644
--- a/chromium/ui/accessibility/platform/test_ax_node_wrapper.cc
+++ b/chromium/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -105,7 +105,14 @@ gfx::NativeViewAccessible TestAXNodeWrapper::ChildAtIndex(int index) {
nullptr;
}
-gfx::Rect TestAXNodeWrapper::GetScreenBoundsRect() const {
+gfx::Rect TestAXNodeWrapper::GetClippedScreenBoundsRect() const {
+ // We could add clipping here if needed.
+ gfx::RectF bounds = GetData().location;
+ bounds.Offset(g_offset);
+ return gfx::ToEnclosingRect(bounds);
+}
+
+gfx::Rect TestAXNodeWrapper::GetUnclippedScreenBoundsRect() const {
gfx::RectF bounds = GetData().location;
bounds.Offset(g_offset);
return gfx::ToEnclosingRect(bounds);
@@ -115,7 +122,7 @@ TestAXNodeWrapper* TestAXNodeWrapper::HitTestSyncInternal(int x, int y) {
// Here we find the deepest child whose bounding box contains the given point.
// The assuptions are that there are no overlapping bounding rects and that
// all children have smaller bounding rects than their parents.
- if (!GetScreenBoundsRect().Contains(gfx::Rect(x, y)))
+ if (!GetClippedScreenBoundsRect().Contains(gfx::Rect(x, y)))
return nullptr;
for (int i = 0; i < GetChildCount(); i++) {
@@ -176,7 +183,7 @@ TestAXNodeWrapper::GetTargetForNativeAccessibilityEvent() {
}
void TestAXNodeWrapper::ReplaceIntAttribute(int32_t node_id,
- AXIntAttribute attribute,
+ ax::mojom::IntAttribute attribute,
int32_t value) {
if (!tree_)
return;
@@ -186,7 +193,7 @@ void TestAXNodeWrapper::ReplaceIntAttribute(int32_t node_id,
return;
AXNodeData new_data = node->data();
- std::vector<std::pair<AXIntAttribute, int32_t>>& attributes =
+ std::vector<std::pair<ax::mojom::IntAttribute, int32_t>>& attributes =
new_data.int_attributes;
auto deleted = std::remove_if(
@@ -200,21 +207,23 @@ void TestAXNodeWrapper::ReplaceIntAttribute(int32_t node_id,
bool TestAXNodeWrapper::AccessibilityPerformAction(
const ui::AXActionData& data) {
- if (data.action == ui::AX_ACTION_SCROLL_TO_POINT) {
+ if (data.action == ax::mojom::Action::kScrollToPoint) {
g_offset = gfx::Vector2d(data.target_point.x(), data.target_point.y());
return true;
}
- if (data.action == ui::AX_ACTION_SCROLL_TO_MAKE_VISIBLE) {
+ if (data.action == ax::mojom::Action::kScrollToMakeVisible) {
auto offset = node_->data().location.OffsetFromOrigin();
g_offset = gfx::Vector2d(-offset.x(), -offset.y());
return true;
}
- if (data.action == ui::AX_ACTION_SET_SELECTION) {
- ReplaceIntAttribute(data.anchor_node_id, AX_ATTR_TEXT_SEL_START,
+ if (data.action == ax::mojom::Action::kSetSelection) {
+ ReplaceIntAttribute(data.anchor_node_id,
+ ax::mojom::IntAttribute::kTextSelStart,
data.anchor_offset);
- ReplaceIntAttribute(data.anchor_node_id, AX_ATTR_TEXT_SEL_END,
+ ReplaceIntAttribute(data.anchor_node_id,
+ ax::mojom::IntAttribute::kTextSelEnd,
data.focus_offset);
return true;
}
@@ -230,13 +239,14 @@ bool TestAXNodeWrapper::IsOffscreen() const {
return false;
}
-std::set<int32_t> TestAXNodeWrapper::GetReverseRelations(AXIntAttribute attr,
- int32_t dst_id) {
+std::set<int32_t> TestAXNodeWrapper::GetReverseRelations(
+ ax::mojom::IntAttribute attr,
+ int32_t dst_id) {
return tree_->GetReverseRelations(attr, dst_id);
}
std::set<int32_t> TestAXNodeWrapper::GetReverseRelations(
- AXIntListAttribute attr,
+ ax::mojom::IntListAttribute attr,
int32_t dst_id) {
return tree_->GetReverseRelations(attr, dst_id);
}
diff --git a/chromium/ui/accessibility/platform/test_ax_node_wrapper.h b/chromium/ui/accessibility/platform/test_ax_node_wrapper.h
index 4327748de82..5dd47a649bc 100644
--- a/chromium/ui/accessibility/platform/test_ax_node_wrapper.h
+++ b/chromium/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -37,7 +37,8 @@ class TestAXNodeWrapper : public AXPlatformNodeDelegate {
gfx::NativeViewAccessible GetParent() override;
int GetChildCount() override;
gfx::NativeViewAccessible ChildAtIndex(int index) override;
- gfx::Rect GetScreenBoundsRect() const override;
+ gfx::Rect GetClippedScreenBoundsRect() const override;
+ gfx::Rect GetUnclippedScreenBoundsRect() const override;
gfx::NativeViewAccessible HitTestSync(int x, int y) override;
gfx::NativeViewAccessible GetFocus() override;
AXPlatformNode* GetFromNodeID(int32_t id) override;
@@ -47,15 +48,15 @@ class TestAXNodeWrapper : public AXPlatformNodeDelegate {
bool ShouldIgnoreHoveredStateForTesting() override;
bool IsOffscreen() const override;
const ui::AXUniqueId& GetUniqueId() const override;
- std::set<int32_t> GetReverseRelations(AXIntAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntAttribute attr,
int32_t dst_id) override;
- std::set<int32_t> GetReverseRelations(AXIntListAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntListAttribute attr,
int32_t dst_id) override;
private:
TestAXNodeWrapper(AXTree* tree, AXNode* node);
void ReplaceIntAttribute(int32_t node_id,
- AXIntAttribute attribute,
+ ax::mojom::IntAttribute attribute,
int32_t value);
TestAXNodeWrapper* HitTestSyncInternal(int x, int y);
diff --git a/chromium/ui/android/BUILD.gn b/chromium/ui/android/BUILD.gn
index d79dff14bfa..a9196e95dc7 100644
--- a/chromium/ui/android/BUILD.gn
+++ b/chromium/ui/android/BUILD.gn
@@ -242,10 +242,13 @@ android_library("ui_full_java") {
"java/src/org/chromium/ui/resources/system/SystemResourceLoader.java",
"java/src/org/chromium/ui/text/NoUnderlineClickableSpan.java",
"java/src/org/chromium/ui/text/SpanApplier.java",
+ "java/src/org/chromium/ui/widget/AnchoredPopupWindow.java",
"java/src/org/chromium/ui/widget/ButtonCompat.java",
+ "java/src/org/chromium/ui/widget/RectProvider.java",
"java/src/org/chromium/ui/widget/TextViewWithClickableSpans.java",
"java/src/org/chromium/ui/widget/TextViewWithLeading.java",
"java/src/org/chromium/ui/widget/Toast.java",
+ "java/src/org/chromium/ui/widget/ViewRectProvider.java",
]
deps = [
":ui_java_resources",
@@ -280,11 +283,13 @@ junit_binary("ui_junit_tests") {
"junit/src/org/chromium/ui/base/ClipboardTest.java",
"junit/src/org/chromium/ui/base/SelectFileDialogTest.java",
"junit/src/org/chromium/ui/text/SpanApplierTest.java",
+ "junit/src/org/chromium/ui/widget/AnchoredPopupWindowTest.java",
]
deps = [
":ui_java",
"//base:base_java",
"//base:base_java_test_support",
+ "//base:base_junit_test_support",
]
}
diff --git a/chromium/ui/android/OWNERS b/chromium/ui/android/OWNERS
index 8dd68c8015f..2a99c692980 100644
--- a/chromium/ui/android/OWNERS
+++ b/chromium/ui/android/OWNERS
@@ -9,5 +9,8 @@ jaekyun@chromium.org
boliu@chromium.org
jinsukkim@chromium.org
+# for CC and Viz integration
+khushalsagar@chromium.org
+
# COMPONENT: UI
# OS: Android
diff --git a/chromium/ui/android/delegated_frame_host_android.cc b/chromium/ui/android/delegated_frame_host_android.cc
index 5520cfc9fc5..07798eaf868 100644
--- a/chromium/ui/android/delegated_frame_host_android.cc
+++ b/chromium/ui/android/delegated_frame_host_android.cc
@@ -14,9 +14,9 @@
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/surface_id.h"
#include "components/viz/host/host_frame_sink_manager.h"
-#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "components/viz/service/surfaces/surface.h"
#include "ui/android/view_android.h"
+#include "ui/android/window_android.h"
#include "ui/android/window_android_compositor.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
@@ -27,12 +27,12 @@ namespace ui {
namespace {
scoped_refptr<cc::SurfaceLayer> CreateSurfaceLayer(
- viz::SurfaceManager* surface_manager,
viz::SurfaceInfo surface_info,
bool surface_opaque) {
// manager must outlive compositors using it.
- auto layer = cc::SurfaceLayer::Create(surface_manager->reference_factory());
- layer->SetPrimarySurfaceId(surface_info.id(), base::nullopt);
+ auto layer = cc::SurfaceLayer::Create();
+ layer->SetPrimarySurfaceId(surface_info.id(),
+ cc::DeadlinePolicy::UseDefaultDeadline());
layer->SetFallbackSurfaceId(surface_info.id());
layer->SetBounds(surface_info.size_in_pixels());
layer->SetIsDrawable(true);
@@ -41,26 +41,16 @@ scoped_refptr<cc::SurfaceLayer> CreateSurfaceLayer(
return layer;
}
-void CopyOutputRequestCallback(
- scoped_refptr<cc::Layer> readback_layer,
- viz::CopyOutputRequest::CopyOutputRequestCallback result_callback,
- std::unique_ptr<viz::CopyOutputResult> copy_output_result) {
- readback_layer->RemoveFromParent();
- std::move(result_callback).Run(std::move(copy_output_result));
-}
-
} // namespace
DelegatedFrameHostAndroid::DelegatedFrameHostAndroid(
ui::ViewAndroid* view,
viz::HostFrameSinkManager* host_frame_sink_manager,
- viz::FrameSinkManagerImpl* frame_sink_manager,
Client* client,
const viz::FrameSinkId& frame_sink_id)
: frame_sink_id_(frame_sink_id),
view_(view),
host_frame_sink_manager_(host_frame_sink_manager),
- frame_sink_manager_(frame_sink_manager),
client_(client),
begin_frame_source_(this),
enable_surface_synchronization_(
@@ -69,10 +59,8 @@ DelegatedFrameHostAndroid::DelegatedFrameHostAndroid(
DCHECK(client_);
host_frame_sink_manager_->RegisterFrameSinkId(frame_sink_id_, this);
-#if DCHECK_IS_ON()
host_frame_sink_manager_->SetFrameSinkDebugLabel(frame_sink_id_,
"DelegatedFrameHostAndroid");
-#endif
CreateNewCompositorFrameSinkSupport();
}
@@ -85,7 +73,8 @@ DelegatedFrameHostAndroid::~DelegatedFrameHostAndroid() {
void DelegatedFrameHostAndroid::SubmitCompositorFrame(
const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame) {
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list) {
if (local_surface_id != surface_info_.id().local_surface_id()) {
DestroyDelegatedContent();
DCHECK(!content_layer_);
@@ -96,16 +85,15 @@ void DelegatedFrameHostAndroid::SubmitCompositorFrame(
viz::SurfaceId(frame_sink_id_, local_surface_id), 1.f, frame_size);
has_transparent_background_ = root_pass->has_transparent_background;
- bool result =
- support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
- DCHECK(result);
+ support_->SubmitCompositorFrame(local_surface_id, std::move(frame),
+ std::move(hit_test_region_list));
content_layer_ =
- CreateSurfaceLayer(frame_sink_manager_->surface_manager(),
- surface_info_, !has_transparent_background_);
+ CreateSurfaceLayer(surface_info_, !has_transparent_background_);
view_->GetLayer()->AddChild(content_layer_);
} else {
- support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
+ support_->SubmitCompositorFrame(local_surface_id, std::move(frame),
+ std::move(hit_test_region_list));
}
compositor_attach_until_frame_lock_.reset();
}
@@ -119,28 +107,52 @@ viz::FrameSinkId DelegatedFrameHostAndroid::GetFrameSinkId() const {
return frame_sink_id_;
}
-void DelegatedFrameHostAndroid::RequestCopyOfSurface(
- WindowAndroidCompositor* compositor,
- const gfx::Rect& src_subrect_in_pixel,
- viz::CopyOutputRequest::CopyOutputRequestCallback result_callback) {
- DCHECK(surface_info_.is_valid());
- DCHECK(!result_callback.is_null());
+void DelegatedFrameHostAndroid::CopyFromCompositingSurface(
+ const gfx::Rect& src_subrect,
+ const gfx::Size& output_size,
+ base::OnceCallback<void(const SkBitmap&)> callback) {
+ if (!CanCopyFromCompositingSurface()) {
+ std::move(callback).Run(SkBitmap());
+ return;
+ }
scoped_refptr<cc::Layer> readback_layer =
- CreateSurfaceLayer(frame_sink_manager_->surface_manager(), surface_info_,
- !has_transparent_background_);
+ CreateSurfaceLayer(surface_info_, !has_transparent_background_);
readback_layer->SetHideLayerAndSubtree(true);
- compositor->AttachLayerForReadback(readback_layer);
- std::unique_ptr<viz::CopyOutputRequest> copy_output_request =
+ view_->GetWindowAndroid()->GetCompositor()->AttachLayerForReadback(
+ readback_layer);
+ std::unique_ptr<viz::CopyOutputRequest> request =
std::make_unique<viz::CopyOutputRequest>(
- viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE,
- base::BindOnce(&CopyOutputRequestCallback, readback_layer,
- std::move(result_callback)));
+ viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
+ base::BindOnce(
+ [](base::OnceCallback<void(const SkBitmap&)> callback,
+ scoped_refptr<cc::Layer> readback_layer,
+ std::unique_ptr<viz::CopyOutputResult> result) {
+ readback_layer->RemoveFromParent();
+ std::move(callback).Run(result->AsSkBitmap());
+ },
+ std::move(callback), std::move(readback_layer)));
+
+ if (src_subrect.IsEmpty()) {
+ request->set_area(gfx::Rect(surface_info_.size_in_pixels()));
+ } else {
+ request->set_area(
+ gfx::ConvertRectToPixel(view_->GetDipScale(), src_subrect));
+ }
+
+ if (!output_size.IsEmpty()) {
+ request->set_result_selection(gfx::Rect(output_size));
+ request->SetScaleRatio(
+ gfx::Vector2d(request->area().width(), request->area().height()),
+ gfx::Vector2d(output_size.width(), output_size.height()));
+ }
- if (!src_subrect_in_pixel.IsEmpty())
- copy_output_request->set_area(src_subrect_in_pixel);
+ support_->RequestCopyOfSurface(std::move(request));
+}
- support_->RequestCopyOfSurface(std::move(copy_output_request));
+bool DelegatedFrameHostAndroid::CanCopyFromCompositingSurface() const {
+ return support_ && surface_info_.is_valid() && view_->GetWindowAndroid() &&
+ view_->GetWindowAndroid()->GetCompositor();
}
void DelegatedFrameHostAndroid::DestroyDelegatedContent() {
@@ -151,7 +163,7 @@ void DelegatedFrameHostAndroid::DestroyDelegatedContent() {
content_layer_->RemoveFromParent();
content_layer_ = nullptr;
- support_->EvictCurrentSurface();
+ support_->EvictLastActivatedSurface();
surface_info_ = viz::SurfaceInfo();
}
diff --git a/chromium/ui/android/delegated_frame_host_android.h b/chromium/ui/android/delegated_frame_host_android.h
index 5fbfd413119..c0fbac92d08 100644
--- a/chromium/ui/android/delegated_frame_host_android.h
+++ b/chromium/ui/android/delegated_frame_host_android.h
@@ -24,7 +24,6 @@ enum class SurfaceDrawStatus;
namespace viz {
class CompositorFrame;
-class FrameSinkManagerImpl;
class HostFrameSinkManager;
} // namespace viz
@@ -50,14 +49,15 @@ class UI_ANDROID_EXPORT DelegatedFrameHostAndroid
DelegatedFrameHostAndroid(ViewAndroid* view,
viz::HostFrameSinkManager* host_frame_sink_manager,
- viz::FrameSinkManagerImpl* frame_sink_manager,
Client* client,
const viz::FrameSinkId& frame_sink_id);
~DelegatedFrameHostAndroid() override;
- void SubmitCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
- viz::CompositorFrame frame);
+ void SubmitCompositorFrame(
+ const viz::LocalSurfaceId& local_surface_id,
+ viz::CompositorFrame frame,
+ viz::mojom::HitTestRegionListPtr hit_test_region_list);
void DidNotProduceFrame(const viz::BeginFrameAck& ack);
void DestroyDelegatedContent();
@@ -69,10 +69,11 @@ class UI_ANDROID_EXPORT DelegatedFrameHostAndroid
// Should only be called when the host has a content layer. Use this for one-
// off screen capture, not for video. Always provides RGBA_BITMAP
// CopyOutputResults.
- void RequestCopyOfSurface(
- WindowAndroidCompositor* compositor,
- const gfx::Rect& src_subrect_in_pixel,
- viz::CopyOutputRequest::CopyOutputRequestCallback result_callback);
+ void CopyFromCompositingSurface(
+ const gfx::Rect& src_subrect,
+ const gfx::Size& output_size,
+ base::OnceCallback<void(const SkBitmap&)> callback);
+ bool CanCopyFromCompositingSurface() const;
void CompositorFrameSinkChanged();
@@ -121,7 +122,6 @@ class UI_ANDROID_EXPORT DelegatedFrameHostAndroid
ViewAndroid* view_;
viz::HostFrameSinkManager* const host_frame_sink_manager_;
- viz::FrameSinkManagerImpl* const frame_sink_manager_;
WindowAndroidCompositor* registered_parent_compositor_ = nullptr;
Client* client_;
diff --git a/chromium/ui/android/event_forwarder.cc b/chromium/ui/android/event_forwarder.cc
index dd63f7babf0..7be0652c95d 100644
--- a/chromium/ui/android/event_forwarder.cc
+++ b/chromium/ui/android/event_forwarder.cc
@@ -12,6 +12,7 @@
#include "ui/base/ui_base_switches_util.h"
#include "ui/events/android/drag_event_android.h"
#include "ui/events/android/gesture_event_android.h"
+#include "ui/events/android/gesture_event_type.h"
#include "ui/events/android/motion_event_android.h"
#include "ui/events/base_event_utils.h"
@@ -175,16 +176,42 @@ bool EventForwarder::OnGestureEvent(JNIEnv* env,
const JavaParamRef<jobject>& jobj,
jint type,
jlong time_ms,
- jfloat delta) {
+ jfloat scale) {
float dip_scale = view_->GetDipScale();
auto size = view_->GetSize();
float x = size.width() / 2;
float y = size.height() / 2;
gfx::PointF root_location =
ScalePoint(view_->GetLocationOnScreen(x, y), 1.f / dip_scale);
- return view_->OnGestureEvent(
- GestureEventAndroid(type, gfx::PointF(x / dip_scale, y / dip_scale),
- root_location, time_ms, delta));
+ return view_->OnGestureEvent(GestureEventAndroid(
+ type, gfx::PointF(x / dip_scale, y / dip_scale), root_location, time_ms,
+ scale, 0, 0, 0, 0, false, false));
+}
+
+void EventForwarder::OnStartFling(JNIEnv* env,
+ const JavaParamRef<jobject>& jobj,
+ jlong time_ms,
+ jfloat velocity_x,
+ jfloat velocity_y,
+ jboolean synthetic_scroll) {
+ OnCancelFling(env, jobj, time_ms);
+ if (velocity_x == 0 && velocity_y == 0)
+ return;
+ // Use velocity as delta in scroll event.
+ view_->OnGestureEvent(GestureEventAndroid(
+ GESTURE_EVENT_TYPE_SCROLL_START, gfx::PointF(), gfx::PointF(), time_ms, 0,
+ velocity_x, velocity_y, 0, 0, true, synthetic_scroll));
+ view_->OnGestureEvent(GestureEventAndroid(
+ GESTURE_EVENT_TYPE_FLING_START, gfx::PointF(), gfx::PointF(), time_ms, 0,
+ 0, 0, velocity_x, velocity_y, true, synthetic_scroll));
+}
+
+void EventForwarder::OnCancelFling(JNIEnv* env,
+ const JavaParamRef<jobject>& jobj,
+ jlong time_ms) {
+ view_->OnGestureEvent(
+ GestureEventAndroid(GESTURE_EVENT_TYPE_FLING_CANCEL, gfx::PointF(),
+ gfx::PointF(), time_ms, 0, 0, 0, 0, 0, false, false));
}
} // namespace ui
diff --git a/chromium/ui/android/event_forwarder.h b/chromium/ui/android/event_forwarder.h
index 5081190f623..68bd4db9735 100644
--- a/chromium/ui/android/event_forwarder.h
+++ b/chromium/ui/android/event_forwarder.h
@@ -88,7 +88,18 @@ class EventForwarder {
const base::android::JavaParamRef<jobject>& jobj,
jint type,
jlong time_ms,
- jfloat delta);
+ jfloat scale);
+
+ void OnStartFling(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj,
+ jlong time_ms,
+ jfloat velocity_x,
+ jfloat velocity_y,
+ jboolean synthetic_scroll);
+
+ void OnCancelFling(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& jobj,
+ jlong time_ms);
private:
friend class ViewAndroid;
diff --git a/chromium/ui/android/resources/resource_manager_impl.cc b/chromium/ui/android/resources/resource_manager_impl.cc
index d59d5e1faaf..24ac7b3661a 100644
--- a/chromium/ui/android/resources/resource_manager_impl.cc
+++ b/chromium/ui/android/resources/resource_manager_impl.cc
@@ -34,6 +34,27 @@ using base::android::JavaArrayOfIntArrayToIntVector;
using base::android::JavaParamRef;
using base::android::JavaRef;
+namespace {
+
+base::trace_event::MemoryAllocatorDump* CreateMemoryDump(
+ const std::string& name,
+ size_t memory_usage,
+ base::trace_event::ProcessMemoryDump* pmd) {
+ base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(name);
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ memory_usage);
+
+ static const char* system_allocator_name =
+ base::trace_event::MemoryDumpManager::GetInstance()
+ ->system_allocator_pool_name();
+ if (system_allocator_name)
+ pmd->AddSuballocation(dump->guid(), system_allocator_name);
+ return dump;
+}
+
+} // namespace
+
namespace ui {
// static
@@ -212,24 +233,21 @@ void ResourceManagerImpl::RemoveResource(
bool ResourceManagerImpl::OnMemoryDump(
const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) {
- size_t memory_usage =
- base::trace_event::EstimateMemoryUsage(resources_) +
- base::trace_event::EstimateMemoryUsage(tinted_resources_);
-
- base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(
- base::StringPrintf("ui/resource_manager_0x%" PRIXPTR,
- reinterpret_cast<uintptr_t>(this)));
- dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
- base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- memory_usage);
-
- const char* system_allocator_name =
- base::trace_event::MemoryDumpManager::GetInstance()
- ->system_allocator_pool_name();
- if (system_allocator_name) {
- pmd->AddSuballocation(dump->guid(), system_allocator_name);
+ std::string prefix = base::StringPrintf("ui/resource_manager_0x%" PRIXPTR,
+ reinterpret_cast<uintptr_t>(this));
+ for (uint32_t type = static_cast<uint32_t>(ANDROID_RESOURCE_TYPE_FIRST);
+ type <= static_cast<uint32_t>(ANDROID_RESOURCE_TYPE_LAST); ++type) {
+ size_t usage = base::trace_event::EstimateMemoryUsage(resources_[type]);
+ auto* dump = CreateMemoryDump(
+ prefix + base::StringPrintf("/default_resource/0x%u",
+ static_cast<uint32_t>(type)),
+ usage, pmd);
+ dump->AddScalar("resource_count", "objects", resources_[type].size());
}
+ size_t tinted_resource_usage =
+ base::trace_event::EstimateMemoryUsage(tinted_resources_);
+ CreateMemoryDump(prefix + "/tinted_resource", tinted_resource_usage, pmd);
return true;
}
diff --git a/chromium/ui/android/resources/resource_manager_impl_unittest.cc b/chromium/ui/android/resources/resource_manager_impl_unittest.cc
index 441a43337cd..58a16219901 100644
--- a/chromium/ui/android/resources/resource_manager_impl_unittest.cc
+++ b/chromium/ui/android/resources/resource_manager_impl_unittest.cc
@@ -154,8 +154,8 @@ TEST_F(ResourceManagerTest, TestOnMemoryDumpEmitsData) {
const char* system_allocator_pool_name =
base::trace_event::MemoryDumpManager::GetInstance()
->system_allocator_pool_name();
- size_t expected_dump_count = system_allocator_pool_name ? 2 : 1;
- EXPECT_EQ(expected_dump_count, allocator_dumps.size());
+ size_t kExpectedDumpCount = 10;
+ EXPECT_EQ(kExpectedDumpCount, allocator_dumps.size());
for (const auto& dump : allocator_dumps) {
ASSERT_TRUE(dump.first.find("ui/resource_manager") == 0 ||
dump.first.find(system_allocator_pool_name) == 0);
diff --git a/chromium/ui/app_list/BUILD.gn b/chromium/ui/app_list/BUILD.gn
index d5a40a53aec..56706f28bd1 100644
--- a/chromium/ui/app_list/BUILD.gn
+++ b/chromium/ui/app_list/BUILD.gn
@@ -5,6 +5,8 @@
import("//build/config/ui.gni")
import("//testing/test.gni")
+assert(is_chromeos)
+
component("app_list") {
sources = [
"app_list_constants.cc",
@@ -12,6 +14,8 @@ component("app_list") {
"app_list_export.h",
"app_list_features.cc",
"app_list_features.h",
+ "app_list_metrics.cc",
+ "app_list_metrics.h",
"app_list_switches.cc",
"app_list_switches.h",
"app_list_util.cc",
@@ -63,16 +67,12 @@ component("app_list") {
"views/image_shadow_animator.h",
"views/indicator_chip_view.cc",
"views/indicator_chip_view.h",
+ "views/page_switcher.cc",
"views/page_switcher.h",
- "views/page_switcher_horizontal.cc",
- "views/page_switcher_horizontal.h",
- "views/page_switcher_vertical.cc",
- "views/page_switcher_vertical.h",
"views/pulsing_block_view.cc",
"views/pulsing_block_view.h",
"views/search_box_view.cc",
"views/search_box_view.h",
- "views/search_box_view_delegate.h",
"views/search_result_actions_view.cc",
"views/search_result_actions_view.h",
"views/search_result_actions_view_delegate.h",
@@ -92,8 +92,6 @@ component("app_list") {
"views/search_result_tile_item_view.h",
"views/search_result_view.cc",
"views/search_result_view.h",
- "views/speech_view.cc",
- "views/speech_view.h",
"views/suggestions_container_view.cc",
"views/suggestions_container_view.h",
"views/top_icon_animation_view.cc",
@@ -121,6 +119,7 @@ component("app_list") {
"//ui/aura",
"//ui/base",
"//ui/base/ime",
+ "//ui/chromeos/search_box",
"//ui/compositor",
"//ui/display",
"//ui/events",
@@ -137,7 +136,6 @@ component("app_list") {
public_deps = [
"//ash/app_list/model:app_list_model",
"//ash/app_list/model:search_model",
- "//ash/app_list/model:speech_ui_model",
"//ash/public/cpp:cpp",
]
}
@@ -185,7 +183,6 @@ executable("app_list_demo") {
"//ui/resources",
"//ui/resources:ui_test_pak",
"//ui/views",
- "//ui/views/controls/webview",
"//ui/views_content_client",
"//url",
]
@@ -213,7 +210,6 @@ test("app_list_unittests") {
"views/search_result_list_view_unittest.cc",
"views/search_result_page_view_unittest.cc",
"views/search_result_tile_item_list_view_unittest.cc",
- "views/speech_view_unittest.cc",
]
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
@@ -229,6 +225,7 @@ test("app_list_unittests") {
"//ui/accessibility",
"//ui/app_list/vector_icons",
"//ui/base",
+ "//ui/chromeos/search_box",
"//ui/compositor",
"//ui/events:test_support",
"//ui/gfx:test_support",
diff --git a/chromium/ui/app_list/presenter/BUILD.gn b/chromium/ui/app_list/presenter/BUILD.gn
index 58cc1463e83..82d6dae01c9 100644
--- a/chromium/ui/app_list/presenter/BUILD.gn
+++ b/chromium/ui/app_list/presenter/BUILD.gn
@@ -51,7 +51,7 @@ component("presenter") {
# Temporary dependency to fix compile flake in http://crbug.com/611898.
# TODO(tapted): Remove once http://crbug.com/612382 is fixed.
- "//ui/accessibility:ax_gen",
+ "//ui/accessibility:ax_enums_mojo",
]
}
@@ -66,7 +66,7 @@ static_library("test_support") {
# Temporary dependency to fix compile flake in http://crbug.com/611898.
# TODO(tapted): Remove once http://crbug.com/612382 is fixed.
- "//ui/accessibility:ax_gen",
+ "//ui/accessibility:ax_enums_mojo",
]
public_deps = [
@@ -105,7 +105,7 @@ test("app_list_presenter_unittests") {
# Temporary dependency to fix compile flake in http://crbug.com/611898.
# TODO(tapted): Remove once http://crbug.com/612382 is fixed.
- "//ui/accessibility:ax_gen",
+ "//ui/accessibility:ax_enums_mojo",
]
data_deps = [
diff --git a/chromium/ui/arc/notification/arc_notification_content_view.cc b/chromium/ui/arc/notification/arc_notification_content_view.cc
index 214f35bda01..baecc8484c1 100644
--- a/chromium/ui/arc/notification/arc_notification_content_view.cc
+++ b/chromium/ui/arc/notification/arc_notification_content_view.cc
@@ -9,7 +9,6 @@
#include "base/memory/ptr_util.h"
#include "components/exo/notification_surface.h"
#include "components/exo/surface.h"
-#include "ui/accessibility/ax_action_data.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/arc/notification/arc_notification_surface.h"
#include "ui/arc/notification/arc_notification_view.h"
@@ -238,18 +237,6 @@ class ArcNotificationContentView::ContentViewDelegate
explicit ContentViewDelegate(ArcNotificationContentView* owner)
: owner_(owner) {}
- bool IsCloseButtonFocused() const override {
- if (!owner_->control_buttons_view_)
- return false;
- return owner_->control_buttons_view_->IsCloseButtonFocused();
- }
-
- void RequestFocusOnCloseButton() override {
- if (owner_->control_buttons_view_)
- owner_->control_buttons_view_->RequestFocusOnCloseButton();
- owner_->UpdateControlButtonsVisibility();
- }
-
void UpdateControlButtonsVisibility() override {
owner_->UpdateControlButtonsVisibility();
}
@@ -264,10 +251,6 @@ class ArcNotificationContentView::ContentViewDelegate
return owner_->control_buttons_view_;
}
- bool IsExpanded() const override { return owner_->IsExpanded(); }
-
- void SetExpanded(bool expanded) override { owner_->SetExpanded(expanded); }
-
void OnContainerAnimationStarted() override {
owner_->OnContainerAnimationStarted();
}
@@ -514,21 +497,6 @@ void ArcNotificationContentView::UpdateAccessibleName() {
accessible_name_ = item_->GetAccessibleName();
}
-bool ArcNotificationContentView::IsExpanded() const {
- return item_->GetExpandState() == mojom::ArcNotificationExpandState::EXPANDED;
-}
-
-void ArcNotificationContentView::SetExpanded(bool expanded) {
- auto expand_state = item_->GetExpandState();
- if (expanded) {
- if (expand_state == mojom::ArcNotificationExpandState::COLLAPSED)
- item_->ToggleExpansion();
- } else {
- if (expand_state == mojom::ArcNotificationExpandState::EXPANDED)
- item_->ToggleExpansion();
- }
-}
-
void ArcNotificationContentView::OnContainerAnimationStarted() {
ShowCopiedSurface();
}
@@ -699,25 +667,16 @@ views::FocusTraversable* ArcNotificationContentView::GetFocusTraversable() {
return nullptr;
}
-bool ArcNotificationContentView::HandleAccessibleAction(
- const ui::AXActionData& action_data) {
- if (item_ && action_data.action == ui::AX_ACTION_DO_DEFAULT) {
- item_->ToggleExpansion();
- return true;
- }
- return false;
-}
-
void ArcNotificationContentView::GetAccessibleNodeData(
ui::AXNodeData* node_data) {
if (surface_ && surface_->GetAXTreeId() != -1) {
- node_data->role = ui::AX_ROLE_CLIENT;
- node_data->AddIntAttribute(ui::AX_ATTR_CHILD_TREE_ID,
+ node_data->role = ax::mojom::Role::kClient;
+ node_data->AddIntAttribute(ax::mojom::IntAttribute::kChildTreeId,
surface_->GetAXTreeId());
} else {
- node_data->role = ui::AX_ROLE_BUTTON;
+ node_data->role = ax::mojom::Role::kButton;
node_data->AddStringAttribute(
- ui::AX_ATTR_ROLE_DESCRIPTION,
+ ax::mojom::StringAttribute::kRoleDescription,
l10n_util::GetStringUTF8(
IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME));
}
@@ -766,11 +725,11 @@ void ArcNotificationContentView::OnNotificationSurfaceAdded(
SetSurface(surface);
- // Notify AX_EVENT_CHILDREN_CHANGED to force AXNodeData of this view updated.
- // As order of OnNotificationSurfaceAdded call is not guaranteed, we are
- // dispatching the event in both ArcNotificationContentView and
+ // Notify ax::mojom::Event::kChildrenChanged to force AXNodeData of this view
+ // updated. As order of OnNotificationSurfaceAdded call is not guaranteed, we
+ // are dispatching the event in both ArcNotificationContentView and
// ArcAccessibilityHelperBridge.
- NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, false);
+ NotifyAccessibilityEvent(ax::mojom::Event::kChildrenChanged, false);
}
void ArcNotificationContentView::OnNotificationSurfaceRemoved(
diff --git a/chromium/ui/arc/notification/arc_notification_content_view.h b/chromium/ui/arc/notification/arc_notification_content_view.h
index 49a64cc7efc..fe405a0c4dd 100644
--- a/chromium/ui/arc/notification/arc_notification_content_view.h
+++ b/chromium/ui/arc/notification/arc_notification_content_view.h
@@ -20,7 +20,6 @@ class NotificationControlButtonsView;
}
namespace ui {
-struct AXActionData;
class LayerTreeOwner;
}
@@ -73,6 +72,8 @@ class ArcNotificationContentView
void UpdateAccessibleName();
void SetExpanded(bool expanded);
bool IsExpanded() const;
+ void SetManuallyExpandedOrCollapsed(bool value);
+ bool IsManuallyExpandedOrCollapsed() const;
void OnContainerAnimationStarted();
void OnContainerAnimationEnded();
@@ -89,7 +90,6 @@ class ArcNotificationContentView
void OnFocus() override;
void OnBlur() override;
views::FocusTraversable* GetFocusTraversable() override;
- bool HandleAccessibleAction(const ui::AXActionData& action) override;
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
// aura::WindowObserver
@@ -109,7 +109,7 @@ class ArcNotificationContentView
// If |item_| is null, we may be about to be destroyed. In this case,
// we have to be careful about what we do.
- ArcNotificationItem* item_ = nullptr;
+ ArcNotificationItem* item_;
ArcNotificationSurface* surface_ = nullptr;
// The flag to prevent an infinite loop of changing the visibility.
diff --git a/chromium/ui/arc/notification/arc_notification_content_view_delegate.h b/chromium/ui/arc/notification/arc_notification_content_view_delegate.h
index c2268bd3cda..2d8e4d04ffc 100644
--- a/chromium/ui/arc/notification/arc_notification_content_view_delegate.h
+++ b/chromium/ui/arc/notification/arc_notification_content_view_delegate.h
@@ -17,14 +17,10 @@ namespace arc {
class ArcNotificationContentViewDelegate {
public:
virtual ~ArcNotificationContentViewDelegate() = default;
- virtual bool IsCloseButtonFocused() const = 0;
- virtual void RequestFocusOnCloseButton() = 0;
virtual void UpdateControlButtonsVisibility() = 0;
virtual void OnSlideChanged() = 0;
virtual message_center::NotificationControlButtonsView*
GetControlButtonsView() const = 0;
- virtual bool IsExpanded() const = 0;
- virtual void SetExpanded(bool expanded) = 0;
virtual void OnContainerAnimationStarted() = 0;
virtual void OnContainerAnimationEnded() = 0;
};
diff --git a/chromium/ui/arc/notification/arc_notification_content_view_unittest.cc b/chromium/ui/arc/notification/arc_notification_content_view_unittest.cc
index b6773b11efa..d69a751faf4 100644
--- a/chromium/ui/arc/notification/arc_notification_content_view_unittest.cc
+++ b/chromium/ui/arc/notification/arc_notification_content_view_unittest.cc
@@ -32,7 +32,7 @@
#include "ui/aura/window.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/test/event_generator.h"
-#include "ui/message_center/notification.h"
+#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/views/message_view_factory.h"
#include "ui/message_center/views/notification_control_buttons_view.h"
#include "ui/message_center/views/padded_button.h"
@@ -113,6 +113,7 @@ class MockArcNotificationItem : public ArcNotificationItem {
return base::EmptyString16();
};
void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data) override {}
+ bool IsManuallyExpandedOrCollapsed() const override { return false; }
private:
std::string notification_key_;
diff --git a/chromium/ui/arc/notification/arc_notification_delegate.cc b/chromium/ui/arc/notification/arc_notification_delegate.cc
index ff764a801f1..4a3ddb0ac03 100644
--- a/chromium/ui/arc/notification/arc_notification_delegate.cc
+++ b/chromium/ui/arc/notification/arc_notification_delegate.cc
@@ -7,7 +7,7 @@
#include "ui/arc/notification/arc_notification_content_view.h"
#include "ui/arc/notification/arc_notification_item.h"
#include "ui/arc/notification/arc_notification_view.h"
-#include "ui/message_center/notification.h"
+#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/views/message_view.h"
namespace arc {
@@ -28,8 +28,9 @@ ArcNotificationDelegate::CreateCustomMessageView(
auto view = std::make_unique<ArcNotificationContentView>(item_.get());
auto content_view_delegate = view->CreateContentViewDelegate();
- return std::make_unique<ArcNotificationView>(
- std::move(view), std::move(content_view_delegate), notification);
+ return std::make_unique<ArcNotificationView>(item_.get(), std::move(view),
+ std::move(content_view_delegate),
+ notification);
}
void ArcNotificationDelegate::Close(bool by_user) {
diff --git a/chromium/ui/arc/notification/arc_notification_delegate.h b/chromium/ui/arc/notification/arc_notification_delegate.h
index 66223939779..c90da5dc3c5 100644
--- a/chromium/ui/arc/notification/arc_notification_delegate.h
+++ b/chromium/ui/arc/notification/arc_notification_delegate.h
@@ -7,7 +7,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "ui/message_center/notification_delegate.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
namespace message_center {
diff --git a/chromium/ui/arc/notification/arc_notification_item.h b/chromium/ui/arc/notification/arc_notification_item.h
index d5d1f973fbe..cbe94104602 100644
--- a/chromium/ui/arc/notification/arc_notification_item.h
+++ b/chromium/ui/arc/notification/arc_notification_item.h
@@ -69,6 +69,9 @@ class ArcNotificationItem {
virtual const gfx::ImageSkia& GetSnapshot() const = 0;
// Returns the current expand state.
virtual mojom::ArcNotificationExpandState GetExpandState() const = 0;
+
+ virtual bool IsManuallyExpandedOrCollapsed() const = 0;
+
// Returns the current type of shown contents.
virtual mojom::ArcNotificationShownContents GetShownContents() const = 0;
// Returns the rect for which Android wants to handle all swipe events.
diff --git a/chromium/ui/arc/notification/arc_notification_item_impl.cc b/chromium/ui/arc/notification/arc_notification_item_impl.cc
index df632b0bb44..a889206a543 100644
--- a/chromium/ui/arc/notification/arc_notification_item_impl.cc
+++ b/chromium/ui/arc/notification/arc_notification_item_impl.cc
@@ -13,10 +13,10 @@
#include "ui/arc/notification/arc_notification_delegate.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_types.h"
-#include "ui/message_center/notifier_id.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_types.h"
+#include "ui/message_center/public/cpp/notifier_id.h"
namespace arc {
@@ -104,6 +104,14 @@ void ArcNotificationItemImpl::OnUpdatedFromAndroid(
new ArcNotificationDelegate(weak_ptr_factory_.GetWeakPtr()));
notification->set_timestamp(base::Time::FromJavaTime(data->time));
+ if (expand_state_ != mojom::ArcNotificationExpandState::FIXED_SIZE &&
+ data->expand_state != mojom::ArcNotificationExpandState::FIXED_SIZE &&
+ expand_state_ != data->expand_state) {
+ // Assuming changing the expand status on Android-side is manually tiggered
+ // by user.
+ manually_expanded_or_collapsed_ = true;
+ }
+
expand_state_ = data->expand_state;
shown_contents_ = data->shown_contents;
swipe_input_rect_ =
@@ -156,6 +164,18 @@ bool ArcNotificationItemImpl::IsOpeningSettingsSupported() const {
}
void ArcNotificationItemImpl::ToggleExpansion() {
+ switch (expand_state_) {
+ case mojom::ArcNotificationExpandState::EXPANDED:
+ expand_state_ = mojom::ArcNotificationExpandState::COLLAPSED;
+ break;
+ case mojom::ArcNotificationExpandState::COLLAPSED:
+ expand_state_ = mojom::ArcNotificationExpandState::EXPANDED;
+ break;
+ case mojom::ArcNotificationExpandState::FIXED_SIZE:
+ // Do not change the state.
+ break;
+ }
+
manager_->SendNotificationToggleExpansionOnChrome(notification_key_);
}
@@ -193,6 +213,10 @@ mojom::ArcNotificationExpandState ArcNotificationItemImpl::GetExpandState()
return expand_state_;
}
+bool ArcNotificationItemImpl::IsManuallyExpandedOrCollapsed() const {
+ return manually_expanded_or_collapsed_;
+}
+
mojom::ArcNotificationShownContents ArcNotificationItemImpl::GetShownContents()
const {
return shown_contents_;
diff --git a/chromium/ui/arc/notification/arc_notification_item_impl.h b/chromium/ui/arc/notification/arc_notification_item_impl.h
index 72c77d32641..33bea528b40 100644
--- a/chromium/ui/arc/notification/arc_notification_item_impl.h
+++ b/chromium/ui/arc/notification/arc_notification_item_impl.h
@@ -44,6 +44,7 @@ class ArcNotificationItemImpl : public ArcNotificationItem {
void DecrementWindowRefCount() override;
const gfx::ImageSkia& GetSnapshot() const override;
mojom::ArcNotificationExpandState GetExpandState() const override;
+ bool IsManuallyExpandedOrCollapsed() const override;
mojom::ArcNotificationShownContents GetShownContents() const override;
gfx::Rect GetSwipeInputRect() const override;
const std::string& GetNotificationKey() const override;
@@ -85,6 +86,8 @@ class ArcNotificationItemImpl : public ArcNotificationItem {
// (2) the removing is initiated by manager
bool being_removed_by_manager_ = false;
+ bool manually_expanded_or_collapsed_ = false;
+
base::ThreadChecker thread_checker_;
base::WeakPtrFactory<ArcNotificationItemImpl> weak_ptr_factory_;
diff --git a/chromium/ui/arc/notification/arc_notification_manager_unittest.cc b/chromium/ui/arc/notification/arc_notification_manager_unittest.cc
index 6a03147aef8..98f586105d2 100644
--- a/chromium/ui/arc/notification/arc_notification_manager_unittest.cc
+++ b/chromium/ui/arc/notification/arc_notification_manager_unittest.cc
@@ -86,9 +86,6 @@ class ArcNotificationManagerTest : public testing::Test {
data->title = "TITLE";
data->message = "MESSAGE";
- std::vector<unsigned char> icon_data;
- data->icon_data = icon_data;
-
arc_notification_manager()->OnNotificationPosted(std::move(data));
return key;
diff --git a/chromium/ui/arc/notification/arc_notification_view.cc b/chromium/ui/arc/notification/arc_notification_view.cc
index 0e33fe23c68..6977d6d385f 100644
--- a/chromium/ui/arc/notification/arc_notification_view.cc
+++ b/chromium/ui/arc/notification/arc_notification_view.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "ui/accessibility/ax_action_data.h"
#include "ui/arc/notification/arc_notification_content_view_delegate.h"
#include "ui/arc/notification/arc_notification_item.h"
#include "ui/base/ime/input_method.h"
@@ -25,14 +26,18 @@ namespace arc {
const char ArcNotificationView::kViewClassName[] = "ArcNotificationView";
ArcNotificationView::ArcNotificationView(
+ ArcNotificationItem* item,
std::unique_ptr<views::View> contents_view,
std::unique_ptr<ArcNotificationContentViewDelegate> contents_view_delegate,
const message_center::Notification& notification)
: message_center::MessageView(notification),
+ item_(item),
contents_view_(contents_view.get()),
contents_view_delegate_(std::move(contents_view_delegate)) {
DCHECK_EQ(message_center::NOTIFICATION_TYPE_CUSTOM, notification.type());
+ item_->AddObserver(this);
+
DCHECK(contents_view);
AddChildView(contents_view.release());
@@ -49,7 +54,10 @@ ArcNotificationView::ArcNotificationView(
message_center::kFocusBorderColor, gfx::Insets(0, 1, 3, 2));
}
-ArcNotificationView::~ArcNotificationView() = default;
+ArcNotificationView::~ArcNotificationView() {
+ if (item_)
+ item_->RemoveObserver(this);
+}
void ArcNotificationView::OnContentFocused() {
SchedulePaint();
@@ -75,14 +83,17 @@ void ArcNotificationView::SetDrawBackgroundAsActive(bool active) {
}
bool ArcNotificationView::IsCloseButtonFocused() const {
- if (!contents_view_delegate_)
+ if (!GetControlButtonsView())
return false;
- return contents_view_delegate_->IsCloseButtonFocused();
+ return GetControlButtonsView()->IsCloseButtonFocused();
}
void ArcNotificationView::RequestFocusOnCloseButton() {
- if (contents_view_delegate_)
- contents_view_delegate_->RequestFocusOnCloseButton();
+ if (GetControlButtonsView()) {
+ GetControlButtonsView()->RequestFocusOnCloseButton();
+ if (contents_view_delegate_)
+ contents_view_delegate_->UpdateControlButtonsVisibility();
+ }
}
const char* ArcNotificationView::GetClassName() const {
@@ -105,14 +116,28 @@ ArcNotificationView::GetControlButtonsView() const {
}
bool ArcNotificationView::IsExpanded() const {
- if (contents_view_delegate_)
- return contents_view_delegate_->IsExpanded();
- return false;
+ return item_ &&
+ item_->GetExpandState() == mojom::ArcNotificationExpandState::EXPANDED;
}
void ArcNotificationView::SetExpanded(bool expanded) {
- if (contents_view_delegate_)
- contents_view_delegate_->SetExpanded(expanded);
+ if (!item_)
+ return;
+
+ auto expand_state = item_->GetExpandState();
+ if (expanded) {
+ if (expand_state == mojom::ArcNotificationExpandState::COLLAPSED)
+ item_->ToggleExpansion();
+ } else {
+ if (expand_state == mojom::ArcNotificationExpandState::EXPANDED)
+ item_->ToggleExpansion();
+ }
+}
+
+bool ArcNotificationView::IsManuallyExpandedOrCollapsed() const {
+ if (item_)
+ return item_->IsManuallyExpandedOrCollapsed();
+ return false;
}
void ArcNotificationView::OnContainerAnimationStarted() {
@@ -197,11 +222,21 @@ void ArcNotificationView::ChildPreferredSizeChanged(View* child) {
bool ArcNotificationView::HandleAccessibleAction(
const ui::AXActionData& action) {
- if (contents_view_)
- return contents_view_->HandleAccessibleAction(action);
+ if (item_ && action.action == ax::mojom::Action::kDoDefault) {
+ item_->ToggleExpansion();
+ return true;
+ }
return false;
}
+void ArcNotificationView::OnItemDestroying() {
+ DCHECK(item_);
+ item_->RemoveObserver(this);
+ item_ = nullptr;
+}
+
+void ArcNotificationView::OnItemUpdated() {}
+
// TODO(yoshiki): move this to MessageView and share the code among
// NotificationView and NotificationViewMD.
void ArcNotificationView::UpdateControlButtonsVisibilityWithNotification(
diff --git a/chromium/ui/arc/notification/arc_notification_view.h b/chromium/ui/arc/notification/arc_notification_view.h
index c8dedeebbe5..e54838bb0b5 100644
--- a/chromium/ui/arc/notification/arc_notification_view.h
+++ b/chromium/ui/arc/notification/arc_notification_view.h
@@ -6,6 +6,7 @@
#define UI_ARC_NOTIFICATION_ARC_NOTIFICATION_VIEW_H_
#include "base/macros.h"
+#include "ui/arc/notification/arc_notification_item.h"
#include "ui/message_center/views/message_view.h"
namespace views {
@@ -18,12 +19,14 @@ class ArcNotificationContentViewDelegate;
// View for custom notification with NOTIFICATION_TYPE_CUSTOM which hosts the
// ArcNotificationContentView which shows content of the notification.
-class ArcNotificationView : public message_center::MessageView {
+class ArcNotificationView : public message_center::MessageView,
+ public ArcNotificationItem::Observer {
public:
static const char kViewClassName[];
// |content_view| is a view to be hosted in this view.
- ArcNotificationView(std::unique_ptr<views::View> content_view,
+ ArcNotificationView(ArcNotificationItem* item,
+ std::unique_ptr<views::View> content_view,
std::unique_ptr<ArcNotificationContentViewDelegate>
contents_view_delegate,
const message_center::Notification& notification);
@@ -46,6 +49,7 @@ class ArcNotificationView : public message_center::MessageView {
const override;
bool IsExpanded() const override;
void SetExpanded(bool expanded) override;
+ bool IsManuallyExpandedOrCollapsed() const override;
void OnContainerAnimationStarted() override;
void OnContainerAnimationEnded() override;
@@ -63,6 +67,10 @@ class ArcNotificationView : public message_center::MessageView {
void ChildPreferredSizeChanged(View* child) override;
bool HandleAccessibleAction(const ui::AXActionData& action) override;
+ // ArcNotificationItem::Observer
+ void OnItemDestroying() override;
+ void OnItemUpdated() override;
+
private:
friend class ArcNotificationContentViewTest;
friend class ArcNotificationViewTest;
@@ -71,6 +79,8 @@ class ArcNotificationView : public message_center::MessageView {
void UpdateControlButtonsVisibilityWithNotification(
const message_center::Notification& notification);
+ ArcNotificationItem* item_;
+
// The view for the custom content. Owned by view hierarchy.
views::View* contents_view_ = nullptr;
std::unique_ptr<ArcNotificationContentViewDelegate> contents_view_delegate_;
diff --git a/chromium/ui/arc/notification/arc_notification_view_unittest.cc b/chromium/ui/arc/notification/arc_notification_view_unittest.cc
index 54935541f4e..e988fdd763b 100644
--- a/chromium/ui/arc/notification/arc_notification_view_unittest.cc
+++ b/chromium/ui/arc/notification/arc_notification_view_unittest.cc
@@ -10,6 +10,7 @@
#include "base/strings/utf_string_conversions.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/arc/notification/arc_notification_content_view_delegate.h"
+#include "ui/arc/notification/arc_notification_item.h"
#include "ui/arc/notification/arc_notification_view.h"
#include "ui/base/ime/dummy_text_input_client.h"
#include "ui/base/ime/input_method.h"
@@ -19,7 +20,7 @@
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"
#include "ui/message_center/message_center.h"
-#include "ui/message_center/notification.h"
+#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/views/message_view_factory.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/image_button.h"
@@ -32,6 +33,7 @@ namespace arc {
namespace {
+constexpr char kNotificationIdPrefix[] = "ARC_NOTIFICATION_";
const SkColor kBackgroundColor = SK_ColorGREEN;
class TestNotificationContentsView : public views::View {
@@ -76,24 +78,68 @@ class TestNotificationContentsView : public views::View {
class TestContentViewDelegate : public ArcNotificationContentViewDelegate {
public:
- bool IsCloseButtonFocused() const override { return false; }
- void RequestFocusOnCloseButton() override {}
void UpdateControlButtonsVisibility() override {}
void OnSlideChanged() override {}
message_center::NotificationControlButtonsView* GetControlButtonsView()
const override {
return nullptr;
}
- bool IsExpanded() const override { return false; }
- void SetExpanded(bool expanded) override {}
void OnContainerAnimationStarted() override {}
void OnContainerAnimationEnded() override {}
};
+class MockArcNotificationItem : public ArcNotificationItem {
+ public:
+ MockArcNotificationItem(const std::string& notification_key)
+ : notification_key_(notification_key),
+ notification_id_(kNotificationIdPrefix + notification_key) {}
+
+ // Overriding methods for testing.
+ void Close(bool by_user) override {}
+ const gfx::ImageSkia& GetSnapshot() const override { return snapshot_; }
+ const std::string& GetNotificationKey() const override {
+ return notification_key_;
+ }
+ const std::string& GetNotificationId() const override {
+ return notification_id_;
+ }
+
+ // Overriding methods for returning dummy data or doing nothing.
+ void OnClosedFromAndroid() override {}
+ void Click() override {}
+ void ToggleExpansion() override {}
+ void OpenSettings() override {}
+ void AddObserver(Observer* observer) override {}
+ void RemoveObserver(Observer* observer) override {}
+ void IncrementWindowRefCount() override {}
+ void DecrementWindowRefCount() override {}
+ bool IsOpeningSettingsSupported() const override { return true; }
+ mojom::ArcNotificationExpandState GetExpandState() const override {
+ return mojom::ArcNotificationExpandState::FIXED_SIZE;
+ }
+ mojom::ArcNotificationShownContents GetShownContents() const override {
+ return mojom::ArcNotificationShownContents::CONTENTS_SHOWN;
+ }
+ gfx::Rect GetSwipeInputRect() const override { return gfx::Rect(); }
+ const base::string16& GetAccessibleName() const override {
+ return base::EmptyString16();
+ };
+ void OnUpdatedFromAndroid(mojom::ArcNotificationDataPtr data) override {}
+ bool IsManuallyExpandedOrCollapsed() const override { return false; }
+
+ private:
+ std::string notification_key_;
+ std::string notification_id_;
+ gfx::ImageSkia snapshot_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockArcNotificationItem);
+};
+
std::unique_ptr<message_center::MessageView> CreateCustomMessageViewForTest(
+ ArcNotificationItem* item,
const Notification& notification) {
return std::make_unique<ArcNotificationView>(
- std::make_unique<TestNotificationContentsView>(),
+ item, std::make_unique<TestNotificationContentsView>(),
std::make_unique<TestContentViewDelegate>(), notification);
}
@@ -124,13 +170,14 @@ class ArcNotificationViewTest : public views::ViewsTestBase {
MessageCenter::Initialize();
+ const std::string notification_id("notification id");
+ item_ = std::make_unique<MockArcNotificationItem>(notification_id);
message_center::MessageViewFactory::SetCustomNotificationViewFactory(
- base::Bind(&CreateCustomMessageViewForTest));
+ base::BindRepeating(&CreateCustomMessageViewForTest, item_.get()));
notification_ = std::make_unique<Notification>(
- message_center::NOTIFICATION_TYPE_CUSTOM,
- std::string("notification id"), base::UTF8ToUTF16("title"),
- base::UTF8ToUTF16("message"), gfx::Image(),
+ message_center::NOTIFICATION_TYPE_CUSTOM, notification_id,
+ base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"), gfx::Image(),
base::UTF8ToUTF16("display source"), GURL(),
message_center::NotifierId(message_center::NotifierId::ARC_APPLICATION,
"test_app_id"),
@@ -233,6 +280,8 @@ class ArcNotificationViewTest : public views::ViewsTestBase {
std::unique_ptr<Notification> notification_;
std::unique_ptr<ArcNotificationView> notification_view_;
+ std::unique_ptr<MockArcNotificationItem> item_;
+
DISALLOW_COPY_AND_ASSIGN(ArcNotificationViewTest);
};
@@ -313,6 +362,7 @@ TEST_F(ArcNotificationViewTest, SlideOutPinned) {
ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
notification()->set_pinned(true);
+ notification_view()->SetIsNested();
UpdateNotificationViews();
std::string notification_id = notification()->id();
diff --git a/chromium/ui/aura/BUILD.gn b/chromium/ui/aura/BUILD.gn
index 0e63f4b6fb1..04f009d70b7 100644
--- a/chromium/ui/aura/BUILD.gn
+++ b/chromium/ui/aura/BUILD.gn
@@ -67,6 +67,7 @@ jumbo_component("aura") {
"mus/window_tree_host_mus.h",
"mus/window_tree_host_mus_delegate.h",
"mus/window_tree_host_mus_init_params.h",
+ "scoped_keyboard_hook.h",
"scoped_window_targeter.h",
"window.h",
"window_delegate.h",
@@ -126,6 +127,7 @@ jumbo_component("aura") {
"mus/window_tree_client_delegate.cc",
"mus/window_tree_host_mus.cc",
"mus/window_tree_host_mus_init_params.cc",
+ "scoped_keyboard_hook.cc",
"scoped_window_targeter.cc",
"window.cc",
"window_event_dispatcher.cc",
@@ -155,6 +157,7 @@ jumbo_component("aura") {
"//mojo/public/cpp/system",
"//net",
"//services/service_manager/public/cpp",
+ "//services/ui/common:mus_common",
"//services/ui/public/cpp",
"//services/ui/public/interfaces",
"//skia",
@@ -176,10 +179,6 @@ jumbo_component("aura") {
"//ui/compositor",
]
- data_deps = [
- "//services/ui",
- ]
-
if (use_x11) {
deps += [
"//ui/events/platform/x11",
@@ -268,6 +267,7 @@ jumbo_static_library("test_support") {
public_deps = [
":aura",
+ "//services/ui/common:mus_common",
# Must be public as headers include ui_features.h.
"//ui/base:ui_features",
diff --git a/chromium/ui/aura/DEPS b/chromium/ui/aura/DEPS
index 7a319fed221..8deffa55def 100644
--- a/chromium/ui/aura/DEPS
+++ b/chromium/ui/aura/DEPS
@@ -11,7 +11,8 @@ include_rules = [
"+mojo/public/cpp/bindings",
"+net/base/filename_util.h",
"+services/service_manager/public/cpp",
- "+services/service_manager/public/interfaces",
+ "+services/service_manager/public/mojom",
+ "+services/ui/common",
"+services/ui/public/interfaces",
"+skia/ext",
"+third_party/skia",
diff --git a/chromium/ui/aura/client/aura_constants.cc b/chromium/ui/aura/client/aura_constants.cc
index 618b51e3121..c171556d287 100644
--- a/chromium/ui/aura/client/aura_constants.cc
+++ b/chromium/ui/aura/client/aura_constants.cc
@@ -73,6 +73,7 @@ DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(base::string16, kTitleKey, nullptr);
DEFINE_UI_CLASS_PROPERTY_KEY(int, kTopViewInset, 0);
DEFINE_UI_CLASS_PROPERTY_KEY(SkColor, kTopViewColor, SK_ColorTRANSPARENT);
DEFINE_OWNED_UI_CLASS_PROPERTY_KEY(gfx::ImageSkia, kWindowIconKey, nullptr);
+DEFINE_UI_CLASS_PROPERTY_KEY(int, kWindowCornerRadiusKey, -1);
DEFINE_UI_CLASS_PROPERTY_KEY(ui::mojom::WindowType,
kWindowTypeKey,
ui::mojom::WindowType::UNKNOWN);
diff --git a/chromium/ui/aura/client/aura_constants.h b/chromium/ui/aura/client/aura_constants.h
index 3730ab710ee..f0f8b6cbf53 100644
--- a/chromium/ui/aura/client/aura_constants.h
+++ b/chromium/ui/aura/client/aura_constants.h
@@ -152,6 +152,10 @@ AURA_EXPORT extern const WindowProperty<gfx::ImageSkia*>* const kWindowIconKey;
// Indicates the type of embedding within the given window.
AURA_EXPORT extern const WindowProperty<WindowEmbedType>* const kEmbedType;
+// The corner radius of a window in DIPs. Currently only used for shadows.
+// Default is -1, meaning "unspecified". 0 Ensures corners are square.
+AURA_EXPORT extern const WindowProperty<int>* const kWindowCornerRadiusKey;
+
AURA_EXPORT extern const WindowProperty<ui::mojom::WindowType>* const
kWindowTypeKey;
diff --git a/chromium/ui/aura/env.cc b/chromium/ui/aura/env.cc
index 08d1d4db88a..b62fcc15aba 100644
--- a/chromium/ui/aura/env.cc
+++ b/chromium/ui/aura/env.cc
@@ -25,8 +25,10 @@
#include "ui/events/platform/platform_event_source.h"
#if defined(USE_OZONE)
+#include "ui/gfx/client_native_pixmap_factory.h"
#include "ui/ozone/public/client_native_pixmap_factory_ozone.h"
#include "ui/ozone/public/ozone_platform.h"
+#include "ui/ozone/public/ozone_switches.h"
#endif
namespace aura {
@@ -163,9 +165,6 @@ Env::Env(Mode mode)
is_touch_down_(false),
get_last_mouse_location_from_mus_(mode_ == Mode::MUS),
input_state_lookup_(InputStateLookup::Create()),
-#if defined(USE_OZONE)
- native_pixmap_factory_(ui::CreateClientNativePixmapFactoryOzone()),
-#endif
context_factory_(nullptr),
context_factory_private_(nullptr) {
DCHECK(lazy_tls_ptr.Pointer()->Get() == NULL);
@@ -173,13 +172,13 @@ Env::Env(Mode mode)
}
void Env::Init() {
+#if defined(USE_OZONE)
+ ui::CreateClientNativePixmapFactoryOzone();
+ DCHECK(gfx::ClientNativePixmapFactory::GetInstance());
+#endif
if (mode_ == Mode::MUS) {
EnableMusOSExchangeDataProvider();
EnableMusOverrideInputInjector();
-#if defined(USE_OZONE)
- // Required by all Aura-using clients of services/ui
- gfx::ClientNativePixmapFactory::SetInstance(native_pixmap_factory_.get());
-#endif
return;
}
@@ -193,8 +192,9 @@ void Env::Init() {
// instead of checking flags here.
params.single_process = command_line->HasSwitch("single-process") ||
command_line->HasSwitch("in-process-gpu");
+ params.using_mojo = command_line->HasSwitch(switches::kEnableDrmMojo);
+
ui::OzonePlatform::InitializeForUI(params);
- gfx::ClientNativePixmapFactory::SetInstance(native_pixmap_factory_.get());
#endif
if (!ui::PlatformEventSource::GetInstance())
event_source_ = ui::PlatformEventSource::CreateDefault();
diff --git a/chromium/ui/aura/env.h b/chromium/ui/aura/env.h
index bf0e401979b..bc615fdb3a1 100644
--- a/chromium/ui/aura/env.h
+++ b/chromium/ui/aura/env.h
@@ -26,12 +26,6 @@ namespace base {
class UnguessableToken;
}
-#if defined(USE_OZONE)
-namespace gfx {
-class ClientNativePixmapFactory;
-}
-#endif
-
namespace mojo {
template <typename MojoInterface>
class InterfacePtr;
@@ -214,12 +208,6 @@ class AURA_EXPORT Env : public ui::EventTarget,
std::unique_ptr<InputStateLookup> input_state_lookup_;
std::unique_ptr<ui::PlatformEventSource> event_source_;
-#if defined(USE_OZONE)
- // Factory for pixmaps that can use be transported from the client to the GPU
- // process using a low-level ozone-provided platform specific mechanism.
- std::unique_ptr<gfx::ClientNativePixmapFactory> native_pixmap_factory_;
-#endif
-
ui::ContextFactory* context_factory_;
ui::ContextFactoryPrivate* context_factory_private_;
diff --git a/chromium/ui/aura/env_input_state_controller.cc b/chromium/ui/aura/env_input_state_controller.cc
index 6807055790b..0478abf599c 100644
--- a/chromium/ui/aura/env_input_state_controller.cc
+++ b/chromium/ui/aura/env_input_state_controller.cc
@@ -47,7 +47,7 @@ void EnvInputStateController::UpdateStateForTouchEvent(
case ui::ET_TOUCH_CANCELLED:
if (!event.HasNativeEvent())
break;
- // fallthrough
+ FALLTHROUGH;
case ui::ET_TOUCH_RELEASED:
touch_ids_down_ = (touch_ids_down_ | (1 << event.pointer_details().id)) ^
(1 << event.pointer_details().id);
diff --git a/chromium/ui/aura/hit_test_data_provider_aura.cc b/chromium/ui/aura/hit_test_data_provider_aura.cc
index 1b35ed642b4..0f7600aae12 100644
--- a/chromium/ui/aura/hit_test_data_provider_aura.cc
+++ b/chromium/ui/aura/hit_test_data_provider_aura.cc
@@ -44,8 +44,8 @@ HitTestDataProviderAura::HitTestDataProviderAura(aura::Window* window)
HitTestDataProviderAura::~HitTestDataProviderAura() {}
-viz::mojom::HitTestRegionListPtr HitTestDataProviderAura::GetHitTestData()
- const {
+viz::mojom::HitTestRegionListPtr HitTestDataProviderAura::GetHitTestData(
+ const viz::CompositorFrame& compositor_frame) const {
const ui::mojom::EventTargetingPolicy event_targeting_policy =
window_->event_targeting_policy();
if (!window_->IsVisible() ||
@@ -58,6 +58,7 @@ viz::mojom::HitTestRegionListPtr HitTestDataProviderAura::GetHitTestData()
ui::mojom::EventTargetingPolicy::DESCENDANTS_ONLY
? viz::mojom::kHitTestIgnore
: viz::mojom::kHitTestMine;
+ // TODO(crbug.com/805416): Use pixels instead of DIP units for bounds.
hit_test_region_list->bounds = window_->bounds();
GetHitTestDataRecursively(window_, hit_test_region_list.get());
diff --git a/chromium/ui/aura/hit_test_data_provider_aura.h b/chromium/ui/aura/hit_test_data_provider_aura.h
index 9993a31ae2c..5887e821702 100644
--- a/chromium/ui/aura/hit_test_data_provider_aura.h
+++ b/chromium/ui/aura/hit_test_data_provider_aura.h
@@ -22,7 +22,8 @@ class AURA_EXPORT HitTestDataProviderAura : public viz::HitTestDataProvider {
~HitTestDataProviderAura() override;
// HitTestDataProvider:
- viz::mojom::HitTestRegionListPtr GetHitTestData() const override;
+ viz::mojom::HitTestRegionListPtr GetHitTestData(
+ const viz::CompositorFrame& compositor_frame) const override;
private:
// Recursively walks the children of |window| and uses |window|'s
diff --git a/chromium/ui/aura/hit_test_data_provider_aura_unittest.cc b/chromium/ui/aura/hit_test_data_provider_aura_unittest.cc
index b157f28fc7d..96a6d82decd 100644
--- a/chromium/ui/aura/hit_test_data_provider_aura_unittest.cc
+++ b/chromium/ui/aura/hit_test_data_provider_aura_unittest.cc
@@ -118,6 +118,7 @@ class HitTestDataProviderAuraTest : public test::AuraTestBaseMus {
root_->AddChild(window2_);
root_->AddChild(window3_);
+ compositor_frame_ = viz::CompositorFrame();
hit_test_data_provider_ = std::make_unique<HitTestDataProviderAura>(root());
}
@@ -130,6 +131,7 @@ class HitTestDataProviderAuraTest : public test::AuraTestBaseMus {
Window* window2() { return window2_; }
Window* window3() { return window3_; }
Window* window4() { return window4_; }
+ viz::CompositorFrame compositor_frame_;
private:
std::unique_ptr<Window> root_;
@@ -146,7 +148,8 @@ class HitTestDataProviderAuraTest : public test::AuraTestBaseMus {
// Tests that the order of reported hit-test regions matches windows Z-order.
TEST_F(HitTestDataProviderAuraTest, Stacking) {
- const auto hit_test_data_1 = hit_test_data_provider()->GetHitTestData();
+ const auto hit_test_data_1 =
+ hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data_1);
EXPECT_EQ(hit_test_data_1->flags, viz::mojom::kHitTestMine);
EXPECT_EQ(hit_test_data_1->bounds, root()->bounds());
@@ -164,7 +167,8 @@ TEST_F(HitTestDataProviderAuraTest, Stacking) {
}
root()->StackChildAbove(window2(), window3());
- const auto hit_test_data_2 = hit_test_data_provider()->GetHitTestData();
+ const auto hit_test_data_2 =
+ hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data_2);
EXPECT_EQ(hit_test_data_2->flags, viz::mojom::kHitTestMine);
EXPECT_EQ(hit_test_data_2->bounds, root()->bounds());
@@ -186,8 +190,9 @@ TEST_F(HitTestDataProviderAuraTest, Stacking) {
// Tests that the hit-test regions get expanded with a custom event targeter.
TEST_F(HitTestDataProviderAuraTest, CustomTargeter) {
window3()->SetEventTargeter(std::make_unique<TestWindowTargeter>());
- window2()->set_embed_frame_sink_id(viz::FrameSinkId(1, 2));
- const auto hit_test_data = hit_test_data_provider()->GetHitTestData();
+ window2()->SetEmbedFrameSinkId(viz::FrameSinkId(1, 2));
+ const auto hit_test_data =
+ hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->flags, viz::mojom::kHitTestMine);
EXPECT_EQ(hit_test_data->bounds, root()->bounds());
@@ -229,7 +234,8 @@ TEST_F(HitTestDataProviderAuraTest, CustomTargeter) {
// Tests that the complex hit-test shape can be set with a custom targeter.
TEST_F(HitTestDataProviderAuraTest, HoleTargeter) {
window3()->SetEventTargeter(std::make_unique<TestHoleWindowTargeter>());
- const auto hit_test_data = hit_test_data_provider()->GetHitTestData();
+ const auto hit_test_data =
+ hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->flags, viz::mojom::kHitTestMine);
EXPECT_EQ(hit_test_data->bounds, root()->bounds());
@@ -263,13 +269,14 @@ TEST_F(HitTestDataProviderAuraTest, HoleTargeter) {
TEST_F(HitTestDataProviderAuraTest, TargetingPolicies) {
root()->SetEventTargetingPolicy(ui::mojom::EventTargetingPolicy::NONE);
- auto hit_test_data = hit_test_data_provider()->GetHitTestData();
+ auto hit_test_data =
+ hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_FALSE(hit_test_data);
root()->SetEventTargetingPolicy(ui::mojom::EventTargetingPolicy::TARGET_ONLY);
window3()->SetEventTargetingPolicy(
ui::mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
- hit_test_data = hit_test_data_provider()->GetHitTestData();
+ hit_test_data = hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->flags, viz::mojom::kHitTestMine);
EXPECT_EQ(hit_test_data->regions.size(), 3u);
@@ -277,7 +284,7 @@ TEST_F(HitTestDataProviderAuraTest, TargetingPolicies) {
root()->SetEventTargetingPolicy(ui::mojom::EventTargetingPolicy::TARGET_ONLY);
window3()->SetEventTargetingPolicy(
ui::mojom::EventTargetingPolicy::TARGET_ONLY);
- hit_test_data = hit_test_data_provider()->GetHitTestData();
+ hit_test_data = hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->flags, viz::mojom::kHitTestMine);
EXPECT_EQ(hit_test_data->regions.size(), 2u);
@@ -286,7 +293,7 @@ TEST_F(HitTestDataProviderAuraTest, TargetingPolicies) {
ui::mojom::EventTargetingPolicy::DESCENDANTS_ONLY);
window3()->SetEventTargetingPolicy(
ui::mojom::EventTargetingPolicy::DESCENDANTS_ONLY);
- hit_test_data = hit_test_data_provider()->GetHitTestData();
+ hit_test_data = hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->flags, viz::mojom::kHitTestIgnore);
EXPECT_EQ(hit_test_data->regions.size(), 2u);
@@ -295,7 +302,7 @@ TEST_F(HitTestDataProviderAuraTest, TargetingPolicies) {
ui::mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
window3()->SetEventTargetingPolicy(
ui::mojom::EventTargetingPolicy::TARGET_AND_DESCENDANTS);
- hit_test_data = hit_test_data_provider()->GetHitTestData();
+ hit_test_data = hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->flags, viz::mojom::kHitTestMine);
EXPECT_EQ(hit_test_data->regions.size(), 3u);
@@ -304,30 +311,31 @@ TEST_F(HitTestDataProviderAuraTest, TargetingPolicies) {
// Tests that we do not submit hit-test data for invisible windows and for
// children of a child surface.
TEST_F(HitTestDataProviderAuraTest, DoNotSubmit) {
- auto hit_test_data = hit_test_data_provider()->GetHitTestData();
+ auto hit_test_data =
+ hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->regions.size(), 3u);
window2()->Hide();
- hit_test_data = hit_test_data_provider()->GetHitTestData();
+ hit_test_data = hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->regions.size(), 2u);
- window3()->set_embed_frame_sink_id(viz::FrameSinkId(1, 3));
- hit_test_data = hit_test_data_provider()->GetHitTestData();
+ window3()->SetEmbedFrameSinkId(viz::FrameSinkId(1, 3));
+ hit_test_data = hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->regions.size(), 1u);
root()->Hide();
- hit_test_data = hit_test_data_provider()->GetHitTestData();
+ hit_test_data = hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_FALSE(hit_test_data);
root()->Show();
- hit_test_data = hit_test_data_provider()->GetHitTestData();
+ hit_test_data = hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->regions.size(), 1u);
- root()->set_embed_frame_sink_id(viz::FrameSinkId(1, 1));
- hit_test_data = hit_test_data_provider()->GetHitTestData();
+ root()->SetEmbedFrameSinkId(viz::FrameSinkId(1, 1));
+ hit_test_data = hit_test_data_provider()->GetHitTestData(compositor_frame_);
ASSERT_TRUE(hit_test_data);
EXPECT_EQ(hit_test_data->regions.size(), 0u);
}
diff --git a/chromium/ui/aura/local/layer_tree_frame_sink_local.cc b/chromium/ui/aura/local/layer_tree_frame_sink_local.cc
index 954176f0fcf..a5ce5a4d677 100644
--- a/chromium/ui/aura/local/layer_tree_frame_sink_local.cc
+++ b/chromium/ui/aura/local/layer_tree_frame_sink_local.cc
@@ -23,12 +23,9 @@ LayerTreeFrameSinkLocal::LayerTreeFrameSinkLocal(
const std::string& debug_label)
: cc::LayerTreeFrameSink(nullptr, nullptr, nullptr, nullptr, nullptr),
frame_sink_id_(frame_sink_id),
- host_frame_sink_manager_(host_frame_sink_manager),
- weak_factory_(this) {
+ host_frame_sink_manager_(host_frame_sink_manager) {
host_frame_sink_manager_->RegisterFrameSinkId(frame_sink_id_, this);
-#if DCHECK_IS_ON()
host_frame_sink_manager_->SetFrameSinkDebugLabel(frame_sink_id_, debug_label);
-#endif
}
LayerTreeFrameSinkLocal::~LayerTreeFrameSinkLocal() {
@@ -56,16 +53,11 @@ void LayerTreeFrameSinkLocal::SetSurfaceChangedCallback(
surface_changed_callback_ = callback;
}
-base::WeakPtr<LayerTreeFrameSinkLocal> LayerTreeFrameSinkLocal::GetWeakPtr() {
- return weak_factory_.GetWeakPtr();
-}
-
void LayerTreeFrameSinkLocal::DetachFromClient() {
DCHECK(thread_checker_);
DCHECK(thread_checker_->CalledOnValidThread());
client_->SetBeginFrameSource(nullptr);
begin_frame_source_.reset();
- support_->EvictCurrentSurface();
support_.reset();
thread_checker_.reset();
cc::LayerTreeFrameSink::DetachFromClient();
@@ -87,9 +79,7 @@ void LayerTreeFrameSinkLocal::SubmitCompositorFrame(
DCHECK(local_surface_id_.is_valid());
- bool result =
- support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
- DCHECK(result);
+ support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
}
void LayerTreeFrameSinkLocal::DidNotProduceFrame(
@@ -101,6 +91,19 @@ void LayerTreeFrameSinkLocal::DidNotProduceFrame(
support_->DidNotProduceFrame(ack);
}
+void LayerTreeFrameSinkLocal::DidAllocateSharedBitmap(
+ mojo::ScopedSharedBufferHandle buffer,
+ const viz::SharedBitmapId& id) {
+ // No software compositing used with this implementation.
+ NOTIMPLEMENTED();
+}
+
+void LayerTreeFrameSinkLocal::DidDeleteSharedBitmap(
+ const viz::SharedBitmapId& id) {
+ // No software compositing used with this implementation.
+ NOTIMPLEMENTED();
+}
+
void LayerTreeFrameSinkLocal::DidReceiveCompositorFrameAck(
const std::vector<viz::ReturnedResource>& resources) {
DCHECK(thread_checker_);
diff --git a/chromium/ui/aura/local/layer_tree_frame_sink_local.h b/chromium/ui/aura/local/layer_tree_frame_sink_local.h
index 25dc6cf74b9..83217f46ce8 100644
--- a/chromium/ui/aura/local/layer_tree_frame_sink_local.h
+++ b/chromium/ui/aura/local/layer_tree_frame_sink_local.h
@@ -42,8 +42,6 @@ class LayerTreeFrameSinkLocal : public cc::LayerTreeFrameSink,
// Set a callback which will be called when the surface is changed.
void SetSurfaceChangedCallback(const SurfaceChangedCallback& callback);
- base::WeakPtr<LayerTreeFrameSinkLocal> GetWeakPtr();
-
const viz::LocalSurfaceId& local_surface_id() const {
return local_surface_id_;
}
@@ -54,6 +52,9 @@ class LayerTreeFrameSinkLocal : public cc::LayerTreeFrameSink,
void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) override;
void SubmitCompositorFrame(viz::CompositorFrame frame) override;
void DidNotProduceFrame(const viz::BeginFrameAck& ack) override;
+ void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer,
+ const viz::SharedBitmapId& id) override;
+ void DidDeleteSharedBitmap(const viz::SharedBitmapId& id) override;
// viz::mojom::CompositorFrameSinkClient:
void DidReceiveCompositorFrameAck(
@@ -84,7 +85,6 @@ class LayerTreeFrameSinkLocal : public cc::LayerTreeFrameSink,
std::unique_ptr<viz::ExternalBeginFrameSource> begin_frame_source_;
std::unique_ptr<base::ThreadChecker> thread_checker_;
SurfaceChangedCallback surface_changed_callback_;
- base::WeakPtrFactory<LayerTreeFrameSinkLocal> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(LayerTreeFrameSinkLocal);
};
diff --git a/chromium/ui/aura/local/window_port_local.cc b/chromium/ui/aura/local/window_port_local.cc
index c9b3213d26f..787fbc5e7cc 100644
--- a/chromium/ui/aura/local/window_port_local.cc
+++ b/chromium/ui/aura/local/window_port_local.cc
@@ -4,7 +4,7 @@
#include "ui/aura/local/window_port_local.h"
-#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
+#include "components/viz/host/host_frame_sink_manager.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
@@ -118,26 +118,20 @@ void WindowPortLocal::OnPropertyChanged(
std::unique_ptr<cc::LayerTreeFrameSink>
WindowPortLocal::CreateLayerTreeFrameSink() {
- DCHECK(!frame_sink_id_.is_valid());
auto* context_factory_private =
aura::Env::GetInstance()->context_factory_private();
- frame_sink_id_ = context_factory_private->AllocateFrameSinkId();
+ auto frame_sink_id = context_factory_private->AllocateFrameSinkId();
auto frame_sink = std::make_unique<LayerTreeFrameSinkLocal>(
- frame_sink_id_, context_factory_private->GetHostFrameSinkManager(),
+ frame_sink_id, context_factory_private->GetHostFrameSinkManager(),
window_->GetName());
+ window_->SetEmbedFrameSinkId(frame_sink_id);
frame_sink->SetSurfaceChangedCallback(base::Bind(
&WindowPortLocal::OnSurfaceChanged, weak_factory_.GetWeakPtr()));
frame_sink_ = frame_sink->GetWeakPtr();
AllocateLocalSurfaceId();
- if (window_->GetRootWindow())
- window_->layer()->GetCompositor()->AddFrameSink(frame_sink_id_);
return std::move(frame_sink);
}
-viz::SurfaceId WindowPortLocal::GetSurfaceId() const {
- return viz::SurfaceId(frame_sink_id_, local_surface_id_);
-}
-
void WindowPortLocal::AllocateLocalSurfaceId() {
last_device_scale_factor_ = ui::GetScaleFactorForNativeView(window_);
last_size_ = window_->bounds().size();
@@ -152,34 +146,14 @@ const viz::LocalSurfaceId& WindowPortLocal::GetLocalSurfaceId() {
return local_surface_id_;
}
-viz::FrameSinkId WindowPortLocal::GetFrameSinkId() const {
- return frame_sink_id_;
-}
-
-void WindowPortLocal::OnWindowAddedToRootWindow() {
- if (frame_sink_id_.is_valid())
- window_->layer()->GetCompositor()->AddFrameSink(frame_sink_id_);
-}
-
-void WindowPortLocal::OnWillRemoveWindowFromRootWindow() {
- if (frame_sink_id_.is_valid())
- window_->layer()->GetCompositor()->RemoveFrameSink(frame_sink_id_);
-}
-
void WindowPortLocal::OnEventTargetingPolicyChanged() {}
void WindowPortLocal::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
- DCHECK_EQ(surface_info.id().frame_sink_id(), frame_sink_id_);
+ DCHECK_EQ(surface_info.id().frame_sink_id(), window_->GetFrameSinkId());
DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_);
- scoped_refptr<viz::SurfaceReferenceFactory> reference_factory =
- aura::Env::GetInstance()
- ->context_factory_private()
- ->GetFrameSinkManager()
- ->surface_manager()
- ->reference_factory();
- window_->layer()->SetShowPrimarySurface(surface_info.id(),
- window_->bounds().size(),
- SK_ColorWHITE, reference_factory);
+ window_->layer()->SetShowPrimarySurface(
+ surface_info.id(), window_->bounds().size(), SK_ColorWHITE,
+ cc::DeadlinePolicy::UseDefaultDeadline());
window_->layer()->SetFallbackSurfaceId(surface_info.id());
}
diff --git a/chromium/ui/aura/local/window_port_local.h b/chromium/ui/aura/local/window_port_local.h
index be24ab4f8d9..58abd724537 100644
--- a/chromium/ui/aura/local/window_port_local.h
+++ b/chromium/ui/aura/local/window_port_local.h
@@ -46,12 +46,8 @@ class AURA_EXPORT WindowPortLocal : public WindowPort {
int64_t old_value,
std::unique_ptr<ui::PropertyData> data) override;
std::unique_ptr<cc::LayerTreeFrameSink> CreateLayerTreeFrameSink() override;
- viz::SurfaceId GetSurfaceId() const override;
void AllocateLocalSurfaceId() override;
const viz::LocalSurfaceId& GetLocalSurfaceId() override;
- viz::FrameSinkId GetFrameSinkId() const override;
- void OnWindowAddedToRootWindow() override;
- void OnWillRemoveWindowFromRootWindow() override;
void OnEventTargetingPolicyChanged() override;
bool ShouldRestackTransientChildren() override;
@@ -59,12 +55,11 @@ class AURA_EXPORT WindowPortLocal : public WindowPort {
void OnSurfaceChanged(const viz::SurfaceInfo& surface_info);
Window* const window_;
- viz::FrameSinkId frame_sink_id_;
gfx::Size last_size_;
float last_device_scale_factor_ = 1.0f;
viz::LocalSurfaceId local_surface_id_;
viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
- base::WeakPtr<aura::LayerTreeFrameSinkLocal> frame_sink_;
+ base::WeakPtr<cc::LayerTreeFrameSink> frame_sink_;
base::WeakPtrFactory<WindowPortLocal> weak_factory_;
diff --git a/chromium/ui/aura/mus/client_surface_embedder.cc b/chromium/ui/aura/mus/client_surface_embedder.cc
index 17029d25b7b..7863b68f365 100644
--- a/chromium/ui/aura/mus/client_surface_embedder.cc
+++ b/chromium/ui/aura/mus/client_surface_embedder.cc
@@ -5,7 +5,6 @@
#include "ui/aura/mus/client_surface_embedder.h"
#include "base/memory/ptr_util.h"
-#include "components/viz/common/surfaces/stub_surface_reference_factory.h"
#include "ui/aura/window.h"
#include "ui/gfx/geometry/dip_util.h"
@@ -30,15 +29,15 @@ ClientSurfaceEmbedder::ClientSurfaceEmbedder(
// this is the case with window decorations provided by Window Manager.
// This content should appear underneath the content of the embedded client.
window_->layer()->StackAtTop(surface_layer_.get());
- ref_factory_ = new viz::StubSurfaceReferenceFactory();
}
ClientSurfaceEmbedder::~ClientSurfaceEmbedder() = default;
void ClientSurfaceEmbedder::SetPrimarySurfaceId(
const viz::SurfaceId& surface_id) {
- surface_layer_->SetShowPrimarySurface(surface_id, window_->bounds().size(),
- SK_ColorWHITE, ref_factory_);
+ surface_layer_->SetShowPrimarySurface(
+ surface_id, window_->bounds().size(), SK_ColorWHITE,
+ cc::DeadlinePolicy::UseDefaultDeadline());
}
void ClientSurfaceEmbedder::SetFallbackSurfaceInfo(
@@ -95,4 +94,9 @@ void ClientSurfaceEmbedder::UpdateSizeAndGutters() {
window_->layer()->StackAtTop(surface_layer_.get());
}
+const viz::SurfaceId& ClientSurfaceEmbedder::GetPrimarySurfaceIdForTesting()
+ const {
+ return *surface_layer_->GetPrimarySurfaceId();
+}
+
} // namespace aura
diff --git a/chromium/ui/aura/mus/client_surface_embedder.h b/chromium/ui/aura/mus/client_surface_embedder.h
index e5085af030e..5017c44951a 100644
--- a/chromium/ui/aura/mus/client_surface_embedder.h
+++ b/chromium/ui/aura/mus/client_surface_embedder.h
@@ -8,19 +8,15 @@
#include <memory>
#include "base/macros.h"
-#include "base/memory/ref_counted.h"
#include "components/viz/common/surfaces/surface_info.h"
-#include "components/viz/common/surfaces/surface_reference_factory.h"
+#include "ui/aura/aura_export.h"
+#include "ui/compositor/layer.h"
#include "ui/gfx/geometry/insets.h"
namespace gfx {
class Insets;
}
-namespace ui {
-class Layer;
-}
-
namespace aura {
class Window;
@@ -28,7 +24,7 @@ class Window;
// Used by WindowPortMus when it is embedding a client. Responsible for setting
// up layers containing content from the client, parenting them to the window's
// layer, and updating them when the client submits new surfaces.
-class ClientSurfaceEmbedder {
+class AURA_EXPORT ClientSurfaceEmbedder {
public:
// TODO(fsamuel): Insets might differ when the window is maximized. We should
// deal with that case as well.
@@ -53,6 +49,8 @@ class ClientSurfaceEmbedder {
ui::Layer* BottomGutterForTesting() { return bottom_gutter_.get(); }
+ const viz::SurfaceId& GetPrimarySurfaceIdForTesting() const;
+
private:
// The window which embeds the client.
Window* window_;
@@ -70,8 +68,6 @@ class ClientSurfaceEmbedder {
bool inject_gutter_;
gfx::Insets client_area_insets_;
- scoped_refptr<viz::SurfaceReferenceFactory> ref_factory_;
-
DISALLOW_COPY_AND_ASSIGN(ClientSurfaceEmbedder);
};
diff --git a/chromium/ui/aura/mus/drag_drop_controller_mus.cc b/chromium/ui/aura/mus/drag_drop_controller_mus.cc
index 55d271583bf..532b0364807 100644
--- a/chromium/ui/aura/mus/drag_drop_controller_mus.cc
+++ b/chromium/ui/aura/mus/drag_drop_controller_mus.cc
@@ -40,7 +40,7 @@ namespace aura {
// State related to a drag initiated by this client.
struct DragDropControllerMus::CurrentDragState {
- Id window_id;
+ ui::Id window_id;
// The change id of the drag. Used to identify the drag on the server.
uint32_t change_id;
diff --git a/chromium/ui/aura/mus/mus_context_factory.cc b/chromium/ui/aura/mus/mus_context_factory.cc
index f95b744e593..f2b4dc0c60e 100644
--- a/chromium/ui/aura/mus/mus_context_factory.cc
+++ b/chromium/ui/aura/mus/mus_context_factory.cc
@@ -21,9 +21,6 @@ namespace aura {
MusContextFactory::MusContextFactory(ui::Gpu* gpu)
: gpu_(gpu),
- resource_settings_(
- // TODO(sad): http://crbug.com/675431
- viz::CreateResourceSettings()),
weak_ptr_factory_(this) {}
MusContextFactory::~MusContextFactory() {}
@@ -89,8 +86,4 @@ cc::TaskGraphRunner* MusContextFactory::GetTaskGraphRunner() {
return raster_thread_helper_.task_graph_runner();
}
-const viz::ResourceSettings& MusContextFactory::GetResourceSettings() const {
- return resource_settings_;
-}
-
} // namespace aura
diff --git a/chromium/ui/aura/mus/mus_context_factory.h b/chromium/ui/aura/mus/mus_context_factory.h
index ab1b1950f62..532af0fad23 100644
--- a/chromium/ui/aura/mus/mus_context_factory.h
+++ b/chromium/ui/aura/mus/mus_context_factory.h
@@ -17,10 +17,6 @@
#include "ui/aura/aura_export.h"
#include "ui/compositor/compositor.h"
-namespace cc {
-class ResourceSettings;
-}
-
namespace gpu {
class GpuChannelHost;
}
@@ -51,13 +47,11 @@ class AURA_EXPORT MusContextFactory : public ui::ContextFactory {
double GetRefreshRate() const override;
gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
cc::TaskGraphRunner* GetTaskGraphRunner() override;
- const viz::ResourceSettings& GetResourceSettings() const override;
void AddObserver(ui::ContextFactoryObserver* observer) override {}
void RemoveObserver(ui::ContextFactoryObserver* observer) override {}
ui::RasterThreadHelper raster_thread_helper_;
ui::Gpu* gpu_;
- const viz::ResourceSettings resource_settings_;
scoped_refptr<viz::ContextProvider> shared_main_thread_context_provider_;
base::WeakPtrFactory<MusContextFactory> weak_ptr_factory_;
diff --git a/chromium/ui/aura/mus/mus_types.h b/chromium/ui/aura/mus/mus_types.h
index 8c4f305f3b2..84b95f65da8 100644
--- a/chromium/ui/aura/mus/mus_types.h
+++ b/chromium/ui/aura/mus/mus_types.h
@@ -7,20 +7,14 @@
#include <stdint.h>
+#include "services/ui/common/types.h"
+
// Typedefs for the transport types. These typedefs match that of the mojom
// file, see it for specifics.
namespace aura {
-// Used to identify windows and change ids.
-using Id = uint32_t;
-
-// Used to identify a client as well as a client-specific window id. For
-// example, the Id for a window consists of the ClientSpecificId of the client
-// and the ClientSpecificId of the window.
-using ClientSpecificId = uint16_t;
-
-constexpr Id kInvalidServerId = 0;
+constexpr ui::Id kInvalidServerId = 0;
enum class WindowMusType {
// The window is an embed root. That is, the client received this window by
diff --git a/chromium/ui/aura/mus/property_converter.cc b/chromium/ui/aura/mus/property_converter.cc
index 8839c507cb6..7a0a67e0177 100644
--- a/chromium/ui/aura/mus/property_converter.cc
+++ b/chromium/ui/aura/mus/property_converter.cc
@@ -49,6 +49,10 @@ bool ValidateShowState(int64_t value) {
value == int64_t(ui::mojom::ShowState::FULLSCREEN);
}
+bool ValidateWindowCornerRadius(int64_t value) {
+ return value >= -1;
+}
+
} // namespace
PropertyConverter::PrimitiveProperty::PrimitiveProperty() {}
@@ -96,6 +100,10 @@ PropertyConverter::PropertyConverter() {
ui::mojom::WindowManager::kName_Property);
RegisterString16Property(client::kTitleKey,
ui::mojom::WindowManager::kWindowTitle_Property);
+ RegisterPrimitiveProperty(
+ client::kWindowCornerRadiusKey,
+ ui::mojom::WindowManager::kWindowCornerRadius_Property,
+ base::BindRepeating(&ValidateWindowCornerRadius));
}
PropertyConverter::~PropertyConverter() {}
diff --git a/chromium/ui/aura/mus/system_input_injector_mus.cc b/chromium/ui/aura/mus/system_input_injector_mus.cc
index 7b062808248..1aa83e5a10f 100644
--- a/chromium/ui/aura/mus/system_input_injector_mus.cc
+++ b/chromium/ui/aura/mus/system_input_injector_mus.cc
@@ -76,6 +76,7 @@ void SystemInputInjectorMus::InjectMouseButton(ui::EventFlags button,
break;
case ui::EF_MIDDLE_MOUSE_BUTTON:
modifier = ui::MODIFIER_MIDDLE_MOUSE_BUTTON;
+ break;
default:
LOG(WARNING) << "Invalid flag: " << button << " for the button parameter";
return;
diff --git a/chromium/ui/aura/mus/text_input_client_impl.cc b/chromium/ui/aura/mus/text_input_client_impl.cc
index 9f926a779c0..514a69a5611 100644
--- a/chromium/ui/aura/mus/text_input_client_impl.cc
+++ b/chromium/ui/aura/mus/text_input_client_impl.cc
@@ -39,8 +39,8 @@ void TextInputClientImpl::ClearCompositionText() {
text_input_client_->ClearCompositionText();
}
-void TextInputClientImpl::InsertText(const std::string& text) {
- text_input_client_->InsertText(base::UTF8ToUTF16(text));
+void TextInputClientImpl::InsertText(const base::string16& text) {
+ text_input_client_->InsertText(text);
}
void TextInputClientImpl::InsertChar(std::unique_ptr<ui::Event> event) {
diff --git a/chromium/ui/aura/mus/text_input_client_impl.h b/chromium/ui/aura/mus/text_input_client_impl.h
index 46bf153d5c3..5f5b98d4807 100644
--- a/chromium/ui/aura/mus/text_input_client_impl.h
+++ b/chromium/ui/aura/mus/text_input_client_impl.h
@@ -31,7 +31,7 @@ class TextInputClientImpl : public ui::mojom::TextInputClient {
void SetCompositionText(const ui::CompositionText& composition) override;
void ConfirmCompositionText() override;
void ClearCompositionText() override;
- void InsertText(const std::string& text) override;
+ void InsertText(const base::string16& text) override;
void InsertChar(std::unique_ptr<ui::Event> event) override;
void DispatchKeyEventPostIME(
std::unique_ptr<ui::Event> event,
diff --git a/chromium/ui/aura/mus/window_mus.h b/chromium/ui/aura/mus/window_mus.h
index 355b4805bac..ade1846d660 100644
--- a/chromium/ui/aura/mus/window_mus.h
+++ b/chromium/ui/aura/mus/window_mus.h
@@ -67,7 +67,7 @@ class AURA_EXPORT WindowMus {
}
static WindowMus* Get(Window* window);
- Id server_id() const { return server_id_; }
+ ui::Id server_id() const { return server_id_; }
WindowMusType window_mus_type() const { return window_mus_type_; }
@@ -135,9 +135,9 @@ class AURA_EXPORT WindowMus {
// Just for set_server_id(), which other places should not call.
friend class WindowTreeClient;
- void set_server_id(Id id) { server_id_ = id; }
+ void set_server_id(ui::Id id) { server_id_ = id; }
- Id server_id_ = kInvalidServerId;
+ ui::Id server_id_ = kInvalidServerId;
const WindowMusType window_mus_type_;
};
diff --git a/chromium/ui/aura/mus/window_port_mus.cc b/chromium/ui/aura/mus/window_port_mus.cc
index 5b4bcab052d..45dd67e18ef 100644
--- a/chromium/ui/aura/mus/window_port_mus.cc
+++ b/chromium/ui/aura/mus/window_port_mus.cc
@@ -6,7 +6,7 @@
#include "base/memory/ptr_util.h"
#include "components/viz/client/local_surface_id_provider.h"
-#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
+#include "components/viz/host/host_frame_sink_manager.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/transient_window_client.h"
#include "ui/aura/env.h"
@@ -19,6 +19,7 @@
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_observer.h"
#include "ui/base/class_property.h"
+#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
@@ -131,10 +132,12 @@ WindowPortMus::RequestLayerTreeFrameSink(
return layer_tree_frame_sink;
}
-viz::FrameSinkId WindowPortMus::GetFrameSinkId() const {
- if (window_->IsEmbeddingClient())
- return window_->embed_frame_sink_id();
- return viz::FrameSinkId(0, server_id());
+viz::FrameSinkId WindowPortMus::GenerateFrameSinkIdFromServerId() const {
+ // With mus, the client does not know its own client id. So it uses a constant
+ // value of 0. This gets replaced in the server side with the correct value
+ // where appropriate.
+ constexpr int kClientSelfId = 0;
+ return viz::FrameSinkId(kClientSelfId, server_id());
}
WindowPortMus::ServerChangeIdType WindowPortMus::ScheduleChange(
@@ -302,7 +305,7 @@ void WindowPortMus::SetFrameSinkIdFromServer(
const viz::FrameSinkId& frame_sink_id) {
DCHECK(window_mus_type() == WindowMusType::TOP_LEVEL_IN_WM ||
window_mus_type() == WindowMusType::EMBED_IN_OWNER);
- window_->set_embed_frame_sink_id(frame_sink_id);
+ window_->SetEmbedFrameSinkId(frame_sink_id);
UpdatePrimarySurfaceId();
}
@@ -331,14 +334,14 @@ void WindowPortMus::SetFallbackSurfaceInfo(
const viz::SurfaceInfo& surface_info) {
if (!window_->IsEmbeddingClient()) {
// |primary_surface_id_| shold not be valid, since we didn't know the
- // |window_->embed_frame_sink_id()|.
+ // |window_->frame_sink_id()|.
DCHECK(!primary_surface_id_.is_valid());
- window_->set_embed_frame_sink_id(surface_info.id().frame_sink_id());
+ window_->SetEmbedFrameSinkId(surface_info.id().frame_sink_id());
UpdatePrimarySurfaceId();
}
// The frame sink id should never be changed.
- DCHECK_EQ(surface_info.id().frame_sink_id(), window_->embed_frame_sink_id());
+ DCHECK_EQ(surface_info.id().frame_sink_id(), window_->GetFrameSinkId());
fallback_surface_info_ = surface_info;
UpdateClientSurfaceEmbedder();
@@ -403,10 +406,11 @@ WindowPortMus::ChangeSource WindowPortMus::OnTransientChildRemoved(
void WindowPortMus::AllocateLocalSurfaceId() {
local_surface_id_ = parent_local_surface_id_allocator_.GenerateId();
+ UpdatePrimarySurfaceId();
}
const viz::LocalSurfaceId& WindowPortMus::GetLocalSurfaceId() {
- if (switches::IsMusHostingViz())
+ if (base::FeatureList::IsEnabled(features::kMash))
return local_surface_id_;
if (!window_->IsEmbeddingClient() && !window_->IsRootWindow())
return local_surface_id_;
@@ -559,17 +563,18 @@ WindowPortMus::CreateLayerTreeFrameSink() {
DCHECK(!local_layer_tree_frame_sink_);
std::unique_ptr<cc::LayerTreeFrameSink> frame_sink;
- if (switches::IsMusHostingViz()) {
+ if (base::FeatureList::IsEnabled(features::kMash)) {
auto client_layer_tree_frame_sink =
RequestLayerTreeFrameSink(nullptr, aura::Env::GetInstance()
->context_factory()
->GetGpuMemoryBufferManager());
local_layer_tree_frame_sink_ = client_layer_tree_frame_sink->GetWeakPtr();
frame_sink = std::move(client_layer_tree_frame_sink);
+ window_->SetEmbedFrameSinkId(GenerateFrameSinkIdFromServerId());
} else {
auto* context_factory_private =
aura::Env::GetInstance()->context_factory_private();
- auto frame_sink_id = GetFrameSinkId();
+ auto frame_sink_id = window_->GetFrameSinkId();
DCHECK(frame_sink_id.is_valid());
auto layer_tree_frame_sink_local =
std::make_unique<LayerTreeFrameSinkLocal>(
@@ -577,10 +582,7 @@ WindowPortMus::CreateLayerTreeFrameSink() {
window_->GetName());
layer_tree_frame_sink_local->SetSurfaceChangedCallback(base::BindRepeating(
&WindowPortMus::OnSurfaceChanged, weak_ptr_factory_.GetWeakPtr()));
- if (window_->layer()->GetCompositor()) {
- window_->layer()->GetCompositor()->AddFrameSink(GetFrameSinkId());
- is_frame_sink_id_added_to_compositor_ = true;
- }
+ window_->SetEmbedFrameSinkId(frame_sink_id);
local_layer_tree_frame_sink_ = layer_tree_frame_sink_local->GetWeakPtr();
frame_sink = std::move(layer_tree_frame_sink_local);
}
@@ -593,29 +595,6 @@ WindowPortMus::CreateLayerTreeFrameSink() {
return frame_sink;
}
-viz::SurfaceId WindowPortMus::GetSurfaceId() const {
- return viz::SurfaceId(window_->embed_frame_sink_id(), local_surface_id_);
-}
-
-void WindowPortMus::OnWindowAddedToRootWindow() {
- if (switches::IsMusHostingViz())
- return;
- if (local_layer_tree_frame_sink_) {
- DCHECK(!is_frame_sink_id_added_to_compositor_);
- window_->layer()->GetCompositor()->AddFrameSink(GetFrameSinkId());
- is_frame_sink_id_added_to_compositor_ = true;
- }
-}
-
-void WindowPortMus::OnWillRemoveWindowFromRootWindow() {
- if (switches::IsMusHostingViz())
- return;
- if (is_frame_sink_id_added_to_compositor_) {
- window_->layer()->GetCompositor()->RemoveFrameSink(GetFrameSinkId());
- is_frame_sink_id_added_to_compositor_ = false;
- }
-}
-
void WindowPortMus::OnEventTargetingPolicyChanged() {
SetEventTargetingPolicy(window_->event_targeting_policy());
}
@@ -636,12 +615,12 @@ void WindowPortMus::UpdatePrimarySurfaceId() {
return;
primary_surface_id_ =
- viz::SurfaceId(window_->embed_frame_sink_id(), local_surface_id_);
+ viz::SurfaceId(window_->GetFrameSinkId(), local_surface_id_);
UpdateClientSurfaceEmbedder();
}
void WindowPortMus::UpdateClientSurfaceEmbedder() {
- if (!switches::IsMusHostingViz())
+ if (!base::FeatureList::IsEnabled(features::kMash))
return;
if (window_mus_type() != WindowMusType::TOP_LEVEL_IN_WM &&
window_mus_type() != WindowMusType::EMBED_IN_OWNER &&
@@ -661,18 +640,14 @@ void WindowPortMus::UpdateClientSurfaceEmbedder() {
}
void WindowPortMus::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
- DCHECK(!switches::IsMusHostingViz());
- DCHECK_EQ(surface_info.id().frame_sink_id(), GetFrameSinkId());
+ // TODO(fsamuel): Rename OnFirstSurfaceActivation() and set primary earlier
+ // based on feedback from LayerTreeFrameSinkLocal.
+ DCHECK(!base::FeatureList::IsEnabled(features::kMash));
+ DCHECK_EQ(surface_info.id().frame_sink_id(), window_->GetFrameSinkId());
DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_);
- scoped_refptr<viz::SurfaceReferenceFactory> reference_factory =
- aura::Env::GetInstance()
- ->context_factory_private()
- ->GetFrameSinkManager()
- ->surface_manager()
- ->reference_factory();
- window_->layer()->SetShowPrimarySurface(surface_info.id(),
- window_->bounds().size(),
- SK_ColorWHITE, reference_factory);
+ window_->layer()->SetShowPrimarySurface(
+ surface_info.id(), window_->bounds().size(), SK_ColorWHITE,
+ cc::DeadlinePolicy::UseDefaultDeadline());
window_->layer()->SetFallbackSurfaceId(surface_info.id());
}
diff --git a/chromium/ui/aura/mus/window_port_mus.h b/chromium/ui/aura/mus/window_port_mus.h
index 318ea8fc5bf..8228ff89d3c 100644
--- a/chromium/ui/aura/mus/window_port_mus.h
+++ b/chromium/ui/aura/mus/window_port_mus.h
@@ -99,10 +99,7 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
scoped_refptr<viz::ContextProvider> context_provider,
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager);
- // WindowPort:
- // Returns either the FrameSinkId set by window server or its server_id with
- // the client id part 0.
- viz::FrameSinkId GetFrameSinkId() const override;
+ viz::FrameSinkId GenerateFrameSinkIdFromServerId() const;
private:
friend class WindowPortMusTest;
@@ -157,7 +154,7 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
// Contains data needed to identify a change from the server.
struct ServerChangeData {
// Applies to ADD, ADD_TRANSIENT, REMOVE, REMOVE_TRANSIENT, and REORDER.
- Id child_id;
+ ui::Id child_id;
// Applies to BOUNDS. This should be in dip.
gfx::Rect bounds_in_dip;
// Applies to VISIBLE.
@@ -275,11 +272,8 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
int64_t old_value,
std::unique_ptr<ui::PropertyData> data) override;
std::unique_ptr<cc::LayerTreeFrameSink> CreateLayerTreeFrameSink() override;
- viz::SurfaceId GetSurfaceId() const override;
void AllocateLocalSurfaceId() override;
const viz::LocalSurfaceId& GetLocalSurfaceId() override;
- void OnWindowAddedToRootWindow() override;
- void OnWillRemoveWindowFromRootWindow() override;
void OnEventTargetingPolicyChanged() override;
bool ShouldRestackTransientChildren() override;
@@ -314,7 +308,6 @@ class AURA_EXPORT WindowPortMus : public WindowPort, public WindowMus {
// for a local aura::Window, we need keep a weak ptr of it, so we can update
// the local surface id when necessary.
base::WeakPtr<cc::LayerTreeFrameSink> local_layer_tree_frame_sink_;
- bool is_frame_sink_id_added_to_compositor_ = false;
base::WeakPtrFactory<WindowPortMus> weak_ptr_factory_;
diff --git a/chromium/ui/aura/mus/window_port_mus_unittest.cc b/chromium/ui/aura/mus/window_port_mus_unittest.cc
index 107d663e87c..8425624d63c 100644
--- a/chromium/ui/aura/mus/window_port_mus_unittest.cc
+++ b/chromium/ui/aura/mus/window_port_mus_unittest.cc
@@ -7,9 +7,10 @@
#include "components/viz/client/client_layer_tree_frame_sink.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
+#include "ui/aura/mus/client_surface_embedder.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window.h"
-#include "ui/base/ui_base_switches_util.h"
+#include "ui/base/ui_base_features.h"
namespace aura {
@@ -34,7 +35,7 @@ TEST_F(WindowPortMusTest, LayerTreeFrameSinkGetsCorrectLocalSurfaceId) {
window.SetBounds(gfx::Rect(300, 300));
// Notify the window that it will embed an external client, so that it
// correctly generates LocalSurfaceId.
- window.set_embed_frame_sink_id(viz::FrameSinkId(0, 1));
+ window.SetEmbedFrameSinkId(viz::FrameSinkId(0, 1));
viz::LocalSurfaceId local_surface_id = window.GetLocalSurfaceId();
ASSERT_TRUE(local_surface_id.is_valid());
@@ -46,7 +47,7 @@ TEST_F(WindowPortMusTest, LayerTreeFrameSinkGetsCorrectLocalSurfaceId) {
auto mus_frame_sink = GetFrameSinkFor(&window);
ASSERT_TRUE(mus_frame_sink);
auto frame_sink_local_surface_id =
- switches::IsMusHostingViz()
+ base::FeatureList::IsEnabled(features::kMash)
? static_cast<viz::ClientLayerTreeFrameSink*>(mus_frame_sink.get())
->local_surface_id()
: static_cast<LayerTreeFrameSinkLocal*>(mus_frame_sink.get())
@@ -55,4 +56,24 @@ TEST_F(WindowPortMusTest, LayerTreeFrameSinkGetsCorrectLocalSurfaceId) {
EXPECT_EQ(frame_sink_local_surface_id, local_surface_id);
}
+TEST_F(WindowPortMusTest, ClientSurfaceEmbedderUpdatesLayer) {
+ // If mus is not hosting viz, we don't have ClientSurfaceEmbedder.
+ if (!base::FeatureList::IsEnabled(features::kMash))
+ return;
+
+ Window window(nullptr);
+ window.Init(ui::LAYER_NOT_DRAWN);
+ window.SetBounds(gfx::Rect(300, 300));
+ window.SetEmbedFrameSinkId(viz::FrameSinkId(0, 1));
+
+ // Allocate a new LocalSurfaceId. The ui::Layer should be updated.
+ window.AllocateLocalSurfaceId();
+
+ auto* window_mus = WindowPortMus::Get(&window);
+ viz::LocalSurfaceId local_surface_id = window.GetLocalSurfaceId();
+ viz::SurfaceId primary_surface_id =
+ window_mus->client_surface_embedder()->GetPrimarySurfaceIdForTesting();
+ EXPECT_EQ(local_surface_id, primary_surface_id.local_surface_id());
+}
+
} // namespace aura
diff --git a/chromium/ui/aura/mus/window_tree_client.cc b/chromium/ui/aura/mus/window_tree_client.cc
index 760d35f4c9d..a75ee126a46 100644
--- a/chromium/ui/aura/mus/window_tree_client.cc
+++ b/chromium/ui/aura/mus/window_tree_client.cc
@@ -24,6 +24,7 @@
#include "mojo/public/cpp/bindings/map.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/ui/common/accelerator_util.h"
+#include "services/ui/common/util.h"
#include "services/ui/public/cpp/gpu/gpu.h"
#include "services/ui/public/cpp/property_type_converters.h"
#include "services/ui/public/interfaces/constants.mojom.h"
@@ -57,6 +58,7 @@
#include "ui/aura/window_port_for_shutdown.h"
#include "ui/aura/window_tracker.h"
#include "ui/base/layout.h"
+#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/base/ui_base_types.h"
#include "ui/display/screen.h"
@@ -69,10 +71,6 @@
namespace aura {
namespace {
-inline uint16_t HiWord(uint32_t id) {
- return static_cast<uint16_t>((id >> 16) & 0xFFFF);
-}
-
struct WindowPortPropertyDataMus : public ui::PropertyData {
std::string transport_name;
std::unique_ptr<std::vector<uint8_t>> transport_value;
@@ -166,24 +164,13 @@ std::unique_ptr<ui::Event> MapEvent(const ui::Event& event) {
return ui::Event::Clone(event);
}
-// Set the |target| to be the target window of this |event| and send it to
-// the EventSink.
-void DispatchEventToTarget(ui::Event* event, WindowMus* target) {
- ui::Event::DispatcherApi dispatch_helper(event);
- // Ignore the target for key events. They need to go to the focused window,
- // which may have changed by the time we process the event.
- if (!event->IsKeyEvent())
- dispatch_helper.set_target(target->GetWindow());
- GetWindowTreeHostMus(target)->SendEventToSink(event);
-}
-
// Use for acks from mus that are expected to always succeed and if they don't
// a crash is triggered.
void OnAckMustSucceed(const base::Location& from_here, bool success) {
CHECK(success) << "Context: " << from_here.ToString();
}
-Id GetServerIdForWindow(Window* window) {
+ui::Id GetServerIdForWindow(Window* window) {
return window ? WindowMus::Get(window)->server_id() : kInvalidServerId;
}
@@ -225,7 +212,7 @@ WindowTreeClient::WindowTreeClient(
io_task_runner = io_thread_->task_runner();
}
- if (switches::IsMusHostingViz()) {
+ if (base::FeatureList::IsEnabled(features::kMash)) {
gpu_ =
ui::Gpu::Create(connector, ui::mojom::kServiceName, io_task_runner);
compositor_context_factory_ =
@@ -402,7 +389,7 @@ void WindowTreeClient::ScheduleEmbed(
}
void WindowTreeClient::AttachCompositorFrameSink(
- Id window_id,
+ ui::Id window_id,
viz::mojom::CompositorFrameSinkRequest compositor_frame_sink,
viz::mojom::CompositorFrameSinkClientPtr client) {
DCHECK(tree_);
@@ -413,9 +400,14 @@ void WindowTreeClient::AttachCompositorFrameSink(
void WindowTreeClient::RegisterWindowMus(WindowMus* window) {
DCHECK(windows_.find(window->server_id()) == windows_.end());
windows_[window->server_id()] = window;
+ if (window->GetWindow()) {
+ auto* port = WindowPortMus::Get(window->GetWindow());
+ window->GetWindow()->set_frame_sink_id(
+ port->GenerateFrameSinkIdFromServerId());
+ }
}
-WindowMus* WindowTreeClient::GetWindowByServerId(Id id) {
+WindowMus* WindowTreeClient::GetWindowByServerId(ui::Id id) {
IdToWindowMap::const_iterator it = windows_.find(id);
return it != windows_.end() ? it->second : nullptr;
}
@@ -606,7 +598,8 @@ std::unique_ptr<WindowTreeHostMus> WindowTreeClient::CreateWindowTreeHost(
if (window_manager_delegate_ &&
(window_mus_type == WindowMusType::EMBED ||
window_mus_type == WindowMusType::DISPLAY_AUTOMATICALLY_CREATED)) {
- init_params.uses_real_accelerated_widget = !::switches::IsMusHostingViz();
+ init_params.uses_real_accelerated_widget =
+ !::base::FeatureList::IsEnabled(features::kMash);
}
std::unique_ptr<WindowTreeHostMus> window_tree_host =
std::make_unique<WindowTreeHostMus>(std::move(init_params));
@@ -712,7 +705,7 @@ void WindowTreeClient::OnEmbedImpl(
ui::mojom::WindowTree* window_tree,
ui::mojom::WindowDataPtr root_data,
int64_t display_id,
- Id focused_window_id,
+ ui::Id focused_window_id,
bool drawn,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) {
WindowTreeConnectionEstablished(window_tree);
@@ -886,8 +879,9 @@ void WindowTreeClient::OnWindowMusCreated(WindowMus* window) {
window_manager_client_->SetDisplayRoot(
display, display_init_params->viewport_metrics.Clone(),
display_init_params->is_primary_display, window->server_id(),
- switches::IsMusHostingViz() ? display_init_params->mirrors
- : std::vector<display::Display>(),
+ base::FeatureList::IsEnabled(features::kMash)
+ ? display_init_params->mirrors
+ : std::vector<display::Display>(),
base::Bind(&OnAckMustSucceed, FROM_HERE));
}
}
@@ -1101,7 +1095,7 @@ std::set<Window*> WindowTreeClient::GetRoots() {
bool WindowTreeClient::WasCreatedByThisClient(const WindowMus* window) const {
// Windows created via CreateTopLevelWindow() are not owned by us, but don't
// have high-word set. const_cast is required by set.
- return !HiWord(window->server_id()) &&
+ return !ui::ClientIdFromTransportId(window->server_id()) &&
roots_.count(const_cast<WindowMus*>(window)) == 0;
}
@@ -1163,7 +1157,7 @@ void WindowTreeClient::OnEmbed(
ui::mojom::WindowDataPtr root_data,
ui::mojom::WindowTreePtr tree,
int64_t display_id,
- Id focused_window_id,
+ ui::Id focused_window_id,
bool drawn,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) {
DCHECK(!tree_ptr_);
@@ -1181,13 +1175,13 @@ void WindowTreeClient::OnEmbed(
focused_window_id, drawn, local_surface_id);
}
-void WindowTreeClient::OnEmbeddedAppDisconnected(Id window_id) {
+void WindowTreeClient::OnEmbeddedAppDisconnected(ui::Id window_id) {
WindowMus* window = GetWindowByServerId(window_id);
if (window)
window->NotifyEmbeddedAppDisconnected();
}
-void WindowTreeClient::OnUnembed(Id window_id) {
+void WindowTreeClient::OnUnembed(ui::Id window_id) {
WindowMus* window = GetWindowByServerId(window_id);
if (!window)
return;
@@ -1196,8 +1190,8 @@ void WindowTreeClient::OnUnembed(Id window_id) {
delete window;
}
-void WindowTreeClient::OnCaptureChanged(Id new_capture_window_id,
- Id old_capture_window_id) {
+void WindowTreeClient::OnCaptureChanged(ui::Id new_capture_window_id,
+ ui::Id old_capture_window_id) {
WindowMus* new_capture_window = GetWindowByServerId(new_capture_window_id);
WindowMus* lost_capture_window = GetWindowByServerId(old_capture_window_id);
if (!new_capture_window && !lost_capture_window)
@@ -1212,8 +1206,10 @@ void WindowTreeClient::OnCaptureChanged(Id new_capture_window_id,
}
void WindowTreeClient::OnFrameSinkIdAllocated(
- Id window_id,
+ ui::Id window_id,
const viz::FrameSinkId& frame_sink_id) {
+ if (!base::FeatureList::IsEnabled(features::kMash))
+ return;
WindowMus* window = GetWindowByServerId(window_id);
if (!window)
return;
@@ -1295,7 +1291,7 @@ void WindowTreeClient::OnTopLevelCreated(
}
void WindowTreeClient::OnWindowBoundsChanged(
- Id window_id,
+ ui::Id window_id,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) {
@@ -1311,7 +1307,7 @@ void WindowTreeClient::OnWindowBoundsChanged(
}
void WindowTreeClient::OnWindowTransformChanged(
- Id window_id,
+ ui::Id window_id,
const gfx::Transform& old_transform,
const gfx::Transform& new_transform) {
WindowMus* window = GetWindowByServerId(window_id);
@@ -1326,7 +1322,7 @@ void WindowTreeClient::OnWindowTransformChanged(
}
void WindowTreeClient::OnClientAreaChanged(
- uint32_t window_id,
+ ui::Id window_id,
const gfx::Insets& new_client_area,
const std::vector<gfx::Rect>& new_additional_client_areas) {
WindowMus* window = GetWindowByServerId(window_id);
@@ -1345,8 +1341,8 @@ void WindowTreeClient::OnClientAreaChanged(
new_additional_client_areas_in_dip);
}
-void WindowTreeClient::OnTransientWindowAdded(uint32_t window_id,
- uint32_t transient_window_id) {
+void WindowTreeClient::OnTransientWindowAdded(ui::Id window_id,
+ ui::Id transient_window_id) {
WindowMus* window = GetWindowByServerId(window_id);
WindowMus* transient_window = GetWindowByServerId(transient_window_id);
// window or transient_window or both may be null if a local delete occurs
@@ -1355,8 +1351,8 @@ void WindowTreeClient::OnTransientWindowAdded(uint32_t window_id,
window->AddTransientChildFromServer(transient_window);
}
-void WindowTreeClient::OnTransientWindowRemoved(uint32_t window_id,
- uint32_t transient_window_id) {
+void WindowTreeClient::OnTransientWindowRemoved(ui::Id window_id,
+ ui::Id transient_window_id) {
WindowMus* window = GetWindowByServerId(window_id);
WindowMus* transient_window = GetWindowByServerId(transient_window_id);
// window or transient_window or both may be null if a local delete occurs
@@ -1366,9 +1362,9 @@ void WindowTreeClient::OnTransientWindowRemoved(uint32_t window_id,
}
void WindowTreeClient::OnWindowHierarchyChanged(
- Id window_id,
- Id old_parent_id,
- Id new_parent_id,
+ ui::Id window_id,
+ ui::Id old_parent_id,
+ ui::Id new_parent_id,
std::vector<ui::mojom::WindowDataPtr> windows) {
const bool was_window_known = GetWindowByServerId(window_id) != nullptr;
@@ -1388,8 +1384,8 @@ void WindowTreeClient::OnWindowHierarchyChanged(
old_parent->RemoveChildFromServer(window);
}
-void WindowTreeClient::OnWindowReordered(Id window_id,
- Id relative_window_id,
+void WindowTreeClient::OnWindowReordered(ui::Id window_id,
+ ui::Id relative_window_id,
ui::mojom::OrderDirection direction) {
WindowMus* window = GetWindowByServerId(window_id);
WindowMus* relative_window = GetWindowByServerId(relative_window_id);
@@ -1400,7 +1396,7 @@ void WindowTreeClient::OnWindowReordered(Id window_id,
}
}
-void WindowTreeClient::OnWindowDeleted(Id window_id) {
+void WindowTreeClient::OnWindowDeleted(ui::Id window_id) {
WindowMus* window = GetWindowByServerId(window_id);
if (!window)
return;
@@ -1418,7 +1414,8 @@ void WindowTreeClient::OnWindowDeleted(Id window_id) {
}
}
-void WindowTreeClient::OnWindowVisibilityChanged(Id window_id, bool visible) {
+void WindowTreeClient::OnWindowVisibilityChanged(ui::Id window_id,
+ bool visible) {
WindowMus* window = GetWindowByServerId(window_id);
if (!window)
return;
@@ -1430,7 +1427,7 @@ void WindowTreeClient::OnWindowVisibilityChanged(Id window_id, bool visible) {
SetWindowVisibleFromServer(window, visible);
}
-void WindowTreeClient::OnWindowOpacityChanged(Id window_id,
+void WindowTreeClient::OnWindowOpacityChanged(ui::Id window_id,
float old_opacity,
float new_opacity) {
WindowMus* window = GetWindowByServerId(window_id);
@@ -1444,7 +1441,7 @@ void WindowTreeClient::OnWindowOpacityChanged(Id window_id,
window->SetOpacityFromServer(new_opacity);
}
-void WindowTreeClient::OnWindowParentDrawnStateChanged(Id window_id,
+void WindowTreeClient::OnWindowParentDrawnStateChanged(ui::Id window_id,
bool drawn) {
// TODO: route to WindowTreeHost.
/*
@@ -1455,7 +1452,7 @@ void WindowTreeClient::OnWindowParentDrawnStateChanged(Id window_id,
}
void WindowTreeClient::OnWindowSharedPropertyChanged(
- Id window_id,
+ ui::Id window_id,
const std::string& name,
const base::Optional<std::vector<uint8_t>>& transport_data) {
WindowMus* window = GetWindowByServerId(window_id);
@@ -1476,14 +1473,13 @@ void WindowTreeClient::OnWindowSharedPropertyChanged(
void WindowTreeClient::OnWindowInputEvent(
uint32_t event_id,
- Id window_id,
+ ui::Id window_id,
int64_t display_id,
- Id display_root_window_id,
+ ui::Id display_root_window_id,
const gfx::PointF& event_location_in_screen_pixel_layout,
std::unique_ptr<ui::Event> event,
bool matches_pointer_watcher) {
DCHECK(event);
-
WindowMus* window = GetWindowByServerId(window_id); // May be null.
if (matches_pointer_watcher && has_pointer_watcher_) {
@@ -1549,23 +1545,30 @@ void WindowTreeClient::OnWindowInputEvent(
#endif
WindowMus* display_root_window = GetWindowByServerId(display_root_window_id);
- if (display_root_window && window && event->IsLocatedEvent() &&
+ if (display_root_window && event->IsLocatedEvent() &&
display::Screen::GetScreen()->GetPrimaryDisplay().id() ==
display::kUnifiedDisplayId) {
- // Dispatch to the root window of the display supplying the event. This
- // allows Ash to determine the event position in the unified desktop mode,
- // where each physical display mirrors part of a single virtual display.
- // This paralells the behavior of unified desktop mode in classic Ash mode.
- DispatchEventToTarget(event_to_dispatch, display_root_window);
- } else {
- DispatchEventToTarget(event_to_dispatch, window);
- }
+ // In Ash's unified desktop mode, each physical display mirrors part of a
+ // single virtual display. Dispatch events to the root window of the mirror
+ // display supplying the event, using locations relative to that display.
+ // Use a null target to ensure events reach the MusUnifiedEventTargeter.
+ // This paralells the behavior of unified desktop mode in classic Ash.
+ ui::Event::DispatcherApi(event_to_dispatch).set_target(nullptr);
+ ui::LocatedEvent* located_event = event_to_dispatch->AsLocatedEvent();
+ located_event->set_location_f(located_event->root_location_f());
+ window = display_root_window;
+ } else if (!event->IsKeyEvent()) {
+ // Set |window| as the target, except for key events. Key events go to the
+ // focused window, which may have changed by the time we process the event.
+ ui::Event::DispatcherApi(event_to_dispatch).set_target(window->GetWindow());
+ }
+ GetWindowTreeHostMus(window)->SendEventToSink(event_to_dispatch);
ack_handler.set_handled(event_to_dispatch->handled());
}
void WindowTreeClient::OnPointerEventObserved(std::unique_ptr<ui::Event> event,
- uint32_t window_id,
+ ui::Id window_id,
int64_t display_id) {
DCHECK(event);
DCHECK(event->IsPointerEvent());
@@ -1580,7 +1583,7 @@ void WindowTreeClient::OnPointerEventObserved(std::unique_ptr<ui::Event> event,
target_window ? target_window->GetWindow() : nullptr);
}
-void WindowTreeClient::OnWindowFocused(Id focused_window_id) {
+void WindowTreeClient::OnWindowFocused(ui::Id focused_window_id) {
WindowMus* focused_window = GetWindowByServerId(focused_window_id);
InFlightFocusChange new_change(this, focus_synchronizer_.get(),
focused_window);
@@ -1590,7 +1593,7 @@ void WindowTreeClient::OnWindowFocused(Id focused_window_id) {
focus_synchronizer_->SetFocusFromServer(focused_window);
}
-void WindowTreeClient::OnWindowCursorChanged(Id window_id,
+void WindowTreeClient::OnWindowCursorChanged(ui::Id window_id,
ui::CursorData cursor) {
WindowMus* window = GetWindowByServerId(window_id);
if (!window)
@@ -1604,7 +1607,7 @@ void WindowTreeClient::OnWindowCursorChanged(Id window_id,
}
void WindowTreeClient::OnWindowSurfaceChanged(
- Id window_id,
+ ui::Id window_id,
const viz::SurfaceInfo& surface_info) {
WindowMus* window = GetWindowByServerId(window_id);
if (!window)
@@ -1623,7 +1626,7 @@ void WindowTreeClient::OnDragDropStart(
drag_drop_controller_->OnDragDropStart(mojo::UnorderedMapToMap(mime_data));
}
-void WindowTreeClient::OnDragEnter(Id window_id,
+void WindowTreeClient::OnDragEnter(ui::Id window_id,
uint32_t key_state,
const gfx::Point& position,
uint32_t effect_bitmask,
@@ -1632,7 +1635,7 @@ void WindowTreeClient::OnDragEnter(Id window_id,
GetWindowByServerId(window_id), key_state, position, effect_bitmask));
}
-void WindowTreeClient::OnDragOver(Id window_id,
+void WindowTreeClient::OnDragOver(ui::Id window_id,
uint32_t key_state,
const gfx::Point& position,
uint32_t effect_bitmask,
@@ -1641,7 +1644,7 @@ void WindowTreeClient::OnDragOver(Id window_id,
GetWindowByServerId(window_id), key_state, position, effect_bitmask));
}
-void WindowTreeClient::OnDragLeave(Id window_id) {
+void WindowTreeClient::OnDragLeave(ui::Id window_id) {
drag_drop_controller_->OnDragLeave(GetWindowByServerId(window_id));
}
@@ -1649,7 +1652,7 @@ void WindowTreeClient::OnDragDropDone() {
drag_drop_controller_->OnDragDropDone();
}
-void WindowTreeClient::OnCompleteDrop(Id window_id,
+void WindowTreeClient::OnCompleteDrop(ui::Id window_id,
uint32_t key_state,
const gfx::Point& position,
uint32_t effect_bitmask,
@@ -1723,7 +1726,7 @@ void WindowTreeClient::GetWindowManager(
this, std::move(internal)));
}
-void WindowTreeClient::RequestClose(uint32_t window_id) {
+void WindowTreeClient::RequestClose(ui::Id window_id) {
WindowMus* window = GetWindowByServerId(window_id);
if (!window || !IsRoot(window))
return;
@@ -1797,7 +1800,7 @@ void WindowTreeClient::WmDisplayModified(const display::Display& display) {
}
void WindowTreeClient::WmSetBounds(uint32_t change_id,
- Id window_id,
+ ui::Id window_id,
const gfx::Rect& transit_bounds_in_pixels) {
WindowMus* window = GetWindowByServerId(window_id);
if (window) {
@@ -1816,7 +1819,7 @@ void WindowTreeClient::WmSetBounds(uint32_t change_id,
void WindowTreeClient::WmSetProperty(
uint32_t change_id,
- Id window_id,
+ ui::Id window_id,
const std::string& name,
const base::Optional<std::vector<uint8_t>>& transit_data) {
WindowMus* window = GetWindowByServerId(window_id);
@@ -1838,13 +1841,13 @@ void WindowTreeClient::WmSetProperty(
window_manager_client_->WmResponse(change_id, result);
}
-void WindowTreeClient::WmSetModalType(Id window_id, ui::ModalType type) {
+void WindowTreeClient::WmSetModalType(ui::Id window_id, ui::ModalType type) {
WindowMus* window = GetWindowByServerId(window_id);
if (window)
window_manager_delegate_->OnWmSetModalType(window->GetWindow(), type);
}
-void WindowTreeClient::WmSetCanFocus(Id window_id, bool can_focus) {
+void WindowTreeClient::WmSetCanFocus(ui::Id window_id, bool can_focus) {
WindowMus* window = GetWindowByServerId(window_id);
if (window)
window_manager_delegate_->OnWmSetCanFocus(window->GetWindow(), can_focus);
@@ -1873,7 +1876,7 @@ void WindowTreeClient::WmCreateTopLevelWindow(
kInvalidServerId);
return;
}
- embedded_windows_[base::checked_cast<ClientSpecificId>(
+ embedded_windows_[base::checked_cast<ui::ClientSpecificId>(
frame_sink_id.client_id())]
.insert(window);
if (window_manager_client_) {
@@ -1883,7 +1886,7 @@ void WindowTreeClient::WmCreateTopLevelWindow(
}
}
-void WindowTreeClient::WmClientJankinessChanged(ClientSpecificId client_id,
+void WindowTreeClient::WmClientJankinessChanged(ui::ClientSpecificId client_id,
bool janky) {
if (window_manager_delegate_) {
auto it = embedded_windows_.find(client_id);
@@ -1926,7 +1929,7 @@ void WindowTreeClient::WmDestroyDragImage() {
}
void WindowTreeClient::WmPerformMoveLoop(uint32_t change_id,
- Id window_id,
+ ui::Id window_id,
ui::mojom::MoveLoopSource source,
const gfx::Point& cursor_location) {
if (!window_manager_delegate_ || current_wm_move_loop_change_ != 0) {
@@ -1956,7 +1959,7 @@ void WindowTreeClient::WmCancelMoveLoop(uint32_t change_id) {
window_manager_delegate_->OnWmCancelMoveLoop(window->GetWindow());
}
-void WindowTreeClient::WmDeactivateWindow(Id window_id) {
+void WindowTreeClient::WmDeactivateWindow(ui::Id window_id) {
if (!window_manager_delegate_)
return;
@@ -1974,8 +1977,9 @@ void WindowTreeClient::WmDeactivateWindow(Id window_id) {
window_manager_delegate_->OnWmDeactivateWindow(window->GetWindow());
}
-void WindowTreeClient::WmStackAbove(uint32_t wm_change_id, Id above_id,
- Id below_id) {
+void WindowTreeClient::WmStackAbove(uint32_t wm_change_id,
+ ui::Id above_id,
+ ui::Id below_id) {
if (!window_manager_delegate_)
return;
@@ -2011,7 +2015,7 @@ void WindowTreeClient::WmStackAbove(uint32_t wm_change_id, Id above_id,
window_manager_client_->WmResponse(wm_change_id, true);
}
-void WindowTreeClient::WmStackAtTop(uint32_t wm_change_id, uint32_t window_id) {
+void WindowTreeClient::WmStackAtTop(uint32_t wm_change_id, ui::Id window_id) {
if (!window_manager_delegate_)
return;
@@ -2030,7 +2034,7 @@ void WindowTreeClient::WmStackAtTop(uint32_t wm_change_id, uint32_t window_id) {
window_manager_client_->WmResponse(wm_change_id, true);
}
-void WindowTreeClient::WmPerformWmAction(Id window_id,
+void WindowTreeClient::WmPerformWmAction(ui::Id window_id,
const std::string& action) {
if (!window_manager_delegate_)
return;
@@ -2056,7 +2060,7 @@ void WindowTreeClient::OnCursorTouchVisibleChanged(bool enabled) {
window_manager_delegate_->OnCursorTouchVisibleChanged(enabled);
}
-void WindowTreeClient::OnEventBlockedByModalWindow(Id window_id) {
+void WindowTreeClient::OnEventBlockedByModalWindow(ui::Id window_id) {
if (!window_manager_delegate_)
return;
@@ -2162,7 +2166,7 @@ void WindowTreeClient::InjectEvent(const ui::Event& event, int64_t display_id) {
// refused.
if (event_injector_) {
event_injector_->DispatchEvent(display_id, ui::Event::Clone(event),
- base::Bind([](bool result) {}));
+ base::DoNothing());
}
}
diff --git a/chromium/ui/aura/mus/window_tree_client.h b/chromium/ui/aura/mus/window_tree_client.h
index de8395f2627..1a887b9a322 100644
--- a/chromium/ui/aura/mus/window_tree_client.h
+++ b/chromium/ui/aura/mus/window_tree_client.h
@@ -165,7 +165,7 @@ class AURA_EXPORT WindowTreeClient
base::OnceCallback<void(const base::UnguessableToken&)> callback);
void AttachCompositorFrameSink(
- Id window_id,
+ ui::Id window_id,
viz::mojom::CompositorFrameSinkRequest compositor_frame_sink,
viz::mojom::CompositorFrameSinkClientPtr client);
@@ -207,14 +207,14 @@ class AURA_EXPORT WindowTreeClient
SERVER,
};
- using IdToWindowMap = std::map<Id, WindowMus*>;
+ using IdToWindowMap = std::map<ui::Id, WindowMus*>;
// TODO(sky): this assumes change_ids never wrap, which is a bad assumption.
using InFlightMap = std::map<uint32_t, std::unique_ptr<InFlightChange>>;
void RegisterWindowMus(WindowMus* window);
- WindowMus* GetWindowByServerId(Id id);
+ WindowMus* GetWindowByServerId(ui::Id id);
bool IsWindowKnown(aura::Window* window);
@@ -296,7 +296,7 @@ class AURA_EXPORT WindowTreeClient
void OnEmbedImpl(ui::mojom::WindowTree* window_tree,
ui::mojom::WindowDataPtr root_data,
int64_t display_id,
- Id focused_window_id,
+ ui::Id focused_window_id,
bool drawn,
const base::Optional<viz::LocalSurfaceId>& local_surface_id);
@@ -361,14 +361,14 @@ class AURA_EXPORT WindowTreeClient
ui::mojom::WindowDataPtr root,
ui::mojom::WindowTreePtr tree,
int64_t display_id,
- Id focused_window_id,
+ ui::Id focused_window_id,
bool drawn,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) override;
- void OnEmbeddedAppDisconnected(Id window_id) override;
- void OnUnembed(Id window_id) override;
- void OnCaptureChanged(Id new_capture_window_id,
- Id old_capture_window_id) override;
- void OnFrameSinkIdAllocated(Id window_id,
+ void OnEmbeddedAppDisconnected(ui::Id window_id) override;
+ void OnUnembed(ui::Id window_id) override;
+ void OnCaptureChanged(ui::Id new_capture_window_id,
+ ui::Id old_capture_window_id) override;
+ void OnFrameSinkIdAllocated(ui::Id window_id,
const viz::FrameSinkId& frame_sink_id) override;
void OnTopLevelCreated(
uint32_t change_id,
@@ -377,79 +377,79 @@ class AURA_EXPORT WindowTreeClient
bool drawn,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) override;
void OnWindowBoundsChanged(
- Id window_id,
+ ui::Id window_id,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
const base::Optional<viz::LocalSurfaceId>& local_surface_id) override;
- void OnWindowTransformChanged(Id window_id,
+ void OnWindowTransformChanged(ui::Id window_id,
const gfx::Transform& old_transform,
const gfx::Transform& new_transform) override;
void OnClientAreaChanged(
- uint32_t window_id,
+ ui::Id window_id,
const gfx::Insets& new_client_area,
const std::vector<gfx::Rect>& new_additional_client_areas) override;
- void OnTransientWindowAdded(uint32_t window_id,
- uint32_t transient_window_id) override;
- void OnTransientWindowRemoved(uint32_t window_id,
- uint32_t transient_window_id) override;
+ void OnTransientWindowAdded(ui::Id window_id,
+ ui::Id transient_window_id) override;
+ void OnTransientWindowRemoved(ui::Id window_id,
+ ui::Id transient_window_id) override;
void OnWindowHierarchyChanged(
- Id window_id,
- Id old_parent_id,
- Id new_parent_id,
+ ui::Id window_id,
+ ui::Id old_parent_id,
+ ui::Id new_parent_id,
std::vector<ui::mojom::WindowDataPtr> windows) override;
- void OnWindowReordered(Id window_id,
- Id relative_window_id,
+ void OnWindowReordered(ui::Id window_id,
+ ui::Id relative_window_id,
ui::mojom::OrderDirection direction) override;
- void OnWindowDeleted(Id window_id) override;
- void OnWindowVisibilityChanged(Id window_id, bool visible) override;
- void OnWindowOpacityChanged(Id window_id,
+ void OnWindowDeleted(ui::Id window_id) override;
+ void OnWindowVisibilityChanged(ui::Id window_id, bool visible) override;
+ void OnWindowOpacityChanged(ui::Id window_id,
float old_opacity,
float new_opacity) override;
- void OnWindowParentDrawnStateChanged(Id window_id, bool drawn) override;
+ void OnWindowParentDrawnStateChanged(ui::Id window_id, bool drawn) override;
void OnWindowSharedPropertyChanged(
- Id window_id,
+ ui::Id window_id,
const std::string& name,
const base::Optional<std::vector<uint8_t>>& transport_data) override;
void OnWindowInputEvent(
uint32_t event_id,
- Id window_id,
+ ui::Id window_id,
int64_t display_id,
- Id display_root_window_id,
+ ui::Id display_root_window_id,
const gfx::PointF& event_location_in_screen_pixel_layout,
std::unique_ptr<ui::Event> event,
bool matches_pointer_watcher) override;
void OnPointerEventObserved(std::unique_ptr<ui::Event> event,
- uint32_t window_id,
+ ui::Id window_id,
int64_t display_id) override;
- void OnWindowFocused(Id focused_window_id) override;
- void OnWindowCursorChanged(Id window_id, ui::CursorData cursor) override;
- void OnWindowSurfaceChanged(Id window_id,
+ void OnWindowFocused(ui::Id focused_window_id) override;
+ void OnWindowCursorChanged(ui::Id window_id, ui::CursorData cursor) override;
+ void OnWindowSurfaceChanged(ui::Id window_id,
const viz::SurfaceInfo& surface_info) override;
void OnDragDropStart(
const std::unordered_map<std::string, std::vector<uint8_t>>& mime_data)
override;
- void OnDragEnter(Id window_id,
+ void OnDragEnter(ui::Id window_id,
uint32_t event_flags,
const gfx::Point& position,
uint32_t effect_bitmask,
const OnDragEnterCallback& callback) override;
- void OnDragOver(Id window_id,
+ void OnDragOver(ui::Id window_id,
uint32_t event_flags,
const gfx::Point& position,
uint32_t effect_bitmask,
const OnDragOverCallback& callback) override;
- void OnDragLeave(Id window_id) override;
- void OnCompleteDrop(Id window_id,
+ void OnDragLeave(ui::Id window_id) override;
+ void OnCompleteDrop(ui::Id window_id,
uint32_t event_flags,
const gfx::Point& position,
uint32_t effect_bitmask,
const OnCompleteDropCallback& callback) override;
- void OnPerformDragDropCompleted(uint32_t window,
+ void OnPerformDragDropCompleted(uint32_t change_id,
bool success,
uint32_t action_taken) override;
void OnDragDropDone() override;
void OnChangeCompleted(uint32_t change_id, bool success) override;
- void RequestClose(uint32_t window_id) override;
+ void RequestClose(ui::Id window_id) override;
void SetBlockingContainers(
const std::vector<BlockingContainers>& all_blocking_containers) override;
void GetWindowManager(
@@ -468,21 +468,21 @@ class AURA_EXPORT WindowTreeClient
void WmDisplayRemoved(int64_t display_id) override;
void WmDisplayModified(const display::Display& display) override;
void WmSetBounds(uint32_t change_id,
- Id window_id,
+ ui::Id window_id,
const gfx::Rect& transit_bounds_in_pixels) override;
void WmSetProperty(
uint32_t change_id,
- Id window_id,
+ ui::Id window_id,
const std::string& name,
const base::Optional<std::vector<uint8_t>>& transit_data) override;
- void WmSetModalType(Id window_id, ui::ModalType type) override;
- void WmSetCanFocus(Id window_id, bool can_focus) override;
+ void WmSetModalType(ui::Id window_id, ui::ModalType type) override;
+ void WmSetCanFocus(ui::Id window_id, bool can_focus) override;
void WmCreateTopLevelWindow(
uint32_t change_id,
const viz::FrameSinkId& frame_sink_id,
const std::unordered_map<std::string, std::vector<uint8_t>>&
transport_properties) override;
- void WmClientJankinessChanged(ClientSpecificId client_id,
+ void WmClientJankinessChanged(ui::ClientSpecificId client_id,
bool janky) override;
void WmBuildDragImage(const gfx::Point& screen_location,
const SkBitmap& drag_image,
@@ -492,19 +492,21 @@ class AURA_EXPORT WindowTreeClient
const WmMoveDragImageCallback& callback) override;
void WmDestroyDragImage() override;
void WmPerformMoveLoop(uint32_t change_id,
- Id window_id,
+ ui::Id window_id,
ui::mojom::MoveLoopSource source,
const gfx::Point& cursor_location) override;
- void WmCancelMoveLoop(uint32_t window_id) override;
- void WmDeactivateWindow(Id window_id) override;
- void WmStackAbove(uint32_t change_id, Id above_id, Id below_id) override;
- void WmStackAtTop(uint32_t change_id, uint32_t window_id) override;
- void WmPerformWmAction(Id window_id, const std::string& action) override;
+ void WmCancelMoveLoop(uint32_t change_id) override;
+ void WmDeactivateWindow(ui::Id window_id) override;
+ void WmStackAbove(uint32_t change_id,
+ ui::Id above_id,
+ ui::Id below_id) override;
+ void WmStackAtTop(uint32_t change_id, ui::Id window_id) override;
+ void WmPerformWmAction(ui::Id window_id, const std::string& action) override;
void OnAccelerator(uint32_t ack_id,
uint32_t accelerator_id,
std::unique_ptr<ui::Event> event) override;
void OnCursorTouchVisibleChanged(bool enabled) override;
- void OnEventBlockedByModalWindow(Id window_id) override;
+ void OnEventBlockedByModalWindow(ui::Id window_id) override;
// Overridden from WindowManagerClient:
void SetFrameDecorationValues(
@@ -602,7 +604,7 @@ class AURA_EXPORT WindowTreeClient
service_manager::Connector* connector_;
// Id assigned to the next window created.
- ClientSpecificId next_window_id_;
+ ui::ClientSpecificId next_window_id_;
// Id used for the next change id supplied to the server.
uint32_t next_change_id_;
@@ -615,7 +617,7 @@ class AURA_EXPORT WindowTreeClient
std::set<WindowMus*> roots_;
IdToWindowMap windows_;
- std::map<ClientSpecificId, std::set<Window*>> embedded_windows_;
+ std::map<ui::ClientSpecificId, std::set<Window*>> embedded_windows_;
std::unique_ptr<CaptureSynchronizer> capture_synchronizer_;
@@ -660,7 +662,7 @@ class AURA_EXPORT WindowTreeClient
// The current change id for the window manager.
uint32_t current_wm_move_loop_change_ = 0u;
- Id current_wm_move_loop_window_id_ = 0u;
+ ui::Id current_wm_move_loop_window_id_ = 0u;
std::unique_ptr<DragDropControllerMus> drag_drop_controller_;
diff --git a/chromium/ui/aura/mus/window_tree_client_delegate.h b/chromium/ui/aura/mus/window_tree_client_delegate.h
index e76d2efbac0..2481d0e0fdf 100644
--- a/chromium/ui/aura/mus/window_tree_client_delegate.h
+++ b/chromium/ui/aura/mus/window_tree_client_delegate.h
@@ -8,7 +8,7 @@
#include <memory>
#include <string>
-#include "services/service_manager/public/interfaces/interface_provider.mojom.h"
+#include "services/service_manager/public/mojom/interface_provider.mojom.h"
#include "services/ui/public/interfaces/window_tree.mojom.h"
#include "ui/aura/aura_export.h"
diff --git a/chromium/ui/aura/mus/window_tree_client_unittest.cc b/chromium/ui/aura/mus/window_tree_client_unittest.cc
index 07e385325c5..1ed6c0c3428 100644
--- a/chromium/ui/aura/mus/window_tree_client_unittest.cc
+++ b/chromium/ui/aura/mus/window_tree_client_unittest.cc
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "cc/base/switches.h"
#include "components/viz/common/surfaces/surface_info.h"
@@ -44,6 +45,7 @@
#include "ui/aura/window_tracker.h"
#include "ui/aura/window_tree_host_observer.h"
#include "ui/base/class_property.h"
+#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/compositor/compositor.h"
#include "ui/display/display.h"
@@ -68,13 +70,13 @@ const char kTestPropertyServerKey1[] = "test-property-server1";
const char kTestPropertyServerKey2[] = "test-property-server2";
const char kTestPropertyServerKey3[] = "test-property-server3";
-Id server_id(Window* window) {
+ui::Id server_id(Window* window) {
return window ? WindowMus::Get(window)->server_id() : 0;
}
std::unique_ptr<Window> CreateWindowUsingId(
WindowTreeClient* window_tree_client,
- Id server_id,
+ ui::Id server_id,
Window* parent = nullptr) {
ui::mojom::WindowData window_data;
window_data.window_id = server_id;
@@ -194,9 +196,7 @@ class WindowTreeClientWmTestSurfaceSync
// WindowTreeClientWmTest:
void SetUp() override {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kMus);
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kMusHostingViz);
+ feature_list_.InitAndEnableFeature(features::kMash);
if (GetParam()) {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kForceDeviceScaleFactor, "2");
@@ -205,6 +205,8 @@ class WindowTreeClientWmTestSurfaceSync
}
private:
+ base::test::ScopedFeatureList feature_list_;
+
DISALLOW_COPY_AND_ASSIGN(WindowTreeClientWmTestSurfaceSync);
};
@@ -485,7 +487,7 @@ TEST_P(WindowTreeClientWmTestSurfaceSync, SetBoundsLocalSurfaceIdChanges) {
// Verifies a new window from the server doesn't result in attempting to add
// the window back to the server.
TEST_F(WindowTreeClientWmTest, AddFromServerDoesntAddAgain) {
- const Id child_window_id = server_id(root_window()) + 11;
+ const ui::Id child_window_id = server_id(root_window()) + 11;
ui::mojom::WindowDataPtr data = ui::mojom::WindowData::New();
data->parent_id = server_id(root_window());
data->window_id = child_window_id;
@@ -527,7 +529,7 @@ TEST_F(WindowTreeClientWmTest, ReparentFromServerDoesntAddAgain) {
TEST_F(WindowTreeClientWmTest, OnWindowHierarchyChangedWithProperties) {
RegisterTestProperties(GetPropertyConverter());
window_tree()->AckAllChanges();
- const Id child_window_id = server_id(root_window()) + 11;
+ const ui::Id child_window_id = server_id(root_window()) + 11;
ui::mojom::WindowDataPtr data = ui::mojom::WindowData::New();
const uint8_t server_test_property1_value = 91;
data->properties[kTestPropertyServerKey1] =
@@ -535,6 +537,9 @@ TEST_F(WindowTreeClientWmTest, OnWindowHierarchyChangedWithProperties) {
data->properties[ui::mojom::WindowManager::kWindowType_InitProperty] =
mojo::ConvertTo<std::vector<uint8_t>>(
static_cast<int32_t>(ui::mojom::WindowType::BUBBLE));
+ constexpr int kWindowCornerRadiusValue = 6;
+ data->properties[ui::mojom::WindowManager::kWindowCornerRadius_Property] =
+ ConvertToPropertyTransportValue(kWindowCornerRadiusValue);
data->parent_id = server_id(root_window());
data->window_id = child_window_id;
data->bounds = gfx::Rect(1, 2, 3, 4);
@@ -549,6 +554,8 @@ TEST_F(WindowTreeClientWmTest, OnWindowHierarchyChangedWithProperties) {
Window* child = root_window()->children()[0];
EXPECT_FALSE(child->TargetVisibility());
EXPECT_EQ(server_test_property1_value, child->GetProperty(kTestPropertyKey1));
+ EXPECT_EQ(kWindowCornerRadiusValue,
+ child->GetProperty(client::kWindowCornerRadiusKey));
EXPECT_EQ(child->type(), client::WINDOW_TYPE_POPUP);
EXPECT_EQ(ui::mojom::WindowType::BUBBLE,
child->GetProperty(client::kWindowTypeKey));
@@ -1009,7 +1016,7 @@ TEST_F(WindowTreeClientClientTest, InputEventBasic) {
new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location_in_child,
gfx::Point(), ui::EventTimeForNow(), ui::EF_NONE, 0));
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location_in_child), ui::Event::Clone(*ui_event.get()),
0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
@@ -1045,7 +1052,7 @@ TEST_F(WindowTreeClientClientTest, InputEventPointerEvent) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0),
base::TimeTicks());
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location), ui::Event::Clone(pointer_event), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ui::mojom::EventResult::HANDLED,
@@ -1081,7 +1088,7 @@ TEST_F(WindowTreeClientClientTest, InputEventPen) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_PEN, 0),
ui::EventTimeForNow());
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location), ui::Event::Clone(pointer_event), 0);
// Pen event was handled.
@@ -1129,7 +1136,7 @@ TEST_F(WindowTreeClientClientTest, InputEventFindTargetAndConversion) {
new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, gfx::Point(),
ui::EventTimeForNow(), ui::EF_NONE, 0));
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child1), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child1), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location), ui::Event::Clone(*ui_event.get()), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ui::mojom::EventResult::HANDLED,
@@ -1150,7 +1157,7 @@ TEST_F(WindowTreeClientClientTest, InputEventFindTargetAndConversion) {
new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, gfx::Point(),
ui::EventTimeForNow(), ui::EF_NONE, 0));
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child1), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child1), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location), ui::Event::Clone(*ui_event1.get()), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ui::mojom::EventResult::HANDLED,
@@ -1198,7 +1205,7 @@ TEST_F(WindowTreeClientClientTest, InputEventCustomWindowTargeter) {
new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, gfx::Point(),
ui::EventTimeForNow(), ui::EF_NONE, 0));
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child1), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child1), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location), ui::Event::Clone(*ui_event.get()), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ui::mojom::EventResult::HANDLED,
@@ -1215,7 +1222,7 @@ TEST_F(WindowTreeClientClientTest, InputEventCustomWindowTargeter) {
window_delegate1.set_event_id(event_id);
window_delegate2.set_event_id(event_id);
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child2), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child2), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location), ui::Event::Clone(*ui_event.get()), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ui::mojom::EventResult::HANDLED,
@@ -1268,8 +1275,9 @@ TEST_F(WindowTreeClientClientTest, InputEventCaptureWindow) {
new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location, root_location,
ui::EventTimeForNow(), ui::EF_NONE, 0));
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(child1.get()), window_tree_host->display_id(), Id(),
- gfx::PointF(root_location), ui::Event::Clone(*ui_event.get()), 0);
+ event_id, server_id(child1.get()), window_tree_host->display_id(),
+ ui::Id(), gfx::PointF(root_location), ui::Event::Clone(*ui_event.get()),
+ 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ui::mojom::EventResult::HANDLED,
window_tree()->GetEventResult(event_id));
@@ -1291,8 +1299,9 @@ TEST_F(WindowTreeClientClientTest, InputEventCaptureWindow) {
window_delegate1->set_event_id(event_id);
window_delegate2->set_event_id(event_id);
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(child1.get()), window_tree_host->display_id(), Id(),
- gfx::PointF(root_location), ui::Event::Clone(*ui_event.get()), 0);
+ event_id, server_id(child1.get()), window_tree_host->display_id(),
+ ui::Id(), gfx::PointF(root_location), ui::Event::Clone(*ui_event.get()),
+ 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ui::mojom::EventResult::HANDLED,
window_tree()->GetEventResult(event_id));
@@ -1338,7 +1347,7 @@ TEST_F(WindowTreeClientClientTest, InputEventRootWindow) {
new ui::MouseEvent(ui::ET_MOUSE_MOVED, event_location_in_child,
gfx::Point(), ui::EventTimeForNow(), ui::EF_NONE, 0));
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(top_level), window_tree_host.display_id(), Id(),
+ event_id, server_id(top_level), window_tree_host.display_id(), ui::Id(),
gfx::PointF(), ui::Event::Clone(*ui_event.get()), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
@@ -1382,14 +1391,14 @@ TEST_F(WindowTreeClientClientTest, InputMouseEventNoWindow) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0),
ui::EventTimeForNow());
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location), ui::Event::Clone(pointer_event_down), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ui::mojom::EventResult::HANDLED,
window_tree()->GetEventResult(event_id));
EXPECT_EQ(1, window_delegate.press_count());
EXPECT_TRUE(env->IsMouseButtonDown());
- EXPECT_EQ(1024, env->mouse_button_flags()); // ui::EF_LEFT_MOUSE_BUTTON
+ EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, env->mouse_button_flags());
EXPECT_EQ(event_location, env->last_mouse_location());
window_delegate.reset();
@@ -1402,7 +1411,7 @@ TEST_F(WindowTreeClientClientTest, InputMouseEventNoWindow) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE, 0),
ui::EventTimeForNow());
window_tree_client()->OnWindowInputEvent(
- event_id, kInvalidServerId, window_tree_host.display_id(), Id(),
+ event_id, kInvalidServerId, window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location), ui::Event::Clone(pointer_event_up), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
// WindowTreeClient::OnWindowInputEvent cannot find a target window with
@@ -1445,7 +1454,7 @@ TEST_F(WindowTreeClientClientTest, InputTouchEventNoWindow) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0),
ui::EventTimeForNow());
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child), window_tree_host.display_id(), ui::Id(),
gfx::PointF(), ui::Event::Clone(pointer_event_down), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
EXPECT_EQ(ui::mojom::EventResult::HANDLED,
@@ -1461,7 +1470,7 @@ TEST_F(WindowTreeClientClientTest, InputTouchEventNoWindow) {
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 0),
ui::EventTimeForNow());
window_tree_client()->OnWindowInputEvent(
- event_id, kInvalidServerId, window_tree_host.display_id(), Id(),
+ event_id, kInvalidServerId, window_tree_host.display_id(), ui::Id(),
gfx::PointF(), ui::Event::Clone(pointer_event_up), 0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
// WindowTreeClient::OnWindowInputEvent cannot find a target window with
@@ -1557,7 +1566,7 @@ TEST_F(WindowTreeClientPointerObserverTest,
ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_CONTROL_DOWN, 0,
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH, 1),
base::TimeTicks::Now()));
- window_tree_client()->OnWindowInputEvent(1, server_id(top_level), 0, Id(),
+ window_tree_client()->OnWindowInputEvent(1, server_id(top_level), 0, ui::Id(),
gfx::PointF(),
std::move(pointer_event_down), true);
@@ -2483,7 +2492,7 @@ TEST_F(WindowTreeClientWmTest, OnWindowHierarchyChangedWithExistingWindow) {
Window* window2 = new Window(nullptr);
window2->Init(ui::LAYER_NOT_DRAWN);
window_tree()->AckAllChanges();
- const Id server_window_id = server_id(root_window()) + 11;
+ const ui::Id server_window_id = server_id(root_window()) + 11;
ui::mojom::WindowDataPtr data1 = ui::mojom::WindowData::New();
ui::mojom::WindowDataPtr data2 = ui::mojom::WindowData::New();
ui::mojom::WindowDataPtr data3 = ui::mojom::WindowData::New();
@@ -2602,7 +2611,7 @@ TEST_F(WindowTreeClientWmTest, FocusInDifferentDisplayThanEvent) {
std::unique_ptr<ui::KeyEvent> key_event = std::make_unique<ui::KeyEvent>(
ui::ET_KEY_PRESSED, ui::VKEY_ESCAPE, ui::EF_NONE);
window_tree_client()->OnWindowInputEvent(1, server_id(&child2), kDisplayId2,
- Id(), gfx::PointF(),
+ ui::Id(), gfx::PointF(),
std::move(key_event), false);
}
@@ -2820,7 +2829,7 @@ TEST_F(WindowTreeClientClientTestHighDPI, InputEventsInDip) {
ui::ET_MOUSE_MOVED, event_location_in_pixels, event_location_in_pixels,
ui::EventTimeForNow(), ui::EF_NONE, 0));
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child1), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child1), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location_in_pixels), ui::Event::Clone(*ui_event.get()),
0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
@@ -2845,7 +2854,7 @@ TEST_F(WindowTreeClientClientTestHighDPI, InputEventsInDip) {
window_delegate1.set_event_id(event_id);
window_delegate2.set_event_id(event_id);
window_tree_client()->OnWindowInputEvent(
- event_id, server_id(&child2), window_tree_host.display_id(), Id(),
+ event_id, server_id(&child2), window_tree_host.display_id(), ui::Id(),
gfx::PointF(event_location_in_pixels), ui::Event::Clone(*ui_event.get()),
0);
EXPECT_TRUE(window_tree()->WasEventAcked(event_id));
diff --git a/chromium/ui/aura/mus/window_tree_host_mus.cc b/chromium/ui/aura/mus/window_tree_host_mus.cc
index a146cfc41b3..3acab45d4e2 100644
--- a/chromium/ui/aura/mus/window_tree_host_mus.cc
+++ b/chromium/ui/aura/mus/window_tree_host_mus.cc
@@ -15,6 +15,7 @@
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host_observer.h"
#include "ui/base/class_property.h"
+#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
@@ -60,8 +61,9 @@ WindowTreeHostMus::WindowTreeHostMus(WindowTreeHostMusInitParams init_params)
// If window-server is hosting viz, then use the FrameSinkId from the server.
// In other cases, let a valid FrameSinkId be selected by
// context_factory_private().
- CreateCompositor(switches::IsMusHostingViz() ? window_mus->GetFrameSinkId()
- : viz::FrameSinkId());
+ CreateCompositor(base::FeatureList::IsEnabled(features::kMash)
+ ? window_mus->GenerateFrameSinkIdFromServerId()
+ : viz::FrameSinkId());
if (!init_params.uses_real_accelerated_widget) {
gfx::AcceleratedWidget accelerated_widget;
// We need accelerated widget numbers to be different for each window and
diff --git a/chromium/ui/aura/scoped_keyboard_hook.cc b/chromium/ui/aura/scoped_keyboard_hook.cc
new file mode 100644
index 00000000000..96d9d778439
--- /dev/null
+++ b/chromium/ui/aura/scoped_keyboard_hook.cc
@@ -0,0 +1,24 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/aura/scoped_keyboard_hook.h"
+
+#include "base/macros.h"
+#include "ui/aura/window_tree_host.h"
+
+namespace aura {
+
+ScopedKeyboardHook::ScopedKeyboardHook(
+ base::WeakPtr<WindowTreeHost> window_tree_host)
+ : window_tree_host_(window_tree_host) {
+ DCHECK(window_tree_host_);
+}
+
+ScopedKeyboardHook::~ScopedKeyboardHook() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+ if (window_tree_host_)
+ window_tree_host_->ReleaseSystemKeyEventCapture();
+}
+
+} // namespace aura
diff --git a/chromium/ui/aura/scoped_keyboard_hook.h b/chromium/ui/aura/scoped_keyboard_hook.h
new file mode 100644
index 00000000000..d061544aff2
--- /dev/null
+++ b/chromium/ui/aura/scoped_keyboard_hook.h
@@ -0,0 +1,35 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_AURA_SCOPED_KEYBOARD_HOOK_H_
+#define UI_AURA_SCOPED_KEYBOARD_HOOK_H_
+
+#include "base/memory/weak_ptr.h"
+#include "base/threading/thread_checker.h"
+#include "ui/aura/aura_export.h"
+
+namespace aura {
+
+class WindowTreeHost;
+
+// Destroying an instance of this class will clean up the KeyboardHook instance
+// owned by WindowTreeHost and prevent future system key events from being
+// captured. If the KeyboardHook or WindowTreeHost instances were already
+// destroyed, then destroying this instance is a noop.
+class AURA_EXPORT ScopedKeyboardHook {
+ public:
+ explicit ScopedKeyboardHook(base::WeakPtr<WindowTreeHost> weak_ptr);
+ ~ScopedKeyboardHook();
+
+ private:
+ THREAD_CHECKER(thread_checker_);
+
+ base::WeakPtr<WindowTreeHost> window_tree_host_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedKeyboardHook);
+};
+
+} // namespace aura
+
+#endif // UI_AURA_SCOPED_KEYBOARD_HOOK_H_
diff --git a/chromium/ui/aura/window.cc b/chromium/ui/aura/window.cc
index 063a2861247..0f224d897e0 100644
--- a/chromium/ui/aura/window.cc
+++ b/chromium/ui/aura/window.cc
@@ -32,6 +32,7 @@
#include "ui/aura/env.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
+#include "ui/aura/scoped_keyboard_hook.h"
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_observer.h"
@@ -39,6 +40,7 @@
#include "ui/aura/window_port.h"
#include "ui/aura/window_tracker.h"
#include "ui/aura/window_tree_host.h"
+#include "ui/base/ui_base_features.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animator.h"
@@ -643,6 +645,19 @@ bool Window::HasCapture() {
return capture_client && capture_client->GetCaptureWindow() == this;
}
+std::unique_ptr<ScopedKeyboardHook> Window::CaptureSystemKeyEvents(
+ base::Optional<base::flat_set<int>> keys) {
+ Window* root_window = GetRootWindow();
+ if (!root_window)
+ return nullptr;
+
+ WindowTreeHost* host = root_window->GetHost();
+ if (!host)
+ return nullptr;
+
+ return host->CaptureSystemKeyEvents(std::move(keys));
+}
+
void Window::SuppressPaint() {
layer()->SuppressPaint();
}
@@ -779,13 +794,11 @@ void Window::SetVisible(bool visible) {
NotifyWindowVisibilityChanged(this, visible);
}
-void Window::SetOccluded(bool occluded) {
- OcclusionState occlusion_state =
- occluded ? OcclusionState::OCCLUDED : OcclusionState::NOT_OCCLUDED;
+void Window::SetOcclusionState(OcclusionState occlusion_state) {
if (occlusion_state != occlusion_state_) {
occlusion_state_ = occlusion_state;
if (delegate_)
- delegate_->OnWindowOcclusionChanged(occluded);
+ delegate_->OnWindowOcclusionChanged(occlusion_state);
}
}
@@ -943,7 +956,8 @@ void Window::OnStackingChanged() {
}
void Window::NotifyRemovingFromRootWindow(Window* new_root) {
- port_->OnWillRemoveWindowFromRootWindow();
+ if (IsEmbeddingClient())
+ UnregisterFrameSinkId();
for (WindowObserver& observer : observers_)
observer.OnWindowRemovingFromRootWindow(this, new_root);
for (Window::Windows::const_iterator it = children_.begin();
@@ -953,7 +967,8 @@ void Window::NotifyRemovingFromRootWindow(Window* new_root) {
}
void Window::NotifyAddedToRootWindow() {
- port_->OnWindowAddedToRootWindow();
+ if (IsEmbeddingClient())
+ RegisterFrameSinkId();
for (WindowObserver& observer : observers_)
observer.OnWindowAddedToRootWindow(this);
for (Window::Windows::const_iterator it = children_.begin();
@@ -1032,23 +1047,18 @@ bool Window::NotifyWindowVisibilityChangedDown(aura::Window* target,
bool visible) {
if (!NotifyWindowVisibilityChangedAtReceiver(target, visible))
return false; // |this| was deleted.
- std::set<const Window*> child_already_processed;
- bool child_destroyed = false;
- do {
- child_destroyed = false;
- for (Window::Windows::const_iterator it = children_.begin();
- it != children_.end(); ++it) {
- if (!child_already_processed.insert(*it).second)
- continue;
- if (!(*it)->NotifyWindowVisibilityChangedDown(target, visible)) {
- // |*it| was deleted, |it| is invalid and |children_| has changed.
- // We exit the current for-loop and enter a new one.
- child_destroyed = true;
- break;
- }
- }
- } while (child_destroyed);
- return true;
+
+ WindowTracker this_tracker;
+ this_tracker.Add(this);
+ // Copy |children_| in case iterating mutates |children_|, or destroys an
+ // existing child.
+ WindowTracker children(children_);
+
+ while (!this_tracker.windows().empty() && !children.windows().empty())
+ children.Pop()->NotifyWindowVisibilityChangedDown(target, visible);
+
+ const bool this_still_valid = !this_tracker.windows().empty();
+ return this_still_valid;
}
void Window::NotifyWindowVisibilityChangedUp(aura::Window* target,
@@ -1075,11 +1085,15 @@ bool Window::CleanupGestureState() {
}
std::unique_ptr<cc::LayerTreeFrameSink> Window::CreateLayerTreeFrameSink() {
- return port_->CreateLayerTreeFrameSink();
+ auto sink = port_->CreateLayerTreeFrameSink();
+ DCHECK(frame_sink_id_.is_valid());
+ DCHECK(embeds_external_client_);
+ DCHECK(GetLocalSurfaceId().is_valid());
+ return sink;
}
viz::SurfaceId Window::GetSurfaceId() const {
- return port_->GetSurfaceId();
+ return viz::SurfaceId(GetFrameSinkId(), port_->GetLocalSurfaceId());
}
void Window::AllocateLocalSurfaceId() {
@@ -1090,18 +1104,25 @@ const viz::LocalSurfaceId& Window::GetLocalSurfaceId() const {
return port_->GetLocalSurfaceId();
}
-viz::FrameSinkId Window::GetFrameSinkId() const {
+const viz::FrameSinkId& Window::GetFrameSinkId() const {
if (IsRootWindow()) {
DCHECK(host_);
auto* compositor = host_->compositor();
DCHECK(compositor);
return compositor->frame_sink_id();
}
- return port_->GetFrameSinkId();
+ return frame_sink_id_;
+}
+
+void Window::SetEmbedFrameSinkId(const viz::FrameSinkId& frame_sink_id) {
+ DCHECK(frame_sink_id.is_valid());
+ frame_sink_id_ = frame_sink_id;
+ embeds_external_client_ = true;
+ RegisterFrameSinkId();
}
bool Window::IsEmbeddingClient() const {
- return embed_frame_sink_id_.is_valid();
+ return embeds_external_client_;
}
void Window::OnPaintLayer(const ui::PaintContext& context) {
@@ -1241,4 +1262,23 @@ void Window::UpdateLayerName() {
#endif
}
+void Window::RegisterFrameSinkId() {
+ DCHECK(frame_sink_id_.is_valid());
+ DCHECK(IsEmbeddingClient());
+ if (registered_frame_sink_id_ || disable_frame_sink_id_registration_)
+ return;
+ if (auto* compositor = layer()->GetCompositor()) {
+ compositor->AddFrameSink(frame_sink_id_);
+ registered_frame_sink_id_ = true;
+ }
+}
+
+void Window::UnregisterFrameSinkId() {
+ if (!registered_frame_sink_id_)
+ return;
+ registered_frame_sink_id_ = false;
+ if (auto* compositor = layer()->GetCompositor())
+ compositor->RemoveFrameSink(frame_sink_id_);
+}
+
} // namespace aura
diff --git a/chromium/ui/aura/window.h b/chromium/ui/aura/window.h
index d2ef6774f3c..b6e2dcfb871 100644
--- a/chromium/ui/aura/window.h
+++ b/chromium/ui/aura/window.h
@@ -14,8 +14,10 @@
#include <vector>
#include "base/compiler_specific.h"
+#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/observer_list.h"
+#include "base/optional.h"
#include "base/strings/string16.h"
#include "ui/aura/aura_export.h"
#include "ui/aura/client/window_types.h"
@@ -53,6 +55,7 @@ enum class EventTargetingPolicy;
namespace aura {
class LayoutManager;
+class ScopedKeyboardHook;
class WindowDelegate;
class WindowObserver;
class WindowPort;
@@ -88,12 +91,26 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// The window's occlusion state isn't tracked
// (WindowOcclusionTracker::Track) or hasn't been computed yet.
UNKNOWN,
- // The window is occluded, i.e. one of these conditions is true:
- // - The window is hidden (Window::IsVisible() is true).
- // - The bounds of the window are completely covered by opaque windows.
+ // The window or one of its descendants IsVisible() [1] and:
+ // - Its bounds aren't completely covered by fully opaque windows [2], or,
+ // - Its transform, bounds or opacity is animated.
+ VISIBLE,
+ // The window or one of its descendants IsVisible() [1], but they all:
+ // - Have bounds completely covered by fully opaque windows [2], and,
+ // - Have no transform, bounds or opacity animation.
OCCLUDED,
- // The window is not occluded.
- NOT_OCCLUDED,
+ // The window is not IsVisible() [1].
+ HIDDEN,
+ // [1] A window can only be IsVisible() if all its parent are IsVisible().
+ // [2] A window is "fully opaque" if:
+ // - It's visible (IsVisible()).
+ // - It's not transparent (transparent()).
+ // - It's transform, bounds and opacity aren't animated.
+ // - Its combined opacity is 1 (GetCombinedOpacity()).
+ // - The type of its layer is not ui::LAYER_NOT_DRAWN.
+ //
+ // TODO(fdoray): A window that clips its children shouldn't be VISIBLE just
+ // because it has an animated child.
};
typedef std::vector<Window*> Windows;
@@ -167,10 +184,10 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// account the visibility of the layer and ancestors, where as this tracks
// whether Show() without a Hide() has been invoked.
bool TargetVisibility() const { return visible_; }
- // Returns the occlusion state of this window. Will be UNKNOWN if the
- // occlusion state of this window isn't tracked
- // (WindowOcclusionTracker::Track). Will be stale if called within the scope
- // of a WindowOcclusionTracker::ScopedPauseOcclusionTracking.
+ // Returns the occlusion state of this window. Is UNKNOWN if the occlusion
+ // state of this window isn't tracked (WindowOcclusionTracker::Track) or
+ // hasn't been computed yet. Is stale if called within the scope of a
+ // WindowOcclusionTracker::ScopedPauseOcclusionTracking.
OcclusionState occlusion_state() const { return occlusion_state_; }
// Returns the window's bounds in root window's coordinates.
@@ -321,6 +338,13 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// Returns true if this window has capture.
bool HasCapture();
+ // Requests that |keys| be intercepted at the platform level and routed
+ // directly to the web content. If |keys| has no value, all keys will be
+ // intercepted. Returns a ScopedKeyboardHook instance which stops capturing
+ // system key events when destroyed.
+ std::unique_ptr<ScopedKeyboardHook> CaptureSystemKeyEvents(
+ base::Optional<base::flat_set<int>> keys);
+
// Suppresses painting window content by disgarding damaged rect and ignoring
// new paint requests. This is a one way operation and there is no way to
// reenable painting.
@@ -368,15 +392,18 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// Returns the FrameSinkId. In LOCAL mode, this returns a valid FrameSinkId
// only if a LayerTreeFrameSink has been created. In MUS mode, this always
// return a valid FrameSinkId.
- viz::FrameSinkId GetFrameSinkId() const;
-
- const viz::FrameSinkId& embed_frame_sink_id() const {
- return embed_frame_sink_id_;
- }
- void set_embed_frame_sink_id(const viz::FrameSinkId& embed_frame_sink_id) {
- embed_frame_sink_id_ = embed_frame_sink_id;
+ const viz::FrameSinkId& GetFrameSinkId() const;
+
+ // Use SetEmbedFrameSinkId() when this window is embedding another client.
+ // See comment for |frame_sink_id_| below for more details.
+ void SetEmbedFrameSinkId(const viz::FrameSinkId& embed_frame_sink_id);
+ void set_frame_sink_id(const viz::FrameSinkId& frame_sink_id) {
+ DCHECK(!embeds_external_client_);
+ DCHECK(!frame_sink_id_.is_valid());
+ frame_sink_id_ = frame_sink_id;
}
- // Returns whether this window is an embed window.
+
+ // Returns whether this window is embedding another client.
bool IsEmbeddingClient() const;
protected:
@@ -415,7 +442,7 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
void SetVisible(bool visible);
// Updates the occlusion state of the window.
- void SetOccluded(bool occluded);
+ void SetOcclusionState(OcclusionState occlusion_state);
// Schedules a paint for the Window's entire bounds.
void SchedulePaint();
@@ -505,6 +532,11 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
// Updates the layer name based on the window's name and id.
void UpdateLayerName();
+ void RegisterFrameSinkId();
+ void UnregisterFrameSinkId();
+ bool registered_frame_sink_id_ = false;
+ bool disable_frame_sink_id_registration_ = false;
+
// Window owns its corresponding WindowPort, but the ref is held as a raw
// pointer in |port_| so that it can still be accessed during destruction.
// This is important as deleting the WindowPort may result in trying to lookup
@@ -547,8 +579,13 @@ class AURA_EXPORT Window : public ui::LayerDelegate,
int id_;
- // Only set when it is embedding another client inside.
- viz::FrameSinkId embed_frame_sink_id_;
+ // The FrameSinkId associated with this window. If this window is embedding
+ // another client, then this should be set to the FrameSinkId of that client,
+ // and |embeds_external_client_| is turned on. However, a window can still
+ // have a valid FrameSinkId without embedding another client, to facilitate
+ // hit-testing.
+ viz::FrameSinkId frame_sink_id_;
+ bool embeds_external_client_ = false;
// Whether layer is initialized as non-opaque. Defaults to false.
bool transparent_;
diff --git a/chromium/ui/aura/window_delegate.h b/chromium/ui/aura/window_delegate.h
index a1ec4d98c72..2b24e2eb0ea 100644
--- a/chromium/ui/aura/window_delegate.h
+++ b/chromium/ui/aura/window_delegate.h
@@ -8,6 +8,7 @@
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "ui/aura/aura_export.h"
+#include "ui/aura/window.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_handler.h"
#include "ui/gfx/native_widget_types.h"
@@ -90,9 +91,10 @@ class AURA_EXPORT WindowDelegate : public ui::EventHandler {
virtual void OnWindowTargetVisibilityChanged(bool visible) = 0;
// Called when the occlusion state of the Window changes while tracked (see
- // WindowOcclusionTracker::Track). |is_occluded| indicates whether the Window
- // is occluded. Impls must not change any aura::Window.
- virtual void OnWindowOcclusionChanged(bool is_occluded) {}
+ // WindowOcclusionTracker::Track). |occlusion_state| is the new occlusion
+ // state of the Window.
+ virtual void OnWindowOcclusionChanged(
+ Window::OcclusionState occlusion_state) {}
// Called from Window::HitTest to check if the window has a custom hit test
// mask. It works similar to the views counterparts. That is, if the function
diff --git a/chromium/ui/aura/window_event_dispatcher.cc b/chromium/ui/aura/window_event_dispatcher.cc
index 6fb791a6183..8bfba9421b2 100644
--- a/chromium/ui/aura/window_event_dispatcher.cc
+++ b/chromium/ui/aura/window_event_dispatcher.cc
@@ -204,15 +204,22 @@ void WindowEventDispatcher::HoldPointerMoves() {
void WindowEventDispatcher::ReleasePointerMoves() {
--move_hold_count_;
DCHECK_GE(move_hold_count_, 0);
- if (!move_hold_count_ && held_move_event_) {
- // We don't want to call DispatchHeldEvents directly, because this might be
- // called from a deep stack while another event, in which case dispatching
- // another one may not be safe/expected. Instead we post a task, that we
- // may cancel if HoldPointerMoves is called again before it executes.
- base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
- FROM_HERE, base::Bind(
- base::IgnoreResult(&WindowEventDispatcher::DispatchHeldEvents),
- held_event_factory_.GetWeakPtr()));
+ if (!move_hold_count_) {
+ if (held_move_event_) {
+ // We don't want to call DispatchHeldEvents directly, because this might
+ // be called from a deep stack while another event, in which case
+ // dispatching another one may not be safe/expected. Instead we post a
+ // task, that we may cancel if HoldPointerMoves is called again before it
+ // executes.
+ base::ThreadTaskRunnerHandle::Get()->PostNonNestableTask(
+ FROM_HERE,
+ base::BindOnce(
+ base::IgnoreResult(&WindowEventDispatcher::DispatchHeldEvents),
+ held_event_factory_.GetWeakPtr()));
+ } else {
+ if (did_dispatch_held_move_event_callback_)
+ base::ResetAndReturn(&did_dispatch_held_move_event_callback_).Run();
+ }
}
TRACE_EVENT_ASYNC_END0("ui", "WindowEventDispatcher::HoldPointerMoves", this);
}
@@ -765,8 +772,11 @@ void WindowEventDispatcher::OnWindowInitialized(Window* window) {
// WindowEventDispatcher, private:
ui::EventDispatchDetails WindowEventDispatcher::DispatchHeldEvents() {
- if (!held_repostable_event_ && !held_move_event_)
+ if (!held_repostable_event_ && !held_move_event_) {
+ if (did_dispatch_held_move_event_callback_)
+ base::ResetAndReturn(&did_dispatch_held_move_event_callback_).Run();
return DispatchDetails();
+ }
CHECK(!dispatching_held_event_);
@@ -798,8 +808,12 @@ ui::EventDispatchDetails WindowEventDispatcher::DispatchHeldEvents() {
held_move_event_.reset();
}
- if (!dispatch_details.dispatcher_destroyed)
+ if (!dispatch_details.dispatcher_destroyed) {
dispatching_held_event_ = nullptr;
+ if (did_dispatch_held_move_event_callback_)
+ base::ResetAndReturn(&did_dispatch_held_move_event_callback_).Run();
+ }
+
return dispatch_details;
}
diff --git a/chromium/ui/aura/window_event_dispatcher.h b/chromium/ui/aura/window_event_dispatcher.h
index 4772bd1c962..283866d50b1 100644
--- a/chromium/ui/aura/window_event_dispatcher.h
+++ b/chromium/ui/aura/window_event_dispatcher.h
@@ -293,6 +293,10 @@ class AURA_EXPORT WindowEventDispatcher : public ui::EventProcessor,
bool skip_ime_;
+ // This callback is called when the held move event is dispatched, or when
+ // pointer moves are released and there is no held move event.
+ base::OnceClosure did_dispatch_held_move_event_callback_;
+
// Used to schedule reposting an event.
base::WeakPtrFactory<WindowEventDispatcher> repost_event_factory_;
diff --git a/chromium/ui/aura/window_event_dispatcher_unittest.cc b/chromium/ui/aura/window_event_dispatcher_unittest.cc
index f70d4b415d9..dc9571ef34e 100644
--- a/chromium/ui/aura/window_event_dispatcher_unittest.cc
+++ b/chromium/ui/aura/window_event_dispatcher_unittest.cc
@@ -35,6 +35,7 @@
#include "ui/aura/window_targeter.h"
#include "ui/aura/window_tracker.h"
#include "ui/base/hit_test.h"
+#include "ui/base/ui_base_features.h"
#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
@@ -2959,19 +2960,19 @@ INSTANTIATE_TEST_CASE_P(/* no prefix */,
WindowEventDispatcherTest,
::testing::Values(test::BackendType::CLASSIC,
test::BackendType::MUS,
- test::BackendType::MUS_HOSTING_VIZ));
+ test::BackendType::MASH));
INSTANTIATE_TEST_CASE_P(/* no prefix */,
WindowEventDispatcherTestWithMessageLoop,
::testing::Values(test::BackendType::CLASSIC,
test::BackendType::MUS,
- test::BackendType::MUS_HOSTING_VIZ));
+ test::BackendType::MASH));
INSTANTIATE_TEST_CASE_P(/* no prefix */,
WindowEventDispatcherTestInHighDPI,
::testing::Values(test::BackendType::CLASSIC,
test::BackendType::MUS,
- test::BackendType::MUS_HOSTING_VIZ));
+ test::BackendType::MASH));
using WindowEventDispatcherMusTest = test::AuraTestBaseMus;
diff --git a/chromium/ui/aura/window_occlusion_tracker.cc b/chromium/ui/aura/window_occlusion_tracker.cc
index 80cc8830197..dff18bd85e7 100644
--- a/chromium/ui/aura/window_occlusion_tracker.cc
+++ b/chromium/ui/aura/window_occlusion_tracker.cc
@@ -4,11 +4,13 @@
#include "ui/aura/window_occlusion_tracker.h"
+#include "base/auto_reset.h"
#include "base/containers/adapters.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/stl_util.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRegion.h"
-#include "ui/aura/window.h"
+#include "ui/aura/window_tracker.h"
#include "ui/gfx/geometry/safe_integer_conversions.h"
#include "ui/gfx/transform.h"
@@ -23,6 +25,10 @@ constexpr ui::LayerAnimationElement::AnimatableProperties
ui::LayerAnimationElement::TRANSFORM |
ui::LayerAnimationElement::BOUNDS | ui::LayerAnimationElement::OPACITY;
+// Maximum number of times that MaybeComputeOcclusion() should have to recompute
+// occlusion states before they become stable.
+constexpr int kMaxRecomputeOcclusion = 2;
+
WindowOcclusionTracker* g_tracker = nullptr;
int g_num_pause_occlusion_tracking = 0;
@@ -80,6 +86,17 @@ SkIRect GetWindowBoundsInRootWindow(
return skirect_bounds;
}
+// Returns true iff the occlusion states in |tracked_windows| match those
+// returned by Window::occlusion_state().
+bool OcclusionStatesMatch(
+ const base::flat_map<Window*, Window::OcclusionState>& tracked_windows) {
+ for (const auto& tracked_window : tracked_windows) {
+ if (tracked_window.second != tracked_window.first->occlusion_state())
+ return false;
+ }
+ return true;
+}
+
} // namespace
WindowOcclusionTracker::ScopedPauseOcclusionTracking::
@@ -92,7 +109,7 @@ WindowOcclusionTracker::ScopedPauseOcclusionTracking::
--g_num_pause_occlusion_tracking;
DCHECK_GE(g_num_pause_occlusion_tracking, 0);
if (g_tracker)
- g_tracker->MaybeRecomputeOcclusion();
+ g_tracker->MaybeComputeOcclusion();
}
void WindowOcclusionTracker::Track(Window* window) {
@@ -102,7 +119,8 @@ void WindowOcclusionTracker::Track(Window* window) {
if (!g_tracker)
g_tracker = new WindowOcclusionTracker();
- auto insert_result = g_tracker->tracked_windows_.insert(window);
+ auto insert_result = g_tracker->tracked_windows_.insert(
+ {window, Window::OcclusionState::UNKNOWN});
DCHECK(insert_result.second);
if (!window->HasObserver(g_tracker))
window->AddObserver(g_tracker);
@@ -114,39 +132,90 @@ WindowOcclusionTracker::WindowOcclusionTracker() = default;
WindowOcclusionTracker::~WindowOcclusionTracker() = default;
-void WindowOcclusionTracker::MaybeRecomputeOcclusion() {
- if (g_num_pause_occlusion_tracking)
+void WindowOcclusionTracker::MaybeComputeOcclusion() {
+ if (g_num_pause_occlusion_tracking || num_times_occlusion_recomputed_ != 0)
return;
- for (auto& root_window_pair : root_windows_) {
- RootWindowState& root_window_state = root_window_pair.second;
- if (root_window_state.dirty == true) {
- ScopedPauseOcclusionTracking scoped_pause_occlusion_tracking;
- root_window_state.dirty = false;
- SkRegion occluded_region;
- RecomputeOcclusionImpl(root_window_pair.first, gfx::Transform(), nullptr,
- &occluded_region);
- // WindowDelegate::OnWindowOcclusionChanged() impls must not change any
- // Window.
- DCHECK(!root_window_state.dirty);
+
+ base::AutoReset<int> auto_reset(&num_times_occlusion_recomputed_, 0);
+
+ // Recompute occlusion states until either:
+ // - They are stable, i.e. calling Window::SetOcclusionState() on all tracked
+ // windows does not provoke changes that could affect occlusion.
+ // - Occlusion states have been recomputed
+ // |kMaxComputeOcclusionIterationsBeforeStable|
+ // times.
+ // If occlusion states have been recomputed
+ // |kMaxComputeOcclusionIterationsBeforeStable| times and are still not
+ // stable, iterate one last time to set the occlusion state of all tracked
+ // windows based on IsVisible().
+ while (num_times_occlusion_recomputed_ <= kMaxRecomputeOcclusion) {
+ const bool exceeded_max_num_times_occlusion_recomputed =
+ num_times_occlusion_recomputed_ == kMaxRecomputeOcclusion;
+ bool found_dirty_root = false;
+
+ // Compute occlusion states and store them in |tracked_windows_|. Do not
+ // call Window::SetOcclusionState() in this phase to prevent changes to the
+ // window tree while it is being traversed.
+ for (auto& root_window_pair : root_windows_) {
+ if (root_window_pair.second.dirty) {
+ found_dirty_root = true;
+ root_window_pair.second.dirty = false;
+ if (!exceeded_max_num_times_occlusion_recomputed) {
+ SkRegion occluded_region;
+ RecomputeOcclusionImpl(root_window_pair.first, gfx::Transform(),
+ nullptr, &occluded_region);
+ }
+ }
+ }
+
+ ++num_times_occlusion_recomputed_;
+
+ if (!found_dirty_root)
+ break;
+
+ // Call Window::SetOcclusionState() on tracked windows. A WindowDelegate may
+ // change the window tree in response to this.
+ WindowTracker tracked_windows_list;
+ for (const auto& tracked_window : tracked_windows_)
+ tracked_windows_list.Add(tracked_window.first);
+
+ while (!tracked_windows_list.windows().empty()) {
+ Window* window = tracked_windows_list.Pop();
+ auto it = tracked_windows_.find(window);
+ if (it != tracked_windows_.end() &&
+ it->second != Window::OcclusionState::UNKNOWN) {
+ // Fallback to VISIBLE/HIDDEN if the maximum number of times that
+ // occlusion can be recomputed was exceeded.
+ if (exceeded_max_num_times_occlusion_recomputed) {
+ it->second = window->IsVisible() ? Window::OcclusionState::VISIBLE
+ : Window::OcclusionState::HIDDEN;
+ }
+
+ window->SetOcclusionState(it->second);
+ }
}
}
+
+ // Sanity check: Occlusion states in |tracked_windows_| should match those
+ // returned by Window::occlusion_state().
+ DCHECK(OcclusionStatesMatch(tracked_windows_));
}
-void WindowOcclusionTracker::RecomputeOcclusionImpl(
+bool WindowOcclusionTracker::RecomputeOcclusionImpl(
Window* window,
const gfx::Transform& parent_transform_relative_to_root,
const SkIRect* clipped_bounds,
SkRegion* occluded_region) {
DCHECK(window);
- if (WindowIsAnimated(window)) {
- SetWindowAndDescendantsAreOccluded(window, false);
- return;
- }
-
if (!window->IsVisible()) {
SetWindowAndDescendantsAreOccluded(window, true);
- return;
+ return false;
+ }
+
+ if (WindowIsAnimated(window)) {
+ SetWindowAndDescendantsAreOccluded(window, false);
+ return true;
}
// Compute window bounds.
@@ -157,7 +226,7 @@ void WindowOcclusionTracker::RecomputeOcclusionImpl(
// For simplicity, windows that are not axis-aligned are considered
// unoccluded and do not occlude other windows.
SetWindowAndDescendantsAreOccluded(window, false);
- return;
+ return true;
}
const SkIRect window_bounds = GetWindowBoundsInRootWindow(
window, transform_relative_to_root, clipped_bounds);
@@ -165,19 +234,23 @@ void WindowOcclusionTracker::RecomputeOcclusionImpl(
// Compute children occlusion states.
const SkIRect* clipped_bounds_for_children =
window->layer()->GetMasksToBounds() ? &window_bounds : clipped_bounds;
+ bool has_visible_child = false;
for (auto* child : base::Reversed(window->children())) {
- RecomputeOcclusionImpl(child, transform_relative_to_root,
- clipped_bounds_for_children, occluded_region);
+ has_visible_child |=
+ RecomputeOcclusionImpl(child, transform_relative_to_root,
+ clipped_bounds_for_children, occluded_region);
}
// Compute window occlusion state.
if (occluded_region->contains(window_bounds)) {
- SetOccluded(window, true);
- } else {
- SetOccluded(window, false);
- if (VisibleWindowIsOpaque(window))
- occluded_region->op(window_bounds, SkRegion::kUnion_Op);
+ SetOccluded(window, !has_visible_child);
+ return has_visible_child;
}
+
+ SetOccluded(window, false);
+ if (VisibleWindowIsOpaque(window))
+ occluded_region->op(window_bounds, SkRegion::kUnion_Op);
+ return true;
}
void WindowOcclusionTracker::CleanupAnimatedWindows() {
@@ -188,7 +261,7 @@ void WindowOcclusionTracker::CleanupAnimatedWindows() {
animator->RemoveObserver(this);
auto root_window_state_it = root_windows_.find(window->GetRootWindow());
if (root_window_state_it != root_windows_.end())
- root_window_state_it->second.dirty = true;
+ MarkRootWindowAsDirty(&root_window_state_it->second);
return true;
});
}
@@ -219,9 +292,17 @@ void WindowOcclusionTracker::SetWindowAndDescendantsAreOccluded(
SetWindowAndDescendantsAreOccluded(child_window, is_occluded);
}
-void WindowOcclusionTracker::SetOccluded(Window* window, bool occluded) {
- if (WindowIsTracked(window))
- window->SetOccluded(occluded);
+void WindowOcclusionTracker::SetOccluded(Window* window, bool is_occluded) {
+ auto tracked_window = tracked_windows_.find(window);
+ if (tracked_window == tracked_windows_.end())
+ return;
+
+ if (!window->IsVisible())
+ tracked_window->second = Window::OcclusionState::HIDDEN;
+ else if (is_occluded)
+ tracked_window->second = Window::OcclusionState::OCCLUDED;
+ else
+ tracked_window->second = Window::OcclusionState::VISIBLE;
}
bool WindowOcclusionTracker::WindowIsTracked(Window* window) const {
@@ -233,7 +314,7 @@ bool WindowOcclusionTracker::WindowIsAnimated(Window* window) const {
}
template <typename Predicate>
-void WindowOcclusionTracker::MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(
+void WindowOcclusionTracker::MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(
Window* window,
Predicate predicate) {
Window* root_window = window->GetRootWindow();
@@ -253,11 +334,28 @@ void WindowOcclusionTracker::MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(
if (root_window_state_it->second.dirty)
return;
if (predicate()) {
- root_window_state_it->second.dirty = true;
- MaybeRecomputeOcclusion();
+ MarkRootWindowAsDirty(&root_window_state_it->second);
+ MaybeComputeOcclusion();
}
}
+void WindowOcclusionTracker::MarkRootWindowAsDirty(
+ RootWindowState* root_window_state) {
+ root_window_state->dirty = true;
+
+ // Generate a crash report when a root window is marked as dirty and occlusion
+ // states have been recomputed |kMaxRecomputeOcclusion| times, because it
+ // indicates that they are not stabilizing. Don't report it when
+ // |num_times_occlusion_recomputed_| is greater than |kMaxRecomputeOcclusion|
+ // to avoid generating multiple reports from the same client.
+ //
+ // TODO(fdoray): Remove this once we are confident that occlusion states are
+ // stable after |kMaxRecomputeOcclusion| iterations in production.
+ // https://crbug.com/813076
+ if (num_times_occlusion_recomputed_ == kMaxRecomputeOcclusion)
+ base::debug::DumpWithoutCrashing();
+}
+
bool WindowOcclusionTracker::WindowOrParentIsAnimated(Window* window) const {
while (window && !WindowIsAnimated(window))
window = window->parent();
@@ -315,8 +413,8 @@ void WindowOcclusionTracker::TrackedWindowAddedToRoot(Window* window) {
++root_window_state.num_tracked_windows;
if (root_window_state.num_tracked_windows == 1)
AddObserverToWindowAndDescendants(root_window);
- root_window_state.dirty = true;
- MaybeRecomputeOcclusion();
+ MarkRootWindowAsDirty(&root_window_state);
+ MaybeComputeOcclusion();
}
void WindowOcclusionTracker::TrackedWindowRemovedFromRoot(Window* window) {
@@ -356,13 +454,13 @@ void WindowOcclusionTracker::AddObserverToWindowAndDescendants(Window* window) {
void WindowOcclusionTracker::OnLayerAnimationEnded(
ui::LayerAnimationSequence* sequence) {
CleanupAnimatedWindows();
- MaybeRecomputeOcclusion();
+ MaybeComputeOcclusion();
}
void WindowOcclusionTracker::OnLayerAnimationAborted(
ui::LayerAnimationSequence* sequence) {
CleanupAnimatedWindows();
- MaybeRecomputeOcclusion();
+ MaybeComputeOcclusion();
}
void WindowOcclusionTracker::OnLayerAnimationScheduled(
@@ -379,12 +477,12 @@ void WindowOcclusionTracker::OnWindowHierarchyChanged(
}
void WindowOcclusionTracker::OnWindowAdded(Window* window) {
- MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(
+ MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(
window, [=]() { return WindowMoveMayAffectOcclusionStates(window); });
}
void WindowOcclusionTracker::OnWillRemoveWindow(Window* window) {
- MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(window, [=]() {
+ MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(window, [=]() {
return !WindowOrParentIsAnimated(window) &&
WindowOrDescendantIsOpaque(window);
});
@@ -392,7 +490,7 @@ void WindowOcclusionTracker::OnWillRemoveWindow(Window* window) {
void WindowOcclusionTracker::OnWindowVisibilityChanged(Window* window,
bool visible) {
- MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(
+ MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(
window, [=]() { return !WindowOrParentIsAnimated(window); });
}
@@ -406,7 +504,7 @@ void WindowOcclusionTracker::OnWindowBoundsChanged(
const bool animation_started =
(reason == ui::PropertyChangeReason::FROM_ANIMATION) &&
MaybeObserveAnimatedWindow(window);
- MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(window, [=]() {
+ MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(window, [=]() {
return animation_started || WindowMoveMayAffectOcclusionStates(window);
});
}
@@ -419,7 +517,7 @@ void WindowOcclusionTracker::OnWindowOpacitySet(
const bool animation_started =
(reason == ui::PropertyChangeReason::FROM_ANIMATION) &&
MaybeObserveAnimatedWindow(window);
- MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(window, [=]() {
+ MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(window, [=]() {
return animation_started || !WindowOrParentIsAnimated(window);
});
}
@@ -432,13 +530,13 @@ void WindowOcclusionTracker::OnWindowTransformed(
const bool animation_started =
(reason == ui::PropertyChangeReason::FROM_ANIMATION) &&
MaybeObserveAnimatedWindow(window);
- MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(window, [=]() {
+ MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(window, [=]() {
return animation_started || WindowMoveMayAffectOcclusionStates(window);
});
}
void WindowOcclusionTracker::OnWindowStackingChanged(Window* window) {
- MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(
+ MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(
window, [=]() { return WindowMoveMayAffectOcclusionStates(window); });
}
@@ -483,8 +581,8 @@ void WindowOcclusionTracker::OnWindowLayerRecreated(Window* window) {
animator->RemoveObserver(this);
auto root_window_state_it = root_windows_.find(window->GetRootWindow());
if (root_window_state_it != root_windows_.end()) {
- root_window_state_it->second.dirty = true;
- MaybeRecomputeOcclusion();
+ MarkRootWindowAsDirty(&root_window_state_it->second);
+ MaybeComputeOcclusion();
}
}
diff --git a/chromium/ui/aura/window_occlusion_tracker.h b/chromium/ui/aura/window_occlusion_tracker.h
index d3aa02b1ee8..c76f4f4eee0 100644
--- a/chromium/ui/aura/window_occlusion_tracker.h
+++ b/chromium/ui/aura/window_occlusion_tracker.h
@@ -9,6 +9,7 @@
#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "ui/aura/aura_export.h"
+#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/compositor/layer_animation_observer.h"
@@ -21,8 +22,6 @@ class Transform;
namespace aura {
-class Window;
-
// Notifies tracked Windows when their occlusion state change.
//
// To start tracking the occlusion state of a Window, call
@@ -55,20 +54,30 @@ class AURA_EXPORT WindowOcclusionTracker : public ui::LayerAnimationObserver,
static void Track(Window* window);
private:
+ struct RootWindowState {
+ // Number of Windows whose occlusion state is tracked under this root
+ // Window.
+ int num_tracked_windows = 0;
+
+ // Whether the occlusion state of tracked Windows under this root is stale.
+ bool dirty = false;
+ };
+
WindowOcclusionTracker();
~WindowOcclusionTracker() override;
// Recomputes the occlusion state of tracked windows under roots marked as
// dirty in |root_windows_| if there are no active
// ScopedPauseOcclusionTracking instance.
- void MaybeRecomputeOcclusion();
+ void MaybeComputeOcclusion();
// Recomputes the occlusion state of |window| and its descendants.
// |parent_transform_relative_to_root| is the transform of |window->parent()|
// relative to the root window. |clipped_bounds| is an optional mask for the
// bounds of |window| and its descendants. |occluded_region| is a region
- // covered by windows which are on top of |window|.
- void RecomputeOcclusionImpl(
+ // covered by windows which are on top of |window|. Returns true if at least
+ // one window in the hierarchy starting at |window| is NOT_OCCLUDED.
+ bool RecomputeOcclusionImpl(
Window* window,
const gfx::Transform& parent_transform_relative_to_root,
const SkIRect* clipped_bounds,
@@ -82,13 +91,14 @@ class AURA_EXPORT WindowOcclusionTracker : public ui::LayerAnimationObserver,
// |animated_windows_|, adds |window| to |animated_windows_| and returns true.
bool MaybeObserveAnimatedWindow(Window* window);
- // Calls SetOccluded(|is_occluded|) on |window| and its descendants if they
- // are in |tracked_windows_|.
+ // Calls SetOccluded() with |is_occluded| as argument for |window| and its
+ // descendants.
void SetWindowAndDescendantsAreOccluded(Window* window, bool is_occluded);
- // Calls SetOccluded() on |window| with |occluded| as argument if |window| is
- // in |tracked_windows_|.
- void SetOccluded(Window* window, bool occluded);
+ // Updates the occlusion state of |window| in |tracked_windows_|, based on
+ // |is_occluded| and window->IsVisible(). No-op if |window| is not in
+ // |tracked_windows_|.
+ void SetOccluded(Window* window, bool is_occluded);
// Returns true if |window| is in |tracked_windows_|.
bool WindowIsTracked(Window* window) const;
@@ -97,12 +107,15 @@ class AURA_EXPORT WindowOcclusionTracker : public ui::LayerAnimationObserver,
bool WindowIsAnimated(Window* window) const;
// If the root of |window| is not dirty and |predicate| is true, marks the
- // root of |window| as dirty. Then, calls MaybeRecomputeOcclusion().
+ // root of |window| as dirty. Then, calls MaybeComputeOcclusion().
// |predicate| is not evaluated if the root of |window| is already dirty when
// this is called.
template <typename Predicate>
- void MarkRootWindowAsDirtyAndMaybeRecomputeOcclusionIf(Window* window,
- Predicate predicate);
+ void MarkRootWindowAsDirtyAndMaybeComputeOcclusionIf(Window* window,
+ Predicate predicate);
+
+ // Marks |root_window| as dirty.
+ void MarkRootWindowAsDirty(RootWindowState* root_window_state);
// Returns true if |window| or one of its parents is in |animated_windows_|.
bool WindowOrParentIsAnimated(Window* window) const;
@@ -162,17 +175,8 @@ class AURA_EXPORT WindowOcclusionTracker : public ui::LayerAnimationObserver,
Window* new_root) override;
void OnWindowLayerRecreated(Window* window) override;
- struct RootWindowState {
- // Number of Windows whose occlusion state is tracked under this root
- // Window.
- int num_tracked_windows = 0;
-
- // Whether the occlusion state of tracked Windows under this root is stale.
- bool dirty = false;
- };
-
// Windows whose occlusion state is tracked.
- base::flat_set<Window*> tracked_windows_;
+ base::flat_map<Window*, Window::OcclusionState> tracked_windows_;
// Windows whose bounds or transform are animated.
//
@@ -186,6 +190,10 @@ class AURA_EXPORT WindowOcclusionTracker : public ui::LayerAnimationObserver,
// Root Windows of Windows in |tracked_windows_|.
base::flat_map<Window*, RootWindowState> root_windows_;
+ // Number of times that the current call to MaybeComputeOcclusion() has
+ // recomputed occlusion states. Always 0 when not in MaybeComputeOcclusion().
+ int num_times_occlusion_recomputed_ = 0;
+
DISALLOW_COPY_AND_ASSIGN(WindowOcclusionTracker);
};
diff --git a/chromium/ui/aura/window_occlusion_tracker_unittest.cc b/chromium/ui/aura/window_occlusion_tracker_unittest.cc
index 1e04ab52382..6394bd7e42f 100644
--- a/chromium/ui/aura/window_occlusion_tracker_unittest.cc
+++ b/chromium/ui/aura/window_occlusion_tracker_unittest.cc
@@ -27,17 +27,6 @@ namespace {
constexpr base::TimeDelta kTransitionDuration = base::TimeDelta::FromSeconds(3);
-enum class WindowOcclusionChangedExpectation {
- // Expect OnWindowOcclusionChanged() to be called with true as argument.
- OCCLUDED,
-
- // Expect OnWindowOcclusionChanged() to be called with false as argument.
- NOT_OCCLUDED,
-
- // Don't expect OnWindowOcclusionChanged() to be called.
- NO_CALL,
-};
-
class MockWindowDelegate : public test::ColorTestWindowDelegate {
public:
MockWindowDelegate() : test::ColorTestWindowDelegate(SK_ColorWHITE) {}
@@ -45,33 +34,24 @@ class MockWindowDelegate : public test::ColorTestWindowDelegate {
void set_window(Window* window) { window_ = window; }
- void set_expectation(WindowOcclusionChangedExpectation expectation) {
+ void set_expectation(Window::OcclusionState expectation) {
expectation_ = expectation;
}
bool is_expecting_call() const {
- return expectation_ != WindowOcclusionChangedExpectation::NO_CALL;
+ return expectation_ != Window::OcclusionState::UNKNOWN;
}
- void OnWindowOcclusionChanged(bool occluded) override {
+ void OnWindowOcclusionChanged(
+ Window::OcclusionState occlusion_state) override {
ASSERT_TRUE(window_);
- if (expectation_ == WindowOcclusionChangedExpectation::OCCLUDED) {
- EXPECT_TRUE(occluded);
- EXPECT_EQ(Window::OcclusionState::OCCLUDED, window_->occlusion_state());
- } else if (expectation_ ==
- WindowOcclusionChangedExpectation::NOT_OCCLUDED) {
- EXPECT_FALSE(occluded);
- EXPECT_EQ(Window::OcclusionState::NOT_OCCLUDED,
- window_->occlusion_state());
- } else {
- ADD_FAILURE() << "Unexpected call to OnWindowOcclusionChanged.";
- }
- expectation_ = WindowOcclusionChangedExpectation::NO_CALL;
+ EXPECT_NE(occlusion_state, Window::OcclusionState::UNKNOWN);
+ EXPECT_EQ(occlusion_state, expectation_);
+ expectation_ = Window::OcclusionState::UNKNOWN;
}
private:
- WindowOcclusionChangedExpectation expectation_ =
- WindowOcclusionChangedExpectation::NO_CALL;
+ Window::OcclusionState expectation_ = Window::OcclusionState::UNKNOWN;
Window* window_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(MockWindowDelegate);
@@ -113,34 +93,34 @@ class WindowOcclusionTrackerTest : public test::AuraTestBase {
} // namespace
-// Verify that the non-overlapping windows are notified are not occluded.
+// Verify that non-overlapping windows have a VISIBLE occlusion state.
// _____ _____
// | | | |
// |____| |____|
TEST_F(WindowOcclusionTrackerTest, NonOverlappingWindows) {
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_b, gfx::Rect(15, 0, 10, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
}
-// Verify that partially overlapping windows are not occluded.
+// Verify that partially overlapping windows have a VISIBLE occlusion state.
// ______
// |__| |
// |_____|
TEST_F(WindowOcclusionTrackerTest, PartiallyOverlappingWindow) {
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_b->is_expecting_call());
}
@@ -154,31 +134,31 @@ TEST_F(WindowOcclusionTrackerTest, PartiallyOverlappingWindow) {
TEST_F(WindowOcclusionTrackerTest, HiddenWindowCoversWindow) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b. Expect it to be non-occluded and expect window a to be
// occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 15, 15));
EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
// Hide window b. Expect window a to be non-occluded and window b to be
// occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ delegate_b->set_expectation(Window::OcclusionState::HIDDEN);
window_b->Hide();
EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
// Show window b. Expect window a to be occluded and window b to be non-
// occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
window_b->Show();
EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
@@ -193,15 +173,15 @@ TEST_F(WindowOcclusionTrackerTest, HiddenWindowCoversWindow) {
TEST_F(WindowOcclusionTrackerTest, SemiTransparentWindowCoversWindow) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b. Expect it to be non-occluded and expect window a to be
// occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 15, 15));
EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
@@ -209,13 +189,13 @@ TEST_F(WindowOcclusionTrackerTest, SemiTransparentWindowCoversWindow) {
// Change the opacity of window b to 0.5f. Expect both windows to be non-
// occluded.
EXPECT_FALSE(delegate_a->is_expecting_call());
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
window_b->layer()->SetOpacity(0.5f);
EXPECT_FALSE(delegate_a->is_expecting_call());
// Change the opacity of window b back to 1.0f. Expect window a to be
// occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
window_b->layer()->SetOpacity(1.0f);
EXPECT_FALSE(delegate_a->is_expecting_call());
}
@@ -225,24 +205,24 @@ TEST_F(WindowOcclusionTrackerTest, SemiTransparentWindowCoversWindow) {
TEST_F(WindowOcclusionTrackerTest, SemiTransparentUntrackedWindowCoversWindow) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create untracked window b. Expect window a to be occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 0, 15, 15));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Change the opacity of window b to 0.5f. Expect both windows to be non-
// occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
window_b->layer()->SetOpacity(0.5f);
EXPECT_FALSE(delegate_a->is_expecting_call());
// Change the opacity of window b back to 1.0f. Expect window a to be
// occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
window_b->layer()->SetOpacity(1.0f);
EXPECT_FALSE(delegate_a->is_expecting_call());
}
@@ -255,14 +235,14 @@ TEST_F(WindowOcclusionTrackerTest, SemiTransparentUntrackedWindowCoversWindow) {
TEST_F(WindowOcclusionTrackerTest, TwoWindowsOccludeOneWindow) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b with bounds that partially cover window a. Expect both
// windows to be non-occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
@@ -270,63 +250,115 @@ TEST_F(WindowOcclusionTrackerTest, TwoWindowsOccludeOneWindow) {
// already covered by window b. Expect window a to be occluded and window a/b
// to be non-occluded.
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_c, gfx::Rect(5, 0, 5, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_c->is_expecting_call());
}
-// Verify that when the bounds of a child window do not cover the bounds of a
-// parent window, both windows are non-occluded.
-TEST_F(WindowOcclusionTrackerTest, ChildDoesNotOccludeParent) {
+// Verify that a window and its child that are covered by a sibling are
+// occluded.
+TEST_F(WindowOcclusionTrackerTest, SiblingOccludesWindowAndChild) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
- Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
EXPECT_FALSE(delegate_a->is_expecting_call());
- // Create window b with window a as parent. The bounds of window b do not
- // fully cover window a. Expect both windows to be non-occluded.
+ // Create window b, with bounds that occlude half of its parent window a.
+ // Expect it to be non-occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
- CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 5), window_a);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 20), window_a);
EXPECT_FALSE(delegate_b->is_expecting_call());
+
+ // Create window c, with bounds that occlude window a and window b. Expect it
+ // to be non-occluded, and window a and b to be occluded.
+ MockWindowDelegate* delegate_c = new MockWindowDelegate();
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 20, 20));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+ EXPECT_FALSE(delegate_c->is_expecting_call());
}
-// Verify that when the bounds of a child window cover the bounds of a parent
-// window, the parent is occluded and the child is non-occluded. Also, verify
-// that when the parent of a window changes, occlusion states are updated.
-TEST_F(WindowOcclusionTrackerTest, ChildOccludesParent) {
+// Verify that a window with one half covered by a child and the other half
+// covered by a sibling is non-occluded.
+TEST_F(WindowOcclusionTrackerTest, ChildAndSiblingOccludeOneWindow) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+
+ // Create window b, with bounds that occlude half of its parent window a.
+ // Expect it to be non-occluded.
+ MockWindowDelegate* delegate_b = new MockWindowDelegate();
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 20), window_a);
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+
+ // Create window c, with bounds that occlude the other half of window a.
+ // Expect it to be non-occluded and expect window a to remain non-occluded.
+ MockWindowDelegate* delegate_c = new MockWindowDelegate();
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_c, gfx::Rect(10, 0, 10, 20));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+ EXPECT_FALSE(delegate_c->is_expecting_call());
+}
+
+// Verify that a window covered by 2 non-occluded children is non-occluded.
+TEST_F(WindowOcclusionTrackerTest, ChildrenOccludeOneWindow) {
+ // Create window a. Expect it to be non-occluded.
+ MockWindowDelegate* delegate_a = new MockWindowDelegate();
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+
+ // Create window b, with bounds that cover half of its parent window a. Expect
+ // it to be non-occluded.
+ MockWindowDelegate* delegate_b = new MockWindowDelegate();
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 20), window_a);
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+
+ // Create window c, with bounds that cover the other half of its parent window
+ // a. Expect it to be non-occluded. Expect window a to remain non-occluded.
+ MockWindowDelegate* delegate_c = new MockWindowDelegate();
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_c, gfx::Rect(10, 0, 10, 20), window_a);
+ EXPECT_FALSE(delegate_c->is_expecting_call());
+}
+
+// Verify that when the bounds of a child window covers the bounds of a parent
+// window but is itself visible, the parent window is visible.
+TEST_F(WindowOcclusionTrackerTest, ChildDoesNotOccludeParent) {
+ // Create window a. Expect it to be non-occluded.
+ MockWindowDelegate* delegate_a = new MockWindowDelegate();
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b with window a as parent. The bounds of window b fully cover
- // window a. Expect window a to be occluded but not window b.
+ // window a. Expect both windows to be non-occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b =
CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10), window_a);
- EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
// Create window c whose bounds don't overlap existing windows.
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(15, 0, 10, 10));
EXPECT_FALSE(delegate_c->is_expecting_call());
- // Change the parent of window b from window a to window c. Expect window a to
- // be non-occluded and window c to be occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ // Change the parent of window b from window a to window c. Expect all windows
+ // to remain non-occluded.
window_c->AddChild(window_b);
- EXPECT_FALSE(delegate_a->is_expecting_call());
- EXPECT_FALSE(delegate_c->is_expecting_call());
}
// Verify that when the stacking order of windows change, occlusion states are
@@ -335,28 +367,28 @@ TEST_F(WindowOcclusionTrackerTest, StackingChanged) {
// Create three windows that have the same bounds. Expect window on top of the
// stack to be non-occluded and other windows to be occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
EXPECT_FALSE(delegate_c->is_expecting_call());
// Move window a on top of the stack. Expect it to be non-occluded and expect
// window c to be occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ delegate_c->set_expectation(Window::OcclusionState::OCCLUDED);
root_window()->StackChildAtTop(window_a);
EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_c->is_expecting_call());
@@ -369,46 +401,47 @@ TEST_F(WindowOcclusionTrackerTest, StackingChanged) {
TEST_F(WindowOcclusionTrackerTest, TransparentParentStackingChanged) {
// Create window a which is transparent. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10),
root_window(), true);
EXPECT_FALSE(delegate_a->is_expecting_call());
- // Create window b which has the same bounds as its parent window a. Expect
- // window b to be non-occluded and window a to be occluded.
+ // Create window b which has the same bounds as its parent window a. Expect it
+ // to be non-occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10), window_a);
- EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
// Create window c which is transparent and has the same bounds as window a
// and window b. Expect it to be non-occluded.
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 10, 10),
root_window(), true);
- EXPECT_FALSE(delegate_b->is_expecting_call());
EXPECT_FALSE(delegate_c->is_expecting_call());
// Create window d which has the same bounds as its parent window c. Expect
- // window d to be non-occluded and all other windows to be occluded.
+ // window d to be non-occluded and window a and b to be occluded.
MockWindowDelegate* delegate_d = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_d->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_d->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_d, gfx::Rect(0, 0, 10, 10), window_c);
+ EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
- EXPECT_FALSE(delegate_c->is_expecting_call());
EXPECT_FALSE(delegate_d->is_expecting_call());
- // Move window a on top of the stack. Expect its child window b to be non-
- // occluded and all other windows to be occluded.
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
- delegate_d->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ // Move window a on top of the stack. Expect window a and b to be non-occluded
+ // and window c and d to be occluded.
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
+ delegate_c->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_d->set_expectation(Window::OcclusionState::OCCLUDED);
root_window()->StackChildAtTop(window_a);
+ EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
+ EXPECT_FALSE(delegate_c->is_expecting_call());
EXPECT_FALSE(delegate_d->is_expecting_call());
}
@@ -419,12 +452,12 @@ TEST_F(WindowOcclusionTrackerTest, UntrackedWindowStackingChanged) {
// Create window b. Expect it to be non-occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_b->is_expecting_call());
// Stack window a on top of window b. Expect window b to be occluded.
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::OCCLUDED);
root_window()->StackChildAtTop(window_a);
EXPECT_FALSE(delegate_b->is_expecting_call());
}
@@ -433,17 +466,17 @@ TEST_F(WindowOcclusionTrackerTest, UntrackedWindowStackingChanged) {
TEST_F(WindowOcclusionTrackerTest, BoundsChanged) {
// Create two non-overlapping windows. Expect them to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
// Move window b on top of window a. Expect window a to be occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
window_b->SetBounds(window_a->bounds());
EXPECT_FALSE(delegate_a->is_expecting_call());
}
@@ -464,26 +497,26 @@ TEST_F(WindowOcclusionTrackerTest, OccludedWindowBoundsAnimated) {
// Create 3 windows. Window a is unoccluded. Window c occludes window b.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
window_b->layer()->SetAnimator(test_controller.animator());
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_c, gfx::Rect(0, 10, 10, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
EXPECT_FALSE(delegate_c->is_expecting_call());
// Start animating the bounds of window b so that it moves on top of window a.
// Window b should be non-occluded when the animation starts.
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
window_b->SetBounds(window_a->bounds());
test_controller.Step(kTransitionDuration / 3);
EXPECT_FALSE(delegate_b->is_expecting_call());
@@ -492,7 +525,7 @@ TEST_F(WindowOcclusionTrackerTest, OccludedWindowBoundsAnimated) {
test_controller.Step(kTransitionDuration / 3);
// Window b should occlude window a at the end of the animation.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
test_controller.Step(kTransitionDuration / 3);
EXPECT_FALSE(delegate_a->is_expecting_call());
@@ -511,18 +544,18 @@ TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowBoundsAnimated) {
// Create 3 windows. Window a is unoccluded. Window c occludes window b.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(0, 10, 10, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
EXPECT_FALSE(delegate_c->is_expecting_call());
@@ -530,7 +563,7 @@ TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowBoundsAnimated) {
// Start animating the bounds of window c so that it moves on top of window a.
// Window b should be non-occluded when the animation starts.
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
window_c->SetBounds(window_a->bounds());
test_controller.Step(kTransitionDuration / 3);
EXPECT_FALSE(delegate_b->is_expecting_call());
@@ -539,7 +572,7 @@ TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowBoundsAnimated) {
test_controller.Step(kTransitionDuration / 3);
// Window c should occlude window a at the end of the animation.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
test_controller.Step(kTransitionDuration / 3);
EXPECT_FALSE(delegate_a->is_expecting_call());
@@ -551,14 +584,14 @@ TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowBoundsAnimated) {
TEST_F(WindowOcclusionTrackerTest, TransparentParentBoundsChanged) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b which doesn't overlap window a and is transparent. Expect
// it to be non-occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10),
root_window(), true);
EXPECT_FALSE(delegate_b->is_expecting_call());
@@ -566,13 +599,13 @@ TEST_F(WindowOcclusionTrackerTest, TransparentParentBoundsChanged) {
// Create window c which has window b as parent and doesn't occlude any
// window.
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 5, 5), window_b);
EXPECT_FALSE(delegate_c->is_expecting_call());
// Move window b so that window c occludes window a. Expect window a to be
// occluded and other windows to be non-occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
window_b->SetBounds(gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
}
@@ -582,7 +615,7 @@ TEST_F(WindowOcclusionTrackerTest, TransparentParentBoundsChanged) {
TEST_F(WindowOcclusionTrackerTest, UntrackedWindowBoundsChanged) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_a->is_expecting_call());
@@ -590,7 +623,7 @@ TEST_F(WindowOcclusionTrackerTest, UntrackedWindowBoundsChanged) {
Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 10, 5, 5));
// Move window b on top of window a. Expect window a to be occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
window_b->SetBounds(window_a->bounds());
EXPECT_FALSE(delegate_a->is_expecting_call());
}
@@ -600,18 +633,18 @@ TEST_F(WindowOcclusionTrackerTest, UntrackedWindowBoundsChanged) {
TEST_F(WindowOcclusionTrackerTest, TransformChanged) {
// Create two non-overlapping windows. Expect them to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 5, 5));
EXPECT_FALSE(delegate_b->is_expecting_call());
// Scale and translate window b so that it covers window a. Expect window a to
// be occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
gfx::Transform transform;
transform.Translate(0.0f, -10.0f);
transform.Scale(2.0f, 2.0f);
@@ -635,26 +668,26 @@ TEST_F(WindowOcclusionTrackerTest, OccludedWindowTransformAnimated) {
// Create 3 windows. Window a is unoccluded. Window c occludes window b.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 5, 5));
EXPECT_FALSE(delegate_b->is_expecting_call());
window_b->layer()->SetAnimator(test_controller.animator());
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_c, gfx::Rect(0, 10, 5, 5));
EXPECT_FALSE(delegate_b->is_expecting_call());
EXPECT_FALSE(delegate_c->is_expecting_call());
// Start animating the transform of window b so that it moves on top of window
// a. Window b should be non-occluded when the animation starts.
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
auto transform = std::make_unique<ui::InterpolatedScale>(
gfx::Point3F(1, 1, 1), gfx::Point3F(2.0f, 2.0f, 1));
transform->SetChild(std::make_unique<ui::InterpolatedTranslation>(
@@ -669,7 +702,7 @@ TEST_F(WindowOcclusionTrackerTest, OccludedWindowTransformAnimated) {
test_controller.Step(kTransitionDuration / 3);
// Window b should occlude window a at the end of the animation.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
test_controller.Step(kTransitionDuration / 3);
EXPECT_FALSE(delegate_a->is_expecting_call());
@@ -688,18 +721,18 @@ TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowTransformAnimated) {
// Create 3 windows. Window a is unoccluded. Window c occludes window b.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 20, 20));
EXPECT_FALSE(delegate_a->is_expecting_call());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_b, gfx::Rect(0, 20, 10, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(0, 20, 10, 10));
EXPECT_FALSE(delegate_b->is_expecting_call());
EXPECT_FALSE(delegate_c->is_expecting_call());
@@ -707,7 +740,7 @@ TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowTransformAnimated) {
// Start animating the bounds of window c so that it moves on top of window a.
// Window b should be non-occluded when the animation starts.
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
auto transform = std::make_unique<ui::InterpolatedScale>(
gfx::Point3F(1, 1, 1), gfx::Point3F(2.0f, 2.0f, 1));
transform->SetChild(std::make_unique<ui::InterpolatedTranslation>(
@@ -722,7 +755,7 @@ TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowTransformAnimated) {
test_controller.Step(kTransitionDuration / 3);
// Window c should occlude window a at the end of the animation.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
test_controller.Step(kTransitionDuration / 3);
EXPECT_FALSE(delegate_a->is_expecting_call());
@@ -734,14 +767,14 @@ TEST_F(WindowOcclusionTrackerTest, NonOccludedWindowTransformAnimated) {
TEST_F(WindowOcclusionTrackerTest, TransparentParentTransformChanged) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b which doesn't overlap window a and is transparent. Expect
// it to be non-occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10),
root_window(), true);
EXPECT_FALSE(delegate_b->is_expecting_call());
@@ -749,13 +782,13 @@ TEST_F(WindowOcclusionTrackerTest, TransparentParentTransformChanged) {
// Create window c which has window b as parent and doesn't occlude any
// window.
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 5, 5), window_b);
EXPECT_FALSE(delegate_c->is_expecting_call());
// Scale and translate window b so that window c occludes window a. Expect
// window a to be occluded and other windows to be non-occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
gfx::Transform transform;
transform.Translate(0.0f, -10.0f);
transform.Scale(2.0f, 2.0f);
@@ -768,7 +801,7 @@ TEST_F(WindowOcclusionTrackerTest, TransparentParentTransformChanged) {
TEST_F(WindowOcclusionTrackerTest, UntrackedWindowTransformChanged) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
@@ -777,7 +810,7 @@ TEST_F(WindowOcclusionTrackerTest, UntrackedWindowTransformChanged) {
// Scale and translate window b so that it occludes window a. Expect window a
// to be occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
gfx::Transform transform;
transform.Translate(0.0f, -10.0f);
transform.Scale(2.0f, 2.0f);
@@ -790,17 +823,17 @@ TEST_F(WindowOcclusionTrackerTest, UntrackedWindowTransformChanged) {
TEST_F(WindowOcclusionTrackerTest, DeleteUntrackedWindow) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b which occludes window a.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Delete window b. Expect a to be non-occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
delete window_b;
EXPECT_FALSE(delegate_a->is_expecting_call());
}
@@ -810,17 +843,17 @@ TEST_F(WindowOcclusionTrackerTest, DeleteUntrackedWindow) {
TEST_F(WindowOcclusionTrackerTest, RemoveUntrackedWindow) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b which occludes window a.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
Window* window_b = CreateUntrackedWindow(gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Delete window b. Expect a to be non-occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
root_window()->RemoveChild(window_b);
EXPECT_FALSE(delegate_a->is_expecting_call());
delete window_b;
@@ -834,7 +867,7 @@ TEST_F(WindowOcclusionTrackerTest, RemoveAndAddTrackedToRoot) {
// Create window b. Expect it to be non-occluded.
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_c->is_expecting_call());
@@ -846,19 +879,19 @@ TEST_F(WindowOcclusionTrackerTest, RemoveAndAddTrackedToRoot) {
// Create untracked window d which covers window a. Expect window a to be
// occluded.
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::OCCLUDED);
Window* window_d = CreateUntrackedWindow(gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_c->is_expecting_call());
// Move window d so that it doesn't cover window c.
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
window_d->SetBounds(gfx::Rect(0, 10, 5, 5));
EXPECT_FALSE(delegate_c->is_expecting_call());
// Stack window a on top of window c. Expect window c to be non-occluded. This
// won't work if WindowOcclusionTracked didn't register as an observer of
// window a when window c was made a child of root_window().
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::OCCLUDED);
root_window()->StackChildAtTop(window_a);
EXPECT_FALSE(delegate_c->is_expecting_call());
}
@@ -874,7 +907,7 @@ class ResizeWindowObserver : public WindowObserver {
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
ui::PropertyChangeReason reason) override {
- window_to_resize_->SetBounds(window->bounds());
+ window_to_resize_->SetBounds(old_bounds);
}
private:
@@ -891,29 +924,35 @@ class ResizeWindowObserver : public WindowObserver {
TEST_F(WindowOcclusionTrackerTest, ResizeChildFromObserver) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
- Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
- // Create window b, which is a child of window a. Expect it to be non-
- // occluded.
+ // Create window b. Expect it to be non-occluded and to occlude window a.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
- Window* window_b =
- CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 5), window_a);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
- // Create an observer that will resize window b when window a is resized.
- ResizeWindowObserver resize_window_observer(window_b);
- window_a->AddObserver(&resize_window_observer);
-
- // Resize window a. Expect window b to be resized so that window a is
+ // Create window c, which is a child of window b. Expect it to be non-
// occluded.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- window_a->SetBounds(gfx::Rect(0, 0, 20, 20));
- EXPECT_FALSE(delegate_a->is_expecting_call());
+ MockWindowDelegate* delegate_c = new MockWindowDelegate();
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_c =
+ CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 5, 5), window_b);
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+
+ // Create an observer that will resize window c when window b is resized.
+ ResizeWindowObserver resize_window_observer(window_c);
+ window_b->AddObserver(&resize_window_observer);
+
+ // Resize window b. Expect window c to be resized so that window a stays
+ // occluded. Window a should not temporarily be non-occluded.
+ window_b->SetBounds(gfx::Rect(0, 0, 5, 5));
- window_a->RemoveObserver(&resize_window_observer);
+ window_b->RemoveObserver(&resize_window_observer);
}
// Verify that the bounds of windows are changed multiple times within the scope
@@ -922,14 +961,14 @@ TEST_F(WindowOcclusionTrackerTest, ResizeChildFromObserver) {
TEST_F(WindowOcclusionTrackerTest, ScopedPauseOcclusionTracking) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b which doesn't overlap window a. Expect it to be non-
// occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 5, 5));
EXPECT_FALSE(delegate_b->is_expecting_call());
@@ -942,7 +981,7 @@ TEST_F(WindowOcclusionTrackerTest, ScopedPauseOcclusionTracking) {
window_a->SetBounds(gfx::Rect(0, 10, 5, 5));
window_b->SetBounds(window_a->bounds());
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
}
EXPECT_FALSE(delegate_a->is_expecting_call());
}
@@ -951,14 +990,14 @@ TEST_F(WindowOcclusionTrackerTest, ScopedPauseOcclusionTracking) {
TEST_F(WindowOcclusionTrackerTest, NestedScopedPauseOcclusionTracking) {
// Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b which doesn't overlap window a. Expect it to be non-
// occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 5, 5));
EXPECT_FALSE(delegate_b->is_expecting_call());
@@ -984,7 +1023,7 @@ TEST_F(WindowOcclusionTrackerTest, NestedScopedPauseOcclusionTracking) {
window_b->SetBounds(window_a->bounds());
}
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
}
EXPECT_FALSE(delegate_a->is_expecting_call());
}
@@ -1006,15 +1045,15 @@ TEST_F(WindowOcclusionTrackerTest, HierarchyOfTransforms) {
CreateUntrackedWindow(gfx::Rect(15, 16, 4, 5), window_b);
MockWindowDelegate* delegate_d = new MockWindowDelegate();
- delegate_d->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_d->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_d = CreateTrackedWindow(delegate_d, gfx::Rect(34, 36, 8, 10));
EXPECT_FALSE(delegate_d->is_expecting_call());
- delegate_d->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_d->set_expectation(Window::OcclusionState::OCCLUDED);
root_window()->StackChildAtBottom(window_d);
EXPECT_FALSE(delegate_d->is_expecting_call());
- delegate_d->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_d->set_expectation(Window::OcclusionState::VISIBLE);
window_d->SetBounds(gfx::Rect(35, 36, 8, 10));
EXPECT_FALSE(delegate_d->is_expecting_call());
@@ -1026,26 +1065,24 @@ TEST_F(WindowOcclusionTrackerTest, HierarchyOfTransforms) {
// Verify that clipping is taken into account when computing occlusion.
TEST_F(WindowOcclusionTrackerTest, Clipping) {
- // Create window b. Expect it to be non-occluded.
+ // Create window a. Expect it to be non-occluded.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
// Create window b. Expect it to be non-occluded.
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 5, 5));
EXPECT_FALSE(delegate_b->is_expecting_call());
window_b->layer()->SetMasksToBounds(true);
- // Create window c which has window b as parent. Expect it to occlude window
- // b, but not window a since it's clipped.
+ // Create window c which has window b as parent. Don't expect it to occlude
+ // window a since its bounds are clipped by window b.
MockWindowDelegate* delegate_c = new MockWindowDelegate();
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_c->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_c, gfx::Rect(0, 0, 10, 10), window_b);
- EXPECT_FALSE(delegate_b->is_expecting_call());
EXPECT_FALSE(delegate_c->is_expecting_call());
}
@@ -1064,7 +1101,7 @@ TEST_F(WindowOcclusionTrackerTest, DestroyWindowWithPendingAnimation) {
layer_animation_settings.SetTransitionDuration(kTransitionDuration);
MockWindowDelegate* delegate = new MockWindowDelegate();
- delegate->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate->set_expectation(Window::OcclusionState::VISIBLE);
Window* window = CreateTrackedWindow(delegate, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate->is_expecting_call());
window->layer()->SetAnimator(test_controller.animator());
@@ -1092,28 +1129,28 @@ TEST_F(WindowOcclusionTrackerTest, RecreateLayerOfAnimatedWindow) {
// Create 2 windows. Window b occludes window a.
MockWindowDelegate* delegate_a = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(2, 2, 1, 1));
EXPECT_FALSE(delegate_a->is_expecting_call());
window_a->layer()->SetAnimator(test_controller.animator());
MockWindowDelegate* delegate_b = new MockWindowDelegate();
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
- delegate_b->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate_a->is_expecting_call());
EXPECT_FALSE(delegate_b->is_expecting_call());
// Start animating the bounds of window a. Window a should be non-occluded
// when the animation starts.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
window_a->SetBounds(gfx::Rect(6, 6, 1, 1));
test_controller.Step(kTransitionDuration / 2);
EXPECT_FALSE(delegate_a->is_expecting_call());
// Recreate the layer of window b. Expect this to behave the same as if the
// animation was abandoned.
- delegate_a->set_expectation(WindowOcclusionChangedExpectation::OCCLUDED);
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
std::unique_ptr<ui::Layer> old_layer = window_a->RecreateLayer();
EXPECT_FALSE(delegate_a->is_expecting_call());
@@ -1143,7 +1180,7 @@ class ObserverChangingWindowBounds : public WindowObserver {
TEST_F(WindowOcclusionTrackerTest, ChangeTrackedWindowBeforeObserveAddToRoot) {
// Create a window. Expect it to be non-occluded.
MockWindowDelegate* delegate = new MockWindowDelegate();
- delegate->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate->set_expectation(Window::OcclusionState::VISIBLE);
Window* window = CreateTrackedWindow(delegate, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate->is_expecting_call());
@@ -1205,7 +1242,7 @@ TEST_F(WindowOcclusionTrackerTest,
// Create a window. Expect it to be non-occluded.
MockWindowDelegate* delegate = new MockWindowDelegate();
- delegate->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate->set_expectation(Window::OcclusionState::VISIBLE);
Window* window = CreateTrackedWindow(delegate, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate->is_expecting_call());
window->layer()->SetAnimator(test_controller.animator());
@@ -1237,7 +1274,7 @@ TEST_F(WindowOcclusionTrackerTest,
// Create a tracked window. Expect it to be non-occluded.
MockWindowDelegate* delegate = new MockWindowDelegate();
- delegate->set_expectation(WindowOcclusionChangedExpectation::NOT_OCCLUDED);
+ delegate->set_expectation(Window::OcclusionState::VISIBLE);
CreateTrackedWindow(delegate, gfx::Rect(0, 0, 10, 10));
EXPECT_FALSE(delegate->is_expecting_call());
@@ -1264,4 +1301,224 @@ TEST_F(WindowOcclusionTrackerTest,
window->layer()->GetAnimator()->StopAnimating();
}
+namespace {
+
+class WindowDelegateHidingWindowIfOccluded : public MockWindowDelegate {
+ public:
+ WindowDelegateHidingWindowIfOccluded(Window* other_window,
+ MockWindowDelegate* other_delegate)
+ : other_window_(other_window), other_delegate_(other_delegate) {}
+
+ // MockWindowDelegate:
+ void OnWindowOcclusionChanged(
+ Window::OcclusionState occlusion_state) override {
+ MockWindowDelegate::OnWindowOcclusionChanged(occlusion_state);
+ if (occlusion_state == Window::OcclusionState::HIDDEN) {
+ other_window_->Hide();
+ other_delegate_->set_expectation(Window::OcclusionState::HIDDEN);
+ }
+ }
+
+ private:
+ Window* other_window_;
+ MockWindowDelegate* other_delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowDelegateHidingWindowIfOccluded);
+};
+
+} // namespace
+
+// Verify that a window delegate can change the visibility of another window
+// when it is notified that its occlusion changed.
+TEST_F(WindowOcclusionTrackerTest, HideFromOnWindowOcclusionChanged) {
+ // Create a tracked window. Expect it to be visible.
+ MockWindowDelegate* delegate_a = new MockWindowDelegate();
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+
+ // Create a tracked window. Expect it to be visible.
+ MockWindowDelegate* delegate_b =
+ new WindowDelegateHidingWindowIfOccluded(window_a, delegate_a);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(5, 5, 10, 10));
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+
+ // Hide the tracked window. It should be able to hide |window_a|.
+ delegate_b->set_expectation(Window::OcclusionState::HIDDEN);
+ window_b->Hide();
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+ EXPECT_FALSE(window_a->IsVisible());
+ EXPECT_FALSE(window_b->IsVisible());
+}
+
+namespace {
+
+class WindowDelegateDeletingWindow : public MockWindowDelegate {
+ public:
+ WindowDelegateDeletingWindow() = default;
+
+ void set_other_window(Window* other_window) { other_window_ = other_window; }
+
+ // MockWindowDelegate:
+ void OnWindowOcclusionChanged(
+ Window::OcclusionState occlusion_state) override {
+ MockWindowDelegate::OnWindowOcclusionChanged(occlusion_state);
+ if (occlusion_state == Window::OcclusionState::OCCLUDED) {
+ delete other_window_;
+ other_window_ = nullptr;
+ }
+ }
+
+ private:
+ Window* other_window_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowDelegateDeletingWindow);
+};
+
+} // namespace
+
+// Verify that a window can delete a window that is on top of it when it is
+// notified that its occlusion changed (a crash would occur if
+// WindowOcclusionTracker accessed that window after it was deleted).
+TEST_F(WindowOcclusionTrackerTest, DeleteFromOnWindowOcclusionChanged) {
+ // Create a tracked window. Expect it to be visible.
+ WindowDelegateDeletingWindow* delegate_a = new WindowDelegateDeletingWindow();
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+
+ // Create a tracked window. Expect it to be visible.
+ MockWindowDelegate* delegate_b = new MockWindowDelegate();
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_b = CreateTrackedWindow(delegate_b, gfx::Rect(10, 0, 10, 10));
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+
+ // Create a tracked window. Expect it to be visible.
+ MockWindowDelegate* delegate_c = new MockWindowDelegate();
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(20, 0, 10, 10));
+ EXPECT_FALSE(delegate_c->is_expecting_call());
+
+ // |window_c| will be deleted when |window_a| is occluded.
+ delegate_a->set_other_window(window_c);
+
+ // Move |window_b| on top of |window_a|.
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ window_b->SetBounds(window_a->bounds());
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+}
+
+namespace {
+
+class WindowDelegateChangingWindowVisibility : public MockWindowDelegate {
+ public:
+ WindowDelegateChangingWindowVisibility() = default;
+
+ void set_window_to_update(Window* window) { window_to_update_ = window; }
+
+ // MockWindowDelegate:
+ void OnWindowOcclusionChanged(
+ Window::OcclusionState occlusion_state) override {
+ MockWindowDelegate::OnWindowOcclusionChanged(occlusion_state);
+ if (!window_to_update_)
+ return;
+
+ if (window_to_update_->IsVisible()) {
+ window_to_update_->Hide();
+ EXPECT_FALSE(did_set_expectation_from_occlusion_changed_);
+ set_expectation(Window::OcclusionState::HIDDEN);
+ did_set_expectation_from_occlusion_changed_ = true;
+ } else {
+ window_to_update_->Show();
+ if (!did_set_expectation_from_occlusion_changed_)
+ set_expectation(Window::OcclusionState::VISIBLE);
+ }
+ }
+
+ private:
+ Window* window_to_update_ = nullptr;
+ bool did_set_expectation_from_occlusion_changed_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(WindowDelegateChangingWindowVisibility);
+};
+} // namespace
+
+// Verify that if a window changes its visibility every time it is notified that
+// its occlusion state changed, the occlusion state of all IsVisible() windows
+// is set to NOT_OCCLUDED and no infinite loop is entered.
+TEST_F(WindowOcclusionTrackerTest, OcclusionStatesDontBecomeStable) {
+ // Create 2 superposed tracked windows.
+ MockWindowDelegate* delegate_a = new MockWindowDelegate();
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+
+ MockWindowDelegate* delegate_b = new MockWindowDelegate();
+ delegate_a->set_expectation(Window::OcclusionState::OCCLUDED);
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_b, gfx::Rect(0, 0, 10, 10));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+
+ // Create a hidden tracked window.
+ MockWindowDelegate* delegate_c = new MockWindowDelegate();
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_c = CreateTrackedWindow(delegate_c, gfx::Rect(10, 0, 10, 10));
+ EXPECT_FALSE(delegate_c->is_expecting_call());
+ delegate_c->set_expectation(Window::OcclusionState::HIDDEN);
+ window_c->Hide();
+ EXPECT_FALSE(delegate_c->is_expecting_call());
+
+ // Create a tracked window. Expect it to be non-occluded.
+ auto* delegate_d = new WindowDelegateChangingWindowVisibility();
+ delegate_d->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_d = CreateTrackedWindow(delegate_d, gfx::Rect(20, 0, 10, 10));
+ EXPECT_FALSE(delegate_d->is_expecting_call());
+
+ // Store a pointer to |window_d| in |delegate_d|. This will cause a call to
+ // Show()/Hide() every time |delegate_d| is notified of an occlusion change.
+ delegate_d->set_window_to_update(window_d);
+
+ // Hide |window_d|. This will cause occlusion to be recomputed multiple times.
+ // Once the maximum number of times that occlusion can be recomputed is
+ // reached, the occlusion state of all IsVisible() windows should be set to
+ // NOT_OCCLUDED.
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ delegate_d->set_expectation(Window::OcclusionState::HIDDEN);
+ window_d->Hide();
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+ EXPECT_FALSE(delegate_d->is_expecting_call());
+}
+
+// Verify that the occlusion states are correctly update when a branch of the
+// tree is hidden.
+TEST_F(WindowOcclusionTrackerTest, HideTreeBranch) {
+ // Create a branch of 3 tracked windows. Expect them to be visible.
+ MockWindowDelegate* delegate_a = new MockWindowDelegate();
+ delegate_a->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_a = CreateTrackedWindow(delegate_a, gfx::Rect(0, 0, 10, 10));
+ EXPECT_FALSE(delegate_a->is_expecting_call());
+
+ MockWindowDelegate* delegate_b = new MockWindowDelegate();
+ delegate_b->set_expectation(Window::OcclusionState::VISIBLE);
+ Window* window_b =
+ CreateTrackedWindow(delegate_b, gfx::Rect(0, 10, 10, 10), window_a);
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+
+ MockWindowDelegate* delegate_c = new MockWindowDelegate();
+ delegate_c->set_expectation(Window::OcclusionState::VISIBLE);
+ CreateTrackedWindow(delegate_c, gfx::Rect(0, 20, 10, 10), window_b);
+ EXPECT_FALSE(delegate_c->is_expecting_call());
+
+ // Hide |window_b| (and hence |window_c|). Expect |window_b| and |window_c| to
+ // be hidden.
+ delegate_b->set_expectation(Window::OcclusionState::HIDDEN);
+ delegate_c->set_expectation(Window::OcclusionState::HIDDEN);
+ window_b->Hide();
+ EXPECT_FALSE(delegate_b->is_expecting_call());
+ EXPECT_FALSE(delegate_c->is_expecting_call());
+}
+
} // namespace aura
diff --git a/chromium/ui/aura/window_port.h b/chromium/ui/aura/window_port.h
index 46e4c1bb811..a57c5134920 100644
--- a/chromium/ui/aura/window_port.h
+++ b/chromium/ui/aura/window_port.h
@@ -85,9 +85,6 @@ class AURA_EXPORT WindowPort {
virtual std::unique_ptr<cc::LayerTreeFrameSink>
CreateLayerTreeFrameSink() = 0;
- // Get the current viz::SurfaceId.
- virtual viz::SurfaceId GetSurfaceId() const = 0;
-
// Forces the window to allocate a new viz::LocalSurfaceId for the next
// CompositorFrame submission in anticipation of a synchronization operation
// that does not involve a resize or a device scale factor change.
@@ -98,12 +95,6 @@ class AURA_EXPORT WindowPort {
// factor.
virtual const viz::LocalSurfaceId& GetLocalSurfaceId() = 0;
- // This can return invalid FrameSinkId.
- virtual viz::FrameSinkId GetFrameSinkId() const = 0;
-
- virtual void OnWindowAddedToRootWindow() = 0;
- virtual void OnWillRemoveWindowFromRootWindow() = 0;
-
virtual void OnEventTargetingPolicyChanged() = 0;
// See description of function with same name in transient_window_client.
diff --git a/chromium/ui/aura/window_port_for_shutdown.cc b/chromium/ui/aura/window_port_for_shutdown.cc
index c29e4faad4e..a11a2eed846 100644
--- a/chromium/ui/aura/window_port_for_shutdown.cc
+++ b/chromium/ui/aura/window_port_for_shutdown.cc
@@ -57,24 +57,12 @@ WindowPortForShutdown::CreateLayerTreeFrameSink() {
return nullptr;
}
-viz::SurfaceId WindowPortForShutdown::GetSurfaceId() const {
- return viz::SurfaceId();
-}
-
void WindowPortForShutdown::AllocateLocalSurfaceId() {}
const viz::LocalSurfaceId& WindowPortForShutdown::GetLocalSurfaceId() {
return local_surface_id_;
}
-viz::FrameSinkId WindowPortForShutdown::GetFrameSinkId() const {
- return frame_sink_id_;
-}
-
-void WindowPortForShutdown::OnWindowAddedToRootWindow() {}
-
-void WindowPortForShutdown::OnWillRemoveWindowFromRootWindow() {}
-
void WindowPortForShutdown::OnEventTargetingPolicyChanged() {}
bool WindowPortForShutdown::ShouldRestackTransientChildren() {
diff --git a/chromium/ui/aura/window_port_for_shutdown.h b/chromium/ui/aura/window_port_for_shutdown.h
index f9b0be555e5..e3d97a5b64d 100644
--- a/chromium/ui/aura/window_port_for_shutdown.h
+++ b/chromium/ui/aura/window_port_for_shutdown.h
@@ -39,18 +39,13 @@ class WindowPortForShutdown : public WindowPort {
int64_t old_value,
std::unique_ptr<ui::PropertyData> data) override;
std::unique_ptr<cc::LayerTreeFrameSink> CreateLayerTreeFrameSink() override;
- viz::SurfaceId GetSurfaceId() const override;
void AllocateLocalSurfaceId() override;
const viz::LocalSurfaceId& GetLocalSurfaceId() override;
- viz::FrameSinkId GetFrameSinkId() const override;
- void OnWindowAddedToRootWindow() override;
- void OnWillRemoveWindowFromRootWindow() override;
void OnEventTargetingPolicyChanged() override;
bool ShouldRestackTransientChildren() override;
private:
viz::LocalSurfaceId local_surface_id_;
- viz::FrameSinkId frame_sink_id_;
DISALLOW_COPY_AND_ASSIGN(WindowPortForShutdown);
};
diff --git a/chromium/ui/aura/window_targeter_unittest.cc b/chromium/ui/aura/window_targeter_unittest.cc
index d81560ae534..a87f7647241 100644
--- a/chromium/ui/aura/window_targeter_unittest.cc
+++ b/chromium/ui/aura/window_targeter_unittest.cc
@@ -303,6 +303,6 @@ INSTANTIATE_TEST_CASE_P(/* no prefix */,
WindowTargeterTest,
::testing::Values(test::BackendType::CLASSIC,
test::BackendType::MUS,
- test::BackendType::MUS_HOSTING_VIZ));
+ test::BackendType::MASH));
} // namespace aura
diff --git a/chromium/ui/aura/window_tree_host.cc b/chromium/ui/aura/window_tree_host.cc
index de85e1d8f2d..cbade2495bb 100644
--- a/chromium/ui/aura/window_tree_host.cc
+++ b/chromium/ui/aura/window_tree_host.cc
@@ -12,6 +12,7 @@
#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
+#include "ui/aura/scoped_keyboard_hook.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_port.h"
@@ -242,6 +243,13 @@ void WindowTreeHost::Hide() {
compositor()->SetVisible(false);
}
+std::unique_ptr<ScopedKeyboardHook> WindowTreeHost::CaptureSystemKeyEvents(
+ base::Optional<base::flat_set<int>> keys) {
+ if (CaptureSystemKeyEventsImpl(std::move(keys)))
+ return std::make_unique<ScopedKeyboardHook>(weak_factory_.GetWeakPtr());
+ return nullptr;
+}
+
////////////////////////////////////////////////////////////////////////////////
// WindowTreeHost, protected:
@@ -252,7 +260,8 @@ WindowTreeHost::WindowTreeHost(std::unique_ptr<WindowPort> window_port)
: window_(new Window(nullptr, std::move(window_port))),
last_cursor_(ui::CursorType::kNull),
input_method_(nullptr),
- owned_input_method_(false) {
+ owned_input_method_(false),
+ weak_factory_(this) {
display::Screen::GetScreen()->AddObserver(this);
}
diff --git a/chromium/ui/aura/window_tree_host.h b/chromium/ui/aura/window_tree_host.h
index b83f6494fb1..4a3e90b7b55 100644
--- a/chromium/ui/aura/window_tree_host.h
+++ b/chromium/ui/aura/window_tree_host.h
@@ -8,11 +8,13 @@
#include <stdint.h>
#include <memory>
-#include <vector>
+#include "base/containers/flat_set.h"
#include "base/event_types.h"
#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
+#include "base/optional.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "ui/aura/aura_export.h"
#include "ui/base/cursor/cursor.h"
@@ -39,6 +41,8 @@ class ViewProp;
}
namespace aura {
+class ScopedKeyboardHook;
+
namespace test {
class WindowTreeHostTestApi;
}
@@ -197,7 +201,15 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
// Releases OS capture of the root window.
virtual void ReleaseCapture() = 0;
+ // Requests that |keys| be intercepted at the platform level and routed
+ // directly to the web content. If |keys| is empty, all keys will be
+ // intercepted. Returns a ScopedKeyboardHook instance which stops capturing
+ // system key events when destroyed.
+ std::unique_ptr<ScopedKeyboardHook> CaptureSystemKeyEvents(
+ base::Optional<base::flat_set<int>> keys);
+
protected:
+ friend class ScopedKeyboardHook;
friend class TestScreen; // TODO(beng): see if we can remove/consolidate.
WindowTreeHost();
@@ -252,6 +264,13 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t metrics) override;
+ // Begins capturing system key events. Returns true if successful.
+ virtual bool CaptureSystemKeyEventsImpl(
+ base::Optional<base::flat_set<int>> keys) = 0;
+
+ // Stops capturing system keyboard events.
+ virtual void ReleaseSystemKeyEventCapture() = 0;
+
protected:
const base::ObserverList<WindowTreeHostObserver>& observers() const {
return observers_;
@@ -308,6 +327,8 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
// Set to true if this WindowTreeHost is currently holding pointer moves.
bool holding_pointer_moves_ = false;
+ base::WeakPtrFactory<WindowTreeHost> weak_factory_;
+
DISALLOW_COPY_AND_ASSIGN(WindowTreeHost);
};
diff --git a/chromium/ui/aura/window_tree_host_platform.cc b/chromium/ui/aura/window_tree_host_platform.cc
index 9f25b25e22e..43294f6f232 100644
--- a/chromium/ui/aura/window_tree_host_platform.cc
+++ b/chromium/ui/aura/window_tree_host_platform.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/macros.h"
#include "base/run_loop.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
@@ -113,6 +114,14 @@ void WindowTreeHostPlatform::ReleaseCapture() {
platform_window_->ReleaseCapture();
}
+bool WindowTreeHostPlatform::CaptureSystemKeyEventsImpl(
+ base::Optional<base::flat_set<int>> native_key_codes) {
+ NOTIMPLEMENTED();
+ return false;
+}
+
+void WindowTreeHostPlatform::ReleaseSystemKeyEventCapture() {}
+
void WindowTreeHostPlatform::SetCursorNative(gfx::NativeCursor cursor) {
if (cursor == current_cursor_)
return;
diff --git a/chromium/ui/aura/window_tree_host_platform.h b/chromium/ui/aura/window_tree_host_platform.h
index 13ef6ca1e57..5935d1634b6 100644
--- a/chromium/ui/aura/window_tree_host_platform.h
+++ b/chromium/ui/aura/window_tree_host_platform.h
@@ -63,6 +63,9 @@ class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost,
float device_pixel_ratio) override;
void OnAcceleratedWidgetDestroyed() override;
void OnActivationChanged(bool active) override;
+ bool CaptureSystemKeyEventsImpl(
+ base::Optional<base::flat_set<int>> native_key_codes) override;
+ void ReleaseSystemKeyEventCapture() override;
private:
gfx::AcceleratedWidget widget_;
diff --git a/chromium/ui/aura/window_unittest.cc b/chromium/ui/aura/window_unittest.cc
index c9aec7a3001..375e2ddc552 100644
--- a/chromium/ui/aura/window_unittest.cc
+++ b/chromium/ui/aura/window_unittest.cc
@@ -32,6 +32,7 @@
#include "ui/aura/window_delegate.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_observer.h"
+#include "ui/aura/window_tracker.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/class_property.h"
#include "ui/base/hit_test.h"
@@ -113,6 +114,7 @@ DEFINE_UI_CLASS_PROPERTY_TYPE(DeletionTestProperty*);
namespace aura {
namespace test {
+namespace {
class WindowTest : public AuraTestBaseWithType {
public:
@@ -140,8 +142,6 @@ class WindowTest : public AuraTestBaseWithType {
DISALLOW_COPY_AND_ASSIGN(WindowTest);
};
-namespace {
-
// Used for verifying destruction methods are invoked.
class DestroyTrackingDelegateImpl : public TestWindowDelegate {
public:
@@ -316,8 +316,6 @@ void OffsetBounds(Window* window, int horizontal, int vertical) {
window->SetBounds(bounds);
}
-} // namespace
-
TEST_P(WindowTest, GetChildById) {
std::unique_ptr<Window> w1(CreateTestWindowWithId(1, root_window()));
std::unique_ptr<Window> w11(CreateTestWindowWithId(11, w1.get()));
@@ -424,18 +422,19 @@ TEST_P(WindowTest, ContainsMouse) {
// Tests that the root window gets a valid LocalSurfaceId.
TEST_P(WindowTest, RootWindowHasValidLocalSurfaceId) {
// When mus is hosting viz, the LocalSurfaceId is sent from mus.
- if (GetParam() == BackendType::MUS_HOSTING_VIZ)
+ if (GetParam() == BackendType::MASH)
return;
EXPECT_TRUE(root_window()->GetLocalSurfaceId().is_valid());
}
TEST_P(WindowTest, WindowEmbeddingClientHasValidLocalSurfaceId) {
// When mus is hosting viz, the LocalSurfaceId is sent from mus.
- if (GetParam() == BackendType::MUS_HOSTING_VIZ)
+ if (GetParam() == BackendType::MASH)
return;
std::unique_ptr<Window> window(CreateTestWindow(
SK_ColorWHITE, 1, gfx::Rect(10, 10, 300, 200), root_window()));
- window->set_embed_frame_sink_id(viz::FrameSinkId(0, 1));
+ test::WindowTestApi(window.get()).DisableFrameSinkRegistration();
+ window->SetEmbedFrameSinkId(viz::FrameSinkId(0, 1));
EXPECT_TRUE(window->GetLocalSurfaceId().is_valid());
}
@@ -1673,8 +1672,6 @@ TEST_P(WindowTest, Property) {
EXPECT_EQ(nullptr, w->GetNativeWindowProperty(native_prop_key));
}
-namespace {
-
class DeletionTestLayoutManager : public LayoutManager {
public:
explicit DeletionTestLayoutManager(DeletionTracker* tracker)
@@ -1696,8 +1693,6 @@ class DeletionTestLayoutManager : public LayoutManager {
DISALLOW_COPY_AND_ASSIGN(DeletionTestLayoutManager);
};
-} // namespace
-
TEST_P(WindowTest, DeleteLayoutManagerBeforeOwnedProps) {
DeletionTracker tracker;
{
@@ -2696,8 +2691,6 @@ TEST_P(WindowTest, OwnedByParentFalse) {
EXPECT_EQ(NULL, w2->parent());
}
-namespace {
-
// Used By DeleteWindowFromOnWindowDestroyed. Destroys a Window from
// OnWindowDestroyed().
class OwningWindowDelegate : public TestWindowDelegate {
@@ -2716,8 +2709,6 @@ class OwningWindowDelegate : public TestWindowDelegate {
DISALLOW_COPY_AND_ASSIGN(OwningWindowDelegate);
};
-} // namespace
-
// Creates a window with two child windows. When the first child window is
// destroyed (WindowDelegate::OnWindowDestroyed) it deletes the second child.
// This synthesizes BrowserView and the status bubble. Both are children of the
@@ -2737,7 +2728,52 @@ TEST_P(WindowTest, DeleteWindowFromOnWindowDestroyed) {
parent.reset();
}
-namespace {
+// WindowObserver implementation that deletes a window in
+// OnWindowVisibilityChanged().
+class DeleteOnVisibilityChangedObserver : public WindowObserver {
+ public:
+ // |to_observe| is the Window this is added as an observer to. When
+ // OnWindowVisibilityChanged() is called |to_delete| is deleted.
+ explicit DeleteOnVisibilityChangedObserver(Window* to_observe,
+ Window* to_delete)
+ : to_observe_(to_observe), to_delete_(to_delete) {
+ to_observe_->AddObserver(this);
+ }
+ ~DeleteOnVisibilityChangedObserver() override {
+ // OnWindowVisibilityChanged() should have been called.
+ DCHECK(!to_delete_);
+ }
+
+ // WindowObserver:
+ void OnWindowVisibilityChanged(Window* window, bool visible) override {
+ to_observe_->RemoveObserver(this);
+ delete to_delete_;
+ to_delete_ = nullptr;
+ }
+
+ private:
+ Window* to_observe_;
+ Window* to_delete_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeleteOnVisibilityChangedObserver);
+};
+
+TEST_P(WindowTest, DeleteParentWindowFromOnWindowVisibiltyChanged) {
+ WindowTracker tracker;
+ Window* root = CreateTestWindowWithId(0, nullptr);
+ tracker.Add(root);
+ Window* child1 = CreateTestWindowWithId(0, root);
+ tracker.Add(child1);
+ tracker.Add(CreateTestWindowWithId(0, root));
+
+ // This deletes |root| (the parent) when OnWindowVisibilityChanged() is
+ // received by |child1|.
+ DeleteOnVisibilityChangedObserver deletion_observer(child1, root);
+ // The Hide() calls trigger deleting |root|, which should delete the whole
+ // tree.
+ root->Hide();
+ EXPECT_TRUE(tracker.windows().empty());
+}
// Used by DelegateNotifiedAsBoundsChange to verify OnBoundsChanged() is
// invoked.
@@ -2763,8 +2799,6 @@ class BoundsChangeDelegate : public TestWindowDelegate {
DISALLOW_COPY_AND_ASSIGN(BoundsChangeDelegate);
};
-} // namespace
-
// Verifies the delegate is notified when the actual bounds of the layer
// change.
TEST_P(WindowTest, DelegateNotifiedAsBoundsChange) {
@@ -2843,8 +2877,6 @@ TEST_P(WindowTest, DelegateNotifiedAsBoundsChangeInHiddenLayer) {
EXPECT_NE("0,0 100x100", window->layer()->bounds().ToString());
}
-namespace {
-
// Used by AddChildNotifications to track notification counts.
class AddChildNotificationsObserver : public WindowObserver {
public:
@@ -2871,8 +2903,6 @@ class AddChildNotificationsObserver : public WindowObserver {
DISALLOW_COPY_AND_ASSIGN(AddChildNotificationsObserver);
};
-} // namespace
-
// Assertions around when root window notifications are sent.
TEST_P(WindowTest, AddChildNotifications) {
AddChildNotificationsObserver observer;
@@ -3094,8 +3124,6 @@ TEST_P(WindowTest, OnWindowHierarchyChange) {
}
}
-namespace {
-
class TestLayerAnimationObserver : public ui::LayerAnimationObserver {
public:
TestLayerAnimationObserver()
@@ -3130,8 +3158,6 @@ class TestLayerAnimationObserver : public ui::LayerAnimationObserver {
DISALLOW_COPY_AND_ASSIGN(TestLayerAnimationObserver);
};
-} // namespace
-
TEST_P(WindowTest, WindowDestroyCompletesAnimations) {
ui::ScopedAnimationDurationScaleMode test_duration_mode(
ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
@@ -3240,13 +3266,14 @@ INSTANTIATE_TEST_CASE_P(/* no prefix */,
WindowTest,
::testing::Values(BackendType::CLASSIC,
BackendType::MUS,
- BackendType::MUS_HOSTING_VIZ));
+ BackendType::MASH));
INSTANTIATE_TEST_CASE_P(/* no prefix */,
WindowObserverTest,
::testing::Values(BackendType::CLASSIC,
BackendType::MUS,
- BackendType::MUS_HOSTING_VIZ));
+ BackendType::MASH));
+} // namespace
} // namespace test
} // namespace aura
diff --git a/chromium/ui/base/BUILD.gn b/chromium/ui/base/BUILD.gn
index 14011a657ff..b5904fe8e63 100644
--- a/chromium/ui/base/BUILD.gn
+++ b/chromium/ui/base/BUILD.gn
@@ -65,6 +65,8 @@ component("base") {
output_name = "ui_base"
sources = [
+ "accelerators/media_keys_listener.cc",
+ "accelerators/media_keys_listener.h",
"accelerators/menu_label_accelerator_util_linux.cc",
"accelerators/menu_label_accelerator_util_linux.h",
"accelerators/platform_accelerator.h",
@@ -141,6 +143,8 @@ component("base") {
"cocoa/remote_layer_api.mm",
"cocoa/scoped_cg_context_smooth_fonts.h",
"cocoa/scoped_cg_context_smooth_fonts.mm",
+ "cocoa/text_services_context_menu.cc",
+ "cocoa/text_services_context_menu.h",
"cocoa/three_part_image.h",
"cocoa/three_part_image.mm",
"cocoa/tool_tip_base_view.h",
@@ -213,7 +217,6 @@ component("base") {
"l10n/time_format.h",
"layout.cc",
"layout.h",
- "layout_mac.mm",
"material_design/material_design_controller.cc",
"material_design/material_design_controller.h",
"models/button_menu_item_model.cc",
@@ -291,6 +294,8 @@ component("base") {
"win/accessibility_misc_utils.cc",
"win/accessibility_misc_utils.h",
"win/atl_module.h",
+ "win/direct_manipulation.cc",
+ "win/direct_manipulation.h",
"win/foreground_helper.cc",
"win/foreground_helper.h",
"win/hidden_window.cc",
@@ -369,6 +374,12 @@ component("base") {
]
}
+ if (is_mac) {
+ sources += [ "accelerators/media_keys_listener_mac.mm" ]
+ } else {
+ sources += [ "accelerators/media_keys_listener_stub.cc" ]
+ }
+
if (is_win) {
sources += [ "touch/touch_device_win.cc" ]
} else if (is_android) {
@@ -875,10 +886,6 @@ test("ui_base_unittests") {
if (use_x11) {
sources += [ "ime/composition_text_util_pango_unittest.cc" ]
}
- if (is_chromeos) {
- # These were already removed in the non-chromeos case.
- sources -= [ "ime/input_method_chromeos_unittest.cc" ]
- }
}
# TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
diff --git a/chromium/ui/base/accelerators/media_keys_listener.cc b/chromium/ui/base/accelerators/media_keys_listener.cc
new file mode 100644
index 00000000000..4429e44f6af
--- /dev/null
+++ b/chromium/ui/base/accelerators/media_keys_listener.cc
@@ -0,0 +1,13 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/accelerators/media_keys_listener.h"
+
+namespace ui {
+
+MediaKeysListener::Delegate::~Delegate() = default;
+
+MediaKeysListener::~MediaKeysListener() = default;
+
+} // namespace ui
diff --git a/chromium/ui/base/accelerators/media_keys_listener.h b/chromium/ui/base/accelerators/media_keys_listener.h
new file mode 100644
index 00000000000..5ffeafc5511
--- /dev/null
+++ b/chromium/ui/base/accelerators/media_keys_listener.h
@@ -0,0 +1,60 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_BASE_ACCELERATORS_MEDIA_KEYS_LISTENER_H_
+#define UI_BASE_ACCELERATORS_MEDIA_KEYS_LISTENER_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "ui/base/ui_base_export.h"
+
+namespace ui {
+
+class Accelerator;
+
+// Create MediaKeyListener to receive accelerators on media keys.
+class UI_BASE_EXPORT MediaKeysListener {
+ public:
+ enum class Scope {
+ kGlobal, // Listener works whenever application in focus or not.
+ kFocused, // Listener only works whan application has focus.
+ };
+
+ enum class MediaKeysHandleResult {
+ kIgnore, // Ignore the key and continue propagation to other system apps.
+ kSuppressPropagation, // Handled. Prevent propagation to other system
+ // apps.
+ };
+
+ // Media keys accelerators receiver.
+ class UI_BASE_EXPORT Delegate {
+ public:
+ virtual ~Delegate();
+
+ // Called on media key event.
+ // Return result - whether event is handled and propagation of event should
+ // be suppressed.
+ virtual MediaKeysHandleResult OnMediaKeysAccelerator(
+ const Accelerator& accelerator) = 0;
+ };
+
+ // Can return nullptr if media keys listening is not implemented.
+ // Currently implemented only on mac.
+ static std::unique_ptr<MediaKeysListener> Create(Delegate* delegate,
+ Scope scope);
+
+ virtual ~MediaKeysListener();
+
+ // Start receiving media keys events.
+ virtual void StartWatchingMediaKeys() = 0;
+ // Stop receiving media keys events.
+ virtual void StopWatchingMediaKeys() = 0;
+ // Whether listener started receiving media keys events.
+ virtual bool IsWatchingMediaKeys() const = 0;
+};
+
+} // namespace ui
+
+#endif // UI_BASE_ACCELERATORS_MEDIA_KEYS_LISTENER_H_
diff --git a/chromium/ui/base/accelerators/media_keys_listener_mac.mm b/chromium/ui/base/accelerators/media_keys_listener_mac.mm
new file mode 100644
index 00000000000..cd595b0c017
--- /dev/null
+++ b/chromium/ui/base/accelerators/media_keys_listener_mac.mm
@@ -0,0 +1,214 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/accelerators/media_keys_listener.h"
+
+#include <ApplicationServices/ApplicationServices.h>
+#include <Carbon/Carbon.h>
+#import <Cocoa/Cocoa.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/hidsystem/ev_keymap.h>
+
+#include "ui/base/accelerators/accelerator.h"
+
+namespace ui {
+
+namespace {
+
+// The media keys subtype. No official docs found, but widely known.
+// http://lists.apple.com/archives/cocoa-dev/2007/Aug/msg00499.html
+const int kSystemDefinedEventMediaKeysSubtype = 8;
+
+ui::KeyboardCode MediaKeyCodeToKeyboardCode(int key_code) {
+ switch (key_code) {
+ case NX_KEYTYPE_PLAY:
+ return ui::VKEY_MEDIA_PLAY_PAUSE;
+ case NX_KEYTYPE_PREVIOUS:
+ case NX_KEYTYPE_REWIND:
+ return ui::VKEY_MEDIA_PREV_TRACK;
+ case NX_KEYTYPE_NEXT:
+ case NX_KEYTYPE_FAST:
+ return ui::VKEY_MEDIA_NEXT_TRACK;
+ }
+ return ui::VKEY_UNKNOWN;
+}
+
+class MediaKeysListenerImpl : public MediaKeysListener {
+ public:
+ MediaKeysListenerImpl(MediaKeysListener::Delegate* delegate, Scope scope);
+
+ ~MediaKeysListenerImpl() override;
+
+ // MediaKeysListener:
+ void StartWatchingMediaKeys() override;
+ void StopWatchingMediaKeys() override;
+ bool IsWatchingMediaKeys() const override;
+
+ private:
+ // Callback on media key event.
+ MediaKeysHandleResult OnMediaKeyEvent(int media_key_code);
+
+ // The callback for when an event tap happens.
+ static CGEventRef EventTapCallback(CGEventTapProxy proxy,
+ CGEventType type,
+ CGEventRef event,
+ void* refcon);
+
+ MediaKeysListener::Delegate* delegate_;
+ const Scope scope_;
+ // Event tap for intercepting mac media keys.
+ CFMachPortRef event_tap_ = nullptr;
+ CFRunLoopSourceRef event_tap_source_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaKeysListenerImpl);
+};
+
+MediaKeysListenerImpl::MediaKeysListenerImpl(
+ MediaKeysListener::Delegate* delegate,
+ Scope scope)
+ : delegate_(delegate), scope_(scope) {
+ CHECK_NE(delegate_, nullptr);
+}
+
+MediaKeysListenerImpl::~MediaKeysListenerImpl() {
+ if (event_tap_) {
+ StopWatchingMediaKeys();
+ }
+}
+
+void MediaKeysListenerImpl::StartWatchingMediaKeys() {
+ // Make sure there's no existing event tap.
+ if (event_tap_) {
+ return;
+ }
+ DCHECK_EQ(event_tap_, nullptr);
+ DCHECK_EQ(event_tap_source_, nullptr);
+
+ // Add an event tap to intercept the system defined media key events.
+ event_tap_ = CGEventTapCreate(
+ kCGSessionEventTap, kCGHeadInsertEventTap, kCGEventTapOptionDefault,
+ CGEventMaskBit(NX_SYSDEFINED), EventTapCallback, this);
+ if (event_tap_ == nullptr) {
+ LOG(ERROR) << "Error: failed to create event tap.";
+ return;
+ }
+
+ event_tap_source_ =
+ CFMachPortCreateRunLoopSource(kCFAllocatorSystemDefault, event_tap_, 0);
+ if (event_tap_source_ == nullptr) {
+ LOG(ERROR) << "Error: failed to create new run loop source.";
+ return;
+ }
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), event_tap_source_,
+ kCFRunLoopCommonModes);
+}
+
+void MediaKeysListenerImpl::StopWatchingMediaKeys() {
+ if (!event_tap_) {
+ return;
+ }
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), event_tap_source_,
+ kCFRunLoopCommonModes);
+ // Ensure both event tap and source are initialized.
+ DCHECK_NE(event_tap_, nullptr);
+ DCHECK_NE(event_tap_source_, nullptr);
+
+ // Invalidate the event tap.
+ CFMachPortInvalidate(event_tap_);
+ CFRelease(event_tap_);
+ event_tap_ = nullptr;
+
+ // Release the event tap source.
+ CFRelease(event_tap_source_);
+ event_tap_source_ = nullptr;
+}
+
+bool MediaKeysListenerImpl::IsWatchingMediaKeys() const {
+ return event_tap_ != nullptr;
+}
+
+MediaKeysListener::MediaKeysHandleResult MediaKeysListenerImpl::OnMediaKeyEvent(
+ int media_key_code) {
+ const ui::KeyboardCode key_code = MediaKeyCodeToKeyboardCode(media_key_code);
+ // Create an accelerator corresponding to the keyCode.
+ const ui::Accelerator accelerator(key_code, 0);
+ return delegate_->OnMediaKeysAccelerator(accelerator);
+}
+
+// Processed events should propagate if they aren't handled by any listeners.
+// For events that don't matter, this handler should return as quickly as
+// possible.
+// Returning event causes the event to propagate to other applications.
+// Returning nullptr prevents the event from propagating.
+// static
+CGEventRef MediaKeysListenerImpl::EventTapCallback(CGEventTapProxy proxy,
+ CGEventType type,
+ CGEventRef event,
+ void* refcon) {
+ MediaKeysListenerImpl* shortcut_listener =
+ static_cast<MediaKeysListenerImpl*>(refcon);
+
+ const bool is_active = [NSApp isActive];
+
+ if (shortcut_listener->scope_ == Scope::kFocused && !is_active) {
+ return event;
+ }
+
+ // Handle the timeout case by re-enabling the tap.
+ if (type == kCGEventTapDisabledByTimeout) {
+ CGEventTapEnable(shortcut_listener->event_tap_, true);
+ return event;
+ }
+
+ // Convert the CGEvent to an NSEvent for access to the data1 field.
+ NSEvent* ns_event = [NSEvent eventWithCGEvent:event];
+ if (ns_event == nil) {
+ return event;
+ }
+
+ // Ignore events that are not system defined media keys.
+ if (type != NX_SYSDEFINED || [ns_event type] != NSSystemDefined ||
+ [ns_event subtype] != kSystemDefinedEventMediaKeysSubtype) {
+ return event;
+ }
+
+ NSInteger data1 = [ns_event data1];
+ // Ignore media keys that aren't previous, next and play/pause.
+ // Magical constants are from http://weblog.rogueamoeba.com/2007/09/29/
+ int key_code = (data1 & 0xFFFF0000) >> 16;
+ if (key_code != NX_KEYTYPE_PLAY && key_code != NX_KEYTYPE_NEXT &&
+ key_code != NX_KEYTYPE_PREVIOUS && key_code != NX_KEYTYPE_FAST &&
+ key_code != NX_KEYTYPE_REWIND) {
+ return event;
+ }
+
+ int key_flags = data1 & 0x0000FFFF;
+ bool is_key_pressed = ((key_flags & 0xFF00) >> 8) == 0xA;
+
+ // If the key wasn't pressed (eg. was released), ignore this event.
+ if (!is_key_pressed)
+ return event;
+
+ // Now we have a media key that we care about. Send it to the caller.
+ auto result = shortcut_listener->OnMediaKeyEvent(key_code);
+
+ // Prevent event from proagating to other apps if handled by Chrome.
+ if (result == MediaKeysHandleResult::kSuppressPropagation) {
+ return nullptr;
+ }
+
+ // By default, pass the event through.
+ return event;
+}
+
+} // namespace
+
+std::unique_ptr<MediaKeysListener> MediaKeysListener::Create(
+ MediaKeysListener::Delegate* delegate,
+ MediaKeysListener::Scope scope) {
+ return std::make_unique<MediaKeysListenerImpl>(delegate, scope);
+}
+
+} // namespace ui
diff --git a/chromium/ui/base/accelerators/media_keys_listener_stub.cc b/chromium/ui/base/accelerators/media_keys_listener_stub.cc
new file mode 100644
index 00000000000..67005291850
--- /dev/null
+++ b/chromium/ui/base/accelerators/media_keys_listener_stub.cc
@@ -0,0 +1,16 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/accelerators/media_keys_listener.h"
+
+namespace ui {
+
+// TODO(ganenkokb): Need implementation for non-mac platforms.
+std::unique_ptr<MediaKeysListener> MediaKeysListener::Create(
+ MediaKeysListener::Delegate* delegate,
+ MediaKeysListener::Scope scope) {
+ return nullptr;
+}
+
+} // namespace ui
diff --git a/chromium/ui/base/cocoa/text_services_context_menu.cc b/chromium/ui/base/cocoa/text_services_context_menu.cc
new file mode 100644
index 00000000000..f7cb1dc3c24
--- /dev/null
+++ b/chromium/ui/base/cocoa/text_services_context_menu.cc
@@ -0,0 +1,152 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/cocoa/text_services_context_menu.h"
+
+#include <utility>
+
+#include <ApplicationServices/ApplicationServices.h>
+#include <CoreAudio/CoreAudio.h>
+
+#include "base/mac/mac_logging.h"
+#include "base/strings/sys_string_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/strings/grit/ui_strings.h"
+
+namespace {
+
+// The speech channel used for speaking. This is shared to check if a speech
+// channel is currently speaking.
+SpeechChannel g_speech_channel;
+
+// Returns the TextDirection associated associated with the given BiDi
+// |command_id|.
+base::i18n::TextDirection GetTextDirectionFromCommandId(int command_id) {
+ switch (command_id) {
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT:
+ return base::i18n::UNKNOWN_DIRECTION;
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR:
+ return base::i18n::LEFT_TO_RIGHT;
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL:
+ return base::i18n::RIGHT_TO_LEFT;
+ default:
+ NOTREACHED();
+ return base::i18n::UNKNOWN_DIRECTION;
+ }
+}
+
+} // namespace
+
+namespace ui {
+
+TextServicesContextMenu::TextServicesContextMenu(Delegate* delegate)
+ : speech_submenu_model_(this),
+ bidi_submenu_model_(this),
+ delegate_(delegate) {
+ DCHECK(delegate);
+
+ speech_submenu_model_.AddItemWithStringId(IDS_SPEECH_START_SPEAKING_MAC,
+ IDS_SPEECH_START_SPEAKING_MAC);
+ speech_submenu_model_.AddItemWithStringId(IDS_SPEECH_STOP_SPEAKING_MAC,
+ IDS_SPEECH_STOP_SPEAKING_MAC);
+
+ bidi_submenu_model_.AddCheckItemWithStringId(
+ IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT,
+ IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT);
+ bidi_submenu_model_.AddCheckItemWithStringId(
+ IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR,
+ IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR);
+ bidi_submenu_model_.AddCheckItemWithStringId(
+ IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL,
+ IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL);
+}
+
+void TextServicesContextMenu::SpeakText(const base::string16& text) {
+ if (IsSpeaking())
+ StopSpeaking();
+
+ if (!g_speech_channel) {
+ OSErr result = NewSpeechChannel(nullptr, &g_speech_channel);
+ OSSTATUS_DCHECK(result == noErr, result);
+ }
+
+ SpeakCFString(g_speech_channel, base::SysUTF16ToCFStringRef(text), nullptr);
+}
+
+void TextServicesContextMenu::StopSpeaking() {
+ DCHECK(g_speech_channel);
+ StopSpeechAt(g_speech_channel, kImmediate);
+ DisposeSpeechChannel(g_speech_channel);
+ g_speech_channel = nullptr;
+}
+
+bool TextServicesContextMenu::IsSpeaking() {
+ return SpeechBusy();
+}
+
+void TextServicesContextMenu::AppendToContextMenu(SimpleMenuModel* model) {
+ model->AddSeparator(NORMAL_SEPARATOR);
+ model->AddSubMenuWithStringId(IDS_SPEECH_MAC, IDS_SPEECH_MAC,
+ &speech_submenu_model_);
+}
+
+void TextServicesContextMenu::AppendEditableItems(SimpleMenuModel* model) {
+ model->AddSubMenuWithStringId(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU,
+ IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU,
+ &bidi_submenu_model_);
+}
+
+bool TextServicesContextMenu::IsCommandIdChecked(int command_id) const {
+ switch (command_id) {
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT:
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR:
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL:
+ return delegate_->IsTextDirectionChecked(
+ GetTextDirectionFromCommandId(command_id));
+ case IDS_SPEECH_START_SPEAKING_MAC:
+ case IDS_SPEECH_STOP_SPEAKING_MAC:
+ return false;
+ }
+
+ NOTREACHED();
+ return false;
+}
+
+bool TextServicesContextMenu::IsCommandIdEnabled(int command_id) const {
+ switch (command_id) {
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT:
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR:
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL:
+ return delegate_->IsTextDirectionEnabled(
+ GetTextDirectionFromCommandId(command_id));
+ case IDS_SPEECH_START_SPEAKING_MAC:
+ return true;
+ case IDS_SPEECH_STOP_SPEAKING_MAC:
+ return IsSpeaking();
+ }
+
+ NOTREACHED();
+ return false;
+}
+
+void TextServicesContextMenu::ExecuteCommand(int command_id, int event_flags) {
+ switch (command_id) {
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT:
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR:
+ case IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL:
+ delegate_->UpdateTextDirection(GetTextDirectionFromCommandId(command_id));
+ break;
+ case IDS_SPEECH_START_SPEAKING_MAC:
+ SpeakText(delegate_->GetSelectedText());
+ break;
+ case IDS_SPEECH_STOP_SPEAKING_MAC:
+ StopSpeaking();
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+} // namespace ui \ No newline at end of file
diff --git a/chromium/ui/base/cocoa/text_services_context_menu.h b/chromium/ui/base/cocoa/text_services_context_menu.h
new file mode 100644
index 00000000000..2c163d7bee7
--- /dev/null
+++ b/chromium/ui/base/cocoa/text_services_context_menu.h
@@ -0,0 +1,74 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_BASE_COCOA_TEXT_SERVICES_CONTEXT_MENU_H_
+#define UI_BASE_COCOA_TEXT_SERVICES_CONTEXT_MENU_H_
+
+#include "base/i18n/rtl.h"
+#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "ui/base/ui_base_export.h"
+
+namespace ui {
+
+// This class is used to append and handle the Speech and BiDi submenu for the
+// context menu.
+// TODO (spqchan): Replace the Speech and BiDi logic in RenderViewContextMenu
+// with TextServicesContextMenu.
+class UI_BASE_EXPORT TextServicesContextMenu
+ : public SimpleMenuModel::Delegate {
+ public:
+ class UI_BASE_EXPORT Delegate {
+ public:
+ // Returns the selected text.
+ virtual base::string16 GetSelectedText() const = 0;
+
+ // Returns true if |direction| should be enabled in the BiDi submenu.
+ virtual bool IsTextDirectionEnabled(
+ base::i18n::TextDirection direction) const = 0;
+
+ // Returns true if |direction| should be checked in the BiDi submenu.
+ virtual bool IsTextDirectionChecked(
+ base::i18n::TextDirection direction) const = 0;
+
+ // Updates the text direction to |direction|.
+ virtual void UpdateTextDirection(base::i18n::TextDirection direction) = 0;
+ };
+
+ explicit TextServicesContextMenu(Delegate* delegate);
+
+ // Methods for speaking.
+ static void SpeakText(const base::string16& text);
+ static void StopSpeaking();
+ static bool IsSpeaking();
+
+ // Appends text service items to |model|. A submenu is added for speech,
+ // which |this| serves as the delegate for.
+ void AppendToContextMenu(SimpleMenuModel* model);
+
+ // Appends items to the context menu applicable to editable content. A
+ // submenu is added for bidirection, which |this| serves as a delegate for.
+ void AppendEditableItems(SimpleMenuModel* model);
+
+ // SimpleMenuModel::Delegate:
+ bool IsCommandIdChecked(int command_id) const override;
+ bool IsCommandIdEnabled(int command_id) const override;
+ void ExecuteCommand(int command_id, int event_flags) override;
+
+ private:
+ // Model for the "Speech" submenu.
+ ui::SimpleMenuModel speech_submenu_model_;
+
+ // Model for the BiDi input submenu.
+ ui::SimpleMenuModel bidi_submenu_model_;
+
+ Delegate* delegate_; // Weak.
+
+ DISALLOW_COPY_AND_ASSIGN(TextServicesContextMenu);
+};
+
+} // namespace ui
+
+#endif // UI_BASE_COCOA_TEXT_SERVICES_CONTEXT_MENU_H_ \ No newline at end of file
diff --git a/chromium/ui/base/ime/ime_bridge.cc b/chromium/ui/base/ime/ime_bridge.cc
index 7b4e8e23638..e30642b3cb5 100644
--- a/chromium/ui/base/ime/ime_bridge.cc
+++ b/chromium/ui/base/ime/ime_bridge.cc
@@ -13,23 +13,25 @@
namespace ui {
-static IMEBridge* g_ime_bridge = NULL;
+static IMEBridge* g_ime_bridge = nullptr;
// An implementation of IMEBridge.
class IMEBridgeImpl : public IMEBridge {
public:
#if defined(OS_CHROMEOS)
IMEBridgeImpl()
- : input_context_handler_(NULL),
- engine_handler_(NULL),
+ : input_context_handler_(nullptr),
+ engine_handler_(nullptr),
+ observer_(nullptr),
current_input_context_(ui::TEXT_INPUT_TYPE_NONE,
ui::TEXT_INPUT_MODE_DEFAULT,
0),
- candidate_window_handler_(NULL) {}
+ candidate_window_handler_(nullptr) {}
#else
IMEBridgeImpl()
- : input_context_handler_(NULL),
- engine_handler_(NULL),
+ : input_context_handler_(nullptr),
+ engine_handler_(nullptr),
+ observer_(nullptr),
current_input_context_(ui::TEXT_INPUT_TYPE_NONE,
ui::TEXT_INPUT_MODE_DEFAULT,
0) {}
@@ -70,6 +72,17 @@ class IMEBridgeImpl : public IMEBridge {
return current_input_context_;
}
+ // IMEBridge override.
+ void SetObserver(ui::IMEBridgeObserver* observer) override {
+ observer_ = observer;
+ }
+
+ // IMEBridge override.
+ void MaybeSwitchEngine() override {
+ if (observer_)
+ observer_->OnRequestSwitchEngine();
+ }
+
#if defined(OS_CHROMEOS)
// IMEBridge override.
void SetCandidateWindowHandler(
@@ -87,6 +100,7 @@ class IMEBridgeImpl : public IMEBridge {
private:
IMEInputContextHandlerInterface* input_context_handler_;
IMEEngineHandlerInterface* engine_handler_;
+ IMEBridgeObserver* observer_;
IMEEngineHandlerInterface::InputContext current_input_context_;
#if defined(OS_CHROMEOS)
@@ -111,7 +125,7 @@ void IMEBridge::Initialize() {
// static.
void IMEBridge::Shutdown() {
delete g_ime_bridge;
- g_ime_bridge = NULL;
+ g_ime_bridge = nullptr;
}
// static.
diff --git a/chromium/ui/base/ime/ime_bridge.h b/chromium/ui/base/ime/ime_bridge.h
index 5db8bbaa19f..e18c03a27b2 100644
--- a/chromium/ui/base/ime/ime_bridge.h
+++ b/chromium/ui/base/ime/ime_bridge.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "build/build_config.h"
+#include "ui/base/ime/ime_bridge_observer.h"
#include "ui/base/ime/ime_engine_handler_interface.h"
#include "ui/base/ime/ime_input_context_handler_interface.h"
#include "ui/base/ime/ui_base_ime_export.h"
@@ -63,6 +64,12 @@ class UI_BASE_IME_EXPORT IMEBridge {
virtual const IMEEngineHandlerInterface::InputContext&
GetCurrentInputContext() const = 0;
+ // Sets the observer that observes the switching engine event.
+ virtual void SetObserver(ui::IMEBridgeObserver* observer) = 0;
+
+ // Switches the engine handler upon top level window focus change.
+ virtual void MaybeSwitchEngine() = 0;
+
#if defined(OS_CHROMEOS)
// Returns current CandidateWindowHandler. This function returns NULL if
// current candidate window is not ready to use.
diff --git a/chromium/ui/base/ime/ime_bridge_observer.h b/chromium/ui/base/ime/ime_bridge_observer.h
new file mode 100644
index 00000000000..a21c5f85a41
--- /dev/null
+++ b/chromium/ui/base/ime/ime_bridge_observer.h
@@ -0,0 +1,23 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_BASE_IME_IME_BRIDGE_OBSERVER_H_
+#define UI_BASE_IME_IME_BRIDGE_OBSERVER_H_
+
+#include "ui/base/ime/ui_base_ime_export.h"
+
+namespace ui {
+
+// A interface to .
+class UI_BASE_IME_EXPORT IMEBridgeObserver {
+ public:
+ virtual ~IMEBridgeObserver() {}
+
+ // Called when requesting to switch the engine handler from ui::InputMethod.
+ virtual void OnRequestSwitchEngine() = 0;
+};
+
+} // namespace ui
+
+#endif // UI_BASE_IME_IME_BRIDGE_OBSERVER_H_
diff --git a/chromium/ui/base/ime/ime_engine_handler_interface.h b/chromium/ui/base/ime/ime_engine_handler_interface.h
index 242f1c781d7..3987085386a 100644
--- a/chromium/ui/base/ime/ime_engine_handler_interface.h
+++ b/chromium/ui/base/ime/ime_engine_handler_interface.h
@@ -71,10 +71,6 @@ class UI_BASE_IME_EXPORT IMEEngineHandlerInterface {
// Called when the IME is reset.
virtual void Reset() = 0;
- // Called when the top-level-window is changed, which could switch the engine
- // handler.
- virtual void MaybeSwitchEngine() = 0;
-
// Called when the key event is received.
// Actual implementation must call |callback| after key event handling.
virtual void ProcessKeyEvent(const KeyEvent& key_event,
diff --git a/chromium/ui/base/ime/input_method_base.cc b/chromium/ui/base/ime/input_method_base.cc
index 18b5a47bdb4..7d4747b5c05 100644
--- a/chromium/ui/base/ime/input_method_base.cc
+++ b/chromium/ui/base/ime/input_method_base.cc
@@ -40,11 +40,10 @@ void InputMethodBase::SetDelegate(internal::InputMethodDelegate* delegate) {
}
void InputMethodBase::OnFocus() {
- if (ui::IMEBridge::Get()) {
- ui::IMEBridge::Get()->SetInputContextHandler(this);
- ui::IMEEngineHandlerInterface* engine = GetEngine();
- if (engine)
- engine->MaybeSwitchEngine();
+ ui::IMEBridge* bridge = ui::IMEBridge::Get();
+ if (bridge) {
+ bridge->SetInputContextHandler(this);
+ bridge->MaybeSwitchEngine();
}
}
diff --git a/chromium/ui/base/ime/input_method_chromeos.cc b/chromium/ui/base/ime/input_method_chromeos.cc
index 64cd9cfb893..fba861cd4a9 100644
--- a/chromium/ui/base/ime/input_method_chromeos.cc
+++ b/chromium/ui/base/ime/input_method_chromeos.cc
@@ -75,6 +75,40 @@ ui::EventDispatchDetails InputMethodChromeOS::DispatchKeyEvent(
// handled in event rewriter.
keyboard->SetCapsLockEnabled(event->IsCapsLockOn());
}
+
+ // For JP106 language input keys, makes sure they can be passed to the app
+ // so that the VDI web apps can be supported. See https://crbug.com/816341.
+ // VKEY_CONVERT: Henkan key
+ // VKEY_NONCONVERT: Muhenkan key
+ // VKEY_DBE_SBCSCHAR/VKEY_DBE_DBCSCHAR: ZenkakuHankaku key
+ chromeos::input_method::InputMethodManager::State* state =
+ manager->GetActiveIMEState().get();
+ if (event->type() == ET_KEY_PRESSED && state) {
+ bool language_input_key = true;
+ switch (event->key_code()) {
+ case ui::VKEY_CONVERT:
+ state->ChangeInputMethodToJpIme();
+ break;
+ case ui::VKEY_NONCONVERT:
+ state->ChangeInputMethodToJpKeyboard();
+ break;
+ case ui::VKEY_DBE_SBCSCHAR:
+ case ui::VKEY_DBE_DBCSCHAR:
+ state->ToggleInputMethodForJpIme();
+ break;
+ default:
+ language_input_key = false;
+ break;
+ }
+ if (language_input_key) {
+ // Dispatches the event to app/blink.
+ // TODO(shuchen): Eventually, the language input keys should be handed
+ // over to the IME extension to process. And IMF can handle if the IME
+ // extension didn't handle.
+ return DispatchKeyEventPostIME(
+ event, std::make_unique<AckCallback>(std::move(ack_callback)));
+ }
+ }
}
// If |context_| is not usable, then we can only dispatch the key event as is.
diff --git a/chromium/ui/base/ime/input_method_chromeos_unittest.cc b/chromium/ui/base/ime/input_method_chromeos_unittest.cc
index 0e64f214863..fc127d28125 100644
--- a/chromium/ui/base/ime/input_method_chromeos_unittest.cc
+++ b/chromium/ui/base/ime/input_method_chromeos_unittest.cc
@@ -16,6 +16,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h"
#include "ui/base/ime/chromeos/mock_ime_engine_handler.h"
+#include "ui/base/ime/chromeos/mock_input_method_manager.h"
#include "ui/base/ime/composition_text.h"
#include "ui/base/ime/dummy_text_input_client.h"
#include "ui/base/ime/ime_bridge.h"
@@ -200,6 +201,64 @@ class SetSurroundingTextVerifier {
DISALLOW_COPY_AND_ASSIGN(SetSurroundingTextVerifier);
};
+class TestInputMethodManager
+ : public chromeos::input_method::MockInputMethodManager {
+ class TestState : public MockInputMethodManager::State {
+ public:
+ TestState() { Reset(); }
+
+ // InputMethodManager::State:
+ void ChangeInputMethodToJpKeyboard() override {
+ is_jp_kbd_ = true;
+ is_jp_ime_ = false;
+ }
+ void ChangeInputMethodToJpIme() override {
+ is_jp_kbd_ = false;
+ is_jp_ime_ = true;
+ }
+ void ToggleInputMethodForJpIme() override {
+ if (!is_jp_ime_) {
+ is_jp_kbd_ = false;
+ is_jp_ime_ = true;
+ } else {
+ is_jp_kbd_ = true;
+ is_jp_ime_ = false;
+ }
+ }
+ void Reset() {
+ is_jp_kbd_ = false;
+ is_jp_ime_ = false;
+ }
+ bool is_jp_kbd() const { return is_jp_kbd_; }
+ bool is_jp_ime() const { return is_jp_ime_; }
+
+ protected:
+ ~TestState() override {}
+
+ private:
+ bool is_jp_kbd_ = false;
+ bool is_jp_ime_ = false;
+
+ DISALLOW_COPY_AND_ASSIGN(TestState);
+ };
+
+ private:
+ scoped_refptr<TestState> state_;
+
+ public:
+ TestInputMethodManager() {
+ state_ = scoped_refptr<TestState>(new TestState());
+ }
+
+ TestState* state() { return state_.get(); }
+
+ scoped_refptr<InputMethodManager::State> GetActiveIMEState() override {
+ return scoped_refptr<InputMethodManager::State>(state_.get());
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(TestInputMethodManager);
+};
+
class InputMethodChromeOSTest : public internal::InputMethodDelegate,
public testing::Test,
public DummyTextInputClient {
@@ -227,6 +286,11 @@ class InputMethodChromeOSTest : public internal::InputMethodDelegate,
ime_.reset(new TestableInputMethodChromeOS(this));
ime_->SetFocusedTextInputClient(this);
+
+ // InputMethodManager owns and delete it in InputMethodManager::Shutdown().
+ input_method_manager_ = new TestInputMethodManager();
+ chromeos::input_method::InputMethodManager::Initialize(
+ input_method_manager_);
}
void TearDown() override {
@@ -238,6 +302,7 @@ class InputMethodChromeOSTest : public internal::InputMethodDelegate,
mock_ime_engine_handler_.reset();
mock_ime_candidate_window_handler_.reset();
IMEBridge::Shutdown();
+ chromeos::input_method::InputMethodManager::Shutdown();
ResetFlags();
}
@@ -257,9 +322,11 @@ class InputMethodChromeOSTest : public internal::InputMethodDelegate,
}
void ConfirmCompositionText() override {
confirmed_text_ = composition_text_;
- composition_text_.Clear();
+ composition_text_ = CompositionText();
+ }
+ void ClearCompositionText() override {
+ composition_text_ = CompositionText();
}
- void ClearCompositionText() override { composition_text_.Clear(); }
void InsertText(const base::string16& text) override {
inserted_text_ = text;
}
@@ -272,8 +339,7 @@ class InputMethodChromeOSTest : public internal::InputMethodDelegate,
bool CanComposeInline() const override { return can_compose_inline_; }
gfx::Rect GetCaretBounds() const override { return caret_bounds_; }
bool HasCompositionText() const override {
- CompositionText empty;
- return composition_text_ != empty;
+ return composition_text_ != CompositionText();
}
bool GetTextRange(gfx::Range* range) const override {
*range = text_range_;
@@ -300,8 +366,8 @@ class InputMethodChromeOSTest : public internal::InputMethodDelegate,
dispatched_key_event_ = ui::KeyEvent(ui::ET_UNKNOWN, ui::VKEY_UNKNOWN,
ui::EF_NONE);
- composition_text_.Clear();
- confirmed_text_.Clear();
+ composition_text_ = CompositionText();
+ confirmed_text_ = CompositionText();
inserted_text_.clear();
inserted_char_ = 0;
inserted_char_flags_ = 0;
@@ -342,6 +408,8 @@ class InputMethodChromeOSTest : public internal::InputMethodDelegate,
bool stop_propagation_post_ime_;
+ TestInputMethodManager* input_method_manager_;
+
DISALLOW_COPY_AND_ASSIGN(InputMethodChromeOSTest);
};
@@ -531,12 +599,13 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_NoAttribute) {
// If there is no selection, |selection| represents cursor position.
EXPECT_EQ(kCursorPos, composition_text.selection.start());
EXPECT_EQ(kCursorPos, composition_text.selection.end());
- // If there is no underline, |underlines| contains one underline and it is
+ // If there is no underline, |ime_text_spans| contains one underline and it is
// whole text underline.
- ASSERT_EQ(1UL, composition_text.underlines.size());
- EXPECT_EQ(0UL, composition_text.underlines[0].start_offset);
- EXPECT_EQ(kSampleAsciiText.size(), composition_text.underlines[0].end_offset);
- EXPECT_FALSE(composition_text.underlines[0].thick);
+ ASSERT_EQ(1UL, composition_text.ime_text_spans.size());
+ EXPECT_EQ(0UL, composition_text.ime_text_spans[0].start_offset);
+ EXPECT_EQ(kSampleAsciiText.size(),
+ composition_text.ime_text_spans[0].end_offset);
+ EXPECT_FALSE(composition_text.ime_text_spans[0].thick);
}
TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_SingleUnderline) {
@@ -545,9 +614,9 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_SingleUnderline) {
// Set up chromeos composition text with one underline attribute.
CompositionText composition_text;
composition_text.text = kSampleText;
- CompositionUnderline underline(1UL, 4UL, SK_ColorBLACK, false,
- SK_ColorTRANSPARENT);
- composition_text.underlines.push_back(underline);
+ ImeTextSpan underline(ImeTextSpan::Type::kComposition, 1UL, 4UL,
+ SK_ColorBLACK, false, SK_ColorTRANSPARENT);
+ composition_text.ime_text_spans.push_back(underline);
CompositionText composition_text2;
ime_->ExtractCompositionText(composition_text, kCursorPos,
@@ -556,16 +625,16 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_SingleUnderline) {
// If there is no selection, |selection| represents cursor position.
EXPECT_EQ(kCursorPos, composition_text2.selection.start());
EXPECT_EQ(kCursorPos, composition_text2.selection.end());
- ASSERT_EQ(1UL, composition_text2.underlines.size());
+ ASSERT_EQ(1UL, composition_text2.ime_text_spans.size());
EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.start_offset),
- composition_text2.underlines[0].start_offset);
+ composition_text2.ime_text_spans[0].start_offset);
EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.end_offset),
- composition_text2.underlines[0].end_offset);
+ composition_text2.ime_text_spans[0].end_offset);
// Single underline represents as black thin line.
- EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
- EXPECT_FALSE(composition_text2.underlines[0].thick);
+ EXPECT_EQ(SK_ColorBLACK, composition_text2.ime_text_spans[0].underline_color);
+ EXPECT_FALSE(composition_text2.ime_text_spans[0].thick);
EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
- composition_text2.underlines[0].background_color);
+ composition_text2.ime_text_spans[0].background_color);
}
TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_DoubleUnderline) {
@@ -574,9 +643,9 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_DoubleUnderline) {
// Set up chromeos composition text with one underline attribute.
CompositionText composition_text;
composition_text.text = kSampleText;
- CompositionUnderline underline(1UL, 4UL, SK_ColorBLACK, true,
- SK_ColorTRANSPARENT);
- composition_text.underlines.push_back(underline);
+ ImeTextSpan underline(ImeTextSpan::Type::kComposition, 1UL, 4UL,
+ SK_ColorBLACK, true, SK_ColorTRANSPARENT);
+ composition_text.ime_text_spans.push_back(underline);
CompositionText composition_text2;
ime_->ExtractCompositionText(composition_text, kCursorPos,
@@ -585,16 +654,16 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_DoubleUnderline) {
// If there is no selection, |selection| represents cursor position.
EXPECT_EQ(kCursorPos, composition_text2.selection.start());
EXPECT_EQ(kCursorPos, composition_text2.selection.end());
- ASSERT_EQ(1UL, composition_text2.underlines.size());
+ ASSERT_EQ(1UL, composition_text2.ime_text_spans.size());
EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.start_offset),
- composition_text2.underlines[0].start_offset);
+ composition_text2.ime_text_spans[0].start_offset);
EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.end_offset),
- composition_text2.underlines[0].end_offset);
+ composition_text2.ime_text_spans[0].end_offset);
// Double underline represents as black thick line.
- EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
- EXPECT_TRUE(composition_text2.underlines[0].thick);
+ EXPECT_EQ(SK_ColorBLACK, composition_text2.ime_text_spans[0].underline_color);
+ EXPECT_TRUE(composition_text2.ime_text_spans[0].thick);
EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
- composition_text2.underlines[0].background_color);
+ composition_text2.ime_text_spans[0].background_color);
}
TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_ErrorUnderline) {
@@ -603,9 +672,9 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_ErrorUnderline) {
// Set up chromeos composition text with one underline attribute.
CompositionText composition_text;
composition_text.text = kSampleText;
- CompositionUnderline underline(1UL, 4UL, SK_ColorRED, false,
- SK_ColorTRANSPARENT);
- composition_text.underlines.push_back(underline);
+ ImeTextSpan underline(ImeTextSpan::Type::kComposition, 1UL, 4UL, SK_ColorRED,
+ false, SK_ColorTRANSPARENT);
+ composition_text.ime_text_spans.push_back(underline);
CompositionText composition_text2;
ime_->ExtractCompositionText(composition_text, kCursorPos,
@@ -613,14 +682,14 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_ErrorUnderline) {
EXPECT_EQ(kSampleText, composition_text2.text);
EXPECT_EQ(kCursorPos, composition_text2.selection.start());
EXPECT_EQ(kCursorPos, composition_text2.selection.end());
- ASSERT_EQ(1UL, composition_text2.underlines.size());
+ ASSERT_EQ(1UL, composition_text2.ime_text_spans.size());
EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.start_offset),
- composition_text2.underlines[0].start_offset);
+ composition_text2.ime_text_spans[0].start_offset);
EXPECT_EQ(GetOffsetInUTF16(kSampleText, underline.end_offset),
- composition_text2.underlines[0].end_offset);
+ composition_text2.ime_text_spans[0].end_offset);
// Error underline represents as red thin line.
- EXPECT_EQ(SK_ColorRED, composition_text2.underlines[0].color);
- EXPECT_FALSE(composition_text2.underlines[0].thick);
+ EXPECT_EQ(SK_ColorRED, composition_text2.ime_text_spans[0].underline_color);
+ EXPECT_FALSE(composition_text2.ime_text_spans[0].thick);
}
TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_Selection) {
@@ -638,15 +707,15 @@ TEST_F(InputMethodChromeOSTest, ExtractCompositionTextTest_Selection) {
EXPECT_EQ(kSampleText, composition_text2.text);
EXPECT_EQ(kCursorPos, composition_text2.selection.start());
EXPECT_EQ(kCursorPos, composition_text2.selection.end());
- ASSERT_EQ(1UL, composition_text2.underlines.size());
+ ASSERT_EQ(1UL, composition_text2.ime_text_spans.size());
EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.start()),
- composition_text2.underlines[0].start_offset);
+ composition_text2.ime_text_spans[0].start_offset);
EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.end()),
- composition_text2.underlines[0].end_offset);
- EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
- EXPECT_TRUE(composition_text2.underlines[0].thick);
+ composition_text2.ime_text_spans[0].end_offset);
+ EXPECT_EQ(SK_ColorBLACK, composition_text2.ime_text_spans[0].underline_color);
+ EXPECT_TRUE(composition_text2.ime_text_spans[0].thick);
EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
- composition_text2.underlines[0].background_color);
+ composition_text2.ime_text_spans[0].background_color);
}
TEST_F(InputMethodChromeOSTest,
@@ -669,15 +738,15 @@ TEST_F(InputMethodChromeOSTest,
composition_text2.selection.start());
EXPECT_EQ(GetOffsetInUTF16(kSampleText, kCursorPos),
composition_text2.selection.end());
- ASSERT_EQ(1UL, composition_text2.underlines.size());
+ ASSERT_EQ(1UL, composition_text2.ime_text_spans.size());
EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.start()),
- composition_text2.underlines[0].start_offset);
+ composition_text2.ime_text_spans[0].start_offset);
EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.end()),
- composition_text2.underlines[0].end_offset);
- EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
- EXPECT_TRUE(composition_text2.underlines[0].thick);
+ composition_text2.ime_text_spans[0].end_offset);
+ EXPECT_EQ(SK_ColorBLACK, composition_text2.ime_text_spans[0].underline_color);
+ EXPECT_TRUE(composition_text2.ime_text_spans[0].thick);
EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
- composition_text2.underlines[0].background_color);
+ composition_text2.ime_text_spans[0].background_color);
}
TEST_F(InputMethodChromeOSTest,
@@ -700,15 +769,15 @@ TEST_F(InputMethodChromeOSTest,
composition_text2.selection.start());
EXPECT_EQ(GetOffsetInUTF16(kSampleText, kCursorPos),
composition_text2.selection.end());
- ASSERT_EQ(1UL, composition_text2.underlines.size());
+ ASSERT_EQ(1UL, composition_text2.ime_text_spans.size());
EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.start()),
- composition_text2.underlines[0].start_offset);
+ composition_text2.ime_text_spans[0].start_offset);
EXPECT_EQ(GetOffsetInUTF16(kSampleText, composition_text.selection.end()),
- composition_text2.underlines[0].end_offset);
- EXPECT_EQ(SK_ColorBLACK, composition_text2.underlines[0].color);
- EXPECT_TRUE(composition_text2.underlines[0].thick);
+ composition_text2.ime_text_spans[0].end_offset);
+ EXPECT_EQ(SK_ColorBLACK, composition_text2.ime_text_spans[0].underline_color);
+ EXPECT_TRUE(composition_text2.ime_text_spans[0].thick);
EXPECT_EQ(static_cast<SkColor>(SK_ColorTRANSPARENT),
- composition_text2.underlines[0].background_color);
+ composition_text2.ime_text_spans[0].background_color);
}
TEST_F(InputMethodChromeOSTest, SurroundingText_NoSelectionTest) {
@@ -973,4 +1042,26 @@ TEST_F(InputMethodChromeOSKeyEventTest, DeadKeyPressTest) {
EXPECT_EQ(eventA.time_stamp(), key_event.time_stamp());
}
+TEST_F(InputMethodChromeOSKeyEventTest, JP106KeyTest) {
+ ui::KeyEvent eventConvert(ET_KEY_PRESSED, VKEY_CONVERT, EF_NONE);
+ ime_->DispatchKeyEvent(&eventConvert);
+ EXPECT_FALSE(input_method_manager_->state()->is_jp_kbd());
+ EXPECT_TRUE(input_method_manager_->state()->is_jp_ime());
+
+ ui::KeyEvent eventNonConvert(ET_KEY_PRESSED, VKEY_NONCONVERT, EF_NONE);
+ ime_->DispatchKeyEvent(&eventNonConvert);
+ EXPECT_TRUE(input_method_manager_->state()->is_jp_kbd());
+ EXPECT_FALSE(input_method_manager_->state()->is_jp_ime());
+
+ ui::KeyEvent eventDbeSbc(ET_KEY_PRESSED, VKEY_DBE_SBCSCHAR, EF_NONE);
+ ime_->DispatchKeyEvent(&eventDbeSbc);
+ EXPECT_FALSE(input_method_manager_->state()->is_jp_kbd());
+ EXPECT_TRUE(input_method_manager_->state()->is_jp_ime());
+
+ ui::KeyEvent eventDbeDbc(ET_KEY_PRESSED, VKEY_DBE_DBCSCHAR, EF_NONE);
+ ime_->DispatchKeyEvent(&eventDbeDbc);
+ EXPECT_TRUE(input_method_manager_->state()->is_jp_kbd());
+ EXPECT_FALSE(input_method_manager_->state()->is_jp_ime());
+}
+
} // namespace ui
diff --git a/chromium/ui/base/l10n/l10n_util_win_unittest.cc b/chromium/ui/base/l10n/l10n_util_win_unittest.cc
index 29ab718535d..3dfa8533722 100644
--- a/chromium/ui/base/l10n/l10n_util_win_unittest.cc
+++ b/chromium/ui/base/l10n/l10n_util_win_unittest.cc
@@ -7,7 +7,7 @@
#include <windows.h>
#include "base/command_line.h"
-#include "base/win/win_util.h"
+#include "base/win/win_client_metrics.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#include "ui/display/display.h"
diff --git a/chromium/ui/base/layout.cc b/chromium/ui/base/layout.cc
index c19b1bdac36..29a0e0e6c77 100644
--- a/chromium/ui/base/layout.cc
+++ b/chromium/ui/base/layout.cc
@@ -10,12 +10,10 @@
#include <cmath>
#include <limits>
-#include "base/command_line.h"
#include "base/logging.h"
#include "base/macros.h"
#include "build/build_config.h"
#include "ui/base/touch/touch_device.h"
-#include "ui/base/ui_base_switches.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/image/image_skia.h"
@@ -104,7 +102,6 @@ ScopedSetSupportedScaleFactors::~ScopedSetSupportedScaleFactors() {
} // namespace test
-#if !defined(OS_MACOSX)
float GetScaleFactorForNativeView(gfx::NativeView view) {
// A number of unit tests do not setup the screen.
if (!display::Screen::GetScreen())
@@ -114,6 +111,5 @@ float GetScaleFactorForNativeView(gfx::NativeView view) {
DCHECK(display.is_valid());
return display.device_scale_factor();
}
-#endif // !defined(OS_MACOSX)
} // namespace ui
diff --git a/chromium/ui/base/layout_mac.mm b/chromium/ui/base/layout_mac.mm
deleted file mode 100644
index 574a662a688..00000000000
--- a/chromium/ui/base/layout_mac.mm
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/base/layout.h"
-
-#import <Cocoa/Cocoa.h>
-
-#include "base/mac/sdk_forward_declarations.h"
-#include "ui/display/display.h"
-
-namespace {
-
-float GetScaleFactorScaleForNativeView(gfx::NativeView view) {
- if (NSWindow* window = [view window]) {
- return [window backingScaleFactor];
- }
-
- NSArray* screens = [NSScreen screens];
- if (![screens count])
- return 1.0f;
-
- NSScreen* screen = [screens objectAtIndex:0];
- return [screen backingScaleFactor];
-}
-
-} // namespace
-
-namespace ui {
-
-float GetScaleFactorForNativeView(gfx::NativeView view) {
- if (display::Display::HasForceDeviceScaleFactor())
- return display::Display::GetForcedDeviceScaleFactor();
- return GetScaleFactorScaleForNativeView(view);
-}
-
-} // namespace ui
diff --git a/chromium/ui/base/material_design/material_design_controller.cc b/chromium/ui/base/material_design/material_design_controller.cc
index e475ce84f56..e19300ed6e1 100644
--- a/chromium/ui/base/material_design/material_design_controller.cc
+++ b/chromium/ui/base/material_design/material_design_controller.cc
@@ -51,6 +51,8 @@ void MaterialDesignController::Initialize() {
SetMode(MATERIAL_NORMAL);
} else if (switch_value == switches::kTopChromeMDMaterialHybrid) {
SetMode(MATERIAL_HYBRID);
+ } else if (switch_value == switches::kTopChromeMDMaterialTouchOptimized) {
+ SetMode(MATERIAL_TOUCH_OPTIMIZED);
} else if (switch_value == switches::kTopChromeMDMaterialAuto) {
#if defined(OS_WIN)
// TODO(girard): add support for switching between modes when
@@ -81,6 +83,11 @@ bool MaterialDesignController::IsSecondaryUiMaterial() {
}
// static
+bool MaterialDesignController::IsTouchOptimizedUiEnabled() {
+ return GetMode() == MATERIAL_TOUCH_OPTIMIZED;
+}
+
+// static
MaterialDesignController::Mode MaterialDesignController::DefaultMode() {
#if defined(OS_CHROMEOS)
// If a scan of available devices has already completed, use material-hybrid
diff --git a/chromium/ui/base/material_design/material_design_controller.h b/chromium/ui/base/material_design/material_design_controller.h
index e498ef2ea1f..731b304ad51 100644
--- a/chromium/ui/base/material_design/material_design_controller.h
+++ b/chromium/ui/base/material_design/material_design_controller.h
@@ -23,7 +23,9 @@ class UI_BASE_EXPORT MaterialDesignController {
// Basic material design.
MATERIAL_NORMAL = 0,
// Material design targeted at mouse/touch hybrid devices.
- MATERIAL_HYBRID = 1
+ MATERIAL_HYBRID = 1,
+ // Material design that is more optimized for touch devices.
+ MATERIAL_TOUCH_OPTIMIZED = 2
};
// Initializes |mode_|. Must be called before checking |mode_|.
@@ -36,6 +38,9 @@ class UI_BASE_EXPORT MaterialDesignController {
// should be extended to cover secondary UI.
static bool IsSecondaryUiMaterial();
+ // Returns true if the touch-optimized UI material design mode is enabled;
+ static bool IsTouchOptimizedUiEnabled();
+
// Returns the per-platform default material design variant.
static Mode DefaultMode();
diff --git a/chromium/ui/base/models/menu_model.cc b/chromium/ui/base/models/menu_model.cc
index 1b5f6ab0bca..2bed40097fd 100644
--- a/chromium/ui/base/models/menu_model.cc
+++ b/chromium/ui/base/models/menu_model.cc
@@ -40,6 +40,10 @@ base::string16 MenuModel::GetMinorTextAt(int index) const {
return base::string16();
}
+const gfx::VectorIcon* MenuModel::GetMinorIconAt(int index) const {
+ return nullptr;
+}
+
const gfx::FontList* MenuModel::GetLabelFontListAt(int index) const {
return NULL;
}
diff --git a/chromium/ui/base/models/menu_model.h b/chromium/ui/base/models/menu_model.h
index 0755f2752f1..605dc1b17e4 100644
--- a/chromium/ui/base/models/menu_model.h
+++ b/chromium/ui/base/models/menu_model.h
@@ -15,6 +15,7 @@
namespace gfx {
class FontList;
class Image;
+struct VectorIcon;
}
namespace ui {
@@ -65,6 +66,10 @@ class UI_BASE_EXPORT MenuModel {
// is rendered to the right of the label and using the font GetLabelFontAt().
virtual base::string16 GetMinorTextAt(int index) const;
+ // Returns the minor icon of the item at the specified index. The minor icon
+ // is rendered to the left of the minor text.
+ virtual const gfx::VectorIcon* GetMinorIconAt(int index) const;
+
// Returns true if the menu item (label/sublabel/icon) at the specified
// index can change over the course of the menu's lifetime. If this function
// returns true, the label, sublabel and icon of the menu item will be
diff --git a/chromium/ui/base/models/simple_menu_model.cc b/chromium/ui/base/models/simple_menu_model.cc
index 377d1eee2db..081f550689f 100644
--- a/chromium/ui/base/models/simple_menu_model.cc
+++ b/chromium/ui/base/models/simple_menu_model.cc
@@ -12,25 +12,11 @@
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "ui/base/l10n/l10n_util.h"
-#include "ui/gfx/image/image.h"
namespace ui {
const int kSeparatorId = -1;
-struct SimpleMenuModel::Item {
- int command_id;
- base::string16 label;
- base::string16 sublabel;
- base::string16 minor_text;
- gfx::Image icon;
- ItemType type;
- int group_id;
- MenuModel* submenu;
- ButtonMenuItemModel* button_model;
- MenuSeparatorType separator_type;
-};
-
////////////////////////////////////////////////////////////////////////////////
// SimpleMenuModel::Delegate, public:
@@ -83,17 +69,14 @@ bool SimpleMenuModel::Delegate::GetAcceleratorForCommandId(
SimpleMenuModel::SimpleMenuModel(Delegate* delegate)
: delegate_(delegate),
- menu_model_delegate_(NULL),
- method_factory_(this) {
-}
+ menu_model_delegate_(nullptr),
+ method_factory_(this) {}
SimpleMenuModel::~SimpleMenuModel() {
}
void SimpleMenuModel::AddItem(int command_id, const base::string16& label) {
- Item item = { command_id, label, base::string16(), base::string16(),
- gfx::Image(), TYPE_COMMAND, -1, NULL, NULL, NORMAL_SEPARATOR };
- AppendItem(item);
+ AppendItem(Item(command_id, TYPE_COMMAND, label));
}
void SimpleMenuModel::AddItemWithStringId(int command_id, int string_id) {
@@ -102,9 +85,7 @@ void SimpleMenuModel::AddItemWithStringId(int command_id, int string_id) {
void SimpleMenuModel::AddCheckItem(int command_id,
const base::string16& label) {
- Item item = { command_id, label, base::string16(), base::string16(),
- gfx::Image(), TYPE_CHECK, -1, NULL, NULL, NORMAL_SEPARATOR };
- AppendItem(item);
+ AppendItem(Item(command_id, TYPE_CHECK, label));
}
void SimpleMenuModel::AddCheckItemWithStringId(int command_id, int string_id) {
@@ -114,10 +95,9 @@ void SimpleMenuModel::AddCheckItemWithStringId(int command_id, int string_id) {
void SimpleMenuModel::AddRadioItem(int command_id,
const base::string16& label,
int group_id) {
- Item item = { command_id, label, base::string16(), base::string16(),
- gfx::Image(), TYPE_RADIO, group_id, NULL, NULL,
- NORMAL_SEPARATOR };
- AppendItem(item);
+ Item item(command_id, TYPE_RADIO, label);
+ item.group_id = group_id;
+ AppendItem(std::move(item));
}
void SimpleMenuModel::AddRadioItemWithStringId(int command_id, int string_id,
@@ -140,26 +120,24 @@ void SimpleMenuModel::AddSeparator(MenuSeparatorType separator_type) {
if (separator_type == SPACING_SEPARATOR)
NOTIMPLEMENTED();
#endif
- Item item = { kSeparatorId, base::string16(), base::string16(),
- base::string16(), gfx::Image(), TYPE_SEPARATOR, -1, NULL, NULL,
- separator_type };
- AppendItem(item);
+ Item item(kSeparatorId, TYPE_SEPARATOR, base::string16());
+ item.separator_type = separator_type;
+ AppendItem(std::move(item));
}
void SimpleMenuModel::AddButtonItem(int command_id,
ButtonMenuItemModel* model) {
- Item item = { command_id, base::string16(), base::string16(),
- base::string16(), gfx::Image(), TYPE_BUTTON_ITEM, -1, NULL,
- model, NORMAL_SEPARATOR };
- AppendItem(item);
+ Item item(command_id, TYPE_BUTTON_ITEM, base::string16());
+ item.button_model = model;
+ AppendItem(std::move(item));
}
void SimpleMenuModel::AddSubMenu(int command_id,
const base::string16& label,
MenuModel* model) {
- Item item = { command_id, label, base::string16(), base::string16(),
- gfx::Image(), TYPE_SUBMENU, -1, model, NULL, NORMAL_SEPARATOR };
- AppendItem(item);
+ Item item(command_id, TYPE_SUBMENU, label);
+ item.submenu = model;
+ AppendItem(std::move(item));
}
void SimpleMenuModel::AddSubMenuWithStringId(int command_id,
@@ -170,9 +148,7 @@ void SimpleMenuModel::AddSubMenuWithStringId(int command_id,
void SimpleMenuModel::InsertItemAt(int index,
int command_id,
const base::string16& label) {
- Item item = { command_id, label, base::string16(), base::string16(),
- gfx::Image(), TYPE_COMMAND, -1, NULL, NULL, NORMAL_SEPARATOR };
- InsertItemAtIndex(item, index);
+ InsertItemAtIndex(Item(command_id, TYPE_COMMAND, label), index);
}
void SimpleMenuModel::InsertItemWithStringIdAt(
@@ -187,18 +163,15 @@ void SimpleMenuModel::InsertSeparatorAt(int index,
NOTIMPLEMENTED();
}
#endif
- Item item = { kSeparatorId, base::string16(), base::string16(),
- base::string16(), gfx::Image(), TYPE_SEPARATOR, -1, NULL, NULL,
- separator_type };
- InsertItemAtIndex(item, index);
+ Item item(kSeparatorId, TYPE_SEPARATOR, base::string16());
+ item.separator_type = separator_type;
+ InsertItemAtIndex(std::move(item), index);
}
void SimpleMenuModel::InsertCheckItemAt(int index,
int command_id,
const base::string16& label) {
- Item item = { command_id, label, base::string16(), base::string16(),
- gfx::Image(), TYPE_CHECK, -1, NULL, NULL, NORMAL_SEPARATOR };
- InsertItemAtIndex(item, index);
+ InsertItemAtIndex(Item(command_id, TYPE_CHECK, label), index);
}
void SimpleMenuModel::InsertCheckItemWithStringIdAt(
@@ -210,10 +183,9 @@ void SimpleMenuModel::InsertRadioItemAt(int index,
int command_id,
const base::string16& label,
int group_id) {
- Item item = { command_id, label, base::string16(), base::string16(),
- gfx::Image(), TYPE_RADIO, group_id, NULL, NULL,
- NORMAL_SEPARATOR };
- InsertItemAtIndex(item, index);
+ Item item(command_id, TYPE_RADIO, label);
+ item.group_id = group_id;
+ InsertItemAtIndex(std::move(item), index);
}
void SimpleMenuModel::InsertRadioItemWithStringIdAt(
@@ -226,10 +198,9 @@ void SimpleMenuModel::InsertSubMenuAt(int index,
int command_id,
const base::string16& label,
MenuModel* model) {
- Item item = { command_id, label, base::string16(), base::string16(),
- gfx::Image(), TYPE_SUBMENU, -1, model, NULL,
- NORMAL_SEPARATOR };
- InsertItemAtIndex(item, index);
+ Item item(command_id, TYPE_SUBMENU, label);
+ item.submenu = model;
+ InsertItemAtIndex(std::move(item), index);
}
void SimpleMenuModel::InsertSubMenuWithStringIdAt(
@@ -258,6 +229,11 @@ void SimpleMenuModel::SetMinorText(int index,
items_[ValidateItemIndex(index)].minor_text = minor_text;
}
+void SimpleMenuModel::SetMinorIcon(int index,
+ const gfx::VectorIcon& minor_icon) {
+ items_[ValidateItemIndex(index)].minor_icon = &minor_icon;
+}
+
void SimpleMenuModel::Clear() {
items_.clear();
MenuItemsChanged();
@@ -317,6 +293,10 @@ base::string16 SimpleMenuModel::GetMinorTextAt(int index) const {
return items_[ValidateItemIndex(index)].minor_text;
}
+const gfx::VectorIcon* SimpleMenuModel::GetMinorIconAt(int index) const {
+ return items_[ValidateItemIndex(index)].minor_icon;
+}
+
bool SimpleMenuModel::IsItemDynamicAt(int index) const {
if (delegate_)
return delegate_->IsItemForCommandIdDynamic(GetCommandIdAt(index));
@@ -433,21 +413,27 @@ void SimpleMenuModel::MenuItemsChanged() {
////////////////////////////////////////////////////////////////////////////////
// SimpleMenuModel, Private:
+SimpleMenuModel::Item::Item(Item&&) = default;
+SimpleMenuModel::Item::Item(int command_id, ItemType type, base::string16 label)
+ : command_id(command_id), type(type), label(label) {}
+SimpleMenuModel::Item& SimpleMenuModel::Item::operator=(Item&&) = default;
+SimpleMenuModel::Item::~Item() = default;
+
int SimpleMenuModel::ValidateItemIndex(int index) const {
CHECK_GE(index, 0);
CHECK_LT(static_cast<size_t>(index), items_.size());
return index;
}
-void SimpleMenuModel::AppendItem(const Item& item) {
+void SimpleMenuModel::AppendItem(Item item) {
ValidateItem(item);
- items_.push_back(item);
+ items_.push_back(std::move(item));
MenuItemsChanged();
}
-void SimpleMenuModel::InsertItemAtIndex(const Item& item, int index) {
+void SimpleMenuModel::InsertItemAtIndex(Item item, int index) {
ValidateItem(item);
- items_.insert(items_.begin() + index, item);
+ items_.insert(items_.begin() + index, std::move(item));
MenuItemsChanged();
}
diff --git a/chromium/ui/base/models/simple_menu_model.h b/chromium/ui/base/models/simple_menu_model.h
index 5f05e870d65..72bf5e0907e 100644
--- a/chromium/ui/base/models/simple_menu_model.h
+++ b/chromium/ui/base/models/simple_menu_model.h
@@ -13,10 +13,7 @@
#include "base/strings/string16.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/models/menu_model.h"
-
-namespace gfx {
-class Image;
-}
+#include "ui/gfx/image/image.h"
namespace ui {
@@ -131,6 +128,9 @@ class UI_BASE_EXPORT SimpleMenuModel : public MenuModel {
// Sets the minor text for the item at |index|.
void SetMinorText(int index, const base::string16& minor_text);
+ // Sets the minor icon for the item at |index|.
+ void SetMinorIcon(int index, const gfx::VectorIcon& minor_icon);
+
// Clears all items. Note that it does not free MenuModel of submenu.
void Clear();
@@ -147,6 +147,7 @@ class UI_BASE_EXPORT SimpleMenuModel : public MenuModel {
base::string16 GetLabelAt(int index) const override;
base::string16 GetSublabelAt(int index) const override;
base::string16 GetMinorTextAt(int index) const override;
+ const gfx::VectorIcon* GetMinorIconAt(int index) const override;
bool IsItemDynamicAt(int index) const override;
bool GetAcceleratorAt(int index, ui::Accelerator* accelerator) const override;
bool IsItemCheckedAt(int index) const override;
@@ -179,7 +180,24 @@ class UI_BASE_EXPORT SimpleMenuModel : public MenuModel {
virtual void MenuItemsChanged();
private:
- struct Item;
+ struct Item {
+ Item(Item&&);
+ Item(int command_id, ItemType type, base::string16 label);
+ Item& operator=(Item&&);
+ ~Item();
+
+ int command_id = 0;
+ ItemType type = TYPE_COMMAND;
+ base::string16 label;
+ base::string16 sublabel;
+ base::string16 minor_text;
+ const gfx::VectorIcon* minor_icon = nullptr;
+ gfx::Image icon;
+ int group_id = -1;
+ MenuModel* submenu = nullptr;
+ ButtonMenuItemModel* button_model = nullptr;
+ MenuSeparatorType separator_type = NORMAL_SEPARATOR;
+ };
typedef std::vector<Item> ItemVector;
@@ -190,8 +208,8 @@ class UI_BASE_EXPORT SimpleMenuModel : public MenuModel {
int ValidateItemIndex(int index) const;
// Functions for inserting items into |items_|.
- void AppendItem(const Item& item);
- void InsertItemAtIndex(const Item& item, int index);
+ void AppendItem(Item item);
+ void InsertItemAtIndex(Item item, int index);
void ValidateItem(const Item& item);
// Notify the delegate that the menu is closed.
diff --git a/chromium/ui/base/mojo/DEPS b/chromium/ui/base/mojo/DEPS
index 4c418e20ff5..e0c12f73402 100644
--- a/chromium/ui/base/mojo/DEPS
+++ b/chromium/ui/base/mojo/DEPS
@@ -1,4 +1,4 @@
include_rules = [
"+mojo/public/cpp/bindings",
- "+third_party/WebKit/common/clipboard/clipboard.mojom-shared.h"
+ "+third_party/WebKit/public/mojom/clipboard/clipboard.mojom-shared.h"
]
diff --git a/chromium/ui/base/mojo/clipboard.typemap b/chromium/ui/base/mojo/clipboard.typemap
index 1063cb3671f..ebd328b5ad3 100644
--- a/chromium/ui/base/mojo/clipboard.typemap
+++ b/chromium/ui/base/mojo/clipboard.typemap
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-mojom = "//third_party/WebKit/common/clipboard/clipboard.mojom"
+mojom = "//third_party/WebKit/public/mojom/clipboard/clipboard.mojom"
public_headers = [ "//ui/base/clipboard/clipboard_types.h" ]
traits_headers = [ "//ui/base/mojo/clipboard_struct_traits.h" ]
deps = [
diff --git a/chromium/ui/base/mojo/clipboard_struct_traits.h b/chromium/ui/base/mojo/clipboard_struct_traits.h
index 81c618e3911..280a1f2bc97 100644
--- a/chromium/ui/base/mojo/clipboard_struct_traits.h
+++ b/chromium/ui/base/mojo/clipboard_struct_traits.h
@@ -5,7 +5,7 @@
#ifndef UI_BASE_MOJO_CLIPBOARD_STRUCT_TRAITS_H_
#define UI_BASE_MOJO_CLIPBOARD_STRUCT_TRAITS_H_
-#include "third_party/WebKit/common/clipboard/clipboard.mojom-shared.h"
+#include "third_party/WebKit/public/mojom/clipboard/clipboard.mojom-shared.h"
#include "ui/base/clipboard/clipboard_types.h"
namespace mojo {
diff --git a/chromium/ui/base/resource/resource_bundle.cc b/chromium/ui/base/resource/resource_bundle.cc
index 56101888f27..3bfd3cd883b 100644
--- a/chromium/ui/base/resource/resource_bundle.cc
+++ b/chromium/ui/base/resource/resource_bundle.cc
@@ -74,25 +74,6 @@ const char kPakFileExtension[] = ".pak";
ResourceBundle* g_shared_instance_ = NULL;
-#if defined(OS_ANDROID)
-// Returns the scale factor closest to |scale| from the full list of factors.
-// Note that it does NOT rely on the list of supported scale factors.
-// Finding the closest match is inefficient and shouldn't be done frequently.
-ScaleFactor FindClosestScaleFactorUnsafe(float scale) {
- float smallest_diff = std::numeric_limits<float>::max();
- ScaleFactor closest_match = SCALE_FACTOR_100P;
- for (int i = SCALE_FACTOR_100P; i < NUM_SCALE_FACTORS; ++i) {
- const ScaleFactor scale_factor = static_cast<ScaleFactor>(i);
- float diff = std::abs(GetScaleForScaleFactor(scale_factor) - scale);
- if (diff < smallest_diff) {
- closest_match = scale_factor;
- smallest_diff = diff;
- }
- }
- return closest_match;
-}
-#endif // OS_ANDROID
-
base::FilePath GetResourcesPakFilePath(const std::string& pak_name) {
base::FilePath path;
if (PathService::Get(base::DIR_MODULE, &path))
@@ -761,22 +742,7 @@ void ResourceBundle::InitSharedInstance(Delegate* delegate) {
DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice";
g_shared_instance_ = new ResourceBundle(delegate);
static std::vector<ScaleFactor> supported_scale_factors;
-#if !defined(OS_IOS)
- // On platforms other than iOS, 100P is always a supported scale factor.
- // For Windows we have a separate case in this function.
- supported_scale_factors.push_back(SCALE_FACTOR_100P);
-#endif
-#if defined(OS_ANDROID)
- float display_density;
- if (display::Display::HasForceDeviceScaleFactor()) {
- display_density = display::Display::GetForcedDeviceScaleFactor();
- } else {
- display_density = GetPrimaryDisplayScale();
- }
- const ScaleFactor closest = FindClosestScaleFactorUnsafe(display_density);
- if (closest != SCALE_FACTOR_100P)
- supported_scale_factors.push_back(closest);
-#elif defined(OS_IOS)
+#if defined(OS_IOS)
display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
if (display.device_scale_factor() > 2.0) {
DCHECK_EQ(3.0, display.device_scale_factor());
@@ -787,9 +753,14 @@ void ResourceBundle::InitSharedInstance(Delegate* delegate) {
} else {
supported_scale_factors.push_back(SCALE_FACTOR_100P);
}
-#elif defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_WIN)
+#else
+ // On platforms other than iOS, 100P is always a supported scale factor.
+ // For Windows we have a separate case in this function.
+ supported_scale_factors.push_back(SCALE_FACTOR_100P);
+#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_WIN)
supported_scale_factors.push_back(SCALE_FACTOR_200P);
#endif
+#endif
ui::SetSupportedScaleFactors(supported_scale_factors);
}
diff --git a/chromium/ui/base/resource/resource_bundle_android.cc b/chromium/ui/base/resource/resource_bundle_android.cc
index 0923b6fd6a3..a91fdabe964 100644
--- a/chromium/ui/base/resource/resource_bundle_android.cc
+++ b/chromium/ui/base/resource/resource_bundle_android.cc
@@ -211,9 +211,4 @@ std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) {
return base::android::ConvertJavaStringToUTF8(env, ret.obj());
}
-float GetPrimaryDisplayScale() {
- return Java_ResourceBundle_getPrimaryDisplayScale(
- base::android::AttachCurrentThread());
-}
-
} // namespace ui
diff --git a/chromium/ui/base/ui_base_features.cc b/chromium/ui/base/ui_base_features.cc
index f6be5b193e0..3e1850d3f45 100644
--- a/chromium/ui/base/ui_base_features.cc
+++ b/chromium/ui/base/ui_base_features.cc
@@ -4,19 +4,69 @@
#include "ui/base/ui_base_features.h"
+#include "ui/base/ui_base_switches_util.h"
+
+#if defined(OS_WIN)
+#include "base/win/windows_version.h"
+#endif
+
namespace features {
+// Enables the floating virtual keyboard behavior.
+const base::Feature kEnableFloatingVirtualKeyboard = {
+ "enable-floating-virtual-keyboard", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Applies the material design mode to elements throughout Chrome (not just top
+// Chrome).
+const base::Feature kSecondaryUiMd = {"SecondaryUiMd",
+// Enabled by default on Windows, Mac and Desktop Linux.
+// http://crbug.com/775847.
+#if defined(OS_WIN) || defined(OS_MACOSX) || \
+ (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+ base::FEATURE_ENABLED_BY_DEFAULT
+#else
+ base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+};
+
+const base::Feature kTouchableAppContextMenu = {
+ "EnableTouchableAppContextMenu", base::FEATURE_DISABLED_BY_DEFAULT};
+
+bool IsTouchableAppContextMenuEnabled() {
+ return base::FeatureList::IsEnabled(kTouchableAppContextMenu) ||
+ switches::IsTouchableAppContextMenuEnabled();
+}
+
#if defined(OS_WIN)
// Enables stylus appearing as touch when in contact with digitizer.
const base::Feature kDirectManipulationStylus = {
"DirectManipulationStylus", base::FEATURE_ENABLED_BY_DEFAULT};
+
+// Enables using WM_POINTER instead of WM_TOUCH for touch events.
+const base::Feature kPointerEventsForTouch = {"PointerEventsForTouch",
+ base::FEATURE_ENABLED_BY_DEFAULT};
+
+bool IsUsingWMPointerForTouch() {
+ return base::win::GetVersion() >= base::win::VERSION_WIN8 &&
+ base::FeatureList::IsEnabled(kPointerEventsForTouch);
+}
#endif // defined(OS_WIN)
-// Applies the material design mode to elements throughout Chrome (not just top
-// Chrome).
-const base::Feature kSecondaryUiMd = {"SecondaryUiMd",
- // Disabled for M65 on all platforms.
- // http://crbug.com/805776.
- base::FEATURE_DISABLED_BY_DEFAULT};
+// Used to have ash run in its own process. This implicitly turns on the
+// WindowService. That is, if this is set IsMusEnabled() returns true.
+const base::Feature kMash = {"Mash", base::FEATURE_DISABLED_BY_DEFAULT};
+
+// Used to control the mus service (aka the UI service). This makes mus run in
+// process.
+const base::Feature kMus = {"Mus", base::FEATURE_DISABLED_BY_DEFAULT};
+
+bool IsMusEnabled() {
+#if defined(USE_AURA)
+ return base::FeatureList::IsEnabled(features::kMus) ||
+ base::FeatureList::IsEnabled(features::kMash);
+#else
+ return false;
+#endif
+}
} // namespace features
diff --git a/chromium/ui/base/ui_base_features.h b/chromium/ui/base/ui_base_features.h
index 191fc9ef391..acff7278164 100644
--- a/chromium/ui/base/ui_base_features.h
+++ b/chromium/ui/base/ui_base_features.h
@@ -11,11 +11,32 @@
namespace features {
+// Keep sorted!
+UI_BASE_EXPORT extern const base::Feature kEnableFloatingVirtualKeyboard;
+UI_BASE_EXPORT extern const base::Feature kSecondaryUiMd;
+UI_BASE_EXPORT extern const base::Feature kTouchableAppContextMenu;
+
+UI_BASE_EXPORT bool IsTouchableAppContextMenuEnabled();
+
#if defined(OS_WIN)
UI_BASE_EXPORT extern const base::Feature kDirectManipulationStylus;
+UI_BASE_EXPORT extern const base::Feature kPointerEventsForTouch;
+
+// Returns true if the system should use WM_POINTER events for touch events.
+UI_BASE_EXPORT bool IsUsingWMPointerForTouch();
#endif // defined(OS_WIN)
-UI_BASE_EXPORT extern const base::Feature kSecondaryUiMd;
+// TODO(sky): rename this to something that better conveys what it means.
+UI_BASE_EXPORT extern const base::Feature kMash;
+// WARNING: generally you should only use this in tests to enable the feature.
+// Outside of tests use IsMusEnabled() to detect if mus is enabled.
+// TODO(sky): rename this to kWindowService.
+UI_BASE_EXPORT extern const base::Feature kMus;
+
+// Returns true if mus (the Window Service) is enabled.
+// NOTE: this returns true if either kMus or kMash is specified.
+// TODO(sky): rename this to IsWindowServiceEnabled().
+UI_BASE_EXPORT bool IsMusEnabled();
} // namespace features
diff --git a/chromium/ui/base/ui_base_switches.cc b/chromium/ui/base/ui_base_switches.cc
index 9f52ad1807c..254140166bc 100644
--- a/chromium/ui/base/ui_base_switches.cc
+++ b/chromium/ui/base/ui_base_switches.cc
@@ -4,14 +4,6 @@
#include "ui/base/ui_base_switches.h"
-namespace features {
-
-// Enables the floating virtual keyboard behavior.
-const base::Feature kEnableFloatingVirtualKeyboard = {
- "enable-floating-virtual-keyboard", base::FEATURE_DISABLED_BY_DEFAULT};
-
-} // namespace features
-
namespace switches {
#if defined(OS_MACOSX) && !defined(OS_IOS)
@@ -45,6 +37,10 @@ const char kDisableTouchDragDrop[] = "disable-touch-drag-drop";
// Enables touch event based drag and drop.
const char kEnableTouchDragDrop[] = "enable-touch-drag-drop";
+// Enables touchable app context menus and notification indicators.
+const char kEnableTouchableAppContextMenu[] =
+ "enable-touchable-app-context-menus";
+
// Forces high-contrast mode in native UI drawing, regardless of system
// settings. Note that this has limited effect on Windows: only Aura colors will
// be switched to high contrast, not other system colors.
@@ -78,6 +74,10 @@ const char kTopChromeMDMaterialAuto[] = "material-auto";
// mouse/touch hybrid devices.
const char kTopChromeMDMaterialHybrid[] = "material-hybrid";
+// Material design mode that is more optimized for touch devices for the
+// |kTopChromeMD| switch.
+const char kTopChromeMDMaterialTouchOptimized[] = "material-touch-optimized";
+
// Classic, non-material, mode for the |kTopChromeMD| switch.
const char kTopChromeMDNonMaterial[] = "non-material";
@@ -96,9 +96,6 @@ const char kUIDisablePartialSwap[] = "ui-disable-partial-swap";
// Red: Overdrawn four or more times.
const char kShowOverdrawFeedback[] = "show-overdraw-feedback";
-// Use draw occlusion to skip draw quads when they are not shown on screen.
-const char kEnableDrawOcclusion[] = "enable-draw-occlusion";
-
// Use SkiaRenderer instead of GLRenderer for direct rendering.
const char kUseSkiaRenderer[] = "use-skia-renderer";
@@ -120,14 +117,4 @@ const char kSlowDownCompositingScaleFactor[] =
// Tint GL-composited color.
const char kTintGlCompositedContent[] = "tint-gl-composited-content";
-#if defined(USE_AURA)
-// Used to enable the mus service (aka the UI service). This makes mus run in
-// process. It is also used to notify the clients that the UI service is being
-// used.
-const char kMus[] = "mus";
-
-// If set mus is hosting Viz. Only applicable is kMus if specified.
-const char kMusHostingViz[] = "mus-hosting-viz";
-#endif
-
} // namespace switches
diff --git a/chromium/ui/base/ui_base_switches.h b/chromium/ui/base/ui_base_switches.h
index 6269678a013..2ce580331e3 100644
--- a/chromium/ui/base/ui_base_switches.h
+++ b/chromium/ui/base/ui_base_switches.h
@@ -7,16 +7,8 @@
#ifndef UI_BASE_UI_BASE_SWITCHES_H_
#define UI_BASE_UI_BASE_SWITCHES_H_
-#include "base/feature_list.h"
#include "build/build_config.h"
#include "ui/base/ui_base_export.h"
-#include "ui/base/ui_features.h"
-
-namespace features {
-
-UI_BASE_EXPORT extern const base::Feature kEnableFloatingVirtualKeyboard;
-
-} // namespace features
namespace switches {
@@ -31,8 +23,8 @@ UI_BASE_EXPORT extern const char kDisableCompositedAntialiasing[];
UI_BASE_EXPORT extern const char kDisableDwmComposition[];
UI_BASE_EXPORT extern const char kDisableTouchAdjustment[];
UI_BASE_EXPORT extern const char kDisableTouchDragDrop[];
-UI_BASE_EXPORT extern const char kEnableDrawOcclusion[];
UI_BASE_EXPORT extern const char kEnableTouchDragDrop[];
+UI_BASE_EXPORT extern const char kEnableTouchableAppContextMenu[];
UI_BASE_EXPORT extern const char kForceHighContrast[];
UI_BASE_EXPORT extern const char kLang[];
UI_BASE_EXPORT extern const char kMaterialDesignInkDropAnimationSpeed[];
@@ -45,6 +37,7 @@ UI_BASE_EXPORT extern const char kTopChromeMD[];
UI_BASE_EXPORT extern const char kTopChromeMDMaterial[];
UI_BASE_EXPORT extern const char kTopChromeMDMaterialAuto[];
UI_BASE_EXPORT extern const char kTopChromeMDMaterialHybrid[];
+UI_BASE_EXPORT extern const char kTopChromeMDMaterialTouchOptimized[];
UI_BASE_EXPORT extern const char kTopChromeMDNonMaterial[];
UI_BASE_EXPORT extern const char kUIDisablePartialSwap[];
UI_BASE_EXPORT extern const char kUseSkiaRenderer[];
@@ -53,11 +46,6 @@ UI_BASE_EXPORT extern const char kUseSkiaRenderer[];
UI_BASE_EXPORT extern const char kDisallowNonExactResourceReuse[];
UI_BASE_EXPORT extern const char kMangleLocalizedStrings[];
-#if defined(USE_AURA)
-UI_BASE_EXPORT extern const char kMus[];
-UI_BASE_EXPORT extern const char kMusHostingViz[];
-#endif
-
} // namespace switches
#endif // UI_BASE_UI_BASE_SWITCHES_H_
diff --git a/chromium/ui/base/ui_base_switches_util.cc b/chromium/ui/base/ui_base_switches_util.cc
index 92019a32a89..ad8161db43d 100644
--- a/chromium/ui/base/ui_base_switches_util.cc
+++ b/chromium/ui/base/ui_base_switches_util.cc
@@ -13,21 +13,16 @@ namespace switches {
bool IsTouchDragDropEnabled() {
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
return !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableTouchDragDrop);
+ kDisableTouchDragDrop);
#else
return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableTouchDragDrop);
+ kEnableTouchDragDrop);
#endif
}
-bool IsMusHostingViz() {
-#if defined(USE_AURA)
- auto* cmd = base::CommandLine::ForCurrentProcess();
- return cmd->HasSwitch(switches::kMus) &&
- cmd->HasSwitch(switches::kMusHostingViz);
-#else
- return false;
-#endif
+bool IsTouchableAppContextMenuEnabled() {
+ return base::CommandLine::ForCurrentProcess()->HasSwitch(
+ kEnableTouchableAppContextMenu);
}
} // namespace switches
diff --git a/chromium/ui/base/ui_base_switches_util.h b/chromium/ui/base/ui_base_switches_util.h
index 70ba67038e3..f84ed94f36a 100644
--- a/chromium/ui/base/ui_base_switches_util.h
+++ b/chromium/ui/base/ui_base_switches_util.h
@@ -12,9 +12,9 @@ namespace switches {
UI_BASE_EXPORT bool IsLinkDisambiguationPopupEnabled();
UI_BASE_EXPORT bool IsTouchDragDropEnabled();
-// Returns whether mus is hosting viz. Mus is hosting viz only if
-// --mus-hosting-viz is set.
-UI_BASE_EXPORT bool IsMusHostingViz();
+// Returns whether the touchable app context menu switch has been set. Prefer
+// features::IsTouchableAppContextMenuEnabled().
+UI_BASE_EXPORT bool IsTouchableAppContextMenuEnabled();
} // namespace switches
diff --git a/chromium/ui/base/ui_features.gni b/chromium/ui/base/ui_features.gni
index 708a8f86fd8..806ef9505ad 100644
--- a/chromium/ui/base/ui_features.gni
+++ b/chromium/ui/base/ui_features.gni
@@ -17,8 +17,8 @@ declare_args() {
# Whether the message center should be included for displaying notifications.
enable_message_center = is_win || is_mac || is_linux || is_chromeos
- # Set to true to if mus (aka the UI service) is enabled. Use --mus (or --mash
- # in chrome code) to start in mus/mash.
+ # Set to true to if mus (aka the UI service) is enabled. Use the features kMus
+ # (or kMash in chrome code) to start in mus/mash.
enable_mus = is_chromeos
# Optimize parts of Chrome's UI written with web technologies (HTML/CSS/JS)
diff --git a/chromium/ui/gfx/win/direct_manipulation.cc b/chromium/ui/base/win/direct_manipulation.cc
index 73084992d12..78f19277727 100644
--- a/chromium/ui/gfx/win/direct_manipulation.cc
+++ b/chromium/ui/base/win/direct_manipulation.cc
@@ -2,13 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/gfx/win/direct_manipulation.h"
+#include "ui/base/win/direct_manipulation.h"
#include <objbase.h>
#include "base/win/windows_version.h"
-namespace gfx {
+namespace ui {
namespace win {
// static
@@ -17,7 +17,7 @@ DirectManipulationHelper::CreateInstance() {
// TODO(dtapuska): Do not create a DirectManipulationHelper on any windows
// versions as it only causes issues. High Precision Touchpad events seem to
// always be sent to apps with recent Windows 10 versions. This class should
- // eventually be removed. See crbug.com/647038.
+ // eventually be removed. See https://crbug.com/647038.
return nullptr;
}
@@ -60,14 +60,14 @@ void DirectManipulationHelper::Initialize(HWND window) {
// Enable the desired configuration for each viewport.
//
DIRECTMANIPULATION_CONFIGURATION configuration =
- DIRECTMANIPULATION_CONFIGURATION_INTERACTION
- | DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_X
- | DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_Y
- | DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_INERTIA
- | DIRECTMANIPULATION_CONFIGURATION_RAILS_X
- | DIRECTMANIPULATION_CONFIGURATION_RAILS_Y
- | DIRECTMANIPULATION_CONFIGURATION_SCALING
- | DIRECTMANIPULATION_CONFIGURATION_SCALING_INERTIA;
+ DIRECTMANIPULATION_CONFIGURATION_INTERACTION |
+ DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_X |
+ DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_Y |
+ DIRECTMANIPULATION_CONFIGURATION_TRANSLATION_INERTIA |
+ DIRECTMANIPULATION_CONFIGURATION_RAILS_X |
+ DIRECTMANIPULATION_CONFIGURATION_RAILS_Y |
+ DIRECTMANIPULATION_CONFIGURATION_SCALING |
+ DIRECTMANIPULATION_CONFIGURATION_SCALING_INERTIA;
hr = view_port_outer_->ActivateConfiguration(configuration);
CHECK(SUCCEEDED(hr));
@@ -103,9 +103,11 @@ void DirectManipulationHelper::Deactivate(HWND window) {
manager_->Deactivate(window);
}
-void DirectManipulationHelper:: HandleMouseWheel(HWND window, UINT message,
- WPARAM w_param, LPARAM l_param) {
- MSG msg = { window, message, w_param, l_param};
+void DirectManipulationHelper::HandleMouseWheel(HWND window,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param) {
+ MSG msg = {window, message, w_param, l_param};
HRESULT hr = view_port_outer_->SetContact(DIRECTMANIPULATION_MOUSEFOCUS);
if (SUCCEEDED(hr)) {
@@ -116,4 +118,4 @@ void DirectManipulationHelper:: HandleMouseWheel(HWND window, UINT message,
}
} // namespace win.
-} // namespace gfx.
+} // namespace ui.
diff --git a/chromium/ui/gfx/win/direct_manipulation.h b/chromium/ui/base/win/direct_manipulation.h
index 155b40b7d09..af7ad807f2e 100644
--- a/chromium/ui/gfx/win/direct_manipulation.h
+++ b/chromium/ui/base/win/direct_manipulation.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_GFX_WIN_DIRECT_MANIPULATION_H_
-#define UI_GFX_WIN_DIRECT_MANIPULATION_H_
+#ifndef UI_WIN_DIRECT_MANIPULATION_H_
+#define UI_WIN_DIRECT_MANIPULATION_H_
#include <directmanipulation.h>
#include <wrl/client.h>
@@ -11,10 +11,10 @@
#include <memory>
#include "base/macros.h"
+#include "ui/base/ui_base_export.h"
#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/gfx_export.h"
-namespace gfx {
+namespace ui {
namespace win {
// Windows 10 provides a new API called Direct Manipulation which generates
@@ -39,7 +39,7 @@ namespace win {
// Direct Manipulation consumer. We don't rely on Direct manipulation
// to do the smooth scrolling in the background thread as documented on
// msdn.
-class GFX_EXPORT DirectManipulationHelper {
+class UI_BASE_EXPORT DirectManipulationHelper {
public:
// Creates an instance of this class if Direct Manipulation is enabled on
// the platform. If not returns NULL.
@@ -63,8 +63,10 @@ class GFX_EXPORT DirectManipulationHelper {
// Passes the WM_MOUSEWHEEL messages to Direct Manipulation. This is for
// logistics purposes.
- void HandleMouseWheel(HWND window, UINT message, WPARAM w_param,
- LPARAM l_param);
+ void HandleMouseWheel(HWND window,
+ UINT message,
+ WPARAM w_param,
+ LPARAM l_param);
~DirectManipulationHelper();
@@ -81,6 +83,6 @@ class GFX_EXPORT DirectManipulationHelper {
};
} // namespace win
-} // namespace gfx
+} // namespace ui
-#endif // UI_GFX_WIN_DIRECT_MANIPULATION_H_
+#endif // UI_WIN_DIRECT_MANIPULATION_H_
diff --git a/chromium/ui/base/win/on_screen_keyboard_display_manager_tab_tip.cc b/chromium/ui/base/win/on_screen_keyboard_display_manager_tab_tip.cc
new file mode 100644
index 00000000000..bbce7bda6eb
--- /dev/null
+++ b/chromium/ui/base/win/on_screen_keyboard_display_manager_tab_tip.cc
@@ -0,0 +1,379 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/win/osk_display_manager.h"
+
+#include <windows.h>
+#include <shellapi.h>
+#include <shlobj.h>
+#include <shobjidl.h> // Must be before propkey.
+
+#include "base/bind.h"
+#include "base/debug/leak_annotations.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/single_thread_task_runner.h"
+#include "base/strings/string_util.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/win/registry.h"
+#include "base/win/scoped_co_mem.h"
+#include "base/win/win_util.h"
+#include "base/win/windows_version.h"
+#include "ui/base/win/hidden_window.h"
+#include "ui/base/win/osk_display_observer.h"
+#include "ui/display/win/dpi.h"
+#include "ui/gfx/geometry/dip_util.h"
+
+namespace {
+
+constexpr int kCheckOSKDelayMs = 1000;
+constexpr int kDismissKeyboardRetryTimeoutMs = 100;
+constexpr int kDismissKeyboardMaxRetries = 5;
+
+constexpr wchar_t kOSKClassName[] = L"IPTip_Main_Window";
+
+constexpr wchar_t kWindows8OSKRegPath[] =
+ L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}"
+ L"\\LocalServer32";
+
+} // namespace
+
+namespace ui {
+
+// This class provides functionality to detect when the on screen keyboard
+// is displayed and move the main window up if it is obscured by the keyboard.
+class OnScreenKeyboardDetector {
+ public:
+ OnScreenKeyboardDetector();
+ ~OnScreenKeyboardDetector();
+
+ // Schedules a delayed task which detects if the on screen keyboard was
+ // displayed.
+ void DetectKeyboard(HWND main_window);
+
+ // Dismisses the on screen keyboard. If a call to display the keyboard was
+ // made, this function waits for the keyboard to become visible by retrying
+ // upto a maximum of kDismissKeyboardMaxRetries.
+ bool DismissKeyboard();
+
+ // Add/Remove keyboard observers.
+ // Please note that this class does not track the |observer| destruction. It
+ // is upto the classes which set up these observers to remove them when they
+ // are destroyed.
+ void AddObserver(OnScreenKeyboardObserver* observer);
+ void RemoveObserver(OnScreenKeyboardObserver* observer);
+
+ // Returns true if the osk is visible. Sets osk bounding rect if non-null
+ static bool IsKeyboardVisible(gfx::Rect* osk_bounding_rect);
+
+ private:
+ // Executes as a task and detects if the on screen keyboard is displayed.
+ // Once the keyboard is displayed it schedules the HideIfNecessary() task to
+ // detect when the keyboard is or should be hidden.
+ void CheckIfKeyboardVisible();
+
+ // Executes as a task and detects if the keyboard was hidden or should be
+ // hidden.
+ void HideIfNecessary();
+
+ // Notifies observers that the keyboard was displayed.
+ // A recurring task HideIfNecessary() is started to detect when the OSK
+ // disappears.
+ void HandleKeyboardVisible();
+
+ // Notifies observers that the keyboard was hidden.
+ // The observer list is cleared out after this notification.
+ void HandleKeyboardHidden();
+
+ // Removes all observers from the list.
+ void ClearObservers();
+
+ // The main window which displays the on screen keyboard.
+ HWND main_window_ = nullptr;
+
+ // Tracks if the keyboard was displayed.
+ bool osk_visible_notification_received_ = false;
+
+ // The keyboard dimensions in pixels.
+ gfx::Rect osk_rect_pixels_;
+
+ // Set to true if a call to DetectKeyboard() was made.
+ bool keyboard_detect_requested_ = false;
+
+ // Contains the number of attempts made to dismiss the keyboard. Please refer
+ // to the DismissKeyboard() function for more information.
+ int keyboard_dismiss_retry_count_ = 0;
+
+ base::ObserverList<OnScreenKeyboardObserver, false> observers_;
+
+ // Should be the last member in the class. Helps ensure that tasks spawned
+ // by this class instance are canceled when it is destroyed.
+ base::WeakPtrFactory<OnScreenKeyboardDetector> keyboard_detector_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(OnScreenKeyboardDetector);
+};
+
+// OnScreenKeyboardDetector member definitions.
+OnScreenKeyboardDetector::OnScreenKeyboardDetector()
+ : keyboard_detector_factory_(this) {}
+
+OnScreenKeyboardDetector::~OnScreenKeyboardDetector() {
+ ClearObservers();
+}
+
+void OnScreenKeyboardDetector::DetectKeyboard(HWND main_window) {
+ main_window_ = main_window;
+ keyboard_detect_requested_ = true;
+ // The keyboard is displayed by TabTip.exe which is launched via a
+ // ShellExecute call in the
+ // OnScreenKeyboardDisplayManager::DisplayVirtualKeyboard() function. We use
+ // a delayed task to check if the keyboard is visible because of the possible
+ // delay between the ShellExecute call and the keyboard becoming visible.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, base::Bind(&OnScreenKeyboardDetector::CheckIfKeyboardVisible,
+ keyboard_detector_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kCheckOSKDelayMs));
+}
+
+bool OnScreenKeyboardDetector::DismissKeyboard() {
+ // We dismiss the virtual keyboard by generating the ESC keystroke
+ // programmatically.
+ HWND osk = ::FindWindow(kOSKClassName, nullptr);
+ if (::IsWindow(osk) && ::IsWindowEnabled(osk)) {
+ keyboard_detect_requested_ = false;
+ keyboard_dismiss_retry_count_ = 0;
+ HandleKeyboardHidden();
+ PostMessage(osk, WM_SYSCOMMAND, SC_CLOSE, 0);
+ return true;
+ } else if (keyboard_detect_requested_) {
+ if (keyboard_dismiss_retry_count_ < kDismissKeyboardMaxRetries) {
+ keyboard_dismiss_retry_count_++;
+ // Please refer to the comments in the DetectKeyboard() function for more
+ // information as to why we need a delayed task here.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, base::Bind(base::IgnoreResult(
+ &OnScreenKeyboardDetector::DismissKeyboard),
+ keyboard_detector_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kDismissKeyboardRetryTimeoutMs));
+ } else {
+ keyboard_dismiss_retry_count_ = 0;
+ }
+ }
+ return false;
+}
+
+void OnScreenKeyboardDetector::AddObserver(OnScreenKeyboardObserver* observer) {
+ observers_.AddObserver(observer);
+}
+
+void OnScreenKeyboardDetector::RemoveObserver(
+ OnScreenKeyboardObserver* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+// static
+bool OnScreenKeyboardDetector::IsKeyboardVisible(gfx::Rect* osk_bounding_rect) {
+ HWND osk = ::FindWindow(kOSKClassName, nullptr);
+ if (!::IsWindow(osk))
+ return false;
+ if (osk_bounding_rect) {
+ RECT osk_rect = {};
+ ::GetWindowRect(osk, &osk_rect);
+ *osk_bounding_rect = gfx::Rect(osk_rect);
+ }
+ return ::IsWindowVisible(osk) && ::IsWindowEnabled(osk);
+}
+
+void OnScreenKeyboardDetector::CheckIfKeyboardVisible() {
+ if (IsKeyboardVisible(&osk_rect_pixels_)) {
+ if (!osk_visible_notification_received_)
+ HandleKeyboardVisible();
+ } else {
+ DVLOG(1) << "OSK did not come up in 1 second. Something wrong.";
+ }
+}
+
+void OnScreenKeyboardDetector::HideIfNecessary() {
+ HWND osk = ::FindWindow(kOSKClassName, nullptr);
+ if (!::IsWindow(osk))
+ return;
+
+ // Three cases here.
+ // 1. OSK was hidden because the user dismissed it.
+ // 2. We are no longer in the foreground.
+ // 3. The OSK is still visible.
+ // In the first case we just have to notify the observers that the OSK was
+ // hidden.
+ // In the second case we need to dismiss the OSK which internally will
+ // notify the observers about the OSK being hidden.
+ if (!::IsWindowEnabled(osk)) {
+ if (osk_visible_notification_received_) {
+ if (main_window_ == ::GetForegroundWindow()) {
+ DVLOG(1) << "OSK window hidden while we are in the foreground.";
+ HandleKeyboardHidden();
+ }
+ }
+ } else if (main_window_ != ::GetForegroundWindow()) {
+ if (osk_visible_notification_received_) {
+ DVLOG(1) << "We are no longer in the foreground. Dismising OSK.";
+ DismissKeyboard();
+ }
+ } else {
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, base::Bind(&OnScreenKeyboardDetector::HideIfNecessary,
+ keyboard_detector_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kCheckOSKDelayMs));
+ }
+}
+
+void OnScreenKeyboardDetector::HandleKeyboardVisible() {
+ DCHECK(!osk_visible_notification_received_);
+ osk_visible_notification_received_ = true;
+
+ for (OnScreenKeyboardObserver& observer : observers_)
+ observer.OnKeyboardVisible(osk_rect_pixels_);
+
+ // Now that the keyboard is visible, run the task to detect if it was hidden.
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, base::Bind(&OnScreenKeyboardDetector::HideIfNecessary,
+ keyboard_detector_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kCheckOSKDelayMs));
+}
+
+void OnScreenKeyboardDetector::HandleKeyboardHidden() {
+ osk_visible_notification_received_ = false;
+ for (OnScreenKeyboardObserver& observer : observers_)
+ observer.OnKeyboardHidden(osk_rect_pixels_);
+ ClearObservers();
+}
+
+void OnScreenKeyboardDetector::ClearObservers() {
+ for (auto& observer : observers_)
+ RemoveObserver(&observer);
+}
+
+// OnScreenKeyboardDisplayManager member definitions.
+OnScreenKeyboardDisplayManager::OnScreenKeyboardDisplayManager() {}
+
+OnScreenKeyboardDisplayManager::~OnScreenKeyboardDisplayManager() {}
+
+OnScreenKeyboardDisplayManager* OnScreenKeyboardDisplayManager::GetInstance() {
+ static OnScreenKeyboardDisplayManager* instance = nullptr;
+ if (!instance) {
+ instance = new OnScreenKeyboardDisplayManager;
+ ANNOTATE_LEAKING_OBJECT_PTR(instance);
+ }
+ return instance;
+}
+
+bool OnScreenKeyboardDisplayManager::DisplayVirtualKeyboard(
+ OnScreenKeyboardObserver* observer) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return false;
+
+ if (base::win::IsKeyboardPresentOnSlate(nullptr, ui::GetHiddenWindow()))
+ return false;
+
+ if (osk_path_.empty() && !GetOSKPath(&osk_path_)) {
+ DLOG(WARNING) << "Failed to get on screen keyboard path from registry";
+ return false;
+ }
+
+ HINSTANCE ret = ::ShellExecuteW(nullptr, L"", osk_path_.c_str(), nullptr,
+ nullptr, SW_SHOW);
+
+ bool success = reinterpret_cast<intptr_t>(ret) > 32;
+ if (success) {
+ // If multiple calls to DisplayVirtualKeyboard occur one after the other,
+ // the last observer would be the one to get notifications.
+ keyboard_detector_.reset(new OnScreenKeyboardDetector);
+ if (observer)
+ keyboard_detector_->AddObserver(observer);
+ keyboard_detector_->DetectKeyboard(::GetForegroundWindow());
+ }
+ return success;
+}
+
+bool OnScreenKeyboardDisplayManager::DismissVirtualKeyboard() {
+ if (base::win::GetVersion() < base::win::VERSION_WIN8)
+ return false;
+
+ return keyboard_detector_ ? keyboard_detector_->DismissKeyboard() : false;
+}
+
+void OnScreenKeyboardDisplayManager::RemoveObserver(
+ OnScreenKeyboardObserver* observer) {
+ if (keyboard_detector_)
+ keyboard_detector_->RemoveObserver(observer);
+}
+
+bool OnScreenKeyboardDisplayManager::GetOSKPath(base::string16* osk_path) {
+ DCHECK(osk_path);
+
+ // We need to launch TabTip.exe from the location specified under the
+ // LocalServer32 key for the {{054AAE20-4BEA-4347-8A35-64A533254A9D}}
+ // CLSID.
+ // TabTip.exe is typically found at
+ // c:\program files\common files\microsoft shared\ink on English Windows.
+ // We don't want to launch TabTip.exe from
+ // c:\program files (x86)\common files\microsoft shared\ink. This path is
+ // normally found on 64 bit Windows.
+ base::win::RegKey key(HKEY_LOCAL_MACHINE, kWindows8OSKRegPath,
+ KEY_READ | KEY_WOW64_64KEY);
+ DWORD osk_path_length = 1024;
+ if (key.ReadValue(nullptr, base::WriteInto(osk_path, osk_path_length),
+ &osk_path_length, nullptr) != ERROR_SUCCESS) {
+ return false;
+ }
+
+ osk_path->resize(base::string16::traits_type::length(osk_path->c_str()));
+
+ *osk_path = base::ToLowerASCII(*osk_path);
+
+ size_t common_program_files_offset = osk_path->find(L"%commonprogramfiles%");
+ // Typically the path to TabTip.exe read from the registry will start with
+ // %CommonProgramFiles% which needs to be replaced with the corrsponding
+ // expanded string.
+ // If the path does not begin with %CommonProgramFiles% we use it as is.
+ if (common_program_files_offset != base::string16::npos) {
+ // Preserve the beginning quote in the path.
+ osk_path->erase(common_program_files_offset,
+ wcslen(L"%commonprogramfiles%"));
+ // The path read from the registry contains the %CommonProgramFiles%
+ // environment variable prefix. On 64 bit Windows the SHGetKnownFolderPath
+ // function returns the common program files path with the X86 suffix for
+ // the FOLDERID_ProgramFilesCommon value.
+ // To get the correct path to TabTip.exe we first read the environment
+ // variable CommonProgramW6432 which points to the desired common
+ // files path. Failing that we fallback to the SHGetKnownFolderPath API.
+
+ // We then replace the %CommonProgramFiles% value with the actual common
+ // files path found in the process.
+ base::string16 common_program_files_path;
+ DWORD buffer_size =
+ GetEnvironmentVariable(L"CommonProgramW6432", nullptr, 0);
+ if (buffer_size) {
+ GetEnvironmentVariable(
+ L"CommonProgramW6432",
+ base::WriteInto(&common_program_files_path, buffer_size),
+ buffer_size);
+ DCHECK(!common_program_files_path.empty());
+ } else {
+ base::win::ScopedCoMem<wchar_t> common_program_files;
+ if (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramFilesCommon, 0, nullptr,
+ &common_program_files))) {
+ return false;
+ }
+ common_program_files_path = common_program_files;
+ }
+ osk_path->insert(common_program_files_offset, common_program_files_path);
+ }
+ return !osk_path->empty();
+}
+
+bool OnScreenKeyboardDisplayManager::IsKeyboardVisible() const {
+ return OnScreenKeyboardDetector::IsKeyboardVisible(nullptr);
+}
+
+} // namespace ui
diff --git a/chromium/ui/base/win/on_screen_keyboard_display_manager_tab_tip.h b/chromium/ui/base/win/on_screen_keyboard_display_manager_tab_tip.h
new file mode 100644
index 00000000000..b5392c4b686
--- /dev/null
+++ b/chromium/ui/base/win/on_screen_keyboard_display_manager_tab_tip.h
@@ -0,0 +1,60 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_BASE_WIN_OSK_DISPLAY_MANAGER_H_
+#define UI_BASE_WIN_OSK_DISPLAY_MANAGER_H_
+
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "base/strings/string16.h"
+#include "ui/base/ui_base_export.h"
+#include "ui/gfx/geometry/rect.h"
+
+namespace ui {
+
+class OnScreenKeyboardDetector;
+class OnScreenKeyboardObserver;
+
+// This class provides functionality to display the on screen keyboard on
+// Windows 8+. It optionally notifies observers that the OSK is displayed,
+// hidden, etc.
+class UI_BASE_EXPORT OnScreenKeyboardDisplayManager {
+ public:
+ static OnScreenKeyboardDisplayManager* GetInstance();
+
+ ~OnScreenKeyboardDisplayManager();
+
+ // Functions to display and dismiss the keyboard.
+ // The optional |observer| parameter allows callers to be notified when the
+ // keyboard is displayed, dismissed, etc.
+ bool DisplayVirtualKeyboard(OnScreenKeyboardObserver* observer);
+ // When the keyboard is dismissed, the registered observer if any is removed
+ // after notifying it.
+ bool DismissVirtualKeyboard();
+
+ // Removes a registered observer.
+ void RemoveObserver(OnScreenKeyboardObserver* observer);
+
+ // Returns the path of the on screen keyboard exe (TabTip.exe) in the
+ // |osk_path| parameter.
+ // Returns true on success.
+ bool GetOSKPath(base::string16* osk_path);
+
+ // Returns true if the virtual keyboard is currently visible.
+ bool IsKeyboardVisible() const;
+
+ private:
+ OnScreenKeyboardDisplayManager();
+
+ std::unique_ptr<OnScreenKeyboardDetector> keyboard_detector_;
+
+ // The location of TabTip.exe.
+ base::string16 osk_path_;
+
+ DISALLOW_COPY_AND_ASSIGN(OnScreenKeyboardDisplayManager);
+};
+
+} // namespace ui
+
+#endif // UI_BASE_WIN_OSK_DISPLAY_MANAGER_H_
diff --git a/chromium/ui/base/win/shell.cc b/chromium/ui/base/win/shell.cc
index ebd6c65d481..b5afdead174 100644
--- a/chromium/ui/base/win/shell.cc
+++ b/chromium/ui/base/win/shell.cc
@@ -27,29 +27,21 @@ namespace win {
namespace {
-// Default ShellExecuteEx flags used with the "openas" verb.
+// Default ShellExecuteEx flags used with "openas", "explore", and default
+// verbs.
//
// SEE_MASK_NOASYNC is specified so that ShellExecuteEx can be invoked from a
// thread whose message loop may not wait around long enough for the
// asynchronous tasks initiated by ShellExecuteEx to complete. Using this flag
// causes ShellExecuteEx() to block until these tasks complete.
-const DWORD kDefaultOpenAsFlags = SEE_MASK_NOASYNC;
-
-// Default ShellExecuteEx flags used with the "explore", "open" or default verb.
-//
-// See kDefaultOpenFlags for description SEE_MASK_NOASYNC flag.
-// SEE_MASK_FLAG_NO_UI is used to suppress any error message boxes that might be
-// displayed if there is an error in opening the file. Failure in invoking the
-// "open" actions result in invocation of the "saveas" verb, making the error
-// dialog superfluous.
-const DWORD kDefaultOpenFlags = SEE_MASK_NOASYNC | SEE_MASK_FLAG_NO_UI;
+const DWORD kDefaultShellExecuteFlags = SEE_MASK_NOASYNC;
// Invokes ShellExecuteExW() with the given parameters.
-DWORD InvokeShellExecute(const base::string16 path,
- const base::string16 working_directory,
- const base::string16 args,
- const base::string16 verb,
- DWORD mask) {
+bool InvokeShellExecute(const base::string16 path,
+ const base::string16 working_directory,
+ const base::string16 args,
+ const base::string16 verb,
+ DWORD mask) {
base::AssertBlockingAllowed();
SHELLEXECUTEINFO sei = {sizeof(sei)};
sei.fMask = mask;
@@ -59,7 +51,7 @@ DWORD InvokeShellExecute(const base::string16 path,
sei.lpDirectory =
(working_directory.empty() ? nullptr : working_directory.c_str());
sei.lpParameters = (args.empty() ? nullptr : args.c_str());
- return ::ShellExecuteExW(&sei) ? ERROR_SUCCESS : ::GetLastError();
+ return ::ShellExecuteExW(&sei);
}
} // namespace
@@ -68,32 +60,22 @@ bool OpenAnyViaShell(const base::string16& full_path,
const base::string16& directory,
const base::string16& args,
DWORD mask) {
- DWORD open_result =
- InvokeShellExecute(full_path, directory, args, base::string16(), mask);
- if (open_result == ERROR_SUCCESS)
- return true;
- // Show the Windows "Open With" dialog box to ask the user to pick an app to
- // open the file with. Note that we are not forwarding |args| for the "openas"
- // call since the target application is nolonger known at this point.
- if (open_result == ERROR_NO_ASSOCIATION)
- return InvokeShellExecute(full_path, directory, base::string16(), L"openas",
- kDefaultOpenAsFlags) == ERROR_SUCCESS;
- return false;
+ return InvokeShellExecute(full_path, directory, args, base::string16(), mask);
}
bool OpenFileViaShell(const base::FilePath& full_path) {
- return OpenAnyViaShell(full_path.value(), full_path.DirName().value(),
- base::string16(), kDefaultOpenFlags);
+ // Invoke the default verb on the file with no arguments.
+ return InvokeShellExecute(full_path.value(), full_path.DirName().value(),
+ base::string16(), base::string16(),
+ kDefaultShellExecuteFlags);
}
bool OpenFolderViaShell(const base::FilePath& full_path) {
// The "explore" verb causes the folder at |full_path| to be displayed in a
- // file browser. This will fail if |full_path| is not a directory. The
- // resulting error does not cause UI due to the SEE_MASK_FLAG_NO_UI flag in
- // kDefaultOpenFlags.
+ // file browser. This will fail if |full_path| is not a directory.
return InvokeShellExecute(full_path.value(), full_path.value(),
base::string16(), L"explore",
- kDefaultOpenFlags) == ERROR_SUCCESS;
+ kDefaultShellExecuteFlags);
}
bool PreventWindowFromPinning(HWND hwnd) {
diff --git a/chromium/ui/base/win/shell.h b/chromium/ui/base/win/shell.h
index df784a6e13b..c47e5ce3f47 100644
--- a/chromium/ui/base/win/shell.h
+++ b/chromium/ui/base/win/shell.h
@@ -17,8 +17,8 @@ class FilePath;
namespace ui {
namespace win {
-// Open the folder at |full_path| via the Windows shell. Does nothing if
-// |full_path| is not a folder.
+// Open the folder at |full_path| via the Windows shell. It is an error if
+// |full_path| does not refer to a folder.
//
// Note: Must be called on a thread that allows blocking.
UI_BASE_EXPORT bool OpenFolderViaShell(const base::FilePath& full_path);
diff --git a/chromium/ui/chromeos/BUILD.gn b/chromium/ui/chromeos/BUILD.gn
index 8ef1bca5769..c15c784e377 100644
--- a/chromium/ui/chromeos/BUILD.gn
+++ b/chromium/ui/chromeos/BUILD.gn
@@ -9,8 +9,6 @@ assert(is_chromeos)
component("chromeos") {
output_name = "ui_chromeos"
sources = [
- "accelerometer/accelerometer_util.cc",
- "accelerometer/accelerometer_util.h",
"devicetype_utils.cc",
"devicetype_utils.h",
"ime/candidate_view.cc",
@@ -26,10 +24,6 @@ component("chromeos") {
"ime/input_method_menu_manager.h",
"ime/mode_indicator_view.cc",
"ime/mode_indicator_view.h",
- "touch_accessibility_enabler.cc",
- "touch_accessibility_enabler.h",
- "touch_exploration_controller.cc",
- "touch_exploration_controller.h",
"user_activity_power_manager_notifier.cc",
"user_activity_power_manager_notifier.h",
]
@@ -70,8 +64,6 @@ test("ui_chromeos_unittests") {
"ime/input_method_menu_item_unittest.cc",
"ime/input_method_menu_manager_unittest.cc",
"run_all_unittests.cc",
- "touch_accessibility_enabler_unittest.cc",
- "touch_exploration_controller_unittest.cc",
]
deps = [
":chromeos",
diff --git a/chromium/ui/chromeos/search_box/BUILD.gn b/chromium/ui/chromeos/search_box/BUILD.gn
new file mode 100644
index 00000000000..826cad941df
--- /dev/null
+++ b/chromium/ui/chromeos/search_box/BUILD.gn
@@ -0,0 +1,24 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("search_box") {
+ sources = [
+ "search_box_constants.h",
+ "search_box_view_base.cc",
+ "search_box_view_base.h",
+ "search_box_view_delegate.h",
+ ]
+
+ defines = [ "SEARCH_BOX_IMPLEMENTATION" ]
+
+ deps = [
+ "//base",
+ "//skia",
+ "//ui/base",
+ "//ui/base/ime",
+ "//ui/events",
+ "//ui/strings",
+ "//ui/views",
+ ]
+}
diff --git a/chromium/ui/compositor/BUILD.gn b/chromium/ui/compositor/BUILD.gn
index b8f0cacc39e..12788fef517 100644
--- a/chromium/ui/compositor/BUILD.gn
+++ b/chromium/ui/compositor/BUILD.gn
@@ -151,8 +151,8 @@ static_library("test_support") {
"//components/viz/host",
"//components/viz/service",
"//components/viz/test:test_support",
- "//gpu/command_buffer/client:gles2_c_lib",
"//gpu/command_buffer/client:gles2_implementation",
+ "//gpu/command_buffer/client:raster",
"//gpu/command_buffer/common",
"//gpu/ipc:gl_in_process_context",
"//gpu/skia_bindings",
@@ -182,6 +182,7 @@ static_library("test_support") {
test("compositor_unittests") {
sources = [
"callback_layer_animation_observer_unittest.cc",
+ "canvas_painter_unittest.cc",
"compositor_lock_unittest.cc",
"compositor_unittest.cc",
"layer_animation_element_unittest.cc",
diff --git a/chromium/ui/compositor/canvas_painter.cc b/chromium/ui/compositor/canvas_painter.cc
index 864d8b03e84..31c4cabdc1f 100644
--- a/chromium/ui/compositor/canvas_painter.cc
+++ b/chromium/ui/compositor/canvas_painter.cc
@@ -9,30 +9,34 @@
namespace ui {
CanvasPainter::CanvasPainter(SkBitmap* output,
- const gfx::Size& paint_size,
- float raster_scale,
+ const gfx::Size& output_size,
+ float device_scale_factor,
SkColor clear_color,
bool is_pixel_canvas)
: output_(output),
- paint_size_(paint_size),
- raster_scale_(raster_scale),
+ pixel_output_size_(
+ gfx::ScaleToCeiledSize(output_size, device_scale_factor)),
+ raster_scale_(is_pixel_canvas ? 1.f : device_scale_factor),
clear_color_(clear_color),
list_(new cc::DisplayItemList),
context_(list_.get(),
- raster_scale,
- gfx::Rect(paint_size_),
+ device_scale_factor,
+ gfx::Rect(output_size),
is_pixel_canvas) {}
CanvasPainter::~CanvasPainter() {
- gfx::Size pixel_size = gfx::ScaleToCeiledSize(paint_size_, raster_scale_);
- SkImageInfo info = SkImageInfo::MakeN32(
- pixel_size.width(), pixel_size.height(), kPremul_SkAlphaType);
+ SkImageInfo info =
+ SkImageInfo::MakeN32(pixel_output_size_.width(),
+ pixel_output_size_.height(), kPremul_SkAlphaType);
if (!output_->tryAllocPixels(info))
return;
SkCanvas canvas(*output_);
canvas.clear(clear_color_);
+ // When pixel canvas is enabled, the recordings and canvas are already scaled
+ // to the correct raster size. This additional scaling is not required and
+ // hence |raster_scale_| should be equal to 1 during this operation.
canvas.scale(raster_scale_, raster_scale_);
list_->Finalize();
diff --git a/chromium/ui/compositor/canvas_painter.h b/chromium/ui/compositor/canvas_painter.h
index da44d7bb166..51e196e2c71 100644
--- a/chromium/ui/compositor/canvas_painter.h
+++ b/chromium/ui/compositor/canvas_painter.h
@@ -27,8 +27,8 @@ namespace ui {
class COMPOSITOR_EXPORT CanvasPainter {
public:
CanvasPainter(SkBitmap* output,
- const gfx::Size& paint_size,
- float raster_scale,
+ const gfx::Size& output_size,
+ float device_scale_factor,
SkColor clear_color,
bool is_pixel_canvas);
~CanvasPainter();
@@ -36,8 +36,10 @@ class COMPOSITOR_EXPORT CanvasPainter {
const PaintContext& context() const { return context_; }
private:
+ friend class CanvasPainterTest;
+
SkBitmap* const output_;
- const gfx::Size paint_size_;
+ const gfx::Size pixel_output_size_;
const float raster_scale_;
const SkColor clear_color_;
scoped_refptr<cc::DisplayItemList> list_;
diff --git a/chromium/ui/compositor/canvas_painter_unittest.cc b/chromium/ui/compositor/canvas_painter_unittest.cc
new file mode 100644
index 00000000000..bdbe4653529
--- /dev/null
+++ b/chromium/ui/compositor/canvas_painter_unittest.cc
@@ -0,0 +1,121 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/compositor/canvas_painter.h"
+
+#include "base/macros.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/compositor/paint_recorder.h"
+#include "ui/gfx/canvas.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+
+namespace ui {
+namespace {
+void CheckPaintedShape(const SkBitmap& bitmap,
+ const gfx::Rect& shape_bounds,
+ const SkColor shape_color,
+ float device_scale_factor) {
+ // Whether pixel canvas is enabled or not, the pixel location of the shape
+ // should remain the same.
+ const gfx::Point expected_top_left_location =
+ gfx::ScaleToRoundedPoint(shape_bounds.origin(), device_scale_factor);
+ const gfx::Point expected_bottom_right_location = gfx::ScaleToRoundedPoint(
+ shape_bounds.bottom_right(), device_scale_factor);
+
+ EXPECT_EQ(bitmap.getColor(expected_top_left_location.x(),
+ expected_top_left_location.y()),
+ shape_color);
+ EXPECT_EQ(bitmap.getColor(expected_bottom_right_location.x(),
+ expected_bottom_right_location.y()),
+ shape_color);
+}
+} // namespace
+
+class CanvasPainterTest : public ::testing::TestWithParam<float> {
+ public:
+ CanvasPainterTest() : device_scale_factor_(GetParam()) {}
+
+ float device_scale_factor() const { return device_scale_factor_; }
+
+ const gfx::Size& pixel_output_size(const CanvasPainter& painter) const {
+ return painter.pixel_output_size_;
+ }
+
+ float raster_scale(const CanvasPainter& painter) const {
+ return painter.raster_scale_;
+ }
+
+ // Paints a rect with bounds |shape_bounds| and color |shape_color| on
+ // |bitmap| with the help of CanvasPainter. The output size of the bitmap in
+ // DIP is |size|.
+ void Paint(SkBitmap* bitmap,
+ const gfx::Size& size,
+ float device_scale_factor,
+ bool is_pixel_canvas,
+ const gfx::Rect& shape_bounds,
+ SkColor shape_color) {
+ CanvasPainter painter(bitmap, size, device_scale_factor,
+ SK_ColorTRANSPARENT, is_pixel_canvas);
+
+ // The paint recording size is scaled to match the raster size if pixel
+ // canvas is enabled.
+ const gfx::Size paint_recording_size = gfx::ScaleToCeiledSize(
+ size, is_pixel_canvas ? device_scale_factor : 1.f);
+
+ PaintRecorder recorder(painter.context(), paint_recording_size,
+ device_scale_factor, device_scale_factor, nullptr);
+ recorder.canvas()->DrawRect(gfx::RectF(shape_bounds), shape_color);
+ }
+
+ private:
+ float device_scale_factor_;
+
+ DISALLOW_COPY_AND_ASSIGN(CanvasPainterTest);
+};
+
+TEST_P(CanvasPainterTest, Initialization) {
+ SkBitmap output;
+ const gfx::Size output_size(100, 100);
+ CanvasPainter painter(&output, output_size, device_scale_factor(),
+ SK_ColorTRANSPARENT, false /* is_pixel_canvas */);
+ EXPECT_EQ(pixel_output_size(painter),
+ gfx::ScaleToCeiledSize(output_size, device_scale_factor()));
+ EXPECT_EQ(raster_scale(painter), device_scale_factor());
+}
+
+TEST_P(CanvasPainterTest, InitializationPixelCanvasEnabled) {
+ SkBitmap output;
+ const gfx::Size output_size(100, 100);
+ CanvasPainter painter(&output, output_size, device_scale_factor(),
+ SK_ColorTRANSPARENT, true /* is_pixel_canvas */);
+ EXPECT_EQ(pixel_output_size(painter),
+ gfx::ScaleToCeiledSize(output_size, device_scale_factor()));
+ EXPECT_EQ(raster_scale(painter), 1.f);
+}
+
+TEST_P(CanvasPainterTest, Paint) {
+ SkBitmap bitmap;
+ const SkColor shape_color = SK_ColorRED;
+ const gfx::Rect shape_bounds(100, 100, 100, 100);
+
+ Paint(&bitmap, gfx::Size(1000, 1000), device_scale_factor(),
+ false /* is_pixel_canvas */, shape_bounds, shape_color);
+ CheckPaintedShape(bitmap, shape_bounds, shape_color, device_scale_factor());
+}
+
+TEST_P(CanvasPainterTest, PaintPixelCanvasEnabled) {
+ SkBitmap bitmap;
+ const SkColor shape_color = SK_ColorRED;
+ const gfx::Rect shape_bounds(100, 100, 100, 100);
+
+ Paint(&bitmap, gfx::Size(1000, 1000), device_scale_factor(),
+ true /* is_pixel_canvas */, shape_bounds, shape_color);
+ CheckPaintedShape(bitmap, shape_bounds, shape_color, device_scale_factor());
+}
+
+INSTANTIATE_TEST_CASE_P(,
+ CanvasPainterTest,
+ ::testing::Values(1.f, 1.25f, 1.5f, 1.6f, 2.f, 2.25f));
+} // namespace ui
diff --git a/chromium/ui/compositor/compositor.cc b/chromium/ui/compositor/compositor.cc
index 7e68848c42f..c843ef6c644 100644
--- a/chromium/ui/compositor/compositor.cc
+++ b/chromium/ui/compositor/compositor.cc
@@ -35,7 +35,9 @@
#include "components/viz/common/resources/resource_format.h"
#include "components/viz/common/resources/resource_settings.h"
#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
+#include "components/viz/common/switches.h"
#include "components/viz/host/host_frame_sink_manager.h"
+#include "components/viz/host/renderer_settings_creation.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/ui_base_switches.h"
@@ -77,10 +79,8 @@ Compositor::Compositor(const viz::FrameSinkId& frame_sink_id,
auto* host_frame_sink_manager =
context_factory_private_->GetHostFrameSinkManager();
host_frame_sink_manager->RegisterFrameSinkId(frame_sink_id_, this);
-#if DCHECK_IS_ON()
host_frame_sink_manager->SetFrameSinkDebugLabel(frame_sink_id_,
"Compositor");
-#endif
}
root_web_layer_ = cc::Layer::Create();
@@ -164,7 +164,6 @@ Compositor::Compositor(const viz::FrameSinkId& frame_sink_id,
if (command_line->HasSwitch(switches::kUIEnableRGBA4444Textures))
settings.preferred_tile_format = viz::RGBA_4444;
- settings.resource_settings = context_factory_->GetResourceSettings();
#if defined(OS_MACOSX)
// Using CoreAnimation to composite requires using GpuMemoryBuffers, which
@@ -173,19 +172,21 @@ Compositor::Compositor(const viz::FrameSinkId& frame_sink_id,
settings.use_zero_copy;
#endif
- settings.gpu_memory_policy.bytes_limit_when_visible = 512 * 1024 * 1024;
- settings.gpu_memory_policy.priority_cutoff_when_visible =
+ settings.memory_policy.bytes_limit_when_visible = 512 * 1024 * 1024;
+ settings.memory_policy.priority_cutoff_when_visible =
gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
settings.disallow_non_exact_resource_reuse =
command_line->HasSwitch(switches::kDisallowNonExactResourceReuse);
- if (command_line->HasSwitch(
- cc::switches::kRunAllCompositorStagesBeforeDraw)) {
+ if (command_line->HasSwitch(switches::kRunAllCompositorStagesBeforeDraw)) {
settings.wait_for_all_pipeline_stages_before_draw = true;
settings.enable_latency_recovery = false;
}
+ settings.always_request_presentation_time =
+ command_line->HasSwitch(cc::switches::kAlwaysRequestPresentationTime);
+
base::TimeTicks before_create = base::TimeTicks::Now();
animation_host_ = cc::AnimationHost::CreateMainInstance();
@@ -205,7 +206,6 @@ Compositor::Compositor(const viz::FrameSinkId& frame_sink_id,
animation_host_->AddAnimationTimeline(animation_timeline_.get());
host_->SetRootLayer(root_web_layer_);
- host_->SetFrameSinkId(frame_sink_id_);
host_->SetVisible(true);
if (command_line->HasSwitch(switches::kUISlowAnimations)) {
@@ -349,17 +349,18 @@ void Compositor::SetScaleAndSize(float scale,
const gfx::Size& size_in_pixel,
const viz::LocalSurfaceId& local_surface_id) {
DCHECK_GT(scale, 0);
+ bool device_scale_factor_changed = device_scale_factor_ != scale;
+ device_scale_factor_ = scale;
+
if (!size_in_pixel.IsEmpty()) {
size_ = size_in_pixel;
- host_->SetViewportSize(size_in_pixel, local_surface_id);
+ host_->SetViewportSizeAndScale(size_in_pixel, scale, local_surface_id);
root_web_layer_->SetBounds(size_in_pixel);
// TODO(fsamuel): Get rid of ContextFactoryPrivate.
if (context_factory_private_)
context_factory_private_->ResizeDisplay(this, size_in_pixel);
}
- if (device_scale_factor_ != scale) {
- device_scale_factor_ = scale;
- host_->SetDeviceScaleFactor(scale);
+ if (device_scale_factor_changed) {
if (is_pixel_canvas())
host_->SetRecordingScaleFactor(scale);
if (root_layer_)
diff --git a/chromium/ui/compositor/compositor.h b/chromium/ui/compositor/compositor.h
index eb56a103f8c..78b36146063 100644
--- a/chromium/ui/compositor/compositor.h
+++ b/chromium/ui/compositor/compositor.h
@@ -21,8 +21,8 @@
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
+#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/common/surfaces/local_surface_id.h"
-#include "components/viz/common/surfaces/surface_sequence.h"
#include "components/viz/host/host_frame_sink_client.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkMatrix44.h"
@@ -66,7 +66,6 @@ class FrameSinkManagerImpl;
class ContextProvider;
class HostFrameSinkManager;
class LocalSurfaceId;
-class ResourceSettings;
}
namespace ui {
@@ -178,9 +177,6 @@ class COMPOSITOR_EXPORT ContextFactory {
// Gets the task graph runner.
virtual cc::TaskGraphRunner* GetTaskGraphRunner() = 0;
- // Gets the renderer settings.
- virtual const viz::ResourceSettings& GetResourceSettings() const = 0;
-
virtual void AddObserver(ContextFactoryObserver* observer) = 0;
virtual void RemoveObserver(ContextFactoryObserver* observer) = 0;
diff --git a/chromium/ui/compositor/dip_util.cc b/chromium/ui/compositor/dip_util.cc
index 0aad3970242..1dd91456930 100644
--- a/chromium/ui/compositor/dip_util.cc
+++ b/chromium/ui/compositor/dip_util.cc
@@ -93,6 +93,14 @@ void SnapLayerToPhysicalPixelBoundary(ui::Layer* snapped_layer,
gfx::Vector2dF fudge = view_offset_snapped - view_offset;
fudge.Scale(1.0 / scale_factor);
+
+ // Apply any scale originating from transforms to the fudge.
+ gfx::Transform transform;
+ layer_to_snap->parent()->GetTargetTransformRelativeTo(snapped_layer,
+ &transform);
+ gfx::Vector2dF transform_scale = transform.Scale2d();
+ fudge.Scale(1.0 / transform_scale.x(), 1.0 / transform_scale.y());
+
layer_to_snap->SetSubpixelPositionOffset(fudge);
#if DCHECK_IS_ON()
gfx::PointF layer_offset;
@@ -105,6 +113,7 @@ void SnapLayerToPhysicalPixelBoundary(ui::Layer* snapped_layer,
} else {
origin = layer_to_snap->position();
}
+ origin.Scale(transform_scale.x(), transform_scale.y());
CheckSnapped((layer_offset.x() + origin.x()) * scale_factor);
CheckSnapped((layer_offset.y() + origin.y()) * scale_factor);
#endif
diff --git a/chromium/ui/compositor/layer.cc b/chromium/ui/compositor/layer.cc
index c5f67114ab7..ffd6f93c307 100644
--- a/chromium/ui/compositor/layer.cc
+++ b/chromium/ui/compositor/layer.cc
@@ -187,10 +187,13 @@ std::unique_ptr<Layer> Layer::Clone() const {
// cc::Layer state.
if (surface_layer_) {
if (surface_layer_->primary_surface_id().is_valid()) {
- clone->SetShowPrimarySurface(surface_layer_->primary_surface_id(),
- frame_size_in_dip_,
- surface_layer_->background_color(),
- surface_layer_->surface_reference_factory());
+ clone->SetShowPrimarySurface(
+ surface_layer_->primary_surface_id(), frame_size_in_dip_,
+ surface_layer_->background_color(),
+ surface_layer_->deadline_in_frames()
+ ? cc::DeadlinePolicy::UseSpecifiedDeadline(
+ *surface_layer_->deadline_in_frames())
+ : cc::DeadlinePolicy::UseDefaultDeadline());
}
if (surface_layer_->fallback_surface_id().is_valid())
clone->SetFallbackSurfaceId(surface_layer_->fallback_surface_id());
@@ -746,29 +749,28 @@ bool Layer::TextureFlipped() const {
return texture_layer_->flipped();
}
-void Layer::SetShowPrimarySurface(
- const viz::SurfaceId& surface_id,
- const gfx::Size& frame_size_in_dip,
- SkColor default_background_color,
- scoped_refptr<viz::SurfaceReferenceFactory> ref_factory) {
+void Layer::SetShowPrimarySurface(const viz::SurfaceId& surface_id,
+ const gfx::Size& frame_size_in_dip,
+ SkColor default_background_color,
+ const cc::DeadlinePolicy& deadline_policy) {
DCHECK(type_ == LAYER_TEXTURED || type_ == LAYER_SOLID_COLOR);
if (!surface_layer_) {
- scoped_refptr<cc::SurfaceLayer> new_layer =
- cc::SurfaceLayer::Create(ref_factory);
+ scoped_refptr<cc::SurfaceLayer> new_layer = cc::SurfaceLayer::Create();
SwitchToLayer(new_layer);
surface_layer_ = new_layer;
}
- surface_layer_->SetPrimarySurfaceId(surface_id, base::nullopt);
+ surface_layer_->SetPrimarySurfaceId(surface_id, deadline_policy);
surface_layer_->SetBackgroundColor(default_background_color);
frame_size_in_dip_ = frame_size_in_dip;
RecomputeDrawsContentAndUVRect();
for (const auto& mirror : mirrors_) {
- mirror->dest()->SetShowPrimarySurface(
- surface_id, frame_size_in_dip, default_background_color, ref_factory);
+ mirror->dest()->SetShowPrimarySurface(surface_id, frame_size_in_dip,
+ default_background_color,
+ deadline_policy);
}
}
diff --git a/chromium/ui/compositor/layer.h b/chromium/ui/compositor/layer.h
index 736c4d53550..8200c6d43be 100644
--- a/chromium/ui/compositor/layer.h
+++ b/chromium/ui/compositor/layer.h
@@ -22,7 +22,6 @@
#include "cc/layers/surface_layer.h"
#include "cc/layers/texture_layer_client.h"
#include "components/viz/common/resources/transferable_resource.h"
-#include "components/viz/common/surfaces/sequence_surface_reference_factory.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer_animation_delegate.h"
@@ -303,12 +302,12 @@ class COMPOSITOR_EXPORT Layer : public LayerAnimationDelegate,
void SetTextureFlipped(bool flipped);
bool TextureFlipped() const;
+ // TODO(fsamuel): Update this comment.
// Begins showing content from a surface with a particular ID.
- void SetShowPrimarySurface(
- const viz::SurfaceId& surface_id,
- const gfx::Size& frame_size_in_dip,
- SkColor default_background_color,
- scoped_refptr<viz::SurfaceReferenceFactory> surface_ref);
+ void SetShowPrimarySurface(const viz::SurfaceId& surface_id,
+ const gfx::Size& frame_size_in_dip,
+ SkColor default_background_color,
+ const cc::DeadlinePolicy& deadline_policy);
// In the event that the primary surface is not yet available in the
// display compositor, the fallback surface will be used.
diff --git a/chromium/ui/compositor/layer_animation_element.cc b/chromium/ui/compositor/layer_animation_element.cc
index cb5ccccd20d..38bd26b8a60 100644
--- a/chromium/ui/compositor/layer_animation_element.cc
+++ b/chromium/ui/compositor/layer_animation_element.cc
@@ -10,8 +10,8 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/stringprintf.h"
-#include "cc/animation/animation.h"
#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/keyframe_model.h"
#include "ui/compositor/float_animation_curve_adapter.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_delegate.h"
@@ -300,7 +300,7 @@ class ThreadedLayerAnimationElement : public LayerAnimationElement {
LayerThreadedAnimationDelegate* threaded =
delegate->GetThreadedAnimationDelegate();
DCHECK(threaded);
- threaded->RemoveThreadedAnimation(animation_id());
+ threaded->RemoveThreadedAnimation(keyframe_model_id());
}
OnEnd(delegate);
@@ -312,7 +312,7 @@ class ThreadedLayerAnimationElement : public LayerAnimationElement {
LayerThreadedAnimationDelegate* threaded =
delegate->GetThreadedAnimationDelegate();
DCHECK(threaded);
- threaded->RemoveThreadedAnimation(animation_id());
+ threaded->RemoveThreadedAnimation(keyframe_model_id());
}
}
@@ -323,18 +323,18 @@ class ThreadedLayerAnimationElement : public LayerAnimationElement {
return;
}
set_effective_start_time(base::TimeTicks());
- std::unique_ptr<cc::Animation> animation = CreateCCAnimation();
- animation->set_needs_synchronized_start_time(true);
+ std::unique_ptr<cc::KeyframeModel> keyframe_model = CreateCCKeyframeModel();
+ keyframe_model->set_needs_synchronized_start_time(true);
LayerThreadedAnimationDelegate* threaded =
delegate->GetThreadedAnimationDelegate();
DCHECK(threaded);
- threaded->AddThreadedAnimation(std::move(animation));
+ threaded->AddThreadedAnimation(std::move(keyframe_model));
}
virtual void OnEnd(LayerAnimationDelegate* delegate) = 0;
- virtual std::unique_ptr<cc::Animation> CreateCCAnimation() = 0;
+ virtual std::unique_ptr<cc::KeyframeModel> CreateCCKeyframeModel() = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ThreadedLayerAnimationElement);
@@ -376,14 +376,14 @@ class ThreadedOpacityTransition : public ThreadedLayerAnimationElement {
PropertyChangeReason::FROM_ANIMATION);
}
- std::unique_ptr<cc::Animation> CreateCCAnimation() override {
+ std::unique_ptr<cc::KeyframeModel> CreateCCKeyframeModel() override {
std::unique_ptr<cc::AnimationCurve> animation_curve(
new FloatAnimationCurveAdapter(tween_type(), start_, target_,
duration()));
- std::unique_ptr<cc::Animation> animation(cc::Animation::Create(
- std::move(animation_curve), animation_id(), animation_group_id(),
+ std::unique_ptr<cc::KeyframeModel> keyframe_model(cc::KeyframeModel::Create(
+ std::move(animation_curve), keyframe_model_id(), animation_group_id(),
cc::TargetProperty::OPACITY));
- return animation;
+ return keyframe_model;
}
void OnGetTarget(TargetValue* target) const override {
@@ -446,14 +446,14 @@ class ThreadedTransformTransition : public ThreadedLayerAnimationElement {
PropertyChangeReason::FROM_ANIMATION);
}
- std::unique_ptr<cc::Animation> CreateCCAnimation() override {
+ std::unique_ptr<cc::KeyframeModel> CreateCCKeyframeModel() override {
std::unique_ptr<cc::AnimationCurve> animation_curve(
new TransformAnimationCurveAdapter(tween_type(), start_, target_,
duration()));
- std::unique_ptr<cc::Animation> animation(cc::Animation::Create(
- std::move(animation_curve), animation_id(), animation_group_id(),
+ std::unique_ptr<cc::KeyframeModel> keyframe_model(cc::KeyframeModel::Create(
+ std::move(animation_curve), keyframe_model_id(), animation_group_id(),
cc::TargetProperty::TRANSFORM));
- return animation;
+ return keyframe_model;
}
void OnGetTarget(TargetValue* target) const override {
@@ -499,7 +499,7 @@ LayerAnimationElement::LayerAnimationElement(AnimatableProperties properties,
properties_(properties),
duration_(GetEffectiveDuration(duration)),
tween_type_(gfx::Tween::LINEAR),
- animation_id_(cc::AnimationIdProvider::NextAnimationId()),
+ keyframe_model_id_(cc::AnimationIdProvider::NextKeyframeModelId()),
animation_group_id_(0),
last_progressed_fraction_(0.0),
animation_metrics_reporter_(nullptr),
@@ -512,7 +512,7 @@ LayerAnimationElement::LayerAnimationElement(
properties_(element.properties_),
duration_(element.duration_),
tween_type_(element.tween_type_),
- animation_id_(cc::AnimationIdProvider::NextAnimationId()),
+ keyframe_model_id_(cc::AnimationIdProvider::NextKeyframeModelId()),
animation_group_id_(element.animation_group_id_),
last_progressed_fraction_(element.last_progressed_fraction_),
animation_metrics_reporter_(nullptr),
@@ -566,7 +566,7 @@ bool LayerAnimationElement::Progress(base::TimeTicks now,
bool LayerAnimationElement::IsFinished(base::TimeTicks time,
base::TimeDelta* total_duration) {
// If an effective start has been requested but the effective start time
- // hasn't yet been set, the animation is not finished, regardless of the
+ // hasn't yet been set, the keyframe_model is not finished, regardless of the
// value of |time|.
if (!first_frame_ && (effective_start_time_ == base::TimeTicks()))
return false;
@@ -639,7 +639,7 @@ std::string LayerAnimationElement::ToString() const {
return base::StringPrintf(
"LayerAnimationElement{name=%s, id=%d, group=%d, "
"last_progressed_fraction=%0.2f}",
- DebugName().c_str(), animation_id_, animation_group_id_,
+ DebugName().c_str(), keyframe_model_id_, animation_group_id_,
last_progressed_fraction_);
}
diff --git a/chromium/ui/compositor/layer_animation_element.h b/chromium/ui/compositor/layer_animation_element.h
index 2ef8f4d8284..5088f879c62 100644
--- a/chromium/ui/compositor/layer_animation_element.h
+++ b/chromium/ui/compositor/layer_animation_element.h
@@ -13,7 +13,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
-#include "cc/animation/animation.h"
+#include "cc/animation/keyframe_model.h"
#include "cc/trees/target_property.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/compositor/compositor_export.h"
@@ -196,10 +196,10 @@ class COMPOSITOR_EXPORT LayerAnimationElement {
animation_metrics_reporter_ = reporter;
}
- // Each LayerAnimationElement has a unique animation_id. Elements belonging
- // to sequences that are supposed to start together have the same
+ // Each LayerAnimationElement has a unique keyframe_model_id. Elements
+ // belonging to sequences that are supposed to start together have the same
// animation_group_id.
- int animation_id() const { return animation_id_; }
+ int keyframe_model_id() const { return keyframe_model_id_; }
int animation_group_id() const { return animation_group_id_; }
void set_animation_group_id(int id) { animation_group_id_ = id; }
@@ -241,7 +241,7 @@ class COMPOSITOR_EXPORT LayerAnimationElement {
const base::TimeDelta duration_;
gfx::Tween::Type tween_type_;
- const int animation_id_;
+ const int keyframe_model_id_;
int animation_group_id_;
double last_progressed_fraction_;
diff --git a/chromium/ui/compositor/layer_animation_element_unittest.cc b/chromium/ui/compositor/layer_animation_element_unittest.cc
index b055f1eb3ac..664daedb561 100644
--- a/chromium/ui/compositor/layer_animation_element_unittest.cc
+++ b/chromium/ui/compositor/layer_animation_element_unittest.cc
@@ -491,7 +491,7 @@ TEST(LayerAnimationElementTest, ToString) {
base::StringPrintf("LayerAnimationElement{name=ThreadedOpacityTransition,"
" id=%d, group=42, "
"last_progressed_fraction=0.00}",
- element->animation_id()),
+ element->keyframe_model_id()),
element->ToString());
}
diff --git a/chromium/ui/compositor/layer_animation_sequence_unittest.cc b/chromium/ui/compositor/layer_animation_sequence_unittest.cc
index 7b4ab3bbf90..ab6527d9739 100644
--- a/chromium/ui/compositor/layer_animation_sequence_unittest.cc
+++ b/chromium/ui/compositor/layer_animation_sequence_unittest.cc
@@ -285,7 +285,7 @@ TEST(LayerAnimationSequenceTest, ToString) {
std::unique_ptr<LayerAnimationElement> brightness =
LayerAnimationElement::CreateBrightnessElement(1.0f, delta);
- int brightness_id = brightness->animation_id();
+ int brightness_id = brightness->keyframe_model_id();
sequence.AddElement(std::move(brightness));
EXPECT_EQ(
base::StringPrintf(
@@ -298,7 +298,7 @@ TEST(LayerAnimationSequenceTest, ToString) {
std::unique_ptr<LayerAnimationElement> opacity =
LayerAnimationElement::CreateOpacityElement(1.0f, delta);
- int opacity_id = opacity->animation_id();
+ int opacity_id = opacity->keyframe_model_id();
sequence.AddElement(std::move(opacity));
sequence.set_is_cyclic(true);
sequence.set_animation_group_id(1973);
diff --git a/chromium/ui/compositor/layer_animator.cc b/chromium/ui/compositor/layer_animator.cc
index 01b17ca798c..5809b9db569 100644
--- a/chromium/ui/compositor/layer_animator.cc
+++ b/chromium/ui/compositor/layer_animator.cc
@@ -12,9 +12,9 @@
#include "base/trace_event/trace_event.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
-#include "cc/animation/animation_player.h"
#include "cc/animation/animation_timeline.h"
#include "cc/animation/element_animations.h"
+#include "cc/animation/single_keyframe_effect_animation.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
@@ -55,8 +55,8 @@ LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
disable_timer_for_test_(false),
adding_animations_(false),
animation_metrics_reporter_(nullptr) {
- animation_player_ =
- cc::AnimationPlayer::Create(cc::AnimationIdProvider::NextPlayerId());
+ animation_ = cc::SingleKeyframeEffectAnimation::Create(
+ cc::AnimationIdProvider::NextAnimationId());
}
LayerAnimator::~LayerAnimator() {
@@ -66,7 +66,7 @@ LayerAnimator::~LayerAnimator() {
}
ClearAnimationsInternal();
delegate_ = NULL;
- DCHECK(!animation_player_->animation_timeline());
+ DCHECK(!animation_->animation_timeline());
}
// static
@@ -138,9 +138,9 @@ void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
void LayerAnimator::SwitchToLayer(scoped_refptr<cc::Layer> new_layer) {
if (delegate_)
- DetachLayerFromAnimationPlayer();
+ DetachLayerFromAnimation();
if (new_layer)
- AttachLayerToAnimationPlayer(new_layer->id());
+ AttachLayerToAnimation(new_layer->id());
}
void LayerAnimator::AttachLayerAndTimeline(Compositor* compositor) {
@@ -148,10 +148,10 @@ void LayerAnimator::AttachLayerAndTimeline(Compositor* compositor) {
cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
DCHECK(timeline);
- timeline->AttachPlayer(animation_player_);
+ timeline->AttachAnimation(animation_);
DCHECK(delegate_->GetCcLayer());
- AttachLayerToAnimationPlayer(delegate_->GetCcLayer()->id());
+ AttachLayerToAnimation(delegate_->GetCcLayer()->id());
}
void LayerAnimator::DetachLayerAndTimeline(Compositor* compositor) {
@@ -160,39 +160,40 @@ void LayerAnimator::DetachLayerAndTimeline(Compositor* compositor) {
cc::AnimationTimeline* timeline = compositor->GetAnimationTimeline();
DCHECK(timeline);
- DetachLayerFromAnimationPlayer();
- timeline->DetachPlayer(animation_player_);
+ DetachLayerFromAnimation();
+ timeline->DetachAnimation(animation_);
}
-void LayerAnimator::AttachLayerToAnimationPlayer(int layer_id) {
+void LayerAnimator::AttachLayerToAnimation(int layer_id) {
// For ui, layer and element ids are equivalent.
cc::ElementId element_id(layer_id);
- if (!animation_player_->element_id())
- animation_player_->AttachElement(element_id);
+ if (!animation_->element_id())
+ animation_->AttachElement(element_id);
else
- DCHECK_EQ(animation_player_->element_id(), element_id);
+ DCHECK_EQ(animation_->element_id(), element_id);
- animation_player_->set_animation_delegate(this);
+ animation_->set_animation_delegate(this);
}
-void LayerAnimator::DetachLayerFromAnimationPlayer() {
- animation_player_->set_animation_delegate(nullptr);
+void LayerAnimator::DetachLayerFromAnimation() {
+ animation_->set_animation_delegate(nullptr);
- if (animation_player_->element_id())
- animation_player_->DetachElement();
+ if (animation_->element_id())
+ animation_->DetachElement();
}
void LayerAnimator::AddThreadedAnimation(
- std::unique_ptr<cc::Animation> animation) {
- animation_player_->AddAnimation(std::move(animation));
+ std::unique_ptr<cc::KeyframeModel> animation) {
+ animation_->AddKeyframeModel(std::move(animation));
}
-void LayerAnimator::RemoveThreadedAnimation(int animation_id) {
- animation_player_->RemoveAnimation(animation_id);
+void LayerAnimator::RemoveThreadedAnimation(int keyframe_model_id) {
+ animation_->RemoveKeyframeModel(keyframe_model_id);
}
-cc::AnimationPlayer* LayerAnimator::GetAnimationPlayerForTesting() const {
- return animation_player_.get();
+cc::SingleKeyframeEffectAnimation* LayerAnimator::GetAnimationForTesting()
+ const {
+ return animation_.get();
}
void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
diff --git a/chromium/ui/compositor/layer_animator.h b/chromium/ui/compositor/layer_animator.h
index 9ad8f5b043d..9f19dce640e 100644
--- a/chromium/ui/compositor/layer_animator.h
+++ b/chromium/ui/compositor/layer_animator.h
@@ -24,9 +24,9 @@
namespace cc {
class Animation;
-class AnimationPlayer;
class AnimationTimeline;
class Layer;
+class SingleKeyframeEffectAnimation;
}
namespace gfx {
@@ -114,12 +114,12 @@ class COMPOSITOR_EXPORT LayerAnimator : public base::RefCounted<LayerAnimator>,
// Unsubscribe from |cc_layer_| and subscribe to |new_layer|.
void SwitchToLayer(scoped_refptr<cc::Layer> new_layer);
- // Attach AnimationPlayer to Layer and AnimationTimeline
+ // Attach Animation to Layer and AnimationTimeline
void AttachLayerAndTimeline(Compositor* compositor);
- // Detach AnimationPlayer from Layer and AnimationTimeline
+ // Detach Animation from Layer and AnimationTimeline
void DetachLayerAndTimeline(Compositor* compositor);
- cc::AnimationPlayer* GetAnimationPlayerForTesting() const;
+ cc::SingleKeyframeEffectAnimation* GetAnimationForTesting() const;
// Sets the animation preemption strategy. This determines the behaviour if
// a property is set during an animation. The default is
@@ -371,11 +371,12 @@ class COMPOSITOR_EXPORT LayerAnimator : public base::RefCounted<LayerAnimator>,
std::unique_ptr<cc::AnimationCurve> curve) override {}
// Implementation of LayerThreadedAnimationDelegate.
- void AddThreadedAnimation(std::unique_ptr<cc::Animation> animation) override;
- void RemoveThreadedAnimation(int animation_id) override;
+ void AddThreadedAnimation(
+ std::unique_ptr<cc::KeyframeModel> keyframe_model) override;
+ void RemoveThreadedAnimation(int keyframe_model_id) override;
- void AttachLayerToAnimationPlayer(int layer_id);
- void DetachLayerFromAnimationPlayer();
+ void AttachLayerToAnimation(int layer_id);
+ void DetachLayerFromAnimation();
void set_animation_metrics_reporter(AnimationMetricsReporter* reporter) {
animation_metrics_reporter_ = reporter;
@@ -388,7 +389,7 @@ class COMPOSITOR_EXPORT LayerAnimator : public base::RefCounted<LayerAnimator>,
LayerAnimationDelegate* delegate_;
// Plays CC animations.
- scoped_refptr<cc::AnimationPlayer> animation_player_;
+ scoped_refptr<cc::SingleKeyframeEffectAnimation> animation_;
// The currently running animations.
RunningAnimations running_animations_;
diff --git a/chromium/ui/compositor/layer_owner_unittest.cc b/chromium/ui/compositor/layer_owner_unittest.cc
index c848ee0d538..3a6b60b7083 100644
--- a/chromium/ui/compositor/layer_owner_unittest.cc
+++ b/chromium/ui/compositor/layer_owner_unittest.cc
@@ -9,7 +9,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/test/null_task_runner.h"
-#include "cc/animation/animation_player.h"
+#include "cc/animation/single_keyframe_effect_animation.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer.h"
@@ -176,7 +176,7 @@ TEST_F(LayerOwnerTestWithCompositor, RecreateNonRootLayerDuringAnimation) {
}
// Tests that if LayerOwner-derived class destroys layer, then
-// LayerAnimator's player becomes detached from compositor timeline.
+// LayerAnimator's animation becomes detached from compositor timeline.
TEST_F(LayerOwnerTestWithCompositor, DetachTimelineOnAnimatorDeletion) {
std::unique_ptr<Layer> root_layer(new Layer);
compositor()->SetRootLayer(root_layer.get());
@@ -186,18 +186,18 @@ TEST_F(LayerOwnerTestWithCompositor, DetachTimelineOnAnimatorDeletion) {
layer->SetOpacity(0.5f);
root_layer->Add(layer);
- scoped_refptr<cc::AnimationPlayer> player =
- layer->GetAnimator()->GetAnimationPlayerForTesting();
- EXPECT_TRUE(player);
- EXPECT_TRUE(player->animation_timeline());
+ scoped_refptr<cc::SingleKeyframeEffectAnimation> animation =
+ layer->GetAnimator()->GetAnimationForTesting();
+ EXPECT_TRUE(animation);
+ EXPECT_TRUE(animation->animation_timeline());
- // Destroying layer/animator must detach animator's player from timeline.
+ // Destroying layer/animator must detach animator's animation from timeline.
owner.DestroyLayerForTesting();
- EXPECT_FALSE(player->animation_timeline());
+ EXPECT_FALSE(animation->animation_timeline());
}
// Tests that if we run threaded opacity animation on already added layer
-// then LayerAnimator's player becomes attached to timeline.
+// then LayerAnimator's animation becomes attached to timeline.
TEST_F(LayerOwnerTestWithCompositor,
AttachTimelineIfAnimatorCreatedAfterSetCompositor) {
std::unique_ptr<Layer> root_layer(new Layer);
@@ -209,10 +209,10 @@ TEST_F(LayerOwnerTestWithCompositor,
layer->SetOpacity(0.5f);
- scoped_refptr<cc::AnimationPlayer> player =
- layer->GetAnimator()->GetAnimationPlayerForTesting();
- EXPECT_TRUE(player);
- EXPECT_TRUE(player->animation_timeline());
+ scoped_refptr<cc::SingleKeyframeEffectAnimation> animation =
+ layer->GetAnimator()->GetAnimationForTesting();
+ EXPECT_TRUE(animation);
+ EXPECT_TRUE(animation->animation_timeline());
}
} // namespace ui
diff --git a/chromium/ui/compositor/layer_threaded_animation_delegate.h b/chromium/ui/compositor/layer_threaded_animation_delegate.h
index 4fcf7f332ec..9b1251d1a17 100644
--- a/chromium/ui/compositor/layer_threaded_animation_delegate.h
+++ b/chromium/ui/compositor/layer_threaded_animation_delegate.h
@@ -7,17 +7,17 @@
#include <memory>
-#include "cc/animation/animation.h"
+#include "cc/animation/keyframe_model.h"
#include "ui/compositor/compositor_export.h"
namespace ui {
-// Attach CC animations using this interface.
+// Attach CC keyframe_models using this interface.
class COMPOSITOR_EXPORT LayerThreadedAnimationDelegate {
public:
virtual void AddThreadedAnimation(
- std::unique_ptr<cc::Animation> animation) = 0;
- virtual void RemoveThreadedAnimation(int animation_id) = 0;
+ std::unique_ptr<cc::KeyframeModel> keyframe_model) = 0;
+ virtual void RemoveThreadedAnimation(int keyframe_model_id) = 0;
protected:
virtual ~LayerThreadedAnimationDelegate() {}
diff --git a/chromium/ui/compositor/layer_unittest.cc b/chromium/ui/compositor/layer_unittest.cc
index 1c8dd0fabde..a544b33d938 100644
--- a/chromium/ui/compositor/layer_unittest.cc
+++ b/chromium/ui/compositor/layer_unittest.cc
@@ -26,17 +26,14 @@
#include "build/build_config.h"
#include "cc/animation/animation_events.h"
#include "cc/animation/animation_host.h"
-#include "cc/animation/animation_player.h"
-#include "cc/animation/animation_ticker.h"
+#include "cc/animation/keyframe_effect.h"
+#include "cc/animation/single_keyframe_effect_animation.h"
#include "cc/layers/layer.h"
#include "cc/test/pixel_test_utils.h"
#include "components/viz/common/frame_sinks/copy_output_request.h"
#include "components/viz/common/frame_sinks/copy_output_result.h"
#include "components/viz/common/resources/transferable_resource.h"
-#include "components/viz/common/surfaces/sequence_surface_reference_factory.h"
#include "components/viz/common/surfaces/surface_id.h"
-#include "components/viz/common/surfaces/surface_reference_factory.h"
-#include "components/viz/common/surfaces/surface_sequence.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2.h"
@@ -1833,26 +1830,6 @@ TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) {
EXPECT_TRUE(delegate.painted());
}
-namespace {
-
-class TestSurfaceReferenceFactory
- : public viz::SequenceSurfaceReferenceFactory {
- public:
- TestSurfaceReferenceFactory() = default;
-
- private:
- ~TestSurfaceReferenceFactory() override = default;
-
- // cc::SequenceSurfaceReferenceFactory implementation:
- void SatisfySequence(const viz::SurfaceSequence& seq) const override {}
- void RequireSequence(const viz::SurfaceId& id,
- const viz::SurfaceSequence& seq) const override {}
-
- DISALLOW_COPY_AND_ASSIGN(TestSurfaceReferenceFactory);
-};
-
-} // namespace
-
TEST_F(LayerWithDelegateTest, ExternalContent) {
std::unique_ptr<Layer> root(
CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)));
@@ -1865,6 +1842,7 @@ TEST_F(LayerWithDelegateTest, ExternalContent) {
// The layer is already showing solid color content, so the cc layer won't
// change.
scoped_refptr<cc::Layer> before = child->cc_layer_for_testing();
+
child->SetShowSolidColorContent();
EXPECT_TRUE(child->cc_layer_for_testing());
EXPECT_EQ(before.get(), child->cc_layer_for_testing());
@@ -1873,9 +1851,17 @@ TEST_F(LayerWithDelegateTest, ExternalContent) {
before = child->cc_layer_for_testing();
child->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10),
SK_ColorWHITE,
- new TestSurfaceReferenceFactory());
- EXPECT_TRUE(child->cc_layer_for_testing());
- EXPECT_NE(before.get(), child->cc_layer_for_testing());
+ cc::DeadlinePolicy::UseDefaultDeadline());
+ scoped_refptr<cc::Layer> after = child->cc_layer_for_testing();
+ const auto* surface = static_cast<cc::SurfaceLayer*>(after.get());
+ EXPECT_TRUE(after.get());
+ EXPECT_NE(before.get(), after.get());
+ EXPECT_EQ(base::nullopt, surface->deadline_in_frames());
+
+ child->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10),
+ SK_ColorWHITE,
+ cc::DeadlinePolicy::UseSpecifiedDeadline(4u));
+ EXPECT_EQ(4u, surface->deadline_in_frames());
// Changing to painted content should change the underlying cc layer.
before = child->cc_layer_for_testing();
@@ -1886,14 +1872,12 @@ TEST_F(LayerWithDelegateTest, ExternalContent) {
TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
std::unique_ptr<Layer> layer(CreateLayer(LAYER_SOLID_COLOR));
- scoped_refptr<viz::SurfaceReferenceFactory> reference_factory(
- new TestSurfaceReferenceFactory());
viz::SurfaceId surface_id(
viz::FrameSinkId(0, 1),
viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
layer->SetShowPrimarySurface(surface_id, gfx::Size(10, 10), SK_ColorWHITE,
- reference_factory);
+ cc::DeadlinePolicy::UseDefaultDeadline());
const auto mirror = layer->Mirror();
auto* const cc_layer = mirror->cc_layer_for_testing();
@@ -1906,12 +1890,12 @@ TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
viz::SurfaceId(viz::FrameSinkId(1, 2),
viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE,
- reference_factory);
+ cc::DeadlinePolicy::UseDefaultDeadline());
// The mirror should continue to use the same cc_layer.
EXPECT_EQ(cc_layer, mirror->cc_layer_for_testing());
layer->SetShowPrimarySurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE,
- reference_factory);
+ cc::DeadlinePolicy::UseDefaultDeadline());
// Surface updates propagate to the mirror.
EXPECT_EQ(surface_id, surface->primary_surface_id());
@@ -1933,7 +1917,7 @@ TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) {
scoped_refptr<cc::Layer> before = layer->cc_layer_for_testing();
layer->SetShowPrimarySurface(viz::SurfaceId(), gfx::Size(10, 10),
SK_ColorWHITE,
- new TestSurfaceReferenceFactory());
+ cc::DeadlinePolicy::UseDefaultDeadline());
EXPECT_EQ(layer->layer_grayscale(), 0.5f);
EXPECT_TRUE(layer->cc_layer_for_testing());
EXPECT_NE(before.get(), layer->cc_layer_for_testing());
@@ -1949,43 +1933,43 @@ TEST_F(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
l2->SetAnimator(LayerAnimator::CreateImplicitAnimator());
- auto* player1 = l1->GetAnimator()->GetAnimationPlayerForTesting();
- auto* player2 = l2->GetAnimator()->GetAnimationPlayerForTesting();
+ auto* animation1 = l1->GetAnimator()->GetAnimationForTesting();
+ auto* animation2 = l2->GetAnimator()->GetAnimationForTesting();
- EXPECT_FALSE(player1->has_any_animation());
+ EXPECT_FALSE(animation1->keyframe_effect()->has_any_keyframe_model());
// Trigger a threaded animation.
l1->SetOpacity(0.5f);
- EXPECT_TRUE(player1->has_any_animation());
+ EXPECT_TRUE(animation1->keyframe_effect()->has_any_keyframe_model());
// Ensure we can remove a pending threaded animation.
l1->GetAnimator()->StopAnimating();
- EXPECT_FALSE(player1->has_any_animation());
+ EXPECT_FALSE(animation1->keyframe_effect()->has_any_keyframe_model());
// Trigger another threaded animation.
l1->SetOpacity(0.2f);
- EXPECT_TRUE(player1->has_any_animation());
+ EXPECT_TRUE(animation1->keyframe_effect()->has_any_keyframe_model());
root->Add(l1.get());
GetCompositor()->SetRootLayer(root.get());
// Now l1 is part of a tree.
- EXPECT_TRUE(player1->has_any_animation());
+ EXPECT_TRUE(animation1->keyframe_effect()->has_any_keyframe_model());
l1->SetOpacity(0.1f);
// IMMEDIATELY_SET_NEW_TARGET is a default preemption strategy for conflicting
// animations.
- EXPECT_FALSE(player1->has_any_animation());
+ EXPECT_FALSE(animation1->keyframe_effect()->has_any_keyframe_model());
// Adding a layer to an existing tree.
l2->SetOpacity(0.5f);
- EXPECT_TRUE(player2->has_any_animation());
+ EXPECT_TRUE(animation2->keyframe_effect()->has_any_keyframe_model());
l1->Add(l2.get());
- EXPECT_TRUE(player2->has_any_animation());
+ EXPECT_TRUE(animation2->keyframe_effect()->has_any_keyframe_model());
}
// Tests that in-progress threaded animations complete when a Layer's
@@ -2222,7 +2206,7 @@ TEST_F(LayerWithDelegateTest, NonAnimatingAnimatorsAreRemovedFromCollection) {
namespace {
-std::string Vector2dFTo100thPercisionString(const gfx::Vector2dF& vector) {
+std::string Vector2dFTo100thPrecisionString(const gfx::Vector2dF& vector) {
return base::StringPrintf("%.2f %0.2f", vector.x(), vector.y());
}
@@ -2245,21 +2229,68 @@ TEST_F(LayerWithRealCompositorTest, SnapLayerToPixels) {
SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
// 0.5 at 1.25 scale : (1 - 0.25 + 0.25) / 1.25 = 0.4
EXPECT_EQ("0.40 0.40",
- Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
+ Vector2dFTo100thPrecisionString(c11->subpixel_position_offset()));
GetCompositor()->SetScaleAndSize(1.5f, gfx::Size(100, 100),
viz::LocalSurfaceId());
SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
// c11 must already be aligned at 1.5 scale.
EXPECT_EQ("0.00 0.00",
- Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
+ Vector2dFTo100thPrecisionString(c11->subpixel_position_offset()));
c11->SetBounds(gfx::Rect(2, 2, 10, 10));
SnapLayerToPhysicalPixelBoundary(root.get(), c11.get());
// c11 is now off the pixel.
// 0.5 / 1.5 = 0.333...
EXPECT_EQ("0.33 0.33",
- Vector2dFTo100thPercisionString(c11->subpixel_position_offset()));
+ Vector2dFTo100thPrecisionString(c11->subpixel_position_offset()));
+}
+
+TEST_F(LayerWithRealCompositorTest, SnapLayerToPixelsWithScaleTransform) {
+ std::unique_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
+ std::unique_ptr<Layer> c1(CreateLayer(LAYER_TEXTURED));
+ std::unique_ptr<Layer> c11(CreateLayer(LAYER_TEXTURED));
+ std::unique_ptr<Layer> c111(CreateLayer(LAYER_TEXTURED));
+
+ GetCompositor()->SetScaleAndSize(1.0f, gfx::Size(100, 100),
+ viz::LocalSurfaceId());
+ GetCompositor()->SetRootLayer(root.get());
+ root->Add(c1.get());
+ c1->Add(c11.get());
+ c11->Add(c111.get());
+
+ root->SetBounds(gfx::Rect(0, 0, 100, 100));
+ c1->SetBounds(gfx::Rect(0, 0, 10, 10));
+ c11->SetBounds(gfx::Rect(0, 0, 10, 10));
+ c111->SetBounds(gfx::Rect(2, 2, 5, 5));
+
+ gfx::Transform transform;
+ transform.Scale(1.25f, 1.25f);
+
+ c1->SetTransform(transform);
+ SnapLayerToPhysicalPixelBoundary(root.get(), c111.get());
+
+ // c111 ends up at 2.5, and is supposed to be snapped to 3.0. So subpixel
+ // offset is expected to be:
+ // 0.5 / 1.25 = 0.40
+ EXPECT_EQ("0.40 0.40",
+ Vector2dFTo100thPrecisionString(c111->subpixel_position_offset()));
+
+ c11->SetTransform(transform);
+ SnapLayerToPhysicalPixelBoundary(root.get(), c111.get());
+
+ // c111 ends up at 3.125, and is supposed to be snapped to 3.0. So subpixel
+ // offset is expected to be:
+ // -0.125 / (1.25 * 1.25) = -0.08
+ EXPECT_EQ("-0.08 -0.08",
+ Vector2dFTo100thPrecisionString(c111->subpixel_position_offset()));
+
+ // A transform on c111 should not affect the subpixel offset so expect it to
+ // be the same as before.
+ c111->SetTransform(transform);
+ SnapLayerToPhysicalPixelBoundary(root.get(), c111.get());
+ EXPECT_EQ("-0.08 -0.08",
+ Vector2dFTo100thPrecisionString(c111->subpixel_position_offset()));
}
// Verify that LayerDelegate::OnLayerBoundsChanged() is called when the bounds
diff --git a/chromium/ui/display/OWNERS b/chromium/ui/display/OWNERS
index 69f028b378a..e60ce6577fc 100644
--- a/chromium/ui/display/OWNERS
+++ b/chromium/ui/display/OWNERS
@@ -1,3 +1,4 @@
derat@chromium.org
marcheu@chromium.org
oshima@chromium.org
+afakhry@chromium.org
diff --git a/chromium/ui/display/display.cc b/chromium/ui/display/display.cc
index 487676642cb..9a10474c49a 100644
--- a/chromium/ui/display/display.cc
+++ b/chromium/ui/display/display.cc
@@ -300,4 +300,17 @@ bool Display::HasInternalDisplay() {
return internal_display_id_ != kInvalidDisplayId;
}
+bool Display::operator==(const Display& rhs) const {
+ return id_ == rhs.id_ && bounds_ == rhs.bounds_ &&
+ size_in_pixels_ == rhs.size_in_pixels_ &&
+ work_area_ == rhs.work_area_ &&
+ device_scale_factor_ == rhs.device_scale_factor_ &&
+ rotation_ == rhs.rotation_ && touch_support_ == rhs.touch_support_ &&
+ accelerometer_support_ == rhs.accelerometer_support_ &&
+ maximum_cursor_size_ == rhs.maximum_cursor_size_ &&
+ color_space_ == rhs.color_space_ && color_depth_ == rhs.color_depth_ &&
+ depth_per_component_ == rhs.depth_per_component_ &&
+ is_monochrome_ == rhs.is_monochrome_;
+}
+
} // namespace display
diff --git a/chromium/ui/display/display.h b/chromium/ui/display/display.h
index ea598a6ea63..49f76438ef3 100644
--- a/chromium/ui/display/display.h
+++ b/chromium/ui/display/display.h
@@ -48,29 +48,28 @@ class DISPLAY_EXPORT Display final {
// The display rotation can have multiple causes for change. A user can set a
// preference. On devices with accelerometers, they can change the rotation.
// RotationSource allows for the tracking of a Rotation per source of the
- // change. ROTATION_SOURCE_ACTIVE is the current rotation of the display.
- // Rotation changes not due to an accelerometer, nor the user, are to use this
- // source directly. ROTATION_SOURCE_UNKNOWN is when no rotation source has
- // been provided.
- enum RotationSource {
- ROTATION_SOURCE_ACCELEROMETER = 0,
- ROTATION_SOURCE_ACTIVE,
- ROTATION_SOURCE_USER,
- ROTATION_SOURCE_UNKNOWN,
+ // change. ACTIVE is the current rotation of the display. Rotation changes not
+ // due to an accelerometer, nor the user, are to use this source directly.
+ // UNKNOWN is when no rotation source has been provided.
+ enum class RotationSource {
+ ACCELEROMETER = 0,
+ ACTIVE,
+ USER,
+ UNKNOWN,
};
// Touch support for the display.
- enum TouchSupport {
- TOUCH_SUPPORT_UNKNOWN,
- TOUCH_SUPPORT_AVAILABLE,
- TOUCH_SUPPORT_UNAVAILABLE,
+ enum class TouchSupport {
+ UNKNOWN,
+ AVAILABLE,
+ UNAVAILABLE,
};
// Accelerometer support for the display.
- enum AccelerometerSupport {
- ACCELEROMETER_SUPPORT_UNKNOWN,
- ACCELEROMETER_SUPPORT_AVAILABLE,
- ACCELEROMETER_SUPPORT_UNAVAILABLE,
+ enum class AccelerometerSupport {
+ UNKNOWN,
+ AVAILABLE,
+ UNAVAILABLE,
};
// Creates a display with kInvalidDisplayId as default.
@@ -143,8 +142,7 @@ class DISPLAY_EXPORT Display final {
accelerometer_support_ = support;
}
- // Utility functions that just return the size of display and
- // work area.
+ // Utility functions that just return the size of display and work area.
const gfx::Size& size() const { return bounds_.size(); }
const gfx::Size& work_area_size() const { return work_area_.size(); }
@@ -226,6 +224,9 @@ class DISPLAY_EXPORT Display final {
is_monochrome_ = is_monochrome;
}
+ bool operator==(const Display& rhs) const;
+ bool operator!=(const Display& rhs) const { return !(*this == rhs); }
+
private:
friend struct mojo::StructTraits<mojom::DisplayDataView, Display>;
@@ -237,8 +238,8 @@ class DISPLAY_EXPORT Display final {
gfx::Rect work_area_;
float device_scale_factor_;
Rotation rotation_ = ROTATE_0;
- TouchSupport touch_support_ = TOUCH_SUPPORT_UNKNOWN;
- AccelerometerSupport accelerometer_support_ = ACCELEROMETER_SUPPORT_UNKNOWN;
+ TouchSupport touch_support_ = TouchSupport::UNKNOWN;
+ AccelerometerSupport accelerometer_support_ = AccelerometerSupport::UNKNOWN;
gfx::Size maximum_cursor_size_;
// NOTE: this is not currently written to the mojom as it is not used in
// aura.
diff --git a/chromium/ui/display/display_switches.cc b/chromium/ui/display/display_switches.cc
index c121928f527..d06ee064e1e 100644
--- a/chromium/ui/display/display_switches.cc
+++ b/chromium/ui/display/display_switches.cc
@@ -53,12 +53,8 @@ const char kScreenConfig[] = "screen-config";
const char kUseFirstDisplayAsInternal[] = "use-first-display-as-internal";
#if defined(OS_CHROMEOS)
-
// Enables unified desktop mode.
const char kEnableUnifiedDesktop[] = "ash-enable-unified-desktop";
-
-// Enables using the monitor's provided color space information when rendering.
-const char kUseMonitorColorSpace[] = "use-monitor-color-space";
#endif
} // namespace switches
@@ -68,4 +64,11 @@ namespace features {
const base::Feature kHighDynamicRange{"HighDynamicRange",
base::FEATURE_ENABLED_BY_DEFAULT};
+#if defined(OS_CHROMEOS)
+// Enables using the monitor's provided color space information when rendering.
+// TODO(mcasas): remove this flag http://crbug.com/771345.
+const base::Feature kUseMonitorColorSpace{"UseMonitorColorSpace",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+#endif
+
} // namespace features
diff --git a/chromium/ui/display/display_switches.h b/chromium/ui/display/display_switches.h
index 7d7c5e44f76..da146eb5359 100644
--- a/chromium/ui/display/display_switches.h
+++ b/chromium/ui/display/display_switches.h
@@ -26,7 +26,6 @@ DISPLAY_EXPORT extern const char kUseFirstDisplayAsInternal[];
#if defined(OS_CHROMEOS)
DISPLAY_EXPORT extern const char kEnableUnifiedDesktop[];
-DISPLAY_EXPORT extern const char kUseMonitorColorSpace[];
#endif
} // namespace switches
@@ -35,6 +34,10 @@ namespace features {
DISPLAY_EXPORT extern const base::Feature kHighDynamicRange;
+#if defined(OS_CHROMEOS)
+DISPLAY_EXPORT extern const base::Feature kUseMonitorColorSpace;
+#endif
+
} // namespace features
#endif // UI_DISPLAY_DISPLAY_SWITCHES_H_
diff --git a/chromium/ui/display/mac/screen_mac.mm b/chromium/ui/display/mac/screen_mac.mm
index 13800125153..4850c795480 100644
--- a/chromium/ui/display/mac/screen_mac.mm
+++ b/chromium/ui/display/mac/screen_mac.mm
@@ -170,8 +170,8 @@ class ScreenMac : public Screen {
}
bool IsWindowUnderCursor(gfx::NativeWindow window) override {
- NOTIMPLEMENTED();
- return false;
+ return [NSWindow windowNumberAtPoint:[NSEvent mouseLocation]
+ belowWindowWithWindowNumber:0] == [window windowNumber];
}
gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override {
diff --git a/chromium/ui/display/manager/chromeos/display_configurator.cc b/chromium/ui/display/manager/chromeos/display_configurator.cc
index b85425bc3f0..b077a4b25db 100644
--- a/chromium/ui/display/manager/chromeos/display_configurator.cc
+++ b/chromium/ui/display/manager/chromeos/display_configurator.cc
@@ -41,8 +41,6 @@ struct DisplayState {
const DisplayMode* mirror_mode = nullptr;
};
-void DoNothing(bool status) {}
-
} // namespace
const int DisplayConfigurator::kSetDisplayPowerNoFlags = 0;
@@ -595,7 +593,7 @@ void DisplayConfigurator::OnDisplayControlTaken(DisplayControlCallback callback,
force_configure_ = true;
// Restore the last power state used before releasing control.
SetDisplayPower(requested_power_state_, kSetDisplayPowerNoFlags,
- base::Bind(&DoNothing));
+ base::DoNothing());
}
std::move(callback).Run(success);
@@ -695,7 +693,7 @@ void DisplayConfigurator::UnregisterContentProtectionClient(
}
}
- set_protection_callbacks_.push(base::Bind(&DoNothing));
+ set_protection_callbacks_.push(base::DoNothing());
ApplyContentProtectionTask* task = new ApplyContentProtectionTask(
layout_manager_.get(), native_display_delegate_.get(), protections,
base::Bind(&DisplayConfigurator::OnContentProtectionClientUnregistered,
@@ -1010,7 +1008,7 @@ void DisplayConfigurator::ResumeDisplays() {
// If requested_power_state_ is ALL_OFF due to idle suspend, powerd will turn
// the display power on when it enables the backlight.
SetDisplayPower(requested_power_state_, kSetDisplayPowerNoFlags,
- base::Bind(&DoNothing));
+ base::DoNothing());
}
void DisplayConfigurator::ConfigureDisplays() {
diff --git a/chromium/ui/display/manager/chromeos/touch_device_manager.cc b/chromium/ui/display/manager/chromeos/touch_device_manager.cc
index 4289ec261c3..4ffd851a402 100644
--- a/chromium/ui/display/manager/chromeos/touch_device_manager.cc
+++ b/chromium/ui/display/manager/chromeos/touch_device_manager.cc
@@ -263,7 +263,7 @@ void TouchDeviceManager::AssociateTouchscreens(
ManagedDisplayInfoList displays;
for (ManagedDisplayInfo& display : *all_displays) {
// Reset touch support from the display.
- display.set_touch_support(Display::TOUCH_SUPPORT_UNAVAILABLE);
+ display.set_touch_support(Display::TouchSupport::UNAVAILABLE);
displays.push_back(&display);
}
@@ -496,7 +496,7 @@ void TouchDeviceManager::AssociateAnyRemainingDevices(
void TouchDeviceManager::Associate(ManagedDisplayInfo* display,
const ui::TouchscreenDevice& device) {
- display->set_touch_support(Display::TOUCH_SUPPORT_AVAILABLE);
+ display->set_touch_support(Display::TouchSupport::AVAILABLE);
active_touch_associations_[TouchDeviceIdentifier::FromDevice(device)] =
display->id();
}
diff --git a/chromium/ui/display/manager/chromeos/update_display_configuration_task.cc b/chromium/ui/display/manager/chromeos/update_display_configuration_task.cc
index 74a17bcb07c..70e19c34920 100644
--- a/chromium/ui/display/manager/chromeos/update_display_configuration_task.cc
+++ b/chromium/ui/display/manager/chromeos/update_display_configuration_task.cc
@@ -27,7 +27,6 @@ UpdateDisplayConfigurationTask::UpdateDisplayConfigurationTask(
power_flags_(power_flags),
force_configure_(force_configure),
callback_(callback),
- force_dpms_(false),
requesting_displays_(false),
weak_ptr_factory_(this) {
delegate_->AddObserver(this);
@@ -72,10 +71,6 @@ void UpdateDisplayConfigurationTask::OnDisplaysUpdated(
<< " flags=" << power_flags_
<< " force_configure=" << force_configure_
<< " display_count=" << cached_displays_.size();
- // If there has been any change in the requested power state and the displays
- // aren't being turned off force a change in DPMS state.
- force_dpms_ = ShouldForceDpms() && ShouldConfigure();
-
if (ShouldConfigure()) {
EnterState(base::Bind(&UpdateDisplayConfigurationTask::OnStateEntered,
weak_ptr_factory_.GetWeakPtr()));
diff --git a/chromium/ui/display/manager/chromeos/update_display_configuration_task.h b/chromium/ui/display/manager/chromeos/update_display_configuration_task.h
index 1538fd0f2e3..13c0df36147 100644
--- a/chromium/ui/display/manager/chromeos/update_display_configuration_task.h
+++ b/chromium/ui/display/manager/chromeos/update_display_configuration_task.h
@@ -93,8 +93,6 @@ class DISPLAY_MANAGER_EXPORT UpdateDisplayConfigurationTask
// Used to signal that the task has finished.
ResponseCallback callback_;
- bool force_dpms_;
-
bool requesting_displays_;
// List of updated displays.
diff --git a/chromium/ui/display/manager/display_manager.cc b/chromium/ui/display/manager/display_manager.cc
index fc1d98157ac..e7fd443794b 100644
--- a/chromium/ui/display/manager/display_manager.cc
+++ b/chromium/ui/display/manager/display_manager.cc
@@ -648,9 +648,9 @@ void DisplayManager::RegisterDisplayProperty(
rotation = Display::ROTATE_0;
display_info_[display_id].SetRotation(rotation,
- Display::ROTATION_SOURCE_USER);
+ Display::RotationSource::USER);
display_info_[display_id].SetRotation(rotation,
- Display::ROTATION_SOURCE_ACTIVE);
+ Display::RotationSource::ACTIVE);
// Just in case the preference file was corrupted.
// TODO(mukai): register |display_modes_| here as well, so the lookup for the
// default mode in GetActiveModeForDisplayId() gets much simpler.
@@ -850,9 +850,9 @@ void DisplayManager::OnNativeDisplaysChanged(
// active again.
Display::Rotation user_rotation =
display_info_[Display::InternalDisplayId()].GetRotation(
- Display::ROTATION_SOURCE_USER);
+ Display::RotationSource::USER);
display_info_[Display::InternalDisplayId()].SetRotation(
- user_rotation, Display::ROTATION_SOURCE_USER);
+ user_rotation, Display::RotationSource::USER);
}
}
@@ -1433,7 +1433,7 @@ void DisplayManager::SetTouchCalibrationData(
for (const auto& display : active_display_list_) {
ManagedDisplayInfo info = GetDisplayInfo(display.id());
if (info.id() == display_id) {
- info.set_touch_support(Display::TOUCH_SUPPORT_AVAILABLE);
+ info.set_touch_support(Display::TouchSupport::AVAILABLE);
update_add_support = true;
} else if (info.id() == previous_display_id) {
// Since we are reassociating the touch device to another display, we need
@@ -1442,7 +1442,7 @@ void DisplayManager::SetTouchCalibrationData(
if (!touch_device_manager_
->GetAssociatedTouchDevicesForDisplay(previous_display_id)
.empty()) {
- info.set_touch_support(Display::TOUCH_SUPPORT_UNAVAILABLE);
+ info.set_touch_support(Display::TouchSupport::UNAVAILABLE);
update_remove_support = true;
}
}
@@ -1452,14 +1452,14 @@ void DisplayManager::SetTouchCalibrationData(
// Update the non active displays.
if (!update_add_support) {
display_info_[display_id].set_touch_support(
- Display::TOUCH_SUPPORT_AVAILABLE);
+ Display::TouchSupport::AVAILABLE);
}
if (!update_remove_support &&
!touch_device_manager_
->GetAssociatedTouchDevicesForDisplay(previous_display_id)
.empty()) {
display_info_[previous_display_id].set_touch_support(
- Display::TOUCH_SUPPORT_UNAVAILABLE);
+ Display::TouchSupport::UNAVAILABLE);
}
// Update the active displays.
if (update_add_support || update_remove_support)
@@ -1983,8 +1983,8 @@ Display DisplayManager::CreateDisplayFromDisplayInfoById(int64_t id) {
new_display.set_touch_support(display_info.touch_support());
new_display.set_maximum_cursor_size(display_info.maximum_cursor_size());
#if defined(OS_CHROMEOS)
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(::switches::kUseMonitorColorSpace))
+ // TODO(mcasas): remove this check, http://crbug.com/771345.
+ if (base::FeatureList::IsEnabled(features::kUseMonitorColorSpace))
new_display.set_color_space(display_info.color_space());
#else
new_display.set_color_space(display_info.color_space());
@@ -1992,10 +1992,10 @@ Display DisplayManager::CreateDisplayFromDisplayInfoById(int64_t id) {
if (internal_display_has_accelerometer_ && Display::IsInternalDisplayId(id)) {
new_display.set_accelerometer_support(
- Display::ACCELEROMETER_SUPPORT_AVAILABLE);
+ Display::AccelerometerSupport::AVAILABLE);
} else {
new_display.set_accelerometer_support(
- Display::ACCELEROMETER_SUPPORT_UNAVAILABLE);
+ Display::AccelerometerSupport::UNAVAILABLE);
}
return new_display;
}
diff --git a/chromium/ui/display/manager/display_manager.h b/chromium/ui/display/manager/display_manager.h
index 58bfde04d50..2ff69b5e70c 100644
--- a/chromium/ui/display/manager/display_manager.h
+++ b/chromium/ui/display/manager/display_manager.h
@@ -8,6 +8,7 @@
#include <stddef.h>
#include <stdint.h>
+#include <algorithm>
#include <map>
#include <memory>
#include <string>
@@ -16,6 +17,7 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
+#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
@@ -354,6 +356,17 @@ class DISPLAY_MANAGER_EXPORT DisplayManager
mixed_mirror_mode_params_ = mixed_params;
}
+ void dec_screen_capture_active_counter() {
+ DCHECK_GT(screen_capture_active_counter_, 0);
+ screen_capture_active_counter_--;
+ }
+
+ void inc_screen_capture_active_counter() { ++screen_capture_active_counter_; }
+
+ bool screen_capture_is_active() const {
+ return screen_capture_active_counter_ > 0;
+ }
+
// Remove mirroring source and destination displays, so that they will be
// updated when UpdateDisplaysWith() is called.
void ClearMirroringSourceAndDestination();
@@ -646,6 +659,10 @@ class DISPLAY_MANAGER_EXPORT DisplayManager
bool internal_display_has_accelerometer_ = false;
+ // Set during screen capture to enable software compositing of mouse cursor,
+ // this is a counter to enable multiple active sessions at once.
+ int screen_capture_active_counter_ = 0;
+
base::Closure created_mirror_window_;
base::ObserverList<DisplayObserver> observers_;
diff --git a/chromium/ui/display/manager/managed_display_info.cc b/chromium/ui/display/manager/managed_display_info.cc
index 7e025920fa2..c4906316e61 100644
--- a/chromium/ui/display/manager/managed_display_info.cc
+++ b/chromium/ui/display/manager/managed_display_info.cc
@@ -240,7 +240,7 @@ ManagedDisplayInfo ManagedDisplayInfo::CreateFromSpecWithID(
ManagedDisplayInfo display_info(
id, base::StringPrintf("Display-%d", static_cast<int>(id)), has_overscan);
display_info.set_device_scale_factor(device_scale_factor);
- display_info.SetRotation(rotation, Display::ROTATION_SOURCE_ACTIVE);
+ display_info.SetRotation(rotation, Display::RotationSource::ACTIVE);
display_info.set_configured_ui_scale(ui_scale);
display_info.SetBounds(bounds_in_native);
display_info.SetManagedDisplayModes(display_modes);
@@ -261,8 +261,8 @@ ManagedDisplayInfo ManagedDisplayInfo::CreateFromSpecWithID(
ManagedDisplayInfo::ManagedDisplayInfo()
: id_(kInvalidDisplayId),
has_overscan_(false),
- active_rotation_source_(Display::ROTATION_SOURCE_UNKNOWN),
- touch_support_(Display::TOUCH_SUPPORT_UNKNOWN),
+ active_rotation_source_(Display::RotationSource::UNKNOWN),
+ touch_support_(Display::TouchSupport::UNKNOWN),
device_scale_factor_(1.0f),
device_dpi_(kDpi96),
overscan_insets_in_dip_(0, 0, 0, 0),
@@ -277,8 +277,8 @@ ManagedDisplayInfo::ManagedDisplayInfo(int64_t id,
: id_(id),
name_(name),
has_overscan_(has_overscan),
- active_rotation_source_(Display::ROTATION_SOURCE_UNKNOWN),
- touch_support_(Display::TOUCH_SUPPORT_UNKNOWN),
+ active_rotation_source_(Display::RotationSource::UNKNOWN),
+ touch_support_(Display::TouchSupport::UNKNOWN),
device_scale_factor_(1.0f),
device_dpi_(kDpi96),
overscan_insets_in_dip_(0, 0, 0, 0),
@@ -295,12 +295,12 @@ ManagedDisplayInfo::~ManagedDisplayInfo() {}
void ManagedDisplayInfo::SetRotation(Display::Rotation rotation,
Display::RotationSource source) {
rotations_[source] = rotation;
- rotations_[Display::ROTATION_SOURCE_ACTIVE] = rotation;
+ rotations_[Display::RotationSource::ACTIVE] = rotation;
active_rotation_source_ = source;
}
Display::Rotation ManagedDisplayInfo::GetActiveRotation() const {
- return GetRotation(Display::ROTATION_SOURCE_ACTIVE);
+ return GetRotation(Display::RotationSource::ACTIVE);
}
Display::Rotation ManagedDisplayInfo::GetRotation(
@@ -423,9 +423,9 @@ std::string ManagedDisplayInfo::ToString() const {
size_in_pixel_.ToString().c_str(), device_scale_factor_,
overscan_insets_in_dip_.ToString().c_str(), rotation_degree,
configured_ui_scale_,
- touch_support_ == Display::TOUCH_SUPPORT_AVAILABLE
+ touch_support_ == Display::TouchSupport::AVAILABLE
? "yes"
- : touch_support_ == Display::TOUCH_SUPPORT_UNAVAILABLE ? "no"
+ : touch_support_ == Display::TouchSupport::UNAVAILABLE ? "no"
: "unknown");
return result;
diff --git a/chromium/ui/display/mojo/display_struct_traits.cc b/chromium/ui/display/mojo/display_struct_traits.cc
index 4b61b0a0950..2603edefccc 100644
--- a/chromium/ui/display/mojo/display_struct_traits.cc
+++ b/chromium/ui/display/mojo/display_struct_traits.cc
@@ -48,11 +48,11 @@ display::mojom::TouchSupport
EnumTraits<display::mojom::TouchSupport, display::Display::TouchSupport>::
ToMojom(display::Display::TouchSupport touch_support) {
switch (touch_support) {
- case display::Display::TOUCH_SUPPORT_UNKNOWN:
+ case display::Display::TouchSupport::UNKNOWN:
return display::mojom::TouchSupport::UNKNOWN;
- case display::Display::TOUCH_SUPPORT_AVAILABLE:
+ case display::Display::TouchSupport::AVAILABLE:
return display::mojom::TouchSupport::AVAILABLE;
- case display::Display::TOUCH_SUPPORT_UNAVAILABLE:
+ case display::Display::TouchSupport::UNAVAILABLE:
return display::mojom::TouchSupport::UNAVAILABLE;
}
NOTREACHED();
@@ -64,13 +64,13 @@ bool EnumTraits<display::mojom::TouchSupport, display::Display::TouchSupport>::
display::Display::TouchSupport* out) {
switch (touch_support) {
case display::mojom::TouchSupport::UNKNOWN:
- *out = display::Display::TOUCH_SUPPORT_UNKNOWN;
+ *out = display::Display::TouchSupport::UNKNOWN;
return true;
case display::mojom::TouchSupport::AVAILABLE:
- *out = display::Display::TOUCH_SUPPORT_AVAILABLE;
+ *out = display::Display::TouchSupport::AVAILABLE;
return true;
case display::mojom::TouchSupport::UNAVAILABLE:
- *out = display::Display::TOUCH_SUPPORT_UNAVAILABLE;
+ *out = display::Display::TouchSupport::UNAVAILABLE;
return true;
}
NOTREACHED();
@@ -82,11 +82,11 @@ EnumTraits<display::mojom::AccelerometerSupport,
display::Display::AccelerometerSupport>::
ToMojom(display::Display::AccelerometerSupport accelerometer_support) {
switch (accelerometer_support) {
- case display::Display::ACCELEROMETER_SUPPORT_UNKNOWN:
+ case display::Display::AccelerometerSupport::UNKNOWN:
return display::mojom::AccelerometerSupport::UNKNOWN;
- case display::Display::ACCELEROMETER_SUPPORT_AVAILABLE:
+ case display::Display::AccelerometerSupport::AVAILABLE:
return display::mojom::AccelerometerSupport::AVAILABLE;
- case display::Display::ACCELEROMETER_SUPPORT_UNAVAILABLE:
+ case display::Display::AccelerometerSupport::UNAVAILABLE:
return display::mojom::AccelerometerSupport::UNAVAILABLE;
}
NOTREACHED();
@@ -99,13 +99,13 @@ bool EnumTraits<display::mojom::AccelerometerSupport,
display::Display::AccelerometerSupport* out) {
switch (accelerometer_support) {
case display::mojom::AccelerometerSupport::UNKNOWN:
- *out = display::Display::ACCELEROMETER_SUPPORT_UNKNOWN;
+ *out = display::Display::AccelerometerSupport::UNKNOWN;
return true;
case display::mojom::AccelerometerSupport::AVAILABLE:
- *out = display::Display::ACCELEROMETER_SUPPORT_AVAILABLE;
+ *out = display::Display::AccelerometerSupport::AVAILABLE;
return true;
case display::mojom::AccelerometerSupport::UNAVAILABLE:
- *out = display::Display::ACCELEROMETER_SUPPORT_UNAVAILABLE;
+ *out = display::Display::AccelerometerSupport::UNAVAILABLE;
return true;
}
NOTREACHED();
diff --git a/chromium/ui/display/mojo/display_struct_traits_unittest.cc b/chromium/ui/display/mojo/display_struct_traits_unittest.cc
index 3dd7d2e3822..1dd6cf72c8a 100644
--- a/chromium/ui/display/mojo/display_struct_traits_unittest.cc
+++ b/chromium/ui/display/mojo/display_struct_traits_unittest.cc
@@ -130,8 +130,8 @@ TEST(DisplayStructTraitsTest, SetAllDisplayValues) {
input.set_work_area(work_area);
input.set_device_scale_factor(2.0f);
input.set_rotation(Display::ROTATE_270);
- input.set_touch_support(Display::TOUCH_SUPPORT_AVAILABLE);
- input.set_accelerometer_support(Display::ACCELEROMETER_SUPPORT_UNAVAILABLE);
+ input.set_touch_support(Display::TouchSupport::AVAILABLE);
+ input.set_accelerometer_support(Display::AccelerometerSupport::UNAVAILABLE);
input.set_maximum_cursor_size(maximum_cursor_size);
input.set_color_depth(input.color_depth() + 1);
input.set_depth_per_component(input.depth_per_component() + 1);
diff --git a/chromium/ui/display/win/color_profile_reader.cc b/chromium/ui/display/win/color_profile_reader.cc
index c53c10e8cc1..7c8d48adeca 100644
--- a/chromium/ui/display/win/color_profile_reader.cc
+++ b/chromium/ui/display/win/color_profile_reader.cc
@@ -9,7 +9,6 @@
#include "base/files/file_util.h"
#include "base/task_scheduler/post_task.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "ui/display/win/display_info.h"
#include "ui/gfx/icc_profile.h"
@@ -60,9 +59,6 @@ void ColorProfileReader::UpdateIfNeeded() {
if (device_to_path_map_ == new_device_to_path_map)
return;
- if (!base::SequencedWorkerPool::IsEnabled())
- return;
-
update_in_flight_ = true;
base::PostTaskWithTraitsAndReplyWithResult(
FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
diff --git a/chromium/ui/events/BUILD.gn b/chromium/ui/events/BUILD.gn
index d6363a7be90..96adf2efb72 100644
--- a/chromium/ui/events/BUILD.gn
+++ b/chromium/ui/events/BUILD.gn
@@ -99,6 +99,13 @@ component("events_base") {
"Carbon.framework",
]
}
+
+ if (is_chromecast && !is_android) {
+ sources += [
+ "chromecast/scroller.cc",
+ "chromecast/scroller.h",
+ ]
+ }
}
component("events") {
@@ -130,6 +137,9 @@ component("events") {
"events_stub.cc",
"gestures/gesture_recognizer_impl_mac.cc",
"gestures/gesture_types.h",
+ "keyboard_hook.h",
+ "keyboard_hook_base.cc",
+ "keyboard_hook_base.h",
"keycodes/platform_key_map_win.cc",
"keycodes/platform_key_map_win.h",
"null_event_targeter.cc",
@@ -139,8 +149,10 @@ component("events") {
"system_input_injector.cc",
"system_input_injector.h",
"win/events_win.cc",
+ "win/keyboard_hook_win.cc",
"win/system_event_state_lookup.cc",
"win/system_event_state_lookup.h",
+ "x/keyboard_hook_posix.cc",
]
defines = [ "EVENTS_IMPLEMENTATION" ]
@@ -487,6 +499,10 @@ if (!is_ios) {
if (is_win) {
sources += [ "blink/web_input_event_builders_win_unittest.cc" ]
}
+
+ if (is_chromecast && !is_android) {
+ sources += [ "chromecast/scroller_unittest.cc" ]
+ }
}
}
diff --git a/chromium/ui/events/android/gesture_event_android.cc b/chromium/ui/events/android/gesture_event_android.cc
index d0f25354b3d..277efb57479 100644
--- a/chromium/ui/events/android/gesture_event_android.cc
+++ b/chromium/ui/events/android/gesture_event_android.cc
@@ -12,12 +12,24 @@ GestureEventAndroid::GestureEventAndroid(int type,
const gfx::PointF& location,
const gfx::PointF& screen_location,
long time_ms,
- float delta)
+ float scale,
+ float delta_x,
+ float delta_y,
+ float velocity_x,
+ float velocity_y,
+ bool target_viewport,
+ bool synthetic_scroll)
: type_(type),
location_(location),
screen_location_(screen_location),
time_ms_(time_ms),
- delta_(delta) {}
+ scale_(scale),
+ delta_x_(delta_x),
+ delta_y_(delta_y),
+ velocity_x_(velocity_x),
+ velocity_y_(velocity_y),
+ target_viewport_(target_viewport),
+ synthetic_scroll_(synthetic_scroll) {}
GestureEventAndroid::~GestureEventAndroid() {}
@@ -26,7 +38,8 @@ std::unique_ptr<GestureEventAndroid> GestureEventAndroid::CreateFor(
auto offset = new_location - location_;
gfx::PointF new_screen_location = screen_location_ + offset;
return std::unique_ptr<GestureEventAndroid>(new GestureEventAndroid(
- type_, new_location, new_screen_location, time_ms_, delta_));
+ type_, new_location, new_screen_location, time_ms_, scale_, delta_x_,
+ delta_y_, velocity_x_, velocity_y_, target_viewport_, synthetic_scroll_));
}
} // namespace ui
diff --git a/chromium/ui/events/android/gesture_event_android.h b/chromium/ui/events/android/gesture_event_android.h
index d07f343ff2c..2824847a103 100644
--- a/chromium/ui/events/android/gesture_event_android.h
+++ b/chromium/ui/events/android/gesture_event_android.h
@@ -21,7 +21,13 @@ class EVENTS_EXPORT GestureEventAndroid {
const gfx::PointF& location,
const gfx::PointF& screen_location,
long time_ms,
- float delta);
+ float scale,
+ float delta_x,
+ float delta_y,
+ float velocity_x,
+ float velocity_y,
+ bool target_viewport,
+ bool synthetic_scroll);
~GestureEventAndroid();
@@ -29,7 +35,13 @@ class EVENTS_EXPORT GestureEventAndroid {
const gfx::PointF& location() const { return location_; }
const gfx::PointF& screen_location() const { return screen_location_; }
long time() const { return time_ms_; }
- float delta() const { return delta_; }
+ float scale() const { return scale_; }
+ float delta_x() const { return delta_x_; }
+ float delta_y() const { return delta_y_; }
+ float velocity_x() const { return velocity_x_; }
+ float velocity_y() const { return velocity_y_; }
+ bool target_viewport() const { return target_viewport_; }
+ bool synthetic_scroll() const { return synthetic_scroll_; }
// Creates a new GestureEventAndroid instance different from |this| only by
// its location.
@@ -42,7 +54,13 @@ class EVENTS_EXPORT GestureEventAndroid {
gfx::PointF screen_location_;
long time_ms_;
- float delta_;
+ float scale_;
+ float delta_x_;
+ float delta_y_;
+ float velocity_x_;
+ float velocity_y_;
+ bool target_viewport_;
+ bool synthetic_scroll_;
DISALLOW_COPY_AND_ASSIGN(GestureEventAndroid);
};
diff --git a/chromium/ui/events/android/motion_event_android.cc b/chromium/ui/events/android/motion_event_android.cc
index 433ff446825..a6ad292d344 100644
--- a/chromium/ui/events/android/motion_event_android.cc
+++ b/chromium/ui/events/android/motion_event_android.cc
@@ -20,43 +20,91 @@ using base::android::ScopedJavaLocalRef;
namespace ui {
namespace {
-#define EVENT_CASE(x) \
- case JNI_MotionEvent::x: \
- return MotionEventAndroid::x
+#define ACTION_CASE(x) \
+ case JNI_MotionEvent::ACTION_##x: \
+ return MotionEventAndroid::Action::x
+
+#define ACTION_REVERSE_CASE(x) \
+ case MotionEventAndroid::Action::x: \
+ return JNI_MotionEvent::ACTION_##x
+
+#define TOOL_TYPE_CASE(x) \
+ case JNI_MotionEvent::TOOL_TYPE_##x: \
+ return MotionEventAndroid::ToolType::x
+
+#define TOOL_TYPE_REVERSE_CASE(x) \
+ case MotionEventAndroid::ToolType::x: \
+ return JNI_MotionEvent::TOOL_TYPE_##x
MotionEventAndroid::Action FromAndroidAction(int android_action) {
switch (android_action) {
- EVENT_CASE(ACTION_DOWN);
- EVENT_CASE(ACTION_UP);
- EVENT_CASE(ACTION_MOVE);
- EVENT_CASE(ACTION_CANCEL);
- EVENT_CASE(ACTION_POINTER_DOWN);
- EVENT_CASE(ACTION_POINTER_UP);
- EVENT_CASE(ACTION_HOVER_ENTER);
- EVENT_CASE(ACTION_HOVER_EXIT);
- EVENT_CASE(ACTION_HOVER_MOVE);
- EVENT_CASE(ACTION_BUTTON_PRESS);
- EVENT_CASE(ACTION_BUTTON_RELEASE);
+ ACTION_CASE(DOWN);
+ ACTION_CASE(UP);
+ ACTION_CASE(MOVE);
+ ACTION_CASE(CANCEL);
+ ACTION_CASE(POINTER_DOWN);
+ ACTION_CASE(POINTER_UP);
+ ACTION_CASE(HOVER_ENTER);
+ ACTION_CASE(HOVER_EXIT);
+ ACTION_CASE(HOVER_MOVE);
+ ACTION_CASE(BUTTON_PRESS);
+ ACTION_CASE(BUTTON_RELEASE);
default:
NOTREACHED() << "Invalid Android MotionEvent action: " << android_action;
};
- return MotionEventAndroid::ACTION_CANCEL;
+ return MotionEventAndroid::Action::CANCEL;
+}
+
+int ToAndroidAction(MotionEventAndroid::Action action) {
+ switch (action) {
+ ACTION_REVERSE_CASE(DOWN);
+ ACTION_REVERSE_CASE(UP);
+ ACTION_REVERSE_CASE(MOVE);
+ ACTION_REVERSE_CASE(CANCEL);
+ ACTION_REVERSE_CASE(POINTER_DOWN);
+ ACTION_REVERSE_CASE(POINTER_UP);
+ ACTION_REVERSE_CASE(HOVER_ENTER);
+ ACTION_REVERSE_CASE(HOVER_EXIT);
+ ACTION_REVERSE_CASE(HOVER_MOVE);
+ ACTION_REVERSE_CASE(BUTTON_PRESS);
+ ACTION_REVERSE_CASE(BUTTON_RELEASE);
+ default:
+ NOTREACHED() << "Invalid MotionEvent action: " << action;
+ };
+ return JNI_MotionEvent::ACTION_CANCEL;
}
MotionEventAndroid::ToolType FromAndroidToolType(int android_tool_type) {
switch (android_tool_type) {
- EVENT_CASE(TOOL_TYPE_UNKNOWN);
- EVENT_CASE(TOOL_TYPE_FINGER);
- EVENT_CASE(TOOL_TYPE_STYLUS);
- EVENT_CASE(TOOL_TYPE_MOUSE);
- EVENT_CASE(TOOL_TYPE_ERASER);
+ TOOL_TYPE_CASE(UNKNOWN);
+ TOOL_TYPE_CASE(FINGER);
+ TOOL_TYPE_CASE(STYLUS);
+ TOOL_TYPE_CASE(MOUSE);
+ TOOL_TYPE_CASE(ERASER);
default:
NOTREACHED() << "Invalid Android MotionEvent tool type: "
<< android_tool_type;
};
- return MotionEventAndroid::TOOL_TYPE_UNKNOWN;
+ return MotionEventAndroid::ToolType::UNKNOWN;
+}
+
+int ToAndroidToolType(MotionEventAndroid::ToolType tool_type) {
+ switch (tool_type) {
+ TOOL_TYPE_REVERSE_CASE(UNKNOWN);
+ TOOL_TYPE_REVERSE_CASE(FINGER);
+ TOOL_TYPE_REVERSE_CASE(STYLUS);
+ TOOL_TYPE_REVERSE_CASE(MOUSE);
+ TOOL_TYPE_REVERSE_CASE(ERASER);
+ default:
+ NOTREACHED() << "Invalid MotionEvent tool type: " << tool_type;
+ };
+ return JNI_MotionEvent::TOOL_TYPE_UNKNOWN;
}
-#undef EVENT_CASE
+
+#undef ACTION_CASE
+#undef ACTION_REVERSE_CASE
+#undef TOOL_TYPE_CASE
+#undef TOOL_TYPE_REVERSE_CASE
int FromAndroidButtonState(int button_state) {
int result = 0;
@@ -131,11 +179,11 @@ float ToValidFloat(float x) {
size_t ToValidHistorySize(jint history_size, ui::MotionEvent::Action action) {
DCHECK_GE(history_size, 0);
- // While the spec states that only ACTION_MOVE events should contain
+ // While the spec states that only Action::MOVE events should contain
// historical entries, it's possible that an embedder could repurpose an
- // ACTION_MOVE event into a different kind of event. In that case, the
+ // Action::MOVE event into a different kind of event. In that case, the
// historical values are meaningless, and should not be exposed.
- if (action != ui::MotionEvent::ACTION_MOVE)
+ if (action != ui::MotionEvent::Action::MOVE)
return 0;
return history_size;
}
@@ -179,7 +227,7 @@ MotionEventAndroid::CachedPointer::CachedPointer()
orientation(0),
tilt_x(0),
tilt_y(0),
- tool_type(TOOL_TYPE_UNKNOWN) {}
+ tool_type(ToolType::UNKNOWN) {}
MotionEventAndroid::MotionEventAndroid(JNIEnv* env,
jobject event,
@@ -253,19 +301,12 @@ MotionEventAndroid::MotionEventAndroid(const MotionEventAndroid& e)
}
// static
-int MotionEventAndroid::GetAndroidActionForTesting(int action) {
- int android_action = JNI_MotionEvent::ACTION_CANCEL;
- switch (action) {
- case ui::MotionEvent::ACTION_DOWN:
- android_action = JNI_MotionEvent::ACTION_DOWN;
- break;
- case ui::MotionEvent::ACTION_UP:
- android_action = JNI_MotionEvent::ACTION_UP;
- break;
- default:
- NOTIMPLEMENTED() << "Conversion not supported: " << action;
- }
- return android_action;
+int MotionEventAndroid::GetAndroidAction(Action action) {
+ return ToAndroidAction(action);
+}
+
+int MotionEventAndroid::GetAndroidToolType(ToolType tool_type) {
+ return ToAndroidToolType(tool_type);
}
std::unique_ptr<MotionEventAndroid> MotionEventAndroid::CreateFor(
@@ -305,8 +346,8 @@ ScopedJavaLocalRef<jobject> MotionEventAndroid::GetJavaObject() const {
}
int MotionEventAndroid::GetActionIndex() const {
- DCHECK(cached_action_ == MotionEvent::ACTION_POINTER_UP ||
- cached_action_ == MotionEvent::ACTION_POINTER_DOWN)
+ DCHECK(cached_action_ == MotionEvent::Action::POINTER_UP ||
+ cached_action_ == MotionEvent::Action::POINTER_DOWN)
<< "Invalid action for GetActionIndex(): " << cached_action_;
DCHECK_GE(cached_action_index_, 0);
DCHECK_LT(cached_action_index_, static_cast<int>(cached_pointer_count_));
@@ -341,6 +382,22 @@ float MotionEventAndroid::GetY(size_t pointer_index) const {
AttachCurrentThread(), event_, pointer_index));
}
+float MotionEventAndroid::GetXPix(size_t pointer_index) const {
+ DCHECK_LT(pointer_index, cached_pointer_count_);
+ if (pointer_index < MAX_POINTERS_TO_CACHE)
+ return cached_pointers_[pointer_index].position.x() / pix_to_dip_;
+ return JNI_MotionEvent::Java_MotionEvent_getXF_I(AttachCurrentThread(),
+ event_, pointer_index);
+}
+
+float MotionEventAndroid::GetYPix(size_t pointer_index) const {
+ DCHECK_LT(pointer_index, cached_pointer_count_);
+ if (pointer_index < MAX_POINTERS_TO_CACHE)
+ return cached_pointers_[pointer_index].position.y() / pix_to_dip_;
+ return JNI_MotionEvent::Java_MotionEvent_getYF_I(AttachCurrentThread(),
+ event_, pointer_index);
+}
+
float MotionEventAndroid::GetRawX(size_t pointer_index) const {
return GetX(pointer_index) + cached_raw_position_offset_.x();
}
@@ -380,7 +437,7 @@ float MotionEventAndroid::GetPressure(size_t pointer_index) const {
// accessed at most once per event instance).
if (!event_.obj())
return 0.f;
- if (cached_action_ == MotionEvent::ACTION_UP)
+ if (cached_action_ == MotionEvent::Action::UP)
return 0.f;
return JNI_MotionEvent::Java_MotionEvent_getPressureF_I(
AttachCurrentThread(), event_, pointer_index);
diff --git a/chromium/ui/events/android/motion_event_android.h b/chromium/ui/events/android/motion_event_android.h
index e23d0e5c0af..53165164f52 100644
--- a/chromium/ui/events/android/motion_event_android.h
+++ b/chromium/ui/events/android/motion_event_android.h
@@ -27,7 +27,8 @@ class EVENTS_EXPORT MotionEventAndroid : public MotionEvent {
public:
// Returns the motion event action defined in Java layer for a given
// MotionEvent::Action.
- static int GetAndroidActionForTesting(int action);
+ static int GetAndroidAction(Action action);
+ static int GetAndroidToolType(ToolType tool_type);
struct Pointer {
Pointer(jint id,
@@ -79,6 +80,9 @@ class EVENTS_EXPORT MotionEventAndroid : public MotionEvent {
// Convenience method returning the pointer at index 0.
gfx::PointF GetPoint() const { return gfx::PointF(GetX(0), GetY(0)); }
+ gfx::PointF GetPointPix() const {
+ return gfx::PointF(GetXPix(0), GetYPix(0));
+ }
// ui::MotionEvent methods.
uint32_t GetUniqueEventId() const override;
@@ -119,6 +123,9 @@ class EVENTS_EXPORT MotionEventAndroid : public MotionEvent {
base::android::ScopedJavaLocalRef<jobject> GetJavaObject() const;
+ float GetXPix(size_t pointer_index) const;
+ float GetYPix(size_t pointer_index) const;
+
private:
struct CachedPointer;
diff --git a/chromium/ui/events/android/motion_event_android_unittest.cc b/chromium/ui/events/android/motion_event_android_unittest.cc
index 6ca7bb7e749..2a6b1671de9 100644
--- a/chromium/ui/events/android/motion_event_android_unittest.cc
+++ b/chromium/ui/events/android/motion_event_android_unittest.cc
@@ -72,7 +72,7 @@ TEST(MotionEventAndroidTest, Constructor) {
action_index, kAndroidActionButton, kAndroidButtonPrimary,
kAndroidAltKeyDown, raw_offset, -raw_offset, false, &p0, &p1);
- EXPECT_EQ(MotionEvent::ACTION_DOWN, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::DOWN, event.GetAction());
EXPECT_EQ(event_time, event.GetEventTime());
EXPECT_EQ(p0.pos_x_pixels * kPixToDip, event.GetX(0));
EXPECT_EQ(p0.pos_y_pixels * kPixToDip, event.GetY(0));
@@ -96,8 +96,8 @@ TEST(MotionEventAndroidTest, Constructor) {
float_error);
EXPECT_EQ(p0.id, event.GetPointerId(0));
EXPECT_EQ(p1.id, event.GetPointerId(1));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(0));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(1));
+ EXPECT_EQ(MotionEvent::ToolType::FINGER, event.GetToolType(0));
+ EXPECT_EQ(MotionEvent::ToolType::FINGER, event.GetToolType(1));
EXPECT_EQ(MotionEvent::BUTTON_PRIMARY, event.GetButtonState());
EXPECT_EQ(ui::EF_ALT_DOWN | ui::EF_LEFT_MOUSE_BUTTON, event.GetFlags());
EXPECT_EQ(static_cast<size_t>(pointer_count), event.GetPointerCount());
@@ -136,7 +136,7 @@ TEST(MotionEventAndroidTest, Cancel) {
0, false, &p0, nullptr);
std::unique_ptr<MotionEvent> cancel_event = event.Cancel();
- EXPECT_EQ(MotionEvent::ACTION_CANCEL, cancel_event->GetAction());
+ EXPECT_EQ(MotionEvent::Action::CANCEL, cancel_event->GetAction());
EXPECT_EQ(event_time, cancel_event->GetEventTime());
EXPECT_EQ(p0.pos_x_pixels * kPixToDip, cancel_event->GetX(0));
EXPECT_EQ(p0.pos_y_pixels * kPixToDip, cancel_event->GetY(0));
@@ -193,7 +193,7 @@ TEST(MotionEventAndroidTest, ActionIndexForPointerDown) {
pointer_count, history_size, action_index, 0, 0, 0,
0, 0, false, &p0, &p1);
- EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::POINTER_DOWN, event.GetAction());
EXPECT_EQ(action_index, event.GetActionIndex());
}
diff --git a/chromium/ui/events/base_event_utils.cc b/chromium/ui/events/base_event_utils.cc
index 6eee6f1f671..20bbed9d18f 100644
--- a/chromium/ui/events/base_event_utils.cc
+++ b/chromium/ui/events/base_event_utils.cc
@@ -47,7 +47,7 @@ bool IsSystemKeyModifier(int flags) {
(EF_ALTGR_DOWN & flags) == 0;
}
-base::LazyInstance<std::unique_ptr<base::TickClock>>::Leaky g_tick_clock =
+base::LazyInstance<base::TickClock*>::Leaky g_tick_clock =
LAZY_INSTANCE_INITIALIZER;
base::TimeTicks EventTimeForNow() {
@@ -55,8 +55,8 @@ base::TimeTicks EventTimeForNow() {
: base::TimeTicks::Now();
}
-void SetEventTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock) {
- g_tick_clock.Get() = std::move(tick_clock);
+void SetEventTickClockForTesting(base::TickClock* tick_clock) {
+ g_tick_clock.Get() = tick_clock;
}
double EventTimeStampToSeconds(base::TimeTicks time_stamp) {
diff --git a/chromium/ui/events/base_event_utils.h b/chromium/ui/events/base_event_utils.h
index 4e177803e27..d030fd15b8d 100644
--- a/chromium/ui/events/base_event_utils.h
+++ b/chromium/ui/events/base_event_utils.h
@@ -27,8 +27,10 @@ EVENTS_BASE_EXPORT bool IsSystemKeyModifier(int flags);
// Create a timestamp based on the current time.
EVENTS_BASE_EXPORT base::TimeTicks EventTimeForNow();
+// Overrides the clock used by EventTimeForNow for testing.
+// This doesn't take the ownership of the clock.
EVENTS_BASE_EXPORT void SetEventTickClockForTesting(
- std::unique_ptr<base::TickClock> tick_clock);
+ base::TickClock* tick_clock);
// Converts an event timestamp ticks to seconds (floating point representation).
// WARNING: This should only be used when interfacing with platform code that
diff --git a/chromium/ui/events/blink/blink_event_util.cc b/chromium/ui/events/blink/blink_event_util.cc
index 6c253aa9c27..c8d058216b2 100644
--- a/chromium/ui/events/blink/blink_event_util.cc
+++ b/chromium/ui/events/blink/blink_event_util.cc
@@ -9,8 +9,8 @@
#include <algorithm>
#include <bitset>
#include <limits>
+#include <memory>
-#include "base/memory/ptr_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "third_party/WebKit/public/platform/WebInputEvent.h"
@@ -44,24 +44,24 @@ const int kInvalidTouchIndex = -1;
WebInputEvent::Type ToWebTouchEventType(MotionEvent::Action action) {
switch (action) {
- case MotionEvent::ACTION_DOWN:
+ case MotionEvent::Action::DOWN:
return WebInputEvent::kTouchStart;
- case MotionEvent::ACTION_MOVE:
+ case MotionEvent::Action::MOVE:
return WebInputEvent::kTouchMove;
- case MotionEvent::ACTION_UP:
+ case MotionEvent::Action::UP:
return WebInputEvent::kTouchEnd;
- case MotionEvent::ACTION_CANCEL:
+ case MotionEvent::Action::CANCEL:
return WebInputEvent::kTouchCancel;
- case MotionEvent::ACTION_POINTER_DOWN:
+ case MotionEvent::Action::POINTER_DOWN:
return WebInputEvent::kTouchStart;
- case MotionEvent::ACTION_POINTER_UP:
+ case MotionEvent::Action::POINTER_UP:
return WebInputEvent::kTouchEnd;
- case MotionEvent::ACTION_NONE:
- case MotionEvent::ACTION_HOVER_ENTER:
- case MotionEvent::ACTION_HOVER_EXIT:
- case MotionEvent::ACTION_HOVER_MOVE:
- case MotionEvent::ACTION_BUTTON_PRESS:
- case MotionEvent::ACTION_BUTTON_RELEASE:
+ case MotionEvent::Action::NONE:
+ case MotionEvent::Action::HOVER_ENTER:
+ case MotionEvent::Action::HOVER_EXIT:
+ case MotionEvent::Action::HOVER_MOVE:
+ case MotionEvent::Action::BUTTON_PRESS:
+ case MotionEvent::Action::BUTTON_RELEASE:
break;
}
NOTREACHED() << "Invalid MotionEvent::Action = " << action;
@@ -69,50 +69,51 @@ WebInputEvent::Type ToWebTouchEventType(MotionEvent::Action action) {
}
// Note that the action index is meaningful only in the context of
-// |ACTION_POINTER_UP| and |ACTION_POINTER_DOWN|; other actions map directly to
-// WebTouchPoint::State.
+// |Action::POINTER_UP| and |Action::POINTER_DOWN|; other actions map directly
+// to WebTouchPoint::State.
WebTouchPoint::State ToWebTouchPointState(const MotionEvent& event,
size_t pointer_index) {
switch (event.GetAction()) {
- case MotionEvent::ACTION_DOWN:
+ case MotionEvent::Action::DOWN:
return WebTouchPoint::kStatePressed;
- case MotionEvent::ACTION_MOVE:
+ case MotionEvent::Action::MOVE:
return WebTouchPoint::kStateMoved;
- case MotionEvent::ACTION_UP:
+ case MotionEvent::Action::UP:
return WebTouchPoint::kStateReleased;
- case MotionEvent::ACTION_CANCEL:
+ case MotionEvent::Action::CANCEL:
return WebTouchPoint::kStateCancelled;
- case MotionEvent::ACTION_POINTER_DOWN:
+ case MotionEvent::Action::POINTER_DOWN:
return static_cast<int>(pointer_index) == event.GetActionIndex()
? WebTouchPoint::kStatePressed
: WebTouchPoint::kStateStationary;
- case MotionEvent::ACTION_POINTER_UP:
+ case MotionEvent::Action::POINTER_UP:
return static_cast<int>(pointer_index) == event.GetActionIndex()
? WebTouchPoint::kStateReleased
: WebTouchPoint::kStateStationary;
- case MotionEvent::ACTION_NONE:
- case MotionEvent::ACTION_HOVER_ENTER:
- case MotionEvent::ACTION_HOVER_EXIT:
- case MotionEvent::ACTION_HOVER_MOVE:
- case MotionEvent::ACTION_BUTTON_PRESS:
- case MotionEvent::ACTION_BUTTON_RELEASE:
+ case MotionEvent::Action::NONE:
+ case MotionEvent::Action::HOVER_ENTER:
+ case MotionEvent::Action::HOVER_EXIT:
+ case MotionEvent::Action::HOVER_MOVE:
+ case MotionEvent::Action::BUTTON_PRESS:
+ case MotionEvent::Action::BUTTON_RELEASE:
break;
}
NOTREACHED() << "Invalid MotionEvent::Action.";
return WebTouchPoint::kStateUndefined;
}
-WebPointerProperties::PointerType ToWebPointerType(int tool_type) {
- switch (static_cast<MotionEvent::ToolType>(tool_type)) {
- case MotionEvent::TOOL_TYPE_UNKNOWN:
+WebPointerProperties::PointerType ToWebPointerType(
+ MotionEvent::ToolType tool_type) {
+ switch (tool_type) {
+ case MotionEvent::ToolType::UNKNOWN:
return WebPointerProperties::PointerType::kUnknown;
- case MotionEvent::TOOL_TYPE_FINGER:
+ case MotionEvent::ToolType::FINGER:
return WebPointerProperties::PointerType::kTouch;
- case MotionEvent::TOOL_TYPE_STYLUS:
+ case MotionEvent::ToolType::STYLUS:
return WebPointerProperties::PointerType::kPen;
- case MotionEvent::TOOL_TYPE_MOUSE:
+ case MotionEvent::ToolType::MOUSE:
return WebPointerProperties::PointerType::kMouse;
- case MotionEvent::TOOL_TYPE_ERASER:
+ case MotionEvent::ToolType::ERASER:
return WebPointerProperties::PointerType::kEraser;
}
NOTREACHED() << "Invalid MotionEvent::ToolType = " << tool_type;
@@ -599,7 +600,8 @@ std::pair<WebGestureEvent, WebGestureEvent> CoalesceScrollAndPinch(
blink::WebTouchEvent CreateWebTouchEventFromMotionEvent(
const MotionEvent& event,
- bool moved_beyond_slop_region) {
+ bool moved_beyond_slop_region,
+ bool hovering) {
static_assert(static_cast<int>(MotionEvent::MAX_TOUCH_POINT_COUNT) ==
static_cast<int>(blink::WebTouchEvent::kTouchesLengthCap),
"inconsistent maximum number of active touch points");
@@ -612,6 +614,7 @@ blink::WebTouchEvent CreateWebTouchEventFromMotionEvent(
? WebInputEvent::kEventNonBlocking
: WebInputEvent::kBlocking;
result.moved_beyond_slop_region = moved_beyond_slop_region;
+ result.hovering = hovering;
// TODO(mustaq): MotionEvent flags seems unrelated, should use
// metaState instead?
@@ -938,23 +941,23 @@ std::unique_ptr<blink::WebInputEvent> TranslateAndScaleWebInputEvent(
WebInputEvent::Type ToWebMouseEventType(MotionEvent::Action action) {
switch (action) {
- case MotionEvent::ACTION_DOWN:
- case MotionEvent::ACTION_BUTTON_PRESS:
+ case MotionEvent::Action::DOWN:
+ case MotionEvent::Action::BUTTON_PRESS:
return WebInputEvent::kMouseDown;
- case MotionEvent::ACTION_MOVE:
- case MotionEvent::ACTION_HOVER_MOVE:
+ case MotionEvent::Action::MOVE:
+ case MotionEvent::Action::HOVER_MOVE:
return WebInputEvent::kMouseMove;
- case MotionEvent::ACTION_HOVER_ENTER:
+ case MotionEvent::Action::HOVER_ENTER:
return WebInputEvent::kMouseEnter;
- case MotionEvent::ACTION_HOVER_EXIT:
+ case MotionEvent::Action::HOVER_EXIT:
return WebInputEvent::kMouseLeave;
- case MotionEvent::ACTION_UP:
- case MotionEvent::ACTION_BUTTON_RELEASE:
+ case MotionEvent::Action::UP:
+ case MotionEvent::Action::BUTTON_RELEASE:
return WebInputEvent::kMouseUp;
- case MotionEvent::ACTION_NONE:
- case MotionEvent::ACTION_CANCEL:
- case MotionEvent::ACTION_POINTER_DOWN:
- case MotionEvent::ACTION_POINTER_UP:
+ case MotionEvent::Action::NONE:
+ case MotionEvent::Action::CANCEL:
+ case MotionEvent::Action::POINTER_DOWN:
+ case MotionEvent::Action::POINTER_UP:
break;
}
NOTREACHED() << "Invalid MotionEvent::Action = " << action;
@@ -1049,11 +1052,11 @@ void SetWebPointerPropertiesFromMotionEventData(
float tilt_x,
float tilt_y,
int android_buttons_changed,
- int tool_type) {
+ MotionEvent::ToolType tool_type) {
webPointerProperties.id = pointer_id;
webPointerProperties.force = pressure;
- if (tool_type == MotionEvent::TOOL_TYPE_STYLUS) {
+ if (tool_type == MotionEvent::ToolType::STYLUS) {
// A stylus points to a direction specified by orientation and tilts to
// the opposite direction. Coordinate system is left-handed.
webPointerProperties.tilt_x = tilt_x;
@@ -1173,11 +1176,20 @@ std::unique_ptr<WebGestureEvent> CreateWebGestureEventFromGestureEventAndroid(
case GESTURE_EVENT_TYPE_PINCH_END:
event_type = WebInputEvent::kGesturePinchEnd;
break;
+ case GESTURE_EVENT_TYPE_SCROLL_START:
+ event_type = WebInputEvent::kGestureScrollBegin;
+ break;
+ case GESTURE_EVENT_TYPE_FLING_START:
+ event_type = WebInputEvent::kGestureFlingStart;
+ break;
+ case GESTURE_EVENT_TYPE_FLING_CANCEL:
+ event_type = WebInputEvent::kGestureFlingCancel;
+ break;
default:
NOTREACHED() << "Unknown gesture event type";
- return base::MakeUnique<WebGestureEvent>();
+ return std::make_unique<WebGestureEvent>();
}
- auto web_event = base::MakeUnique<WebGestureEvent>(
+ auto web_event = std::make_unique<WebGestureEvent>(
event_type, WebInputEvent::kNoModifiers, event.time() / 1000.0);
// NOTE: Source gesture events are synthetic ones that simulate
// gesture from keyboard (zoom in/out) for now. Should populate Blink
@@ -1187,8 +1199,24 @@ std::unique_ptr<WebGestureEvent> CreateWebGestureEventFromGestureEventAndroid(
web_event->global_x = event.screen_location().x();
web_event->global_x = event.screen_location().y();
web_event->source_device = blink::kWebGestureDeviceTouchscreen;
- if (event_type == WebInputEvent::kGesturePinchUpdate)
- web_event->data.pinch_update.scale = event.delta();
+ if (event.synthetic_scroll())
+ web_event->source_device = blink::kWebGestureDeviceSyntheticAutoscroll;
+ if (event_type == WebInputEvent::kGesturePinchUpdate) {
+ web_event->data.pinch_update.scale = event.scale();
+ } else if (event_type == WebInputEvent::kGestureScrollBegin) {
+ web_event->data.scroll_begin.delta_x_hint = event.delta_x();
+ web_event->data.scroll_begin.delta_y_hint = event.delta_y();
+ web_event->data.scroll_begin.target_viewport = event.target_viewport();
+ } else if (event_type == WebInputEvent::kGestureFlingStart) {
+ web_event->data.fling_start.velocity_x = event.velocity_x();
+ web_event->data.fling_start.velocity_y = event.velocity_y();
+ web_event->data.fling_start.target_viewport = event.target_viewport();
+ } else if (event_type == WebInputEvent::kGestureFlingCancel) {
+ web_event->data.fling_cancel.prevent_boosting = true;
+ if (event.synthetic_scroll())
+ web_event->data.fling_cancel.target_viewport = true;
+ }
+
return web_event;
}
#endif
diff --git a/chromium/ui/events/blink/blink_event_util.h b/chromium/ui/events/blink/blink_event_util.h
index 53caa592cfc..24b85de5204 100644
--- a/chromium/ui/events/blink/blink_event_util.h
+++ b/chromium/ui/events/blink/blink_event_util.h
@@ -44,7 +44,8 @@ CoalesceScrollAndPinch(const blink::WebGestureEvent* second_last_event,
blink::WebTouchEvent CreateWebTouchEventFromMotionEvent(
const MotionEvent& event,
- bool may_cause_scrolling);
+ bool may_cause_scrolling,
+ bool hovering);
blink::WebGestureEvent CreateWebGestureEvent(const GestureEventDetails& details,
base::TimeTicks timestamp,
@@ -85,7 +86,7 @@ void SetWebPointerPropertiesFromMotionEventData(
float tilt_x,
float tilt_y,
int android_buttons_changed,
- int tool_type);
+ MotionEvent::ToolType tool_type);
int WebEventModifiersToEventFlags(int modifiers);
diff --git a/chromium/ui/events/blink/blink_event_util_unittest.cc b/chromium/ui/events/blink/blink_event_util_unittest.cc
index d895b48caa8..b8cb09a9f16 100644
--- a/chromium/ui/events/blink/blink_event_util_unittest.cc
+++ b/chromium/ui/events/blink/blink_event_util_unittest.cc
@@ -30,9 +30,9 @@ TEST(BlinkEventUtilTest, NoScalingWith1DSF) {
}
TEST(BlinkEventUtilTest, NonPaginatedWebMouseWheelEvent) {
- blink::WebMouseWheelEvent event(blink::WebInputEvent::kMouseWheel,
- blink::WebInputEvent::kNoModifiers,
- blink::WebInputEvent::kTimeStampForTesting);
+ blink::WebMouseWheelEvent event(
+ blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
event.delta_x = 1.f;
event.delta_y = 1.f;
event.wheel_ticks_x = 1.f;
@@ -50,9 +50,9 @@ TEST(BlinkEventUtilTest, NonPaginatedWebMouseWheelEvent) {
}
TEST(BlinkEventUtilTest, PaginatedWebMouseWheelEvent) {
- blink::WebMouseWheelEvent event(blink::WebInputEvent::kMouseWheel,
- blink::WebInputEvent::kNoModifiers,
- blink::WebInputEvent::kTimeStampForTesting);
+ blink::WebMouseWheelEvent event(
+ blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
+ blink::WebInputEvent::GetStaticTimeStampForTests());
event.delta_x = 1.f;
event.delta_y = 1.f;
event.wheel_ticks_x = 1.f;
@@ -158,13 +158,13 @@ TEST(BlinkEventUtilTest, TouchEventCoalescing) {
TEST(BlinkEventUtilTest, WebMouseWheelEventCoalescing) {
blink::WebMouseWheelEvent coalesced_event(
blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
- blink::WebInputEvent::kTimeStampForTesting);
+ blink::WebInputEvent::GetStaticTimeStampForTests());
coalesced_event.delta_x = 1;
coalesced_event.delta_y = 1;
blink::WebMouseWheelEvent event_to_be_coalesced(
blink::WebInputEvent::kMouseWheel, blink::WebInputEvent::kNoModifiers,
- blink::WebInputEvent::kTimeStampForTesting);
+ blink::WebInputEvent::GetStaticTimeStampForTests());
event_to_be_coalesced.delta_x = 3;
event_to_be_coalesced.delta_y = 4;
@@ -201,14 +201,14 @@ TEST(BlinkEventUtilTest, WebGestureEventCoalescing) {
blink::WebGestureEvent coalesced_event(
blink::WebInputEvent::kGestureScrollUpdate,
blink::WebInputEvent::kNoModifiers,
- blink::WebInputEvent::kTimeStampForTesting);
+ blink::WebInputEvent::GetStaticTimeStampForTests());
coalesced_event.data.scroll_update.delta_x = 1;
coalesced_event.data.scroll_update.delta_y = 1;
blink::WebGestureEvent event_to_be_coalesced(
blink::WebInputEvent::kGestureScrollUpdate,
blink::WebInputEvent::kNoModifiers,
- blink::WebInputEvent::kTimeStampForTesting);
+ blink::WebInputEvent::GetStaticTimeStampForTests());
event_to_be_coalesced.data.scroll_update.delta_x = 3;
event_to_be_coalesced.data.scroll_update.delta_y = 4;
diff --git a/chromium/ui/events/blink/input_handler_proxy.cc b/chromium/ui/events/blink/input_handler_proxy.cc
index ba36cfb0d5d..6d77910839f 100644
--- a/chromium/ui/events/blink/input_handler_proxy.cc
+++ b/chromium/ui/events/blink/input_handler_proxy.cc
@@ -161,7 +161,7 @@ InputHandlerProxy::InputHandlerProxy(
current_overscroll_params_(nullptr),
has_ongoing_compositor_scroll_fling_pinch_(false),
is_first_gesture_scroll_update_(false),
- tick_clock_(std::make_unique<base::DefaultTickClock>()) {
+ tick_clock_(base::DefaultTickClock::GetInstance()) {
DCHECK(client);
input_handler_->BindToClient(this,
touchpad_and_wheel_scroll_latching_enabled_);
@@ -299,6 +299,7 @@ void InputHandlerProxy::DispatchSingleInputEvent(
switch (event_with_callback->event().GetType()) {
case blink::WebGestureEvent::kGestureScrollBegin:
is_first_gesture_scroll_update_ = true;
+ FALLTHROUGH;
case blink::WebGestureEvent::kGestureFlingStart:
case blink::WebGestureEvent::kGesturePinchBegin:
case blink::WebGestureEvent::kGestureScrollUpdate:
@@ -736,6 +737,12 @@ InputHandlerProxy::HandleGestureScrollUpdate(
DCHECK(expect_scroll_update_end_);
#endif
+ gfx::Vector2dF scroll_delta(-gesture_event.data.scroll_update.delta_x,
+ -gesture_event.data.scroll_update.delta_y);
+ TRACE_EVENT_INSTANT2("input", "InputHandlerProxy::HandleGestureScrollUpdate",
+ TRACE_EVENT_SCOPE_THREAD, "dx", scroll_delta.x(), "dy",
+ scroll_delta.y());
+
if (scroll_sequence_ignored_)
return DROP_EVENT;
@@ -744,8 +751,6 @@ InputHandlerProxy::HandleGestureScrollUpdate(
cc::ScrollState scroll_state = CreateScrollStateForGesture(gesture_event);
gfx::Point scroll_point(gesture_event.x, gesture_event.y);
- gfx::Vector2dF scroll_delta(-gesture_event.data.scroll_update.delta_x,
- -gesture_event.data.scroll_update.delta_y);
if (ShouldAnimate(gesture_event.data.scroll_update.delta_units !=
blink::WebGestureEvent::ScrollUnits::kPixels)) {
@@ -760,7 +765,12 @@ InputHandlerProxy::HandleGestureScrollUpdate(
return DID_HANDLE;
case cc::InputHandler::SCROLL_IGNORED:
return DROP_EVENT;
- default:
+ case cc::InputHandler::SCROLL_ON_MAIN_THREAD:
+ case cc::InputHandler::SCROLL_UNKNOWN:
+ if (input_handler_->ScrollingShouldSwitchtoMainThread()) {
+ gesture_scroll_on_impl_thread_ = false;
+ client_->GenerateScrollBeginAndSendToMainThread(gesture_event);
+ }
return DID_NOT_HANDLE;
}
}
@@ -1325,9 +1335,8 @@ void InputHandlerProxy::HandleScrollElasticityOverscroll(
scroll_result));
}
-void InputHandlerProxy::SetTickClockForTesting(
- std::unique_ptr<base::TickClock> tick_clock) {
- tick_clock_ = std::move(tick_clock);
+void InputHandlerProxy::SetTickClockForTesting(base::TickClock* tick_clock) {
+ tick_clock_ = tick_clock;
}
void InputHandlerProxy::UpdateCurrentFlingState(
diff --git a/chromium/ui/events/blink/input_handler_proxy.h b/chromium/ui/events/blink/input_handler_proxy.h
index bb67ec43501..feeea9d1c65 100644
--- a/chromium/ui/events/blink/input_handler_proxy.h
+++ b/chromium/ui/events/blink/input_handler_proxy.h
@@ -176,7 +176,10 @@ class InputHandlerProxy : public cc::InputHandlerClient,
const blink::WebGestureEvent& gesture_event,
const cc::InputHandlerScrollResult& scroll_result);
- void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
+ // Overrides the internal clock for testing.
+ // This doesn't take the ownership of the clock. |tick_clock| must outlive the
+ // InputHandlerProxy instance.
+ void SetTickClockForTesting(base::TickClock* tick_clock);
// |is_touching_scrolling_layer| indicates if one of the points that has
// been touched hits a currently scrolling layer.
@@ -257,7 +260,7 @@ class InputHandlerProxy : public cc::InputHandlerClient,
bool has_ongoing_compositor_scroll_fling_pinch_;
bool is_first_gesture_scroll_update_;
- std::unique_ptr<base::TickClock> tick_clock_;
+ base::TickClock* tick_clock_;
std::unique_ptr<FlingBooster> fling_booster_;
diff --git a/chromium/ui/events/blink/input_handler_proxy_client.h b/chromium/ui/events/blink/input_handler_proxy_client.h
index 9f2fb2fa22f..3d992cd12fb 100644
--- a/chromium/ui/events/blink/input_handler_proxy_client.h
+++ b/chromium/ui/events/blink/input_handler_proxy_client.h
@@ -23,8 +23,7 @@ class InputHandlerProxyClient {
// Dispatch a non blocking event to the main thread. This is used when a
// gesture fling from a touchpad is processed and the target only has
- // passive event listeners. If the target has blocking event listeners
- // |TransferActiveWheelFlingAnimation| will be used instead.
+ // passive event listeners.
virtual void DispatchNonBlockingEventToMainThread(
WebScopedInputEvent event,
const ui::LatencyInfo& latency_info) = 0;
diff --git a/chromium/ui/events/blink/input_handler_proxy_unittest.cc b/chromium/ui/events/blink/input_handler_proxy_unittest.cc
index beef5fc3d56..2f1830b4735 100644
--- a/chromium/ui/events/blink/input_handler_proxy_unittest.cc
+++ b/chromium/ui/events/blink/input_handler_proxy_unittest.cc
@@ -9,15 +9,11 @@
#include "base/bind.h"
#include "base/containers/circular_deque.h"
#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/ref_counted_memory.h"
#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
#include "base/test/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/trace_event_analyzer.h"
-#include "base/trace_event/trace_buffer.h"
#include "cc/input/main_thread_scrolling_reason.h"
#include "cc/trees/swap_promise_monitor.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -111,12 +107,8 @@ WebGestureEvent CreateFling(WebGestureDevice source_device,
WebPoint point,
WebPoint global_point,
int modifiers) {
- return CreateFling(base::TimeTicks(),
- source_device,
- velocity,
- point,
- global_point,
- modifiers);
+ return CreateFling(base::TimeTicks(), source_device, velocity, point,
+ global_point, modifiers);
}
WebScopedInputEvent CreateGestureScrollFlingPinch(
@@ -126,7 +118,7 @@ WebScopedInputEvent CreateGestureScrollFlingPinch(
int x = 0,
int y = 0) {
WebGestureEvent gesture(type, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
gesture.source_device = source_device;
if (type == WebInputEvent::kGestureScrollUpdate) {
gesture.data.scroll_update.delta_y = delta_y_or_scale;
@@ -142,15 +134,6 @@ WebScopedInputEvent CreateGestureScrollFlingPinch(
return WebInputEventTraits::Clone(gesture);
}
-void OnTraceDataCollected(base::Closure quit_closure,
- base::trace_event::TraceResultBuffer* buffer,
- const scoped_refptr<base::RefCountedString>& json,
- bool has_more_events) {
- buffer->AddFragment(json->data());
- if (!has_more_events)
- quit_closure.Run();
-}
-
class MockInputHandler : public cc::InputHandler {
public:
MockInputHandler() {}
@@ -544,32 +527,6 @@ class InputHandlerProxyEventQueueTest : public testing::TestWithParam<bool> {
std::make_unique<CompositorThreadEventQueue>();
}
- void StartTracing() {
- base::trace_event::TraceLog::GetInstance()->SetEnabled(
- base::trace_event::TraceConfig("*"),
- base::trace_event::TraceLog::RECORDING_MODE);
- }
-
- void StopTracing() {
- base::trace_event::TraceLog::GetInstance()->SetDisabled();
- }
-
- std::unique_ptr<trace_analyzer::TraceAnalyzer> CreateTraceAnalyzer() {
- base::trace_event::TraceResultBuffer buffer;
- base::trace_event::TraceResultBuffer::SimpleOutput trace_output;
- buffer.SetOutputCallback(trace_output.GetCallback());
- base::RunLoop run_loop;
- buffer.Start();
- base::trace_event::TraceLog::GetInstance()->Flush(
- base::Bind(&OnTraceDataCollected, run_loop.QuitClosure(),
- base::Unretained(&buffer)));
- run_loop.Run();
- buffer.Finish();
-
- return base::WrapUnique(
- trace_analyzer::TraceAnalyzer::Create(trace_output.json_output));
- }
-
void HandleGestureEvent(WebInputEvent::Type type,
float delta_y_or_scale = 0,
int x = 0,
@@ -606,9 +563,8 @@ class InputHandlerProxyEventQueueTest : public testing::TestWithParam<bool> {
return input_handler_proxy_->compositor_event_queue_->queue_;
}
- void SetInputHandlerProxyTickClockForTesting(
- std::unique_ptr<base::TickClock> tick_clock) {
- input_handler_proxy_->SetTickClockForTesting(std::move(tick_clock));
+ void SetInputHandlerProxyTickClockForTesting(base::TickClock* tick_clock) {
+ input_handler_proxy_->SetTickClockForTesting(tick_clock);
}
protected:
@@ -632,7 +588,7 @@ TEST_P(InputHandlerProxyTest, MouseWheelNoListener) {
WebMouseWheelEvent wheel(WebInputEvent::kMouseWheel,
WebInputEvent::kControlKey,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
VERIFY_AND_RESET_MOCKS();
}
@@ -645,7 +601,7 @@ TEST_P(InputHandlerProxyTest, MouseWheelPassiveListener) {
WebMouseWheelEvent wheel(WebInputEvent::kMouseWheel,
WebInputEvent::kControlKey,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
VERIFY_AND_RESET_MOCKS();
}
@@ -658,7 +614,7 @@ TEST_P(InputHandlerProxyTest, MouseWheelBlockingListener) {
WebMouseWheelEvent wheel(WebInputEvent::kMouseWheel,
WebInputEvent::kControlKey,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
VERIFY_AND_RESET_MOCKS();
}
@@ -672,7 +628,7 @@ TEST_P(InputHandlerProxyTest, MouseWheelBlockingAndPassiveListener) {
WebMouseWheelEvent wheel(WebInputEvent::kMouseWheel,
WebInputEvent::kControlKey,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(wheel));
VERIFY_AND_RESET_MOCKS();
}
@@ -1759,7 +1715,7 @@ TEST_P(InputHandlerProxyTest, HitTestTouchEventNonNullTouchAction) {
// hit-testing for the third touch point.
WebTouchEvent touch(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
touch.touches_length = 3;
touch.touch_start_or_first_touch_move = true;
@@ -1801,7 +1757,7 @@ TEST_P(InputHandlerProxyTest, HitTestTouchEventNullTouchAction) {
// hit-testing for the third touch point.
WebTouchEvent touch(WebInputEvent::kTouchMove, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
touch.touches_length = 3;
touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::kStatePressed, 0, 0);
@@ -1846,7 +1802,7 @@ TEST_P(InputHandlerProxyTest, MultiTouchPointHitTestNegative) {
.WillOnce(testing::Return());
WebTouchEvent touch(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
touch.unique_touch_event_id = 1;
touch.touches_length = 3;
@@ -1892,7 +1848,7 @@ TEST_P(InputHandlerProxyTest, MultiTouchPointHitTestPositive) {
// hit-testing for the third touch point.
WebTouchEvent touch(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
touch.unique_touch_event_id = 1;
touch.touches_length = 3;
@@ -1934,7 +1890,7 @@ TEST_P(InputHandlerProxyTest, MultiTouchPointHitTestPassivePositive) {
.WillOnce(testing::Return());
WebTouchEvent touch(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
touch.unique_touch_event_id = 1;
touch.touches_length = 3;
@@ -1975,7 +1931,7 @@ TEST_P(InputHandlerProxyTest, TouchStartPassiveAndTouchEndBlocking) {
.WillOnce(testing::Return());
WebTouchEvent touch(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
touch.unique_touch_event_id = 1;
touch.touches_length = 1;
touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::kStatePressed, 0, 0);
@@ -2010,7 +1966,7 @@ TEST_P(InputHandlerProxyTest, TouchMoveBlockingAddedAfterPassiveTouchStart) {
.WillOnce(testing::Return());
WebTouchEvent touch(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
touch.touches_length = 1;
touch.touch_start_or_first_touch_move = true;
touch.touches[0] = CreateWebTouchPoint(WebTouchPoint::kStatePressed, 0, 0);
@@ -2050,7 +2006,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) {
// Keyboard events received during a scroll should have no effect.
WebKeyboardEvent key_event(WebInputEvent::kKeyDown,
WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
EXPECT_EQ(InputHandlerProxy::DID_NOT_HANDLE,
input_handler_->HandleInputEvent(key_event));
EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
@@ -2111,7 +2067,7 @@ TEST_P(InputHandlerProxyTest, GestureFlingCancelledByWheelEvent) {
WebMouseWheelEvent wheel_event(WebInputEvent::kMouseWheel,
WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
input_handler_->HandleInputEvent(wheel_event);
EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
VERIFY_AND_RESET_MOCKS();
@@ -2136,7 +2092,6 @@ TEST_P(InputHandlerProxyTest, GestureFlingCancelledByWheelEvent) {
GetEventListenerProperties(cc::EventListenerClass::kMouseWheel))
.WillOnce(testing::Return(cc::EventListenerProperties::kBlocking));
-
input_handler_->HandleInputEvent(wheel_event);
EXPECT_FALSE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
VERIFY_AND_RESET_MOCKS();
@@ -2638,7 +2593,7 @@ TEST_P(InputHandlerProxyTest, DidReceiveInputEvent_ForFlingTouchscreen) {
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(kImplThreadScrollState));
EXPECT_EQ(InputHandlerProxy::DID_HANDLE,
- input_handler_->HandleInputEvent(gesture_));
+ input_handler_->HandleInputEvent(gesture_));
VERIFY_AND_RESET_MOCKS();
EXPECT_SET_NEEDS_ANIMATE_INPUT(1);
@@ -2751,7 +2706,7 @@ TEST_P(InputHandlerProxyTest, GestureScrollingThreadStatusHistogram) {
WebTouchEvent touch_start(WebInputEvent::kTouchStart,
WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
touch_start.touches_length = 1;
touch_start.touch_start_or_first_touch_move = true;
touch_start.touches[0] =
@@ -2859,7 +2814,7 @@ TEST_P(InputHandlerProxyTest, WheelScrollingThreadStatusHistogram) {
WebMouseWheelEvent wheel(WebInputEvent::kMouseWheel,
WebInputEvent::kControlKey,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
WebGestureEvent gesture_scroll_begin;
gesture_scroll_begin.SetType(WebInputEvent::kGestureScrollBegin);
@@ -3068,11 +3023,9 @@ TEST_P(InputHandlerProxyEventQueueTest, VSyncAlignedGestureScrollPinchScroll) {
TEST_P(InputHandlerProxyEventQueueTest, VSyncAlignedQueueingTime) {
base::HistogramTester histogram_tester;
- std::unique_ptr<base::SimpleTestTickClock> tick_clock =
- std::make_unique<base::SimpleTestTickClock>();
- base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get();
- tick_clock_ptr->SetNowTicks(base::TimeTicks::Now());
- SetInputHandlerProxyTickClockForTesting(std::move(tick_clock));
+ base::SimpleTestTickClock tick_clock;
+ tick_clock.SetNowTicks(base::TimeTicks::Now());
+ SetInputHandlerProxyTickClockForTesting(&tick_clock);
// Handle scroll on compositor.
cc::InputHandlerScrollResult scroll_result_did_scroll_;
@@ -3088,17 +3041,17 @@ TEST_P(InputHandlerProxyEventQueueTest, VSyncAlignedQueueingTime) {
EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_, true));
HandleGestureEvent(WebInputEvent::kGestureScrollBegin);
- tick_clock_ptr->Advance(base::TimeDelta::FromMicroseconds(10));
+ tick_clock.Advance(base::TimeDelta::FromMicroseconds(10));
HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -20);
- tick_clock_ptr->Advance(base::TimeDelta::FromMicroseconds(40));
+ tick_clock.Advance(base::TimeDelta::FromMicroseconds(40));
HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -40);
- tick_clock_ptr->Advance(base::TimeDelta::FromMicroseconds(20));
+ tick_clock.Advance(base::TimeDelta::FromMicroseconds(20));
HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -10);
- tick_clock_ptr->Advance(base::TimeDelta::FromMicroseconds(10));
+ tick_clock.Advance(base::TimeDelta::FromMicroseconds(10));
HandleGestureEvent(WebInputEvent::kGestureScrollEnd);
// Dispatch all queued events.
- tick_clock_ptr->Advance(base::TimeDelta::FromMicroseconds(70));
+ tick_clock.Advance(base::TimeDelta::FromMicroseconds(70));
input_handler_proxy_->DeliverInputForBeginFrame();
EXPECT_EQ(0ul, event_queue().size());
EXPECT_EQ(5ul, event_disposition_recorder_.size());
@@ -3183,7 +3136,7 @@ TEST_P(InputHandlerProxyEventQueueTest, OriginalEventsTracing) {
EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_, true))
.Times(::testing::AtLeast(1));
- StartTracing();
+ trace_analyzer::Start("*");
// Simulate scroll.
HandleGestureEvent(WebInputEvent::kGestureScrollBegin);
HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -20);
@@ -3201,11 +3154,9 @@ TEST_P(InputHandlerProxyEventQueueTest, OriginalEventsTracing) {
// Dispatch all events.
input_handler_proxy_->DeliverInputForBeginFrame();
- StopTracing();
// Retrieve tracing data.
- std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
- CreateTraceAnalyzer();
+ auto analyzer = trace_analyzer::Stop();
trace_analyzer::TraceEventVector begin_events;
trace_analyzer::Query begin_query = trace_analyzer::Query::EventPhaseIs(
TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN);
diff --git a/chromium/ui/events/blink/web_input_event_traits.cc b/chromium/ui/events/blink/web_input_event_traits.cc
index c4a1e920677..6fc2c8718dc 100644
--- a/chromium/ui/events/blink/web_input_event_traits.cc
+++ b/chromium/ui/events/blink/web_input_event_traits.cc
@@ -80,9 +80,10 @@ void ApppendTouchPointDetails(const WebTouchPoint& point, std::string* result) {
void ApppendEventDetails(const WebTouchEvent& event, std::string* result) {
StringAppendF(result,
"{\n Touches: %u, DispatchType: %d, CausesScrolling: %d,"
- " uniqueTouchEventId: %u\n[\n",
+ " Hovering: %d, uniqueTouchEventId: %u\n[\n",
event.touches_length, event.dispatch_type,
- event.moved_beyond_slop_region, event.unique_touch_event_id);
+ event.moved_beyond_slop_region, event.hovering,
+ event.unique_touch_event_id);
for (unsigned i = 0; i < event.touches_length; ++i)
ApppendTouchPointDetails(event.touches[i], result);
result->append(" ]\n}");
diff --git a/chromium/ui/events/blink/web_input_event_traits_unittest.cc b/chromium/ui/events/blink/web_input_event_traits_unittest.cc
index d00bff5beb7..a904dc421d6 100644
--- a/chromium/ui/events/blink/web_input_event_traits_unittest.cc
+++ b/chromium/ui/events/blink/web_input_event_traits_unittest.cc
@@ -26,27 +26,27 @@ using WebInputEventTraitsTest = testing::Test;
// Very basic smoke test to ensure stringification doesn't explode.
TEST_F(WebInputEventTraitsTest, ToString) {
WebKeyboardEvent key(WebInputEvent::kRawKeyDown, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
EXPECT_FALSE(WebInputEventTraits::ToString(key).empty());
WebMouseEvent mouse(WebInputEvent::kMouseMove, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
EXPECT_FALSE(WebInputEventTraits::ToString(mouse).empty());
WebMouseWheelEvent mouse_wheel(WebInputEvent::kMouseWheel,
WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
EXPECT_FALSE(WebInputEventTraits::ToString(mouse_wheel).empty());
WebGestureEvent gesture(WebInputEvent::kGesturePinchBegin,
WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
gesture.x = 1;
gesture.y = 1;
EXPECT_FALSE(WebInputEventTraits::ToString(gesture).empty());
WebTouchEvent touch(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers,
- WebInputEvent::kTimeStampForTesting);
+ WebInputEvent::GetStaticTimeStampForTests());
touch.touches_length = 1;
EXPECT_FALSE(WebInputEventTraits::ToString(touch).empty());
}
diff --git a/chromium/ui/events/chromecast/scroller.cc b/chromium/ui/events/chromecast/scroller.cc
new file mode 100644
index 00000000000..9c989a95f10
--- /dev/null
+++ b/chromium/ui/events/chromecast/scroller.cc
@@ -0,0 +1,477 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/chromecast/scroller.h"
+
+#include <cmath>
+
+#include "base/lazy_instance.h"
+#include "base/macros.h"
+
+namespace ui {
+namespace {
+
+// Default scroll duration from android.widget.Scroller.
+const int kDefaultDurationMs = 250;
+
+// Default friction constant in android.view.ViewConfiguration.
+const float kDefaultFriction = 0.015f;
+
+// == std::log(0.78f) / std::log(0.9f)
+const float kDecelerationRate = 2.3582018f;
+
+// Tension lines cross at (kInflexion, 1).
+const float kInflexion = 0.35f;
+
+const float kEpsilon = 1e-5f;
+
+// Fling scroll is stopped when the scroll position is |kThresholdForFlingEnd|
+// pixels or closer from the end.
+const float kThresholdForFlingEnd = 0.1;
+
+bool ApproxEquals(float a, float b) {
+ return std::abs(a - b) < kEpsilon;
+}
+
+struct ViscosityConstants {
+ ViscosityConstants()
+ : viscous_fluid_scale_(8.f), viscous_fluid_normalize_(1.f) {
+ viscous_fluid_normalize_ = 1.0f / ApplyViscosity(1.0f);
+ }
+
+ float ApplyViscosity(float x) {
+ x *= viscous_fluid_scale_;
+ if (x < 1.0f) {
+ x -= (1.0f - std::exp(-x));
+ } else {
+ float start = 0.36787944117f; // 1/e == exp(-1)
+ x = 1.0f - std::exp(1.0f - x);
+ x = start + x * (1.0f - start);
+ }
+ x *= viscous_fluid_normalize_;
+ return x;
+ }
+
+ private:
+ // This controls the intensity of the viscous fluid effect.
+ float viscous_fluid_scale_;
+ float viscous_fluid_normalize_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViscosityConstants);
+};
+
+struct SplineConstants {
+ SplineConstants() {
+ const float kStartTension = 0.5f;
+ const float kEndTension = 1.0f;
+ const float kP1 = kStartTension * kInflexion;
+ const float kP2 = 1.0f - kEndTension * (1.0f - kInflexion);
+
+ float x_min = 0.0f;
+ float y_min = 0.0f;
+ for (int i = 0; i < NUM_SAMPLES; i++) {
+ const float alpha = static_cast<float>(i) / NUM_SAMPLES;
+
+ float x_max = 1.0f;
+ float x, tx, coef;
+ while (true) {
+ x = x_min + (x_max - x_min) / 2.0f;
+ coef = 3.0f * x * (1.0f - x);
+ tx = coef * ((1.0f - x) * kP1 + x * kP2) + x * x * x;
+ if (ApproxEquals(tx, alpha))
+ break;
+ if (tx > alpha)
+ x_max = x;
+ else
+ x_min = x;
+ }
+ spline_position_[i] = coef * ((1.0f - x) * kStartTension + x) + x * x * x;
+
+ float y_max = 1.0f;
+ float y, dy;
+ while (true) {
+ y = y_min + (y_max - y_min) / 2.0f;
+ coef = 3.0f * y * (1.0f - y);
+ dy = coef * ((1.0f - y) * kStartTension + y) + y * y * y;
+ if (ApproxEquals(dy, alpha))
+ break;
+ if (dy > alpha)
+ y_max = y;
+ else
+ y_min = y;
+ }
+ spline_time_[i] = coef * ((1.0f - y) * kP1 + y * kP2) + y * y * y;
+ }
+ spline_position_[NUM_SAMPLES] = spline_time_[NUM_SAMPLES] = 1.0f;
+ }
+
+ void CalculateCoefficients(float t,
+ float* distance_coef,
+ float* velocity_coef) {
+ *distance_coef = 1.f;
+ *velocity_coef = 0.f;
+ const int index = static_cast<int>(NUM_SAMPLES * t);
+ if (index < NUM_SAMPLES) {
+ const float t_inf = static_cast<float>(index) / NUM_SAMPLES;
+ const float t_sup = static_cast<float>(index + 1) / NUM_SAMPLES;
+ const float d_inf = spline_position_[index];
+ const float d_sup = spline_position_[index + 1];
+ *velocity_coef = (d_sup - d_inf) / (t_sup - t_inf);
+ *distance_coef = d_inf + (t - t_inf) * *velocity_coef;
+ }
+ }
+
+ private:
+ enum { NUM_SAMPLES = 100 };
+
+ float spline_position_[NUM_SAMPLES + 1];
+ float spline_time_[NUM_SAMPLES + 1];
+
+ DISALLOW_COPY_AND_ASSIGN(SplineConstants);
+};
+
+float ComputeDeceleration(float friction) {
+ const float kGravityEarth = 9.80665f;
+ return kGravityEarth // g (m/s^2)
+ * 39.37f // inch/meter
+ * 160.f // pixels/inch
+ * friction;
+}
+
+template <typename T>
+int Signum(T t) {
+ return (T(0) < t) - (t < T(0));
+}
+
+template <typename T>
+T Clamped(T t, T a, T b) {
+ return t < a ? a : (t > b ? b : t);
+}
+
+// Leaky to allow access from the impl thread.
+base::LazyInstance<ViscosityConstants>::Leaky g_viscosity_constants =
+ LAZY_INSTANCE_INITIALIZER;
+
+base::LazyInstance<SplineConstants>::Leaky g_spline_constants =
+ LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
+Scroller::Config::Config()
+ : fling_friction(kDefaultFriction), flywheel_enabled(false) {
+}
+
+Scroller::Scroller(const Config& config)
+ : mode_(UNDEFINED),
+ start_x_(0),
+ start_y_(0),
+ final_x_(0),
+ final_y_(0),
+ min_x_(0),
+ max_x_(0),
+ min_y_(0),
+ max_y_(0),
+ curr_x_(0),
+ curr_y_(0),
+ duration_seconds_reciprocal_(1),
+ delta_x_(0),
+ delta_x_norm_(1),
+ delta_y_(0),
+ delta_y_norm_(1),
+ finished_(true),
+ flywheel_enabled_(config.flywheel_enabled),
+ velocity_(0),
+ curr_velocity_(0),
+ distance_(0),
+ fling_friction_(config.fling_friction),
+ deceleration_(ComputeDeceleration(fling_friction_)),
+ tuning_coeff_(ComputeDeceleration(0.84f)) {
+}
+
+Scroller::~Scroller() {
+}
+
+bool Scroller::ComputeScrollOffset(base::TimeTicks time,
+ gfx::Vector2dF* offset,
+ gfx::Vector2dF* velocity) {
+ DCHECK(offset);
+ DCHECK(velocity);
+ if (!ComputeScrollOffsetInternal(time)) {
+ *offset = gfx::Vector2dF(GetFinalX(), GetFinalY());
+ *velocity = gfx::Vector2dF();
+ return false;
+ }
+
+ *offset = gfx::Vector2dF(GetCurrX(), GetCurrY());
+ *velocity = gfx::Vector2dF(GetCurrVelocityX(), GetCurrVelocityY());
+ return true;
+}
+
+void Scroller::StartScroll(float start_x,
+ float start_y,
+ float dx,
+ float dy,
+ base::TimeTicks start_time) {
+ StartScroll(start_x,
+ start_y,
+ dx,
+ dy,
+ start_time,
+ base::TimeDelta::FromMilliseconds(kDefaultDurationMs));
+}
+
+void Scroller::StartScroll(float start_x,
+ float start_y,
+ float dx,
+ float dy,
+ base::TimeTicks start_time,
+ base::TimeDelta duration) {
+ DCHECK_GT(duration, base::TimeDelta());
+ mode_ = SCROLL_MODE;
+ finished_ = false;
+ duration_ = duration;
+ duration_seconds_reciprocal_ = 1.0 / duration_.InSecondsF();
+ start_time_ = start_time;
+ curr_x_ = start_x_ = start_x;
+ curr_y_ = start_y_ = start_y;
+ final_x_ = start_x + dx;
+ final_y_ = start_y + dy;
+ RecomputeDeltas();
+ curr_time_ = start_time_;
+}
+
+void Scroller::Fling(float start_x,
+ float start_y,
+ float velocity_x,
+ float velocity_y,
+ float min_x,
+ float max_x,
+ float min_y,
+ float max_y,
+ base::TimeTicks start_time) {
+ DCHECK(velocity_x || velocity_y);
+
+ // Continue a scroll or fling in progress.
+ if (flywheel_enabled_ && !finished_) {
+ float old_velocity_x = GetCurrVelocityX();
+ float old_velocity_y = GetCurrVelocityY();
+ if (Signum(velocity_x) == Signum(old_velocity_x) &&
+ Signum(velocity_y) == Signum(old_velocity_y)) {
+ velocity_x += old_velocity_x;
+ velocity_y += old_velocity_y;
+ }
+ }
+
+ mode_ = FLING_MODE;
+ finished_ = false;
+
+ float velocity = std::sqrt(velocity_x * velocity_x + velocity_y * velocity_y);
+
+ velocity_ = velocity;
+ duration_ = GetSplineFlingDuration(velocity);
+ DCHECK_GT(duration_, base::TimeDelta());
+ duration_seconds_reciprocal_ = 1.0 / duration_.InSecondsF();
+ start_time_ = start_time;
+ curr_time_ = start_time_;
+ curr_x_ = start_x_ = start_x;
+ curr_y_ = start_y_ = start_y;
+
+ float coeff_x = velocity == 0 ? 1.0f : velocity_x / velocity;
+ float coeff_y = velocity == 0 ? 1.0f : velocity_y / velocity;
+
+ double total_distance = GetSplineFlingDistance(velocity);
+ distance_ = total_distance * Signum(velocity);
+
+ min_x_ = min_x;
+ max_x_ = max_x;
+ min_y_ = min_y;
+ max_y_ = max_y;
+
+ final_x_ = start_x + total_distance * coeff_x;
+ final_x_ = Clamped(final_x_, min_x_, max_x_);
+
+ final_y_ = start_y + total_distance * coeff_y;
+ final_y_ = Clamped(final_y_, min_y_, max_y_);
+
+ RecomputeDeltas();
+}
+
+void Scroller::ExtendDuration(base::TimeDelta extend) {
+ base::TimeDelta passed = GetTimePassed();
+ duration_ = passed + extend;
+ duration_seconds_reciprocal_ = 1.0 / duration_.InSecondsF();
+ finished_ = false;
+}
+
+void Scroller::SetFinalX(float new_x) {
+ final_x_ = new_x;
+ finished_ = false;
+ RecomputeDeltas();
+}
+
+void Scroller::SetFinalY(float new_y) {
+ final_y_ = new_y;
+ finished_ = false;
+ RecomputeDeltas();
+}
+
+void Scroller::AbortAnimation() {
+ curr_x_ = final_x_;
+ curr_y_ = final_y_;
+ curr_velocity_ = 0;
+ curr_time_ = start_time_ + duration_;
+ finished_ = true;
+}
+
+void Scroller::ForceFinished(bool finished) {
+ finished_ = finished;
+}
+
+bool Scroller::IsFinished() const {
+ return finished_;
+}
+
+base::TimeDelta Scroller::GetTimePassed() const {
+ return curr_time_ - start_time_;
+}
+
+base::TimeDelta Scroller::GetDuration() const {
+ return duration_;
+}
+
+float Scroller::GetCurrX() const {
+ return curr_x_;
+}
+
+float Scroller::GetCurrY() const {
+ return curr_y_;
+}
+
+float Scroller::GetCurrVelocity() const {
+ if (finished_)
+ return 0;
+ if (mode_ == FLING_MODE)
+ return curr_velocity_;
+ return velocity_ - deceleration_ * GetTimePassed().InSecondsF() * 0.5f;
+}
+
+float Scroller::GetCurrVelocityX() const {
+ return delta_x_norm_ * GetCurrVelocity();
+}
+
+float Scroller::GetCurrVelocityY() const {
+ return delta_y_norm_ * GetCurrVelocity();
+}
+
+float Scroller::GetStartX() const {
+ return start_x_;
+}
+
+float Scroller::GetStartY() const {
+ return start_y_;
+}
+
+float Scroller::GetFinalX() const {
+ return final_x_;
+}
+
+float Scroller::GetFinalY() const {
+ return final_y_;
+}
+
+bool Scroller::IsScrollingInDirection(float xvel, float yvel) const {
+ return !finished_ && Signum(xvel) == Signum(delta_x_) &&
+ Signum(yvel) == Signum(delta_y_);
+}
+
+bool Scroller::ComputeScrollOffsetInternal(base::TimeTicks time) {
+ if (finished_)
+ return false;
+
+ if (time <= start_time_)
+ return true;
+
+ if (time == curr_time_)
+ return true;
+
+ base::TimeDelta time_passed = time - start_time_;
+ if (time_passed >= duration_) {
+ AbortAnimation();
+ return false;
+ }
+
+ curr_time_ = time;
+
+ const float u = time_passed.InSecondsF() * duration_seconds_reciprocal_;
+ switch (mode_) {
+ case UNDEFINED:
+ NOTREACHED() << "|StartScroll()| or |Fling()| must be called prior to "
+ "scroll offset computation.";
+ return false;
+
+ case SCROLL_MODE: {
+ float x = g_viscosity_constants.Get().ApplyViscosity(u);
+
+ curr_x_ = start_x_ + x * delta_x_;
+ curr_y_ = start_y_ + x * delta_y_;
+ } break;
+
+ case FLING_MODE: {
+ float distance_coef = 1.f;
+ float velocity_coef = 0.f;
+ g_spline_constants.Get().CalculateCoefficients(
+ u, &distance_coef, &velocity_coef);
+
+ curr_velocity_ = velocity_coef * distance_ * duration_seconds_reciprocal_;
+
+ curr_x_ = start_x_ + distance_coef * delta_x_;
+ curr_x_ = Clamped(curr_x_, min_x_, max_x_);
+
+ curr_y_ = start_y_ + distance_coef * delta_y_;
+ curr_y_ = Clamped(curr_y_, min_y_, max_y_);
+
+ float diff_x = std::abs(curr_x_ - final_x_);
+ float diff_y = std::abs(curr_y_ - final_y_);
+ if (diff_x < kThresholdForFlingEnd && diff_y < kThresholdForFlingEnd)
+ AbortAnimation();
+ } break;
+ }
+
+ return !finished_;
+}
+
+void Scroller::RecomputeDeltas() {
+ delta_x_ = final_x_ - start_x_;
+ delta_y_ = final_y_ - start_y_;
+
+ const float hyp = std::sqrt(delta_x_ * delta_x_ + delta_y_ * delta_y_);
+ if (hyp > kEpsilon) {
+ delta_x_norm_ = delta_x_ / hyp;
+ delta_y_norm_ = delta_y_ / hyp;
+ } else {
+ delta_x_norm_ = delta_y_norm_ = 1;
+ }
+}
+
+double Scroller::GetSplineDeceleration(float velocity) const {
+ return std::log(kInflexion * std::abs(velocity) /
+ (fling_friction_ * tuning_coeff_));
+}
+
+base::TimeDelta Scroller::GetSplineFlingDuration(float velocity) const {
+ const double l = GetSplineDeceleration(velocity);
+ const double decel_minus_one = kDecelerationRate - 1.0;
+ const double time_seconds = std::exp(l / decel_minus_one);
+ return base::TimeDelta::FromMicroseconds(time_seconds *
+ base::Time::kMicrosecondsPerSecond);
+}
+
+double Scroller::GetSplineFlingDistance(float velocity) const {
+ const double l = GetSplineDeceleration(velocity);
+ const double decel_minus_one = kDecelerationRate - 1.0;
+ return fling_friction_ * tuning_coeff_ *
+ std::exp(kDecelerationRate / decel_minus_one * l);
+}
+
+} // namespace ui
diff --git a/chromium/ui/events/chromecast/scroller.h b/chromium/ui/events/chromecast/scroller.h
new file mode 100644
index 00000000000..f4ef836775e
--- /dev/null
+++ b/chromium/ui/events/chromecast/scroller.h
@@ -0,0 +1,151 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_EVENTS_CHROMECAST_SCROLLER_H_
+#define UI_EVENTS_CHROMECAST_SCROLLER_H_
+
+#include "base/time/time.h"
+#include "ui/events/events_base_export.h"
+#include "ui/events/gesture_curve.h"
+#include "ui/gfx/geometry/vector2d_f.h"
+
+namespace ui {
+
+// Native port of android.widget.Scroller.
+// * Change-Id: I4365946f890a76fcfa78ca9d69f2a8e0848095a9
+// * Please update the Change-Id as upstream Android changes are pulled.
+class EVENTS_BASE_EXPORT Scroller : public GestureCurve {
+ public:
+ struct Config {
+ Config();
+
+ // Controls fling deceleration. Defaults to 0.015f.
+ float fling_friction;
+
+ // Controls fling accumulation. Defaults to disabled.
+ bool flywheel_enabled;
+ };
+
+ explicit Scroller(const Config& config);
+ ~Scroller() override;
+
+ // GestureCurve implementation.
+ bool ComputeScrollOffset(base::TimeTicks time,
+ gfx::Vector2dF* offset,
+ gfx::Vector2dF* velocity) override;
+
+ // Start scrolling by providing a starting point and the distance to travel.
+ // The default value of 250 milliseconds will be used for the duration.
+ void StartScroll(float start_x,
+ float start_y,
+ float dx,
+ float dy,
+ base::TimeTicks start_time);
+
+ // Start scrolling by providing a starting point, the distance to travel,
+ // and the duration of the scroll.
+ void StartScroll(float start_x,
+ float start_y,
+ float dx,
+ float dy,
+ base::TimeTicks start_time,
+ base::TimeDelta duration);
+
+ // Start scrolling based on a fling gesture. The distance travelled will
+ // depend on the initial velocity of the fling.
+ void Fling(float start_x,
+ float start_y,
+ float velocity_x,
+ float velocity_y,
+ float min_x,
+ float max_x,
+ float min_y,
+ float max_y,
+ base::TimeTicks start_time);
+
+ // Extend the scroll animation by |extend|. This allows a running animation
+ // to scroll further and longer when used with |SetFinalX()| or |SetFinalY()|.
+ void ExtendDuration(base::TimeDelta extend);
+ void SetFinalX(float new_x);
+ void SetFinalY(float new_y);
+
+ // Stops the animation. Contrary to |ForceFinished()|, aborting the animation
+ // causes the scroller to move to the final x and y position.
+ void AbortAnimation();
+
+ // Terminate the scroll without affecting the current x and y positions.
+ void ForceFinished(bool finished);
+
+ // Returns whether the scroller has finished scrolling.
+ bool IsFinished() const;
+
+ // Returns the time elapsed since the beginning of the scrolling.
+ base::TimeDelta GetTimePassed() const;
+
+ // Returns how long the scroll event will take.
+ base::TimeDelta GetDuration() const;
+
+ float GetStartX() const;
+ float GetStartY() const;
+ float GetCurrX() const;
+ float GetCurrY() const;
+ float GetCurrVelocity() const;
+ float GetCurrVelocityX() const;
+ float GetCurrVelocityY() const;
+ float GetFinalX() const;
+ float GetFinalY() const;
+
+ bool IsScrollingInDirection(float xvel, float yvel) const;
+
+ private:
+ enum Mode {
+ UNDEFINED,
+ SCROLL_MODE,
+ FLING_MODE,
+ };
+
+ bool ComputeScrollOffsetInternal(base::TimeTicks time);
+ void RecomputeDeltas();
+
+ double GetSplineDeceleration(float velocity) const;
+ base::TimeDelta GetSplineFlingDuration(float velocity) const;
+ double GetSplineFlingDistance(float velocity) const;
+
+ Mode mode_;
+
+ float start_x_;
+ float start_y_;
+ float final_x_;
+ float final_y_;
+
+ float min_x_;
+ float max_x_;
+ float min_y_;
+ float max_y_;
+
+ float curr_x_;
+ float curr_y_;
+ base::TimeTicks start_time_;
+ base::TimeTicks curr_time_;
+ base::TimeDelta duration_;
+ double duration_seconds_reciprocal_;
+ float delta_x_;
+ float delta_x_norm_;
+ float delta_y_;
+ float delta_y_norm_;
+ bool finished_;
+ bool flywheel_enabled_;
+
+ float velocity_;
+ float curr_velocity_;
+ float distance_;
+
+ float fling_friction_;
+ float deceleration_;
+ float tuning_coeff_;
+};
+
+} // namespace ui
+
+#endif // UI_EVENTS_CHROMECAST_SCROLLER_H_
diff --git a/chromium/ui/events/chromecast/scroller_unittest.cc b/chromium/ui/events/chromecast/scroller_unittest.cc
new file mode 100644
index 00000000000..1303f7f80c9
--- /dev/null
+++ b/chromium/ui/events/chromecast/scroller_unittest.cc
@@ -0,0 +1,178 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <limits.h>
+
+#include "base/time/time.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/chromecast/scroller.h"
+
+namespace ui {
+namespace {
+
+const float kDefaultStartX = 7.f;
+const float kDefaultStartY = 25.f;
+const float kDefaultDeltaX = -20.f;
+const float kDefaultDeltaY = 73.f;
+const float kDefaultVelocityX = -350.f;
+const float kDefaultVelocityY = 220.f;
+const float kEpsilon = 1e-3f;
+
+Scroller::Config DefaultConfig() {
+ return Scroller::Config();
+}
+
+} // namespace
+
+class ScrollerTest : public testing::Test {};
+
+TEST_F(ScrollerTest, Scroll) {
+ Scroller scroller(DefaultConfig());
+ base::TimeTicks start_time = base::TimeTicks::Now();
+
+ // Start a scroll and verify initialized values.
+ scroller.StartScroll(kDefaultStartX,
+ kDefaultStartY,
+ kDefaultDeltaX,
+ kDefaultDeltaY,
+ start_time);
+
+ EXPECT_EQ(kDefaultStartX, scroller.GetStartX());
+ EXPECT_EQ(kDefaultStartY, scroller.GetStartY());
+ EXPECT_EQ(kDefaultStartX, scroller.GetCurrX());
+ EXPECT_EQ(kDefaultStartY, scroller.GetCurrY());
+ EXPECT_EQ(kDefaultStartX + kDefaultDeltaX, scroller.GetFinalX());
+ EXPECT_EQ(kDefaultStartY + kDefaultDeltaY, scroller.GetFinalY());
+ EXPECT_FALSE(scroller.IsFinished());
+ EXPECT_EQ(base::TimeDelta(), scroller.GetTimePassed());
+
+ // Advance halfway through the scroll.
+ const base::TimeDelta scroll_duration = scroller.GetDuration();
+ gfx::Vector2dF offset, velocity;
+ EXPECT_TRUE(scroller.ComputeScrollOffset(
+ start_time + scroll_duration / 2, &offset, &velocity));
+
+ // Ensure we've moved in the direction of the delta, but have yet to reach
+ // the target.
+ EXPECT_GT(kDefaultStartX, offset.x());
+ EXPECT_LT(kDefaultStartY, offset.y());
+ EXPECT_LT(scroller.GetFinalX(), offset.x());
+ EXPECT_GT(scroller.GetFinalY(), offset.y());
+ EXPECT_FALSE(scroller.IsFinished());
+
+ // Ensure our velocity is non-zero and in the same direction as the delta.
+ EXPECT_GT(0.f, velocity.x() * kDefaultDeltaX);
+ EXPECT_GT(0.f, velocity.y() * kDefaultDeltaY);
+ EXPECT_TRUE(scroller.IsScrollingInDirection(kDefaultDeltaX, kDefaultDeltaY));
+
+ // Repeated offset computations at the same timestamp should yield identical
+ // results.
+ float curr_x = offset.x();
+ float curr_y = offset.y();
+ float curr_velocity_x = velocity.x();
+ float curr_velocity_y = velocity.y();
+ EXPECT_TRUE(scroller.ComputeScrollOffset(
+ start_time + scroll_duration / 2, &offset, &velocity));
+ EXPECT_EQ(curr_x, offset.x());
+ EXPECT_EQ(curr_y, offset.y());
+ EXPECT_EQ(curr_velocity_x, velocity.x());
+ EXPECT_EQ(curr_velocity_y, velocity.y());
+
+ // Advance to the end.
+ EXPECT_FALSE(scroller.ComputeScrollOffset(
+ start_time + scroll_duration, &offset, &velocity));
+ EXPECT_EQ(scroller.GetFinalX(), offset.x());
+ EXPECT_EQ(scroller.GetFinalY(), offset.y());
+ EXPECT_TRUE(scroller.IsFinished());
+ EXPECT_EQ(scroll_duration, scroller.GetTimePassed());
+ EXPECT_NEAR(0.f, velocity.x(), kEpsilon);
+ EXPECT_NEAR(0.f, velocity.y(), kEpsilon);
+
+ // Try to advance further; nothing should change.
+ EXPECT_FALSE(scroller.ComputeScrollOffset(
+ start_time + scroll_duration * 2, &offset, &velocity));
+ EXPECT_EQ(scroller.GetFinalX(), offset.x());
+ EXPECT_EQ(scroller.GetFinalY(), offset.y());
+ EXPECT_TRUE(scroller.IsFinished());
+ EXPECT_EQ(scroll_duration, scroller.GetTimePassed());
+}
+
+TEST_F(ScrollerTest, Fling) {
+ Scroller scroller(DefaultConfig());
+ base::TimeTicks start_time = base::TimeTicks::Now();
+
+ // Start a fling and verify initialized values.
+ scroller.Fling(kDefaultStartX,
+ kDefaultStartY,
+ kDefaultVelocityX,
+ kDefaultVelocityY,
+ INT_MIN,
+ INT_MAX,
+ INT_MIN,
+ INT_MAX,
+ start_time);
+
+ EXPECT_EQ(kDefaultStartX, scroller.GetStartX());
+ EXPECT_EQ(kDefaultStartY, scroller.GetStartY());
+ EXPECT_EQ(kDefaultStartX, scroller.GetCurrX());
+ EXPECT_EQ(kDefaultStartY, scroller.GetCurrY());
+ EXPECT_GT(kDefaultStartX, scroller.GetFinalX());
+ EXPECT_LT(kDefaultStartY, scroller.GetFinalY());
+ EXPECT_FALSE(scroller.IsFinished());
+ EXPECT_EQ(base::TimeDelta(), scroller.GetTimePassed());
+
+ // Advance halfway through the fling.
+ const base::TimeDelta scroll_duration = scroller.GetDuration();
+ gfx::Vector2dF offset, velocity;
+ scroller.ComputeScrollOffset(
+ start_time + scroll_duration / 2, &offset, &velocity);
+
+ // Ensure we've moved in the direction of the velocity, but have yet to reach
+ // the target.
+ EXPECT_GT(kDefaultStartX, offset.x());
+ EXPECT_LT(kDefaultStartY, offset.y());
+ EXPECT_LT(scroller.GetFinalX(), offset.x());
+ EXPECT_GT(scroller.GetFinalY(), offset.y());
+ EXPECT_FALSE(scroller.IsFinished());
+
+ // Ensure our velocity is non-zero and in the same direction as the original
+ // velocity.
+ EXPECT_LT(0.f, velocity.x() * kDefaultVelocityX);
+ EXPECT_LT(0.f, velocity.y() * kDefaultVelocityY);
+ EXPECT_TRUE(
+ scroller.IsScrollingInDirection(kDefaultVelocityX, kDefaultVelocityY));
+
+ // Repeated offset computations at the same timestamp should yield identical
+ // results.
+ float curr_x = offset.x();
+ float curr_y = offset.y();
+ float curr_velocity_x = velocity.x();
+ float curr_velocity_y = velocity.y();
+ EXPECT_TRUE(scroller.ComputeScrollOffset(
+ start_time + scroll_duration / 2, &offset, &velocity));
+ EXPECT_EQ(curr_x, offset.x());
+ EXPECT_EQ(curr_y, offset.y());
+ EXPECT_EQ(curr_velocity_x, velocity.x());
+ EXPECT_EQ(curr_velocity_y, velocity.y());
+
+ // Advance to the end.
+ EXPECT_FALSE(scroller.ComputeScrollOffset(
+ start_time + scroll_duration, &offset, &velocity));
+ EXPECT_EQ(scroller.GetFinalX(), offset.x());
+ EXPECT_EQ(scroller.GetFinalY(), offset.y());
+ EXPECT_TRUE(scroller.IsFinished());
+ EXPECT_EQ(scroll_duration, scroller.GetTimePassed());
+ EXPECT_NEAR(0.f, velocity.x(), kEpsilon);
+ EXPECT_NEAR(0.f, velocity.y(), kEpsilon);
+
+ // Try to advance further; nothing should change.
+ EXPECT_FALSE(scroller.ComputeScrollOffset(
+ start_time + scroll_duration * 2, &offset, &velocity));
+ EXPECT_EQ(scroller.GetFinalX(), offset.x());
+ EXPECT_EQ(scroller.GetFinalY(), offset.y());
+ EXPECT_TRUE(scroller.IsFinished());
+ EXPECT_EQ(scroll_duration, scroller.GetTimePassed());
+}
+
+} // namespace ui
diff --git a/chromium/ui/events/devices/x11/touch_factory_x11.cc b/chromium/ui/events/devices/x11/touch_factory_x11.cc
index dc2dbfe79af..30992476602 100644
--- a/chromium/ui/events/devices/x11/touch_factory_x11.cc
+++ b/chromium/ui/events/devices/x11/touch_factory_x11.cc
@@ -179,8 +179,12 @@ bool TouchFactory::ShouldProcessXI2Event(XEvent* xev) {
(virtual_core_keyboard_device_ == xiev->deviceid);
}
- if (event->evtype != XI_ButtonPress &&
- event->evtype != XI_ButtonRelease &&
+ // Don't automatically accept XI_Enter or XI_Leave. They should be checked
+ // against the pointer_device_lookup_ to prevent handling for slave devices.
+ // This happens for unknown reasons when using xtest.
+ // https://crbug.com/683434.
+ if (event->evtype != XI_ButtonPress && event->evtype != XI_ButtonRelease &&
+ event->evtype != XI_Enter && event->evtype != XI_Leave &&
event->evtype != XI_Motion) {
return true;
}
diff --git a/chromium/ui/events/event.cc b/chromium/ui/events/event.cc
index 3b38945471f..68daf98868e 100644
--- a/chromium/ui/events/event.cc
+++ b/chromium/ui/events/event.cc
@@ -828,6 +828,7 @@ TouchEvent::TouchEvent(const base::NativeEvent& native_event)
unique_event_id_(ui::GetNextTouchEventId()),
may_cause_scrolling_(false),
should_remove_native_touch_id_mapping_(false),
+ hovering_(false),
pointer_details_(GetTouchPointerDetailsFromNative(native_event)) {
latency()->AddLatencyNumberWithTimestamp(
INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0, time_stamp(), 1);
@@ -842,6 +843,7 @@ TouchEvent::TouchEvent(const PointerEvent& pointer_event)
unique_event_id_(ui::GetNextTouchEventId()),
may_cause_scrolling_(false),
should_remove_native_touch_id_mapping_(false),
+ hovering_(false),
pointer_details_(pointer_event.pointer_details()) {
DCHECK(pointer_event.IsTouchPointerEvent() ||
pointer_event.IsPenPointerEvent());
@@ -881,6 +883,7 @@ TouchEvent::TouchEvent(EventType type,
unique_event_id_(ui::GetNextTouchEventId()),
may_cause_scrolling_(false),
should_remove_native_touch_id_mapping_(false),
+ hovering_(false),
pointer_details_(pointer_details) {
latency()->AddLatencyNumber(INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0);
pointer_details_.twist = angle;
@@ -891,6 +894,7 @@ TouchEvent::TouchEvent(const TouchEvent& copy)
unique_event_id_(copy.unique_event_id_),
may_cause_scrolling_(copy.may_cause_scrolling_),
should_remove_native_touch_id_mapping_(false),
+ hovering_(copy.hovering_),
pointer_details_(copy.pointer_details_) {
// Copied events should not remove touch id mapping, as this either causes the
// mapping to be lost before the initial event has finished dispatching, or
@@ -1178,6 +1182,7 @@ KeyEvent::KeyEvent(const base::NativeEvent& native_event, int event_flags)
// Only Windows has native character events.
if (is_char_) {
key_ = DomKey::FromCharacter(native_event.wParam);
+ set_flags(PlatformKeyMap::ReplaceControlAndAltWithAltGraph(flags()));
} else {
int adjusted_flags = flags();
key_ = PlatformKeyMap::DomKeyFromKeyboardCode(key_code(), &adjusted_flags);
diff --git a/chromium/ui/events/event.h b/chromium/ui/events/event.h
index b1baf5a5502..01fbde3ce9a 100644
--- a/chromium/ui/events/event.h
+++ b/chromium/ui/events/event.h
@@ -716,6 +716,9 @@ class EVENTS_EXPORT TouchEvent : public LocatedEvent {
void set_may_cause_scrolling(bool causes) { may_cause_scrolling_ = causes; }
bool may_cause_scrolling() const { return may_cause_scrolling_; }
+ void set_hovering(bool hovering) { hovering_ = hovering; }
+ bool hovering() const { return hovering_; }
+
void set_should_remove_native_touch_id_mapping(
bool should_remove_native_touch_id_mapping) {
should_remove_native_touch_id_mapping_ =
@@ -753,6 +756,10 @@ class EVENTS_EXPORT TouchEvent : public LocatedEvent {
// created a mapping between the native id and the touch_id_.
bool should_remove_native_touch_id_mapping_;
+ // True for devices like some pens when they support hovering over
+ // digitizer and they send events while hovering.
+ bool hovering_;
+
// Structure for holding pointer details for implementing PointerEvents API.
PointerDetails pointer_details_;
};
diff --git a/chromium/ui/events/event_constants.h b/chromium/ui/events/event_constants.h
index 79ca132182b..9340ec0b28f 100644
--- a/chromium/ui/events/event_constants.h
+++ b/chromium/ui/events/event_constants.h
@@ -103,7 +103,7 @@ enum EventFlags {
EF_ALTGR_DOWN = 1 << 5,
EF_MOD3_DOWN = 1 << 6,
- // Other keyboard state.
+ // Other keyboard states.
EF_NUM_LOCK_ON = 1 << 7,
EF_CAPS_LOCK_ON = 1 << 8,
EF_SCROLL_LOCK_ON = 1 << 9,
@@ -116,7 +116,7 @@ enum EventFlags {
EF_FORWARD_MOUSE_BUTTON = 1 << 14,
};
-// Flags specific to key events
+// Flags specific to key events.
enum KeyEventFlags {
EF_IME_FABRICATED_KEY = 1 << 15, // Key event fabricated by the underlying
// IME without a user action.
@@ -127,7 +127,7 @@ enum KeyEventFlags {
EF_IS_EXTENDED_KEY = 1 << 18, // Windows extended key (see WM_KEYDOWN doc)
};
-// Flags specific to mouse events
+// Flags specific to mouse events.
enum MouseEventFlags {
EF_IS_DOUBLE_CLICK = 1 << 15,
EF_IS_TRIPLE_CLICK = 1 << 16,
diff --git a/chromium/ui/events/event_unittest.cc b/chromium/ui/events/event_unittest.cc
index be300ce3ddd..3702b5b1daa 100644
--- a/chromium/ui/events/event_unittest.cc
+++ b/chromium/ui/events/event_unittest.cc
@@ -11,12 +11,15 @@
#include "base/macros.h"
#include "base/test/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
+#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/events/test/events_test_utils.h"
+#include "ui/events/test/keyboard_layout.h"
#include "ui/events/test/test_event_target.h"
#include "ui/gfx/transform.h"
@@ -1123,4 +1126,122 @@ TEST(EventTest, UpdateForRootTransformation) {
}
}
+#if defined(OS_WIN)
+namespace {
+
+const struct AltGraphEventTestCase {
+ KeyboardCode key_code;
+ KeyboardLayout layout;
+ std::vector<KeyboardCode> modifier_key_codes;
+ int expected_flags;
+} kAltGraphEventTestCases[] = {
+ // US English -> AltRight never behaves as AltGraph.
+ {VKEY_C,
+ KEYBOARD_LAYOUT_ENGLISH_US,
+ {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
+ EF_ALT_DOWN | EF_CONTROL_DOWN},
+ {VKEY_E,
+ KEYBOARD_LAYOUT_ENGLISH_US,
+ {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
+ EF_ALT_DOWN | EF_CONTROL_DOWN},
+
+ // French -> Always expect AltGraph if VKEY_RMENU is pressed.
+ {VKEY_C,
+ KEYBOARD_LAYOUT_FRENCH,
+ {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
+ EF_ALTGR_DOWN},
+ {VKEY_E,
+ KEYBOARD_LAYOUT_FRENCH,
+ {VKEY_RMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
+ EF_ALTGR_DOWN},
+
+ // French -> Expect Control+Alt is AltGraph on AltGraph-shifted keys.
+ {VKEY_C,
+ KEYBOARD_LAYOUT_FRENCH,
+ {VKEY_LMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
+ EF_ALT_DOWN | EF_CONTROL_DOWN},
+ {VKEY_E,
+ KEYBOARD_LAYOUT_FRENCH,
+ {VKEY_LMENU, VKEY_LCONTROL, VKEY_MENU, VKEY_CONTROL},
+ EF_ALTGR_DOWN},
+};
+
+class AltGraphEventTest : public testing::TestWithParam<
+ std::tr1::tuple<UINT, AltGraphEventTestCase>> {
+ public:
+ AltGraphEventTest()
+ : msg_({nullptr, message_type(),
+ static_cast<WPARAM>(test_case().key_code)}) {
+ // Save the current keyboard layout and state, to restore later.
+ CHECK(GetKeyboardState(original_keyboard_state_));
+ original_keyboard_layout_ = GetKeyboardLayout(0);
+
+ // Configure specified layout, and update keyboard state for specified
+ // modifier keys.
+ CHECK(ActivateKeyboardLayout(GetPlatformKeyboardLayout(test_case().layout),
+ 0));
+ BYTE test_keyboard_state[256] = {};
+ for (const auto& key_code : test_case().modifier_key_codes)
+ test_keyboard_state[key_code] = 0x80;
+ CHECK(SetKeyboardState(test_keyboard_state));
+ }
+
+ ~AltGraphEventTest() {
+ // Restore the original keyboard layout & key states.
+ CHECK(ActivateKeyboardLayout(original_keyboard_layout_, 0));
+ CHECK(SetKeyboardState(original_keyboard_state_));
+ }
+
+ protected:
+ UINT message_type() const { return std::tr1::get<0>(GetParam()); }
+ const AltGraphEventTestCase& test_case() const {
+ return std::tr1::get<1>(GetParam());
+ }
+
+ const MSG msg_;
+ base::test::ScopedFeatureList feature_list_;
+ BYTE original_keyboard_state_[256] = {};
+ HKL original_keyboard_layout_ = nullptr;
+};
+
+} // namespace
+
+TEST_P(AltGraphEventTest, OldKeyEventAltGraphModifier) {
+ feature_list_.InitFromCommandLine("", "FixAltGraph");
+
+ // Old behaviour always sets AltGraph modifier whenever both Control and Alt
+ // are pressed.
+ KeyEvent event(msg_);
+ EXPECT_EQ(event.flags() & (EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN),
+ EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN);
+}
+
+TEST_P(AltGraphEventTest, KeyEventAltGraphModifer) {
+ feature_list_.InitFromCommandLine("FixAltGraph", "");
+
+ KeyEvent event(msg_);
+ if (message_type() == WM_CHAR) {
+ // By definition, if we receive a WM_CHAR message when Control and Alt are
+ // pressed, it indicates AltGraph.
+ EXPECT_EQ(event.flags() & (EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN),
+ EF_ALTGR_DOWN);
+ } else {
+ EXPECT_EQ(event.flags() & (EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN),
+ test_case().expected_flags);
+ }
+}
+
+INSTANTIATE_TEST_CASE_P(
+ WM_KEY,
+ AltGraphEventTest,
+ ::testing::Combine(::testing::Values(WM_KEYDOWN, WM_KEYUP),
+ ::testing::ValuesIn(kAltGraphEventTestCases)));
+INSTANTIATE_TEST_CASE_P(
+ WM_CHAR,
+ AltGraphEventTest,
+ ::testing::Combine(::testing::Values(WM_CHAR),
+ ::testing::ValuesIn(kAltGraphEventTestCases)));
+
+#endif // defined(OS_WIN)
+
} // namespace ui
diff --git a/chromium/ui/events/event_utils.cc b/chromium/ui/events/event_utils.cc
index 796518f1c5e..aa9b26e309d 100644
--- a/chromium/ui/events/event_utils.cc
+++ b/chromium/ui/events/event_utils.cc
@@ -86,21 +86,21 @@ void ValidateEventTimeClock(base::TimeTicks* timestamp) {
bool ShouldDefaultToNaturalScroll() {
return GetInternalDisplayTouchSupport() ==
- display::Display::TOUCH_SUPPORT_AVAILABLE;
+ display::Display::TouchSupport::AVAILABLE;
}
display::Display::TouchSupport GetInternalDisplayTouchSupport() {
display::Screen* screen = display::Screen::GetScreen();
// No screen in some unit tests.
if (!screen)
- return display::Display::TOUCH_SUPPORT_UNKNOWN;
+ return display::Display::TouchSupport::UNKNOWN;
const std::vector<display::Display>& displays = screen->GetAllDisplays();
for (std::vector<display::Display>::const_iterator it = displays.begin();
it != displays.end(); ++it) {
if (it->IsInternal())
return it->touch_support();
}
- return display::Display::TOUCH_SUPPORT_UNAVAILABLE;
+ return display::Display::TouchSupport::UNAVAILABLE;
}
void ComputeEventLatencyOS(const base::NativeEvent& native_event) {
@@ -135,4 +135,19 @@ void ComputeEventLatencyOS(const base::NativeEvent& native_event) {
}
}
+void ConvertEventLocationToTargetWindowLocation(
+ const gfx::Point& target_window_origin,
+ const gfx::Point& current_window_origin,
+ ui::LocatedEvent* located_event) {
+ if (current_window_origin == target_window_origin)
+ return;
+
+ DCHECK(located_event);
+ gfx::Vector2d offset = current_window_origin - target_window_origin;
+ gfx::PointF location_in_pixel_in_host =
+ located_event->location_f() + gfx::Vector2dF(offset);
+ located_event->set_location_f(location_in_pixel_in_host);
+ located_event->set_root_location_f(location_in_pixel_in_host);
+}
+
} // namespace ui
diff --git a/chromium/ui/events/event_utils.h b/chromium/ui/events/event_utils.h
index f15a2dba849..5e1d931efea 100644
--- a/chromium/ui/events/event_utils.h
+++ b/chromium/ui/events/event_utils.h
@@ -177,6 +177,14 @@ EVENTS_EXPORT void UpdateX11EventForChangedButtonFlags(MouseEvent* event);
// Registers a custom event type.
EVENTS_EXPORT int RegisterCustomEventType();
+// Updates the location of |located_event| from |current_window_origin| to be in
+// |target_window_origin|'s coordinate system so that it can be dispatched to a
+// window based on |target_window_origin|.
+EVENTS_EXPORT void ConvertEventLocationToTargetWindowLocation(
+ const gfx::Point& target_window_origin,
+ const gfx::Point& current_window_origin,
+ ui::LocatedEvent* located_event);
+
} // namespace ui
#endif // UI_EVENTS_EVENT_UTILS_H_
diff --git a/chromium/ui/events/gesture_detection/filtered_gesture_provider.cc b/chromium/ui/events/gesture_detection/filtered_gesture_provider.cc
index 10b93b25730..8038aa73902 100644
--- a/chromium/ui/events/gesture_detection/filtered_gesture_provider.cc
+++ b/chromium/ui/events/gesture_detection/filtered_gesture_provider.cc
@@ -31,7 +31,7 @@ FilteredGestureProvider::OnTouchEvent(const MotionEvent& event) {
pending_gesture_packet_ = GestureEventDataPacket::FromTouch(event);
- if (event.GetAction() == MotionEvent::ACTION_DOWN)
+ if (event.GetAction() == MotionEvent::Action::DOWN)
any_touch_moved_beyond_slop_region_ = false;
if (!gesture_provider_.OnTouchEvent(event))
diff --git a/chromium/ui/events/gesture_detection/gesture_detector.cc b/chromium/ui/events/gesture_detection/gesture_detector.cc
index adb22f572c1..baa63d31d2e 100644
--- a/chromium/ui/events/gesture_detection/gesture_detector.cc
+++ b/chromium/ui/events/gesture_detection/gesture_detector.cc
@@ -150,7 +150,7 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
velocity_tracker_.AddMovement(ev);
- const bool pointer_up = action == MotionEvent::ACTION_POINTER_UP;
+ const bool pointer_up = action == MotionEvent::Action::POINTER_UP;
const int skip_index = pointer_up ? ev.GetActionIndex() : -1;
// Determine focal point.
@@ -169,16 +169,16 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
bool handled = false;
switch (action) {
- case MotionEvent::ACTION_NONE:
- case MotionEvent::ACTION_HOVER_ENTER:
- case MotionEvent::ACTION_HOVER_EXIT:
- case MotionEvent::ACTION_HOVER_MOVE:
- case MotionEvent::ACTION_BUTTON_PRESS:
- case MotionEvent::ACTION_BUTTON_RELEASE:
+ case MotionEvent::Action::NONE:
+ case MotionEvent::Action::HOVER_ENTER:
+ case MotionEvent::Action::HOVER_EXIT:
+ case MotionEvent::Action::HOVER_MOVE:
+ case MotionEvent::Action::BUTTON_PRESS:
+ case MotionEvent::Action::BUTTON_RELEASE:
NOTREACHED();
return handled;
- case MotionEvent::ACTION_POINTER_DOWN: {
+ case MotionEvent::Action::POINTER_DOWN: {
down_focus_x_ = last_focus_x_ = focus_x;
down_focus_y_ = last_focus_y_ = focus_y;
// Cancel long press and taps.
@@ -204,7 +204,7 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
two_finger_tap_allowed_for_gesture_ = false;
} break;
- case MotionEvent::ACTION_POINTER_UP: {
+ case MotionEvent::Action::POINTER_UP: {
down_focus_x_ = last_focus_x_ = focus_x;
down_focus_y_ = last_focus_y_ = focus_y;
@@ -246,7 +246,7 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
two_finger_tap_allowed_for_gesture_ = false;
} break;
- case MotionEvent::ACTION_DOWN: {
+ case MotionEvent::Action::DOWN: {
bool is_repeated_tap =
current_down_event_ && previous_up_event_ &&
IsRepeatedTap(*current_down_event_, *previous_up_event_, ev);
@@ -292,35 +292,15 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
handled |= listener_->OnDown(ev);
} break;
- case MotionEvent::ACTION_MOVE:
- {
- const float scroll_x = last_focus_x_ - focus_x;
- const float scroll_y = last_focus_y_ - focus_y;
- if (is_double_tapping_) {
- // Give the move events of the double-tap.
- DCHECK(double_tap_listener_);
- handled |= double_tap_listener_->OnDoubleTapEvent(ev);
- } else if (all_pointers_within_slop_regions_) {
- if (!IsWithinTouchSlop(ev)) {
- handled = listener_->OnScroll(
- *current_down_event_, ev,
- (maximum_pointer_count_ > 1 && secondary_pointer_down_event_)
- ? *secondary_pointer_down_event_
- : ev,
- scroll_x, scroll_y);
- last_focus_x_ = focus_x;
- last_focus_y_ = focus_y;
- all_pointers_within_slop_regions_ = false;
- timeout_handler_->Stop();
- }
-
- const float delta_x = focus_x - down_focus_x_;
- const float delta_y = focus_y - down_focus_y_;
- const float distance_square = delta_x * delta_x + delta_y * delta_y;
- if (distance_square > double_tap_touch_slop_square_)
- always_in_bigger_tap_region_ = false;
- } else if (std::abs(scroll_x) > kScrollEpsilon ||
- std::abs(scroll_y) > kScrollEpsilon) {
+ case MotionEvent::Action::MOVE: {
+ const float scroll_x = last_focus_x_ - focus_x;
+ const float scroll_y = last_focus_y_ - focus_y;
+ if (is_double_tapping_) {
+ // Give the move events of the double-tap.
+ DCHECK(double_tap_listener_);
+ handled |= double_tap_listener_->OnDoubleTapEvent(ev);
+ } else if (all_pointers_within_slop_regions_) {
+ if (!IsWithinTouchSlop(ev)) {
handled = listener_->OnScroll(
*current_down_event_, ev,
(maximum_pointer_count_ > 1 && secondary_pointer_down_event_)
@@ -329,22 +309,40 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
scroll_x, scroll_y);
last_focus_x_ = focus_x;
last_focus_y_ = focus_y;
+ all_pointers_within_slop_regions_ = false;
+ timeout_handler_->Stop();
}
- if (!two_finger_tap_allowed_for_gesture_)
- break;
+ const float delta_x = focus_x - down_focus_x_;
+ const float delta_y = focus_y - down_focus_y_;
+ const float distance_square = delta_x * delta_x + delta_y * delta_y;
+ if (distance_square > double_tap_touch_slop_square_)
+ always_in_bigger_tap_region_ = false;
+ } else if (std::abs(scroll_x) > kScrollEpsilon ||
+ std::abs(scroll_y) > kScrollEpsilon) {
+ handled = listener_->OnScroll(
+ *current_down_event_, ev,
+ (maximum_pointer_count_ > 1 && secondary_pointer_down_event_)
+ ? *secondary_pointer_down_event_
+ : ev,
+ scroll_x, scroll_y);
+ last_focus_x_ = focus_x;
+ last_focus_y_ = focus_y;
+ }
- // Two-finger tap should be prevented if either pointer exceeds its
- // (independent) slop region.
- // If the event has had more than two pointers down at any time,
- // two finger tap should be prevented.
- if (maximum_pointer_count_ > 2 || !IsWithinTouchSlop(ev)) {
- two_finger_tap_allowed_for_gesture_ = false;
- }
+ if (!two_finger_tap_allowed_for_gesture_)
+ break;
+
+ // Two-finger tap should be prevented if either pointer exceeds its
+ // (independent) slop region.
+ // If the event has had more than two pointers down at any time,
+ // two finger tap should be prevented.
+ if (maximum_pointer_count_ > 2 || !IsWithinTouchSlop(ev)) {
+ two_finger_tap_allowed_for_gesture_ = false;
}
- break;
+ } break;
- case MotionEvent::ACTION_UP:
+ case MotionEvent::Action::UP:
still_down_ = false;
{
if (is_double_tapping_) {
@@ -375,8 +373,8 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
if ((std::abs(velocity_y) > min_fling_velocity_) ||
(std::abs(velocity_x) > min_fling_velocity_)) {
- handled = listener_->OnFling(
- *current_down_event_, ev, velocity_x, velocity_y);
+ handled = listener_->OnFling(*current_down_event_, ev, velocity_x,
+ velocity_y);
}
handled |= HandleSwipeIfNeeded(ev, velocity_x, velocity_y);
@@ -393,7 +391,7 @@ bool GestureDetector::OnTouchEvent(const MotionEvent& ev) {
maximum_pointer_count_ = 0;
break;
- case MotionEvent::ACTION_CANCEL:
+ case MotionEvent::Action::CANCEL:
Cancel();
break;
}
diff --git a/chromium/ui/events/gesture_detection/gesture_event_data.cc b/chromium/ui/events/gesture_detection/gesture_event_data.cc
index 74a11be246a..e72d2104814 100644
--- a/chromium/ui/events/gesture_detection/gesture_event_data.cc
+++ b/chromium/ui/events/gesture_detection/gesture_event_data.cc
@@ -12,15 +12,15 @@ namespace {
EventPointerType ToEventPointerType(MotionEvent::ToolType tool_type) {
switch (tool_type) {
- case MotionEvent::TOOL_TYPE_UNKNOWN:
+ case MotionEvent::ToolType::UNKNOWN:
return EventPointerType::POINTER_TYPE_UNKNOWN;
- case MotionEvent::TOOL_TYPE_FINGER:
+ case MotionEvent::ToolType::FINGER:
return EventPointerType::POINTER_TYPE_TOUCH;
- case MotionEvent::TOOL_TYPE_STYLUS:
+ case MotionEvent::ToolType::STYLUS:
return EventPointerType::POINTER_TYPE_PEN;
- case MotionEvent::TOOL_TYPE_MOUSE:
+ case MotionEvent::ToolType::MOUSE:
return EventPointerType::POINTER_TYPE_MOUSE;
- case MotionEvent::TOOL_TYPE_ERASER:
+ case MotionEvent::ToolType::ERASER:
return EventPointerType::POINTER_TYPE_ERASER;
default:
NOTREACHED() << "Invalid ToolType = " << tool_type;
@@ -80,13 +80,12 @@ GestureEventData::GestureEventData(const GestureEventData& other) = default;
GestureEventData::GestureEventData()
: motion_event_id(0),
- primary_tool_type(MotionEvent::TOOL_TYPE_UNKNOWN),
+ primary_tool_type(MotionEvent::ToolType::UNKNOWN),
x(0),
y(0),
raw_x(0),
raw_y(0),
flags(EF_NONE),
- unique_touch_event_id(0U) {
-}
+ unique_touch_event_id(0U) {}
} // namespace ui
diff --git a/chromium/ui/events/gesture_detection/gesture_event_data_packet.cc b/chromium/ui/events/gesture_detection/gesture_event_data_packet.cc
index 5edd34a610b..d5b17225bd4 100644
--- a/chromium/ui/events/gesture_detection/gesture_event_data_packet.cc
+++ b/chromium/ui/events/gesture_detection/gesture_event_data_packet.cc
@@ -13,24 +13,24 @@ namespace {
GestureEventDataPacket::GestureSource ToGestureSource(
const ui::MotionEvent& event) {
switch (event.GetAction()) {
- case ui::MotionEvent::ACTION_DOWN:
+ case ui::MotionEvent::Action::DOWN:
return GestureEventDataPacket::TOUCH_SEQUENCE_START;
- case ui::MotionEvent::ACTION_UP:
+ case ui::MotionEvent::Action::UP:
return GestureEventDataPacket::TOUCH_SEQUENCE_END;
- case ui::MotionEvent::ACTION_MOVE:
+ case ui::MotionEvent::Action::MOVE:
return GestureEventDataPacket::TOUCH_MOVE;
- case ui::MotionEvent::ACTION_CANCEL:
+ case ui::MotionEvent::Action::CANCEL:
return GestureEventDataPacket::TOUCH_SEQUENCE_CANCEL;
- case ui::MotionEvent::ACTION_POINTER_DOWN:
+ case ui::MotionEvent::Action::POINTER_DOWN:
return GestureEventDataPacket::TOUCH_START;
- case ui::MotionEvent::ACTION_POINTER_UP:
+ case ui::MotionEvent::Action::POINTER_UP:
return GestureEventDataPacket::TOUCH_END;
- case ui::MotionEvent::ACTION_NONE:
- case ui::MotionEvent::ACTION_HOVER_ENTER:
- case ui::MotionEvent::ACTION_HOVER_EXIT:
- case ui::MotionEvent::ACTION_HOVER_MOVE:
- case ui::MotionEvent::ACTION_BUTTON_PRESS:
- case ui::MotionEvent::ACTION_BUTTON_RELEASE:
+ case ui::MotionEvent::Action::NONE:
+ case ui::MotionEvent::Action::HOVER_ENTER:
+ case ui::MotionEvent::Action::HOVER_EXIT:
+ case ui::MotionEvent::Action::HOVER_MOVE:
+ case ui::MotionEvent::Action::BUTTON_PRESS:
+ case ui::MotionEvent::Action::BUTTON_RELEASE:
NOTREACHED();
return GestureEventDataPacket::INVALID;
};
diff --git a/chromium/ui/events/gesture_detection/gesture_event_data_packet_unittest.cc b/chromium/ui/events/gesture_detection/gesture_event_data_packet_unittest.cc
index 1b7ec0e279c..ed46774ee35 100644
--- a/chromium/ui/events/gesture_detection/gesture_event_data_packet_unittest.cc
+++ b/chromium/ui/events/gesture_detection/gesture_event_data_packet_unittest.cc
@@ -18,18 +18,11 @@ const float kTouchY = 14.2f;
const uint32_t uniqueTouchEventId = 1234U;
GestureEventData CreateGesture(EventType type) {
- return GestureEventData(GestureEventDetails(type),
- 0,
- MotionEvent::TOOL_TYPE_FINGER,
- base::TimeTicks(),
- kTouchX,
- kTouchY,
- kTouchX + 5.f,
- kTouchY + 10.f,
- 1,
+ return GestureEventData(GestureEventDetails(type), 0,
+ MotionEvent::ToolType::FINGER, base::TimeTicks(),
+ kTouchX, kTouchY, kTouchX + 5.f, kTouchY + 10.f, 1,
gfx::RectF(kTouchX - 1.f, kTouchY - 1.f, 2.f, 2.f),
- EF_NONE,
- uniqueTouchEventId);
+ EF_NONE, uniqueTouchEventId);
}
} // namespace
@@ -75,7 +68,7 @@ TEST_F(GestureEventDataPacketTest, Basic) {
EXPECT_EQ(GestureEventDataPacket::UNDEFINED, packet.gesture_source());
packet = GestureEventDataPacket::FromTouch(
- MockMotionEvent(MotionEvent::ACTION_DOWN, touch_time, kTouchX, kTouchY));
+ MockMotionEvent(MotionEvent::Action::DOWN, touch_time, kTouchX, kTouchY));
EXPECT_TRUE(touch_time == packet.timestamp());
EXPECT_EQ(0U, packet.gesture_count());
EXPECT_EQ(gfx::PointF(kTouchX, kTouchY), packet.touch_location());
@@ -94,7 +87,7 @@ TEST_F(GestureEventDataPacketTest, Basic) {
TEST_F(GestureEventDataPacketTest, Copy) {
GestureEventDataPacket packet0 = GestureEventDataPacket::FromTouch(
- MockMotionEvent(MotionEvent::ACTION_UP));
+ MockMotionEvent(MotionEvent::Action::UP));
packet0.Push(CreateGesture(ET_GESTURE_TAP_DOWN));
packet0.Push(CreateGesture(ET_GESTURE_SCROLL_BEGIN));
@@ -107,30 +100,30 @@ TEST_F(GestureEventDataPacketTest, Copy) {
TEST_F(GestureEventDataPacketTest, GestureSource) {
GestureEventDataPacket packet = GestureEventDataPacket::FromTouch(
- MockMotionEvent(MotionEvent::ACTION_DOWN));
+ MockMotionEvent(MotionEvent::Action::DOWN));
EXPECT_EQ(GestureEventDataPacket::TOUCH_SEQUENCE_START,
packet.gesture_source());
packet = GestureEventDataPacket::FromTouch(
- MockMotionEvent(MotionEvent::ACTION_UP));
+ MockMotionEvent(MotionEvent::Action::UP));
EXPECT_EQ(GestureEventDataPacket::TOUCH_SEQUENCE_END,
packet.gesture_source());
packet = GestureEventDataPacket::FromTouch(
- MockMotionEvent(MotionEvent::ACTION_CANCEL));
+ MockMotionEvent(MotionEvent::Action::CANCEL));
EXPECT_EQ(GestureEventDataPacket::TOUCH_SEQUENCE_CANCEL,
packet.gesture_source());
packet = GestureEventDataPacket::FromTouch(
- MockMotionEvent(MotionEvent::ACTION_MOVE));
+ MockMotionEvent(MotionEvent::Action::MOVE));
EXPECT_EQ(GestureEventDataPacket::TOUCH_MOVE, packet.gesture_source());
packet = GestureEventDataPacket::FromTouch(
- MockMotionEvent(MotionEvent::ACTION_POINTER_DOWN));
+ MockMotionEvent(MotionEvent::Action::POINTER_DOWN));
EXPECT_EQ(GestureEventDataPacket::TOUCH_START, packet.gesture_source());
packet = GestureEventDataPacket::FromTouch(
- MockMotionEvent(MotionEvent::ACTION_POINTER_UP));
+ MockMotionEvent(MotionEvent::Action::POINTER_UP));
EXPECT_EQ(GestureEventDataPacket::TOUCH_END, packet.gesture_source());
GestureEventData gesture = CreateGesture(ET_GESTURE_TAP);
diff --git a/chromium/ui/events/gesture_detection/gesture_provider.cc b/chromium/ui/events/gesture_detection/gesture_provider.cc
index c933f99d16b..d05af6677f4 100644
--- a/chromium/ui/events/gesture_detection/gesture_provider.cc
+++ b/chromium/ui/events/gesture_detection/gesture_provider.cc
@@ -28,30 +28,30 @@ const float kDoubleTapDragZoomSpeed = 0.005f;
const char* GetMotionEventActionName(MotionEvent::Action action) {
switch (action) {
- case MotionEvent::ACTION_NONE:
- return "ACTION_NONE";
- case MotionEvent::ACTION_POINTER_DOWN:
- return "ACTION_POINTER_DOWN";
- case MotionEvent::ACTION_POINTER_UP:
- return "ACTION_POINTER_UP";
- case MotionEvent::ACTION_DOWN:
- return "ACTION_DOWN";
- case MotionEvent::ACTION_UP:
- return "ACTION_UP";
- case MotionEvent::ACTION_CANCEL:
- return "ACTION_CANCEL";
- case MotionEvent::ACTION_MOVE:
- return "ACTION_MOVE";
- case MotionEvent::ACTION_HOVER_ENTER:
- return "ACTION_HOVER_ENTER";
- case MotionEvent::ACTION_HOVER_EXIT:
- return "ACTION_HOVER_EXIT";
- case MotionEvent::ACTION_HOVER_MOVE:
- return "ACTION_HOVER_MOVE";
- case MotionEvent::ACTION_BUTTON_PRESS:
- return "ACTION_BUTTON_PRESS";
- case MotionEvent::ACTION_BUTTON_RELEASE:
- return "ACTION_BUTTON_RELEASE";
+ case MotionEvent::Action::NONE:
+ return "Action::NONE";
+ case MotionEvent::Action::POINTER_DOWN:
+ return "Action::POINTER_DOWN";
+ case MotionEvent::Action::POINTER_UP:
+ return "Action::POINTER_UP";
+ case MotionEvent::Action::DOWN:
+ return "Action::DOWN";
+ case MotionEvent::Action::UP:
+ return "Action::UP";
+ case MotionEvent::Action::CANCEL:
+ return "Action::CANCEL";
+ case MotionEvent::Action::MOVE:
+ return "Action::MOVE";
+ case MotionEvent::Action::HOVER_ENTER:
+ return "Action::HOVER_ENTER";
+ case MotionEvent::Action::HOVER_EXIT:
+ return "Action::HOVER_EXIT";
+ case MotionEvent::Action::HOVER_MOVE:
+ return "Action::HOVER_MOVE";
+ case MotionEvent::Action::BUTTON_PRESS:
+ return "Action::BUTTON_PRESS";
+ case MotionEvent::Action::BUTTON_RELEASE:
+ return "Action::BUTTON_RELEASE";
}
return "";
}
@@ -118,7 +118,7 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener,
SetIgnoreSingleTap(true);
const MotionEvent::Action action = event.GetAction();
- if (action == MotionEvent::ACTION_DOWN) {
+ if (action == MotionEvent::Action::DOWN) {
current_down_time_ = event.GetEventTime();
current_longpress_time_ = base::TimeTicks();
ignore_single_tap_ = false;
@@ -132,14 +132,14 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener,
gesture_detector_.OnTouchEvent(event);
scale_gesture_detector_.OnTouchEvent(event);
- if (action == MotionEvent::ACTION_UP ||
- action == MotionEvent::ACTION_CANCEL) {
+ if (action == MotionEvent::Action::UP ||
+ action == MotionEvent::Action::CANCEL) {
// Note: This call will have no effect if a fling was just generated, as
// |Fling()| will have already signalled an end to touch-scrolling.
if (scroll_event_sent_)
Send(CreateGesture(ET_GESTURE_SCROLL_END, event));
current_down_time_ = base::TimeTicks();
- } else if (action == MotionEvent::ACTION_MOVE) {
+ } else if (action == MotionEvent::Action::MOVE) {
if (!show_press_event_sent_ && !scroll_event_sent_) {
max_diameter_before_show_press_ =
std::max(max_diameter_before_show_press_, event.GetTouchMajor());
@@ -157,8 +157,8 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener,
gesture.type() == ET_GESTURE_BEGIN ||
gesture.type() == ET_GESTURE_END);
- if (gesture.primary_tool_type == MotionEvent::TOOL_TYPE_UNKNOWN ||
- gesture.primary_tool_type == MotionEvent::TOOL_TYPE_FINGER) {
+ if (gesture.primary_tool_type == MotionEvent::ToolType::UNKNOWN ||
+ gesture.primary_tool_type == MotionEvent::ToolType::FINGER) {
gesture.details.set_bounding_box(
ClampBoundingBox(gesture.details.bounding_box_f(),
config_.min_gesture_bounds_length,
@@ -203,6 +203,7 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener,
// which case the press should simply be dropped.
if (pinch_event_sent_ || scroll_event_sent_)
return;
+ break;
default:
break;
};
@@ -457,7 +458,7 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener,
}
}
- if (e.GetAction() == MotionEvent::ACTION_UP &&
+ if (e.GetAction() == MotionEvent::Action::UP &&
!current_longpress_time_.is_null() &&
!IsScaleGestureDetectionInProgress()) {
GestureEventDetails long_tap_details(ET_GESTURE_LONG_TAP);
@@ -480,11 +481,11 @@ class GestureProvider::GestureListenerImpl : public ScaleGestureListener,
bool OnDoubleTapEvent(const MotionEvent& e) override {
switch (e.GetAction()) {
- case MotionEvent::ACTION_DOWN:
+ case MotionEvent::Action::DOWN:
gesture_detector_.set_longpress_enabled(false);
break;
- case MotionEvent::ACTION_UP:
+ case MotionEvent::Action::UP:
if (!IsPinchInProgress() && !IsScrollInProgress()) {
Send(CreateTapGesture(ET_GESTURE_DOUBLE_TAP, e, 1));
return true;
@@ -803,9 +804,8 @@ bool GestureProvider::OnTouchEvent(const MotionEvent& event) {
}
void GestureProvider::ResetDetection() {
- MotionEventGeneric generic_cancel_event(MotionEvent::ACTION_CANCEL,
- base::TimeTicks::Now(),
- PointerProperties());
+ MotionEventGeneric generic_cancel_event(
+ MotionEvent::Action::CANCEL, base::TimeTicks::Now(), PointerProperties());
OnTouchEvent(generic_cancel_event);
}
@@ -843,19 +843,20 @@ bool GestureProvider::CanHandle(const MotionEvent& event) const {
// Aura requires one cancel event per touch point, whereas Android requires
// one cancel event per touch sequence. Thus we need to allow extra cancel
// events.
- return current_down_event_ || event.GetAction() == MotionEvent::ACTION_DOWN ||
- event.GetAction() == MotionEvent::ACTION_CANCEL;
+ return current_down_event_ ||
+ event.GetAction() == MotionEvent::Action::DOWN ||
+ event.GetAction() == MotionEvent::Action::CANCEL;
}
void GestureProvider::OnTouchEventHandlingBegin(const MotionEvent& event) {
switch (event.GetAction()) {
- case MotionEvent::ACTION_DOWN:
+ case MotionEvent::Action::DOWN:
current_down_event_ = event.Clone();
if (gesture_begin_end_types_enabled_)
gesture_listener_->Send(
gesture_listener_->CreateGesture(ET_GESTURE_BEGIN, event));
break;
- case MotionEvent::ACTION_POINTER_DOWN:
+ case MotionEvent::Action::POINTER_DOWN:
if (gesture_begin_end_types_enabled_) {
const int action_index = event.GetActionIndex();
gesture_listener_->Send(gesture_listener_->CreateGesture(
@@ -872,17 +873,17 @@ void GestureProvider::OnTouchEventHandlingBegin(const MotionEvent& event) {
event.GetFlags()));
}
break;
- case MotionEvent::ACTION_POINTER_UP:
- case MotionEvent::ACTION_UP:
- case MotionEvent::ACTION_CANCEL:
- case MotionEvent::ACTION_MOVE:
+ case MotionEvent::Action::POINTER_UP:
+ case MotionEvent::Action::UP:
+ case MotionEvent::Action::CANCEL:
+ case MotionEvent::Action::MOVE:
break;
- case MotionEvent::ACTION_NONE:
- case MotionEvent::ACTION_HOVER_ENTER:
- case MotionEvent::ACTION_HOVER_EXIT:
- case MotionEvent::ACTION_HOVER_MOVE:
- case MotionEvent::ACTION_BUTTON_PRESS:
- case MotionEvent::ACTION_BUTTON_RELEASE:
+ case MotionEvent::Action::NONE:
+ case MotionEvent::Action::HOVER_ENTER:
+ case MotionEvent::Action::HOVER_EXIT:
+ case MotionEvent::Action::HOVER_MOVE:
+ case MotionEvent::Action::BUTTON_PRESS:
+ case MotionEvent::Action::BUTTON_RELEASE:
NOTREACHED();
break;
}
@@ -890,8 +891,8 @@ void GestureProvider::OnTouchEventHandlingBegin(const MotionEvent& event) {
void GestureProvider::OnTouchEventHandlingEnd(const MotionEvent& event) {
switch (event.GetAction()) {
- case MotionEvent::ACTION_UP:
- case MotionEvent::ACTION_CANCEL: {
+ case MotionEvent::Action::UP:
+ case MotionEvent::Action::CANCEL: {
if (gesture_begin_end_types_enabled_)
gesture_listener_->Send(
gesture_listener_->CreateGesture(ET_GESTURE_END, event));
@@ -901,21 +902,21 @@ void GestureProvider::OnTouchEventHandlingEnd(const MotionEvent& event) {
UpdateDoubleTapDetectionSupport();
break;
}
- case MotionEvent::ACTION_POINTER_UP:
+ case MotionEvent::Action::POINTER_UP:
if (gesture_begin_end_types_enabled_)
gesture_listener_->Send(
gesture_listener_->CreateGesture(ET_GESTURE_END, event));
break;
- case MotionEvent::ACTION_DOWN:
- case MotionEvent::ACTION_POINTER_DOWN:
- case MotionEvent::ACTION_MOVE:
+ case MotionEvent::Action::DOWN:
+ case MotionEvent::Action::POINTER_DOWN:
+ case MotionEvent::Action::MOVE:
break;
- case MotionEvent::ACTION_NONE:
- case MotionEvent::ACTION_HOVER_ENTER:
- case MotionEvent::ACTION_HOVER_EXIT:
- case MotionEvent::ACTION_HOVER_MOVE:
- case MotionEvent::ACTION_BUTTON_PRESS:
- case MotionEvent::ACTION_BUTTON_RELEASE:
+ case MotionEvent::Action::NONE:
+ case MotionEvent::Action::HOVER_ENTER:
+ case MotionEvent::Action::HOVER_EXIT:
+ case MotionEvent::Action::HOVER_MOVE:
+ case MotionEvent::Action::BUTTON_PRESS:
+ case MotionEvent::Action::BUTTON_RELEASE:
NOTREACHED();
break;
}
diff --git a/chromium/ui/events/gesture_detection/gesture_provider_unittest.cc b/chromium/ui/events/gesture_detection/gesture_provider_unittest.cc
index 39eae93a98f..354c0ae88f6 100644
--- a/chromium/ui/events/gesture_detection/gesture_provider_unittest.cc
+++ b/chromium/ui/events/gesture_detection/gesture_provider_unittest.cc
@@ -305,18 +305,17 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
int motion_event_flags = EF_SHIFT_DOWN | EF_CAPS_LOCK_ON;
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetPrimaryPointerId(motion_event_id);
event.set_flags(motion_event_flags);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(motion_event_flags, GetMostRecentGestureEvent().flags);
- event = ObtainMotionEvent(event_time + kOneSecond,
- MotionEvent::ACTION_MOVE,
- scroll_to_x,
- scroll_to_y);
- event.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
+ event =
+ ObtainMotionEvent(event_time + kOneSecond, MotionEvent::Action::MOVE,
+ scroll_to_x, scroll_to_y);
+ event.SetToolType(0, MotionEvent::ToolType::FINGER);
event.SetPrimaryPointerId(motion_event_id);
event.set_flags(motion_event_flags);
@@ -337,11 +336,11 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
EXPECT_EQ(ET_GESTURE_SCROLL_BEGIN, GetReceivedGesture(1).type());
EXPECT_EQ(motion_event_id, GetReceivedGesture(1).motion_event_id);
EXPECT_EQ(event_time + kOneSecond, GetReceivedGesture(1).time)
- << "ScrollBegin should have the time of the ACTION_MOVE";
+ << "ScrollBegin should have the time of the Action::MOVE";
event = ObtainMotionEvent(
event_time + kOneSecond, end_action_type, scroll_to_x, scroll_to_y);
- event.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
+ event.SetToolType(0, MotionEvent::ToolType::FINGER);
event.SetPrimaryPointerId(motion_event_id);
gesture_provider_->OnTouchEvent(event);
@@ -399,11 +398,11 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
std::vector<gfx::PointF> event_positions(pointer_count);
event_positions.assign(positions.begin(),
positions.begin() + pointer_count);
- MockMotionEvent event =
- ObtainMotionEvent(event_time,
- pointer_count > 1 ? MotionEvent::ACTION_POINTER_DOWN
- : MotionEvent::ACTION_DOWN,
- event_positions);
+ MockMotionEvent event = ObtainMotionEvent(
+ event_time,
+ pointer_count > 1 ? MotionEvent::Action::POINTER_DOWN
+ : MotionEvent::Action::DOWN,
+ event_positions);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
}
@@ -411,20 +410,17 @@ class GestureProviderTest : public testing::Test, public GestureProviderClient {
positions[i] += gfx::ScaleVector2d(velocities[i], dt);
MockMotionEvent event =
ObtainMotionEvent(event_time + kDeltaTimeForFlingSequences,
- MotionEvent::ACTION_MOVE,
- positions);
+ MotionEvent::Action::MOVE, positions);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
for (size_t i = 0; i < positions.size(); ++i)
positions[i] += gfx::ScaleVector2d(velocities[i], dt);
event = ObtainMotionEvent(event_time + 2 * kDeltaTimeForFlingSequences,
- MotionEvent::ACTION_MOVE,
- positions);
+ MotionEvent::Action::MOVE, positions);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + 2 * kDeltaTimeForFlingSequences,
- MotionEvent::ACTION_POINTER_UP,
- positions);
+ MotionEvent::Action::POINTER_UP, positions);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
}
@@ -449,8 +445,8 @@ TEST_F(GestureProviderTest, GestureTap) {
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
- event.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
+ event.SetToolType(0, MotionEvent::ToolType::FINGER);
event.SetPrimaryPointerId(motion_event_id);
event.set_flags(motion_event_flags);
@@ -463,9 +459,9 @@ TEST_F(GestureProviderTest, GestureTap) {
EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
GetMostRecentGestureEvent().details.bounding_box_f());
- event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP);
- event.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
+ event =
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::UP);
+ event.SetToolType(0, MotionEvent::ToolType::FINGER);
event.SetPrimaryPointerId(motion_event_id);
event.set_flags(motion_event_flags);
@@ -492,7 +488,7 @@ TEST_F(GestureProviderTest, GestureTapWithDelay) {
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetPrimaryPointerId(motion_event_id);
event.set_flags(motion_event_flags);
@@ -504,8 +500,8 @@ TEST_F(GestureProviderTest, GestureTapWithDelay) {
EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
GetMostRecentGestureEvent().details.bounding_box_f());
- event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP);
+ event =
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::UP);
event.SetPrimaryPointerId(motion_event_id);
event.set_flags(motion_event_flags);
@@ -535,7 +531,7 @@ TEST_F(GestureProviderTest, GestureFlingAndCancelLongPress) {
int motion_event_flags = EF_ALT_DOWN;
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetPrimaryPointerId(motion_event_id);
event.set_flags(motion_event_flags);
@@ -545,18 +541,15 @@ TEST_F(GestureProviderTest, GestureFlingAndCancelLongPress) {
EXPECT_EQ(motion_event_flags, GetMostRecentGestureEvent().flags);
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
- event = ObtainMotionEvent(event_time + delta_time,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX * 10,
- kFakeCoordY * 10);
+ event = ObtainMotionEvent(event_time + delta_time, MotionEvent::Action::MOVE,
+ kFakeCoordX * 10, kFakeCoordY * 10);
event.SetPrimaryPointerId(motion_event_id);
event.set_flags(motion_event_flags);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time + delta_time * 2,
- MotionEvent::ACTION_UP,
- kFakeCoordX * 10,
- kFakeCoordY * 10);
+ event =
+ ObtainMotionEvent(event_time + delta_time * 2, MotionEvent::Action::UP,
+ kFakeCoordX * 10, kFakeCoordY * 10);
event.SetPrimaryPointerId(motion_event_id);
event.set_flags(motion_event_flags);
@@ -576,7 +569,7 @@ TEST_F(GestureProviderTest, GestureFlingAndCancelLongPress) {
// - ET_GESTURE_SCROLL_UPDATE
// - ET_GESTURE_SCROLL_END
TEST_F(GestureProviderTest, ScrollEventActionUpSequence) {
- CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_UP);
+ CheckScrollEventSequenceForEndActionType(MotionEvent::Action::UP);
}
// Verify that for a cancelled scroll the following events are sent:
@@ -584,7 +577,7 @@ TEST_F(GestureProviderTest, ScrollEventActionUpSequence) {
// - ET_GESTURE_SCROLL_UPDATE
// - ET_GESTURE_SCROLL_END
TEST_F(GestureProviderTest, ScrollEventActionCancelSequence) {
- CheckScrollEventSequenceForEndActionType(MotionEvent::ACTION_CANCEL);
+ CheckScrollEventSequenceForEndActionType(MotionEvent::Action::CANCEL);
}
// Verify that for a normal fling (fling after scroll) the following events are
@@ -597,15 +590,13 @@ TEST_F(GestureProviderTest, FlingEventSequence) {
int motion_event_id = 6;
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetPrimaryPointerId(motion_event_id);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time + delta_time,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX * 5,
- kFakeCoordY * 5);
+ event = ObtainMotionEvent(event_time + delta_time, MotionEvent::Action::MOVE,
+ kFakeCoordX * 5, kFakeCoordY * 5);
event.SetPrimaryPointerId(motion_event_id);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -624,10 +615,9 @@ TEST_F(GestureProviderTest, FlingEventSequence) {
EXPECT_TRUE(hint_x > 0 && hint_y > 0 && hint_x > hint_y)
<< "ScrollBegin hint should be in positive X axis";
- event = ObtainMotionEvent(event_time + delta_time * 2,
- MotionEvent::ACTION_UP,
- kFakeCoordX * 10,
- kFakeCoordY * 10);
+ event =
+ ObtainMotionEvent(event_time + delta_time * 2, MotionEvent::Action::UP,
+ kFakeCoordX * 10, kFakeCoordY * 10);
event.SetPrimaryPointerId(motion_event_id);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -637,14 +627,14 @@ TEST_F(GestureProviderTest, FlingEventSequence) {
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_END));
EXPECT_EQ(event_time + delta_time * 2, GetMostRecentGestureEvent().time)
- << "FlingStart should have the time of the ACTION_UP";
+ << "FlingStart should have the time of the Action::UP";
}
TEST_F(GestureProviderTest, GestureCancelledOnCancelEvent) {
const base::TimeTicks event_time = TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
@@ -658,9 +648,9 @@ TEST_F(GestureProviderTest, GestureCancelledOnCancelEvent) {
EXPECT_TRUE(CancelActiveTouchSequence());
EXPECT_FALSE(HasDownEvent());
- // A final ACTION_UP should have no effect.
+ // A final Action::UP should have no effect.
event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_UP);
+ MotionEvent::Action::UP);
EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
}
@@ -668,7 +658,7 @@ TEST_F(GestureProviderTest, GestureCancelledOnDetectionReset) {
const base::TimeTicks event_time = TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
@@ -680,9 +670,9 @@ TEST_F(GestureProviderTest, GestureCancelledOnDetectionReset) {
ResetGestureDetection();
EXPECT_FALSE(HasDownEvent());
- // A final ACTION_UP should have no effect.
+ // A final Action::UP should have no effect.
event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_UP);
+ MotionEvent::Action::UP);
EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
}
@@ -690,23 +680,20 @@ TEST_F(GestureProviderTest, NoTapAfterScrollBegins) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
- event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + 50,
- kFakeCoordY + 50);
+ event =
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::MOVE,
+ kFakeCoordX + 50, kFakeCoordY + 50);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
- event = ObtainMotionEvent(event_time + kOneSecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX + 50,
- kFakeCoordY + 50);
+ event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::Action::UP,
+ kFakeCoordX + 50, kFakeCoordY + 50);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
@@ -716,24 +703,20 @@ TEST_F(GestureProviderTest, DoubleTap) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_DOWN,
- kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, kFakeCoordX,
kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
@@ -741,18 +724,16 @@ TEST_F(GestureProviderTest, DoubleTap) {
// Moving a very small amount of distance should not trigger the double tap
// drag zoom mode.
- event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
- kFakeCoordY + 1);
+ event =
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::MOVE,
+ kFakeCoordX, kFakeCoordY + 1);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
- event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY + 1);
+ event =
+ ObtainMotionEvent(event_time + kOneMicrosecond * 2,
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY + 1);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
const GestureEventData& double_tap = GetMostRecentGestureEvent();
@@ -768,26 +749,23 @@ TEST_F(GestureProviderTest, DoubleTapDragZoomBasic) {
const base::TimeTicks down_time_2 = down_time_1 + GetValidDoubleTapDelay();
MockMotionEvent event =
- ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(down_time_1, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
- event = ObtainMotionEvent(
- down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event = ObtainMotionEvent(down_time_2, MotionEvent::Action::DOWN, kFakeCoordX,
+ kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 100);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
@@ -798,8 +776,7 @@ TEST_F(GestureProviderTest, DoubleTapDragZoomBasic) {
GetMostRecentGestureEvent().details.bounding_box_f());
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
ASSERT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
@@ -808,8 +785,7 @@ TEST_F(GestureProviderTest, DoubleTapDragZoomBasic) {
GetMostRecentGestureEvent().details.bounding_box_f());
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 100);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
ASSERT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
@@ -818,8 +794,7 @@ TEST_F(GestureProviderTest, DoubleTapDragZoomBasic) {
GetMostRecentGestureEvent().details.bounding_box_f());
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 4,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
+ MotionEvent::Action::UP, kFakeCoordX,
kFakeCoordY - 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
@@ -839,20 +814,18 @@ TEST_F(GestureProviderTest, ScrollUpdateValues) {
const base::TimeTicks event_time = TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Move twice so that we get two ET_GESTURE_SCROLL_UPDATE events and can
// compare the relative and absolute coordinates.
- event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX - delta_x / 2,
- kFakeCoordY - delta_y / 2);
+ event =
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::MOVE,
+ kFakeCoordX - delta_x / 2, kFakeCoordY - delta_y / 2);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX - delta_x,
+ MotionEvent::Action::MOVE, kFakeCoordX - delta_x,
kFakeCoordY - delta_y);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -882,26 +855,22 @@ TEST_F(GestureProviderTest, FractionalScroll) {
const base::TimeTicks event_time = TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Skip past the touch slop and move back.
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 100);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Now move up slowly, mostly vertically but with a (fractional) bit of
// horizontal motion.
for (int i = 1; i <= 10; i++) {
- event = ObtainMotionEvent(event_time + kOneMicrosecond * i,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + delta_x * i,
- kFakeCoordY + delta_y * i);
+ event = ObtainMotionEvent(
+ event_time + kOneMicrosecond * i, MotionEvent::Action::MOVE,
+ kFakeCoordX + delta_x * i, kFakeCoordY + delta_y * i);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
ASSERT_LT(0U, GetReceivedGestureCount());
@@ -937,21 +906,19 @@ TEST_F(GestureProviderTest, ScrollBeginValues) {
const base::TimeTicks event_time = TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Move twice such that the first event isn't sufficient to start
// scrolling on it's own.
- event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + 2,
- kFakeCoordY + 1);
+ event =
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::MOVE,
+ kFakeCoordX + 2, kFakeCoordY + 1);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(gesture_provider_->IsScrollInProgress());
event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + delta_x,
+ MotionEvent::Action::MOVE, kFakeCoordX + delta_x,
kFakeCoordY + delta_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(gesture_provider_->IsScrollInProgress());
@@ -973,20 +940,20 @@ TEST_F(GestureProviderTest, SlopRegionCheckOnOneFingerScroll) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 0, 0);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 0, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Move within slop region.
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_MOVE, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, 0,
scaled_touch_slop / 2);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Exceed slop region.
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_MOVE, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, 0,
2 * scaled_touch_slop);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP, 0,
2 * scaled_touch_slop);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -1004,41 +971,41 @@ TEST_F(GestureProviderTest, SlopRegionCheckOnTwoFingerScroll) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 0, 0);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 0, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN, 0, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 0, 0,
kMaxTwoFingerTapSeparation / 2, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Move within slop region: two-finger tap happens.
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_MOVE, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, 0,
scaled_touch_slop / 2,
kMaxTwoFingerTapSeparation / 2, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_UP, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_UP, 0,
scaled_touch_slop / 2,
kMaxTwoFingerTapSeparation / 2, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Exceed slop region: scroll.
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 0,
scaled_touch_slop / 2,
kMaxTwoFingerTapSeparation / 2, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_MOVE, 0, scaled_touch_slop / 2,
+ event_time, MotionEvent::Action::MOVE, 0, scaled_touch_slop / 2,
kMaxTwoFingerTapSeparation / 2, 2 * scaled_touch_slop);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_POINTER_UP, 0, scaled_touch_slop / 2,
+ event_time, MotionEvent::Action::POINTER_UP, 0, scaled_touch_slop / 2,
kMaxTwoFingerTapSeparation / 2, 2 * scaled_touch_slop);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP, 0,
scaled_touch_slop / 2);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -1059,13 +1026,13 @@ TEST_F(GestureProviderTest, SlopRegionCheckOnMissingSecondaryPointerDownEvent) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 0, 0);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 0, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- // Don't send ACTION_POINTER_DOWN event to the gesture_provider.
- // This is for simulating the cases that the ACTION_POINTER_DOWN event is
+ // Don't send Action::POINTER_DOWN event to the gesture_provider.
+ // This is for simulating the cases that the Action::POINTER_DOWN event is
// missing from the event sequence.
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN, 0, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 0, 0,
kMaxTwoFingerTapSeparation / 2, 0);
event.MovePoint(1, 0, 3 * scaled_touch_slop);
@@ -1091,21 +1058,21 @@ TEST_F(GestureProviderTest, NoSlopRegionCheckOnThreeFingerScroll) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 0, 0);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 0, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN, 0, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 0, 0,
kMaxTwoFingerTapSeparation / 2, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN, 0, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 0, 0,
kMaxTwoFingerTapSeparation / 2, 0,
2 * kMaxTwoFingerTapSeparation, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Move within slop region, three-finger scroll always happens.
event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_MOVE, 0, scaled_touch_slop / 2,
+ event_time, MotionEvent::Action::MOVE, 0, scaled_touch_slop / 2,
kMaxTwoFingerTapSeparation / 2, 0, 2 * kMaxTwoFingerTapSeparation, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -1122,10 +1089,10 @@ TEST_F(GestureProviderTest, ScrollStartWithSecondaryPointer) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 0, 0);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 0, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN, 0, 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 0, 0,
kMaxTwoFingerTapSeparation / 2, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -1152,21 +1119,21 @@ TEST_F(GestureProviderTest, NoFlingBeforeExeedingSlopRegion) {
base::TimeTicks event_time = base::TimeTicks::Now();
base::TimeDelta delta_time = kDeltaTimeForFlingSequences;
MockMotionEvent event = ObtainMotionEvent(event_time + delta_time,
- MotionEvent::ACTION_DOWN, 0, 0);
+ MotionEvent::Action::DOWN, 0, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + 2 * delta_time,
- MotionEvent::ACTION_POINTER_DOWN, 0, 0, 10, 0);
+ MotionEvent::Action::POINTER_DOWN, 0, 0, 10, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
// Fast pointer movements within touch slop region.
event = ObtainMotionEvent(event_time + 3 * delta_time,
- MotionEvent::ACTION_MOVE, 1, 0, 11, 0);
+ MotionEvent::Action::MOVE, 1, 0, 11, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + 4 * delta_time,
- MotionEvent::ACTION_MOVE, 2, 0, 12, 0);
+ MotionEvent::Action::MOVE, 2, 0, 12, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + 5 * delta_time,
- MotionEvent::ACTION_MOVE, 3, 0, 13, 0);
+ MotionEvent::Action::MOVE, 3, 0, 13, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event.ReleasePointAtIndex(0);
@@ -1184,16 +1151,14 @@ TEST_F(GestureProviderTest, LongPressAndTapCancelledWhenScrollBegins) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX * 5,
- kFakeCoordY * 5);
+ event =
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::MOVE,
+ kFakeCoordX * 5, kFakeCoordY * 5);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX * 10,
+ MotionEvent::Action::MOVE, kFakeCoordX * 10,
kFakeCoordY * 10);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -1211,7 +1176,7 @@ TEST_F(GestureProviderTest, GestureLongTap) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
const base::TimeDelta long_press_timeout =
@@ -1223,7 +1188,7 @@ TEST_F(GestureProviderTest, GestureLongTap) {
EXPECT_EQ(BoundsForSingleMockTouchAtLocation(kFakeCoordX, kFakeCoordY),
GetMostRecentGestureEvent().details.bounding_box_f());
- event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::Action::UP);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_LONG_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
@@ -1235,7 +1200,7 @@ TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
const base::TimeDelta long_press_timeout =
@@ -1245,8 +1210,7 @@ TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) {
EXPECT_EQ(ET_GESTURE_LONG_PRESS, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
event = ObtainMotionEvent(event_time + long_press_timeout,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + 100,
+ MotionEvent::Action::MOVE, kFakeCoordX + 100,
kFakeCoordY + 100);
gesture_provider_->OnTouchEvent(event);
@@ -1255,7 +1219,7 @@ TEST_F(GestureProviderTest, GestureLongPressDoesNotPreventScrolling) {
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
event = ObtainMotionEvent(event_time + long_press_timeout,
- MotionEvent::ACTION_UP);
+ MotionEvent::Action::UP);
gesture_provider_->OnTouchEvent(event);
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
}
@@ -1265,21 +1229,17 @@ TEST_F(GestureProviderTest, NoGestureLongPressDuringDoubleTap) {
int motion_event_id = 6;
MockMotionEvent event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event_time, MotionEvent::Action::DOWN, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_DOWN,
- kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, kFakeCoordX,
kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
@@ -1292,8 +1252,7 @@ TEST_F(GestureProviderTest, NoGestureLongPressDuringDoubleTap) {
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_PRESS));
event = ObtainMotionEvent(event_time + long_press_timeout,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + 20,
+ MotionEvent::Action::MOVE, kFakeCoordX + 20,
kFakeCoordY + 20);
event.SetPrimaryPointerId(motion_event_id);
@@ -1304,10 +1263,9 @@ TEST_F(GestureProviderTest, NoGestureLongPressDuringDoubleTap) {
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
EXPECT_TRUE(gesture_provider_->IsDoubleTapInProgress());
- event = ObtainMotionEvent(event_time + long_press_timeout + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY + 1);
+ event =
+ ObtainMotionEvent(event_time + long_press_timeout + kOneMicrosecond,
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY + 1);
event.SetPrimaryPointerId(motion_event_id);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
@@ -1325,12 +1283,11 @@ TEST_F(GestureProviderTest, TouchSlopRemovedFromScroll) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + touch_slop + scroll_delta);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -1351,42 +1308,36 @@ TEST_F(GestureProviderTest, NoScrollWithinTouchSlop) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + touch_slop_pixels / scale_factor,
- kFakeCoordY);
+ event = ObtainMotionEvent(
+ event_time + kOneMicrosecond * 2, MotionEvent::Action::MOVE,
+ kFakeCoordX + touch_slop_pixels / scale_factor, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + touch_slop_pixels / scale_factor);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
- event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX - touch_slop_pixels / scale_factor,
- kFakeCoordY);
+ event = ObtainMotionEvent(
+ event_time + kOneMicrosecond * 2, MotionEvent::Action::MOVE,
+ kFakeCoordX - touch_slop_pixels / scale_factor, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY - touch_slop_pixels / scale_factor);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
- event =
- ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
- kFakeCoordY + (touch_slop_pixels + 1.f) / scale_factor);
+ event = ObtainMotionEvent(
+ event_time + kOneMicrosecond * 2, MotionEvent::Action::MOVE, kFakeCoordX,
+ kFakeCoordY + (touch_slop_pixels + 1.f) / scale_factor);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
}
@@ -1395,16 +1346,14 @@ TEST_F(GestureProviderTest, NoDoubleTapWhenTooRapid) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
@@ -1412,18 +1361,14 @@ TEST_F(GestureProviderTest, NoDoubleTapWhenTooRapid) {
// If the second tap follows the first in too short a time span, no double-tap
// will occur.
event_time += (GetDoubleTapMinTime() / 2);
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_DOWN,
- kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, kFakeCoordX,
kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
}
@@ -1434,29 +1379,23 @@ TEST_F(GestureProviderTest, NoDoubleTapWhenExplicitlyDisabled) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event_time, MotionEvent::Action::DOWN, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_DOWN,
- kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, kFakeCoordX,
kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
@@ -1464,15 +1403,13 @@ TEST_F(GestureProviderTest, NoDoubleTapWhenExplicitlyDisabled) {
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
event_time = base::TimeTicks::Now();
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, kFakeCoordX,
+ kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(5U, GetReceivedGestureCount());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
@@ -1483,32 +1420,24 @@ TEST_F(GestureProviderTest, NoDoubleTapWhenExplicitlyDisabled) {
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_DOWN,
- kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, kFakeCoordX,
kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_DOWN,
- kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, kFakeCoordX,
kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_DOUBLE_TAP, GetMostRecentGestureEventType());
}
@@ -1518,15 +1447,13 @@ TEST_F(GestureProviderTest, NoDelayedTapWhenDoubleTapSupportToggled) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event_time, MotionEvent::Action::DOWN, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1U, GetReceivedGestureCount());
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
EXPECT_EQ(2U, GetReceivedGestureCount());
@@ -1550,22 +1477,19 @@ TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPlatform) {
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(false);
MockMotionEvent event =
- ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(down_time_1, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
gesture_provider_->OnTouchEvent(event);
- event = ObtainMotionEvent(
- down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event = ObtainMotionEvent(down_time_2, MotionEvent::Action::DOWN, kFakeCoordX,
+ kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 100);
// The move should become a scroll, as doubletap drag zoom is disabled.
@@ -1574,8 +1498,7 @@ TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPlatform) {
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
@@ -1585,8 +1508,7 @@ TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPlatform) {
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
+ MotionEvent::Action::UP, kFakeCoordX,
kFakeCoordY + 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
@@ -1602,22 +1524,19 @@ TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPage) {
gesture_provider_->SetDoubleTapSupportForPageEnabled(false);
MockMotionEvent event =
- ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(down_time_1, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
gesture_provider_->OnTouchEvent(event);
- event = ObtainMotionEvent(
- down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event = ObtainMotionEvent(down_time_2, MotionEvent::Action::DOWN, kFakeCoordX,
+ kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 100);
// The move should become a scroll, as double tap drag zoom is disabled.
@@ -1626,8 +1545,7 @@ TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPage) {
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_SCROLL_UPDATE, GetMostRecentGestureEventType());
@@ -1635,8 +1553,7 @@ TEST_F(GestureProviderTest, NoDoubleTapDragZoomWhenDisabledOnPage) {
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
+ MotionEvent::Action::UP, kFakeCoordX,
kFakeCoordY + 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
@@ -1653,19 +1570,16 @@ TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) {
// Start a double-tap drag gesture.
MockMotionEvent event =
- ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(down_time_1, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
gesture_provider_->OnTouchEvent(event);
- event = ObtainMotionEvent(
- down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event = ObtainMotionEvent(down_time_2, MotionEvent::Action::DOWN, kFakeCoordX,
+ kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 100);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
@@ -1680,16 +1594,14 @@ TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) {
// Double tap zoom updates should continue.
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
EXPECT_LT(1.f, GetMostRecentGestureEvent().details.scale());
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
+ MotionEvent::Action::UP, kFakeCoordX,
kFakeCoordY + 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_PINCH_END));
@@ -1703,19 +1615,16 @@ TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) {
down_time_2 += kOneMicrosecond * 40;
// Start a double-tap drag gesture.
- event = ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
+ event = ObtainMotionEvent(down_time_1, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(down_time_1 + kOneMicrosecond,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
- kFakeCoordY);
+ MotionEvent::Action::UP, kFakeCoordX, kFakeCoordY);
gesture_provider_->OnTouchEvent(event);
- event = ObtainMotionEvent(
- down_time_2, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event = ObtainMotionEvent(down_time_2, MotionEvent::Action::DOWN, kFakeCoordX,
+ kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 100);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
@@ -1724,15 +1633,13 @@ TEST_F(GestureProviderTest, FixedPageScaleDuringDoubleTapDragZoom) {
// Double tap zoom updates should not be sent.
// Instead, the second tap drag becomes a scroll gesture sequence.
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY + 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_UPDATE));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
- MotionEvent::ACTION_UP,
- kFakeCoordX,
+ MotionEvent::Action::UP, kFakeCoordX,
kFakeCoordY + 200);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_END));
@@ -1754,7 +1661,7 @@ TEST_F(GestureProviderTest, PinchZoom) {
int secondary_coord_y = kFakeCoordY + 20 * touch_slop;
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -1770,11 +1677,8 @@ TEST_F(GestureProviderTest, PinchZoom) {
// Toggling double-tap support should not take effect until the next sequence.
gesture_provider_->SetDoubleTapSupportForPageEnabled(true);
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_DOWN,
- kFakeCoordX,
- kFakeCoordY,
- secondary_coord_x,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN,
+ kFakeCoordX, kFakeCoordY, secondary_coord_x,
secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
@@ -1787,12 +1691,8 @@ TEST_F(GestureProviderTest, PinchZoom) {
secondary_coord_x += 5 * touch_slop;
secondary_coord_y += 5 * touch_slop;
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
- kFakeCoordY,
- secondary_coord_x,
- secondary_coord_y);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
+ kFakeCoordY, secondary_coord_x, secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
@@ -1821,12 +1721,8 @@ TEST_F(GestureProviderTest, PinchZoom) {
secondary_coord_x += 2 * touch_slop;
secondary_coord_y += 2 * touch_slop;
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
- kFakeCoordY,
- secondary_coord_x,
- secondary_coord_y);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
+ kFakeCoordY, secondary_coord_x, secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
// Toggling double-tap support should not take effect until the next sequence.
@@ -1844,11 +1740,8 @@ TEST_F(GestureProviderTest, PinchZoom) {
secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
GetMostRecentGestureEvent().details.bounding_box_f());
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_UP,
- kFakeCoordX,
- kFakeCoordY,
- secondary_coord_x,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_UP,
+ kFakeCoordX, kFakeCoordY, secondary_coord_x,
secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
@@ -1863,7 +1756,7 @@ TEST_F(GestureProviderTest, PinchZoom) {
secondary_coord_y - kFakeCoordY + kMockTouchRadius * 2),
GetMostRecentGestureEvent().details.bounding_box_f());
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
@@ -1883,49 +1776,45 @@ TEST_F(GestureProviderTest, NoPinchZoomWithFatFinger) {
gesture_provider_->SetMultiTouchZoomSupportEnabled(true);
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1U, GetReceivedGestureCount());
- event = ObtainMotionEvent(event_time + kOneSecond,
- MotionEvent::ACTION_MOVE);
+ event = ObtainMotionEvent(event_time + kOneSecond, MotionEvent::Action::MOVE);
event.SetTouchMajor(0.1f);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(1U, GetReceivedGestureCount());
- event = ObtainMotionEvent(event_time + kOneSecond * 2,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + 1.f,
- kFakeCoordY);
+ event =
+ ObtainMotionEvent(event_time + kOneSecond * 2, MotionEvent::Action::MOVE,
+ kFakeCoordX + 1.f, kFakeCoordY);
event.SetTouchMajor(1.f);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(1U, GetReceivedGestureCount());
- event = ObtainMotionEvent(event_time + kOneSecond * 3,
- MotionEvent::ACTION_MOVE);
+ event =
+ ObtainMotionEvent(event_time + kOneSecond * 3, MotionEvent::Action::MOVE);
event.SetTouchMajor(kFatFingerSize * 3.5f);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(1U, GetReceivedGestureCount());
- event = ObtainMotionEvent(event_time + kOneSecond * 4,
- MotionEvent::ACTION_MOVE);
+ event =
+ ObtainMotionEvent(event_time + kOneSecond * 4, MotionEvent::Action::MOVE);
event.SetTouchMajor(kFatFingerSize * 5.f);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(1U, GetReceivedGestureCount());
- event = ObtainMotionEvent(event_time + kOneSecond * 4,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + 50.f,
- kFakeCoordY - 25.f);
+ event =
+ ObtainMotionEvent(event_time + kOneSecond * 4, MotionEvent::Action::MOVE,
+ kFakeCoordX + 50.f, kFakeCoordY - 25.f);
event.SetTouchMajor(kFatFingerSize * 10.f);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
- event = ObtainMotionEvent(event_time + kOneSecond * 4,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX + 100.f,
- kFakeCoordY - 50.f);
+ event =
+ ObtainMotionEvent(event_time + kOneSecond * 4, MotionEvent::Action::MOVE,
+ kFakeCoordX + 100.f, kFakeCoordY - 50.f);
event.SetTouchMajor(kFatFingerSize * 5.f);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_BEGIN));
@@ -2065,7 +1954,7 @@ TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
const base::TimeDelta long_press_timeout =
@@ -2078,7 +1967,7 @@ TEST_F(GestureProviderTest, GesturesCancelledAfterLongPressCausesLostFocus) {
EXPECT_FALSE(HasDownEvent());
event = ObtainMotionEvent(event_time + long_press_timeout,
- MotionEvent::ACTION_UP);
+ MotionEvent::Action::UP);
gesture_provider_->OnTouchEvent(event);
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_LONG_TAP));
}
@@ -2093,7 +1982,7 @@ TEST_F(GestureProviderTest, CancelActiveTouchSequence) {
EXPECT_EQ(0U, GetReceivedGestureCount());
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetPrimaryPointerId(motion_event_id);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
@@ -2103,17 +1992,17 @@ TEST_F(GestureProviderTest, CancelActiveTouchSequence) {
ASSERT_TRUE(CancelActiveTouchSequence());
EXPECT_FALSE(HasDownEvent());
- // Subsequent MotionEvent's are dropped until ACTION_DOWN.
+ // Subsequent MotionEvent's are dropped until Action::DOWN.
event = ObtainMotionEvent(event_time + kOneMicrosecond,
- MotionEvent::ACTION_MOVE);
+ MotionEvent::Action::MOVE);
EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + kOneMicrosecond * 2,
- MotionEvent::ACTION_UP);
+ MotionEvent::Action::UP);
EXPECT_FALSE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(event_time + kOneMicrosecond * 3,
- MotionEvent::ACTION_DOWN);
+ MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
@@ -2126,25 +2015,24 @@ TEST_F(GestureProviderTest, DoubleTapDragZoomCancelledOnSecondaryPointerDown) {
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
MockMotionEvent event =
- ObtainMotionEvent(down_time_1, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(down_time_1, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
event =
- ObtainMotionEvent(down_time_1 + kOneMicrosecond, MotionEvent::ACTION_UP);
+ ObtainMotionEvent(down_time_1 + kOneMicrosecond, MotionEvent::Action::UP);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_TAP_UNCONFIRMED, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
- event = ObtainMotionEvent(down_time_2, MotionEvent::ACTION_DOWN);
+ event = ObtainMotionEvent(down_time_2, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
event = ObtainMotionEvent(down_time_2 + kOneMicrosecond,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY - 30);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_TRUE(HasReceivedGesture(ET_GESTURE_SCROLL_BEGIN));
@@ -2152,28 +2040,21 @@ TEST_F(GestureProviderTest, DoubleTapDragZoomCancelledOnSecondaryPointerDown) {
EXPECT_EQ(ET_GESTURE_PINCH_UPDATE, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
- event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 2,
- MotionEvent::ACTION_POINTER_DOWN,
- kFakeCoordX,
- kFakeCoordY - 30,
- kFakeCoordX + 50,
- kFakeCoordY + 50);
+ event = ObtainMotionEvent(
+ down_time_2 + kOneMicrosecond * 2, MotionEvent::Action::POINTER_DOWN,
+ kFakeCoordX, kFakeCoordY - 30, kFakeCoordX + 50, kFakeCoordY + 50);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_PINCH_END, GetMostRecentGestureEventType());
EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
const size_t gesture_count = GetReceivedGestureCount();
- event = ObtainMotionEvent(down_time_2 + kOneMicrosecond * 3,
- MotionEvent::ACTION_POINTER_UP,
- kFakeCoordX,
- kFakeCoordY - 30,
- kFakeCoordX + 50,
- kFakeCoordY + 50);
+ event = ObtainMotionEvent(
+ down_time_2 + kOneMicrosecond * 3, MotionEvent::Action::POINTER_UP,
+ kFakeCoordX, kFakeCoordY - 30, kFakeCoordX + 50, kFakeCoordY + 50);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(gesture_count, GetReceivedGestureCount());
- event = ObtainMotionEvent(down_time_2 + kOneSecond,
- MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(down_time_2 + kOneSecond, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(gesture_count + 1, GetReceivedGestureCount());
EXPECT_EQ(ET_GESTURE_SCROLL_END, GetMostRecentGestureEventType());
@@ -2189,7 +2070,7 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
EXPECT_EQ(0U, GetReceivedGestureCount());
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 1, 1);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 1, 1);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type());
@@ -2204,8 +2085,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
kMockTouchRadius * 2, kMockTouchRadius * 2),
GetMostRecentGestureEvent().details.bounding_box_f());
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 1, 1,
+ 2, 2);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
@@ -2216,8 +2097,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
EXPECT_EQ(2 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
EXPECT_EQ(2 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2, 3, 3);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 1, 1,
+ 2, 2, 3, 3);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
@@ -2228,8 +2109,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
EXPECT_EQ(3 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
EXPECT_EQ(3 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_POINTER_UP, 1, 1, 2, 2, 3, 3);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_UP, 1, 1,
+ 2, 2, 3, 3);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
@@ -2240,8 +2121,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
EXPECT_EQ(1 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
EXPECT_EQ(1 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_POINTER_DOWN, 2, 2, 3, 3, 4, 4);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 2, 2,
+ 3, 3, 4, 4);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
@@ -2252,8 +2133,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
EXPECT_EQ(4 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
EXPECT_EQ(4 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_POINTER_UP, 2, 2, 3, 3, 4, 4);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_UP, 2, 2,
+ 3, 3, 4, 4);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
@@ -2264,8 +2145,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
EXPECT_EQ(2 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
EXPECT_EQ(2 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
- event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_UP, 3, 3, 4, 4);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_UP, 3, 3,
+ 4, 4);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
@@ -2276,8 +2157,7 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
EXPECT_EQ(3 + raw_offset_x, GetMostRecentGestureEvent().raw_x);
EXPECT_EQ(3 + raw_offset_y, GetMostRecentGestureEvent().raw_y);
-
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP, 4, 4);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP, 4, 4);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEventType());
@@ -2290,14 +2170,14 @@ TEST_F(GestureProviderTest, GestureBeginAndEnd) {
}
// Verify that gesture begin and gesture end events are dispatched correctly
-// when an ACTION_CANCEL is received.
+// when an Action::CANCEL is received.
TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
EnableBeginEndTypes();
base::TimeTicks event_time = base::TimeTicks::Now();
EXPECT_EQ(0U, GetReceivedGestureCount());
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 1, 1);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 1, 1);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_BEGIN, GetReceivedGesture(0).type());
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
@@ -2309,8 +2189,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
EXPECT_EQ(1, GetMostRecentGestureEvent().x);
EXPECT_EQ(1, GetMostRecentGestureEvent().y);
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 1, 1,
+ 2, 2);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
EXPECT_EQ(3U, GetReceivedGestureCount());
@@ -2318,8 +2198,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
EXPECT_EQ(2, GetMostRecentGestureEvent().x);
EXPECT_EQ(2, GetMostRecentGestureEvent().y);
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_POINTER_DOWN, 1, 1, 2, 2, 3, 3);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 1, 1,
+ 2, 2, 3, 3);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_BEGIN, GetMostRecentGestureEventType());
EXPECT_EQ(4U, GetReceivedGestureCount());
@@ -2327,8 +2207,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
EXPECT_EQ(3, GetMostRecentGestureEvent().x);
EXPECT_EQ(3, GetMostRecentGestureEvent().y);
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_CANCEL, 1, 1, 2, 2, 3, 3);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::CANCEL, 1, 1, 2, 2,
+ 3, 3);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(5U, GetReceivedGestureCount());
EXPECT_EQ(3, GetReceivedGesture(4).details.touch_points());
@@ -2336,8 +2216,8 @@ TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
EXPECT_EQ(1, GetMostRecentGestureEvent().x);
EXPECT_EQ(1, GetMostRecentGestureEvent().y);
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_CANCEL, 1, 1, 3, 3);
+ event =
+ ObtainMotionEvent(event_time, MotionEvent::Action::CANCEL, 1, 1, 3, 3);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(6U, GetReceivedGestureCount());
EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
@@ -2345,8 +2225,7 @@ TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
EXPECT_EQ(1, GetMostRecentGestureEvent().x);
EXPECT_EQ(1, GetMostRecentGestureEvent().y);
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_CANCEL, 3, 3);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::CANCEL, 3, 3);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
EXPECT_EQ(ET_GESTURE_END, GetMostRecentGestureEvent().type());
@@ -2356,7 +2235,7 @@ TEST_F(GestureProviderTest, GestureBeginAndEndOnCancel) {
// Test a simple two finger tap
TEST_F(GestureProviderTest, TwoFingerTap) {
- // The time between ACTION_POINTER_DOWN and ACTION_POINTER_UP must be <= the
+ // The time between Action::POINTER_DOWN and Action::POINTER_UP must be <= the
// two finger tap delay.
EnableTwoFingerTap(kMaxTwoFingerTapSeparation, base::TimeDelta());
const float scaled_touch_slop = GetTouchSlop();
@@ -2364,37 +2243,23 @@ TEST_F(GestureProviderTest, TwoFingerTap) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 0, 0);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 0, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE,
- 0,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, 0,
scaled_touch_slop / 2);
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_DOWN,
- 0,
- 0,
- kMaxTwoFingerTapSeparation / 2,
- 0);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 0, 0,
+ kMaxTwoFingerTapSeparation / 2, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event =
- ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE,
- 0,
- -scaled_touch_slop / 2,
- kMaxTwoFingerTapSeparation / 2 + scaled_touch_slop / 2,
- 0);
+ event = ObtainMotionEvent(
+ event_time, MotionEvent::Action::MOVE, 0, -scaled_touch_slop / 2,
+ kMaxTwoFingerTapSeparation / 2 + scaled_touch_slop / 2, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_UP,
- 0,
- 0,
- kMaxTwoFingerTapSeparation,
- 0);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_UP, 0, 0,
+ kMaxTwoFingerTapSeparation, 0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
@@ -2413,28 +2278,20 @@ TEST_F(GestureProviderTest, TwoFingerTapCancelledByFingerMovement) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event_time, MotionEvent::Action::DOWN, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_DOWN,
- kFakeCoordX,
- kFakeCoordY,
- kFakeCoordX,
- kFakeCoordY);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN,
+ kFakeCoordX, kFakeCoordY, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_MOVE, kFakeCoordX, kFakeCoordY,
+ event_time, MotionEvent::Action::MOVE, kFakeCoordX, kFakeCoordY,
kFakeCoordX + 2 * scaled_touch_slop + 2, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_UP,
- kFakeCoordX,
- kFakeCoordY,
- kFakeCoordX,
- kFakeCoordY);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_UP,
+ kFakeCoordX, kFakeCoordY, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
@@ -2458,28 +2315,21 @@ TEST_F(GestureProviderTest, TwoFingerTapCancelledByDelay) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event_time, MotionEvent::Action::DOWN, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY);
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_DOWN,
- kFakeCoordX,
- kFakeCoordY,
- kFakeCoordX + kMaxTwoFingerTapSeparation / 2,
- kFakeCoordY);
+ event = ObtainMotionEvent(
+ event_time, MotionEvent::Action::POINTER_DOWN, kFakeCoordX, kFakeCoordY,
+ kFakeCoordX + kMaxTwoFingerTapSeparation / 2, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time + kOneSecond + kOneMicrosecond,
- MotionEvent::ACTION_POINTER_UP,
- kFakeCoordX,
- kFakeCoordY,
- kFakeCoordX + kMaxTwoFingerTapSeparation / 2,
- kFakeCoordY);
+ event = ObtainMotionEvent(
+ event_time + kOneSecond + kOneMicrosecond,
+ MotionEvent::Action::POINTER_UP, kFakeCoordX, kFakeCoordY,
+ kFakeCoordX + kMaxTwoFingerTapSeparation / 2, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
@@ -2493,23 +2343,17 @@ TEST_F(GestureProviderTest, TwoFingerTapCancelledByDistanceBetweenPointers) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_DOWN, kFakeCoordX, kFakeCoordY);
+ event_time, MotionEvent::Action::DOWN, kFakeCoordX, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_DOWN,
- kFakeCoordX,
- kFakeCoordY,
- kFakeCoordX + kMaxTwoFingerTapSeparation,
- kFakeCoordY);
+ event = ObtainMotionEvent(
+ event_time, MotionEvent::Action::POINTER_DOWN, kFakeCoordX, kFakeCoordY,
+ kFakeCoordX + kMaxTwoFingerTapSeparation, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_UP,
- kFakeCoordX,
- kFakeCoordY,
- kFakeCoordX + kMaxTwoFingerTapSeparation,
- kFakeCoordY);
+ event = ObtainMotionEvent(
+ event_time, MotionEvent::Action::POINTER_UP, kFakeCoordX, kFakeCoordY,
+ kFakeCoordX + kMaxTwoFingerTapSeparation, kFakeCoordY);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetReceivedGesture(0).type());
@@ -2535,7 +2379,7 @@ TEST_F(GestureProviderTest, PinchExceedingSlopCausesUpdate) {
// First Finger Down
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -2544,7 +2388,7 @@ TEST_F(GestureProviderTest, PinchExceedingSlopCausesUpdate) {
EXPECT_EQ(kFakeCoordY, GetMostRecentGestureEvent().y);
// Second Finger Down
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN,
kFakeCoordX, kFakeCoordY, secondary_coord_x,
secondary_coord_y);
@@ -2557,7 +2401,7 @@ TEST_F(GestureProviderTest, PinchExceedingSlopCausesUpdate) {
// Move second finger by exactly the touch slop. This shouldn't yet generate
// a Pinch Begin.
secondary_coord_y += touch_slop * 2;
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_MOVE, kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY, secondary_coord_x, secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
@@ -2569,7 +2413,7 @@ TEST_F(GestureProviderTest, PinchExceedingSlopCausesUpdate) {
// Move second finger that should *just* cross the slop threshold.
secondary_coord_y += 1;
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_MOVE, kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY, secondary_coord_x, secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
@@ -2600,7 +2444,7 @@ TEST_F(GestureProviderTest, PinchBelowMinSpanCausesUpdate) {
// First Finger Down
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -2609,7 +2453,7 @@ TEST_F(GestureProviderTest, PinchBelowMinSpanCausesUpdate) {
EXPECT_EQ(kFakeCoordY, GetMostRecentGestureEvent().y);
// Second Finger Down
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN,
kFakeCoordX, kFakeCoordY, secondary_coord_x,
secondary_coord_y);
@@ -2621,7 +2465,7 @@ TEST_F(GestureProviderTest, PinchBelowMinSpanCausesUpdate) {
// Move second finger enough to exceed the touch slop and start zooming.
secondary_coord_y -= (touch_slop * 2 + 1);
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_MOVE, kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY, secondary_coord_x, secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
@@ -2635,7 +2479,7 @@ TEST_F(GestureProviderTest, PinchBelowMinSpanCausesUpdate) {
// Move second finger so that the span becomes smaller than the min scaling
// span. The pinch should end but we should receive an update before it does.
secondary_coord_y -= touch_slop * 2;
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_MOVE, kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY, secondary_coord_x, secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
@@ -2670,7 +2514,7 @@ TEST_F(GestureProviderTest, PinchExceedingSlopWithinMinScale) {
// First Finger Down
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -2679,7 +2523,7 @@ TEST_F(GestureProviderTest, PinchExceedingSlopWithinMinScale) {
EXPECT_EQ(kFakeCoordY, GetMostRecentGestureEvent().y);
// Second Finger Down
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_POINTER_DOWN,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN,
kFakeCoordX, kFakeCoordY, secondary_coord_x,
secondary_coord_y);
@@ -2692,7 +2536,7 @@ TEST_F(GestureProviderTest, PinchExceedingSlopWithinMinScale) {
// Move second finger to exceed the touch slop. This shouldn't yet generate
// a Pinch Begin since we're still within the minimum scaling span.
secondary_coord_y += touch_slop * 2 + 1;
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_MOVE, kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY, secondary_coord_x, secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
@@ -2704,7 +2548,7 @@ TEST_F(GestureProviderTest, PinchExceedingSlopWithinMinScale) {
// Move second finger that should *just* cross the min scaling span threshold.
secondary_coord_y = kFakeCoordY + min_scaling_span + 1;
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_MOVE, kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY, secondary_coord_x, secondary_coord_y);
event.SetPrimaryPointerId(motion_event_id);
event.SetRawOffset(raw_offset_x, raw_offset_y);
@@ -2738,17 +2582,14 @@ TEST_F(GestureProviderTest, PinchZoomWithThreshold) {
// First finger down.
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.touch_points());
// Second finger down.
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_POINTER_DOWN,
- kFakeCoordX,
- kFakeCoordY,
- secondary_coord_x,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN,
+ kFakeCoordX, kFakeCoordY, secondary_coord_x,
secondary_coord_y);
gesture_provider_->OnTouchEvent(event);
@@ -2758,12 +2599,8 @@ TEST_F(GestureProviderTest, PinchZoomWithThreshold) {
// Move second finger.
secondary_coord_x += 5 * touch_slop;
secondary_coord_y += 5 * touch_slop;
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
- kFakeCoordY,
- secondary_coord_x,
- secondary_coord_y);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
+ kFakeCoordY, secondary_coord_x, secondary_coord_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(2, GetMostRecentGestureEvent().details.touch_points());
@@ -2774,12 +2611,9 @@ TEST_F(GestureProviderTest, PinchZoomWithThreshold) {
// Small move, shouldn't trigger pinch.
gestures_.clear();
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
- kFakeCoordY,
- secondary_coord_x + kMinPinchUpdateDistance,
- secondary_coord_y);
+ event = ObtainMotionEvent(
+ event_time, MotionEvent::Action::MOVE, kFakeCoordX, kFakeCoordY,
+ secondary_coord_x + kMinPinchUpdateDistance, secondary_coord_y);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_FALSE(HasReceivedGesture(ET_GESTURE_PINCH_UPDATE));
@@ -2789,9 +2623,7 @@ TEST_F(GestureProviderTest, PinchZoomWithThreshold) {
// need to overshoot kMinPinchUpdateDistance by a fair bit, as the span
// calculation factors in touch radius.
const float kOvershootMinPinchUpdateDistance = 3;
- event = ObtainMotionEvent(event_time,
- MotionEvent::ACTION_MOVE,
- kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, kFakeCoordX,
kFakeCoordY,
secondary_coord_x + kMinPinchUpdateDistance +
kOvershootMinPinchUpdateDistance,
@@ -2810,7 +2642,7 @@ TEST_F(GestureProviderTest, MinGestureBoundsLength) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
@@ -2820,7 +2652,7 @@ TEST_F(GestureProviderTest, MinGestureBoundsLength) {
GetMostRecentGestureEvent().details.bounding_box_f().height());
event =
- ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(kMinGestureBoundsLength,
@@ -2836,7 +2668,7 @@ TEST_F(GestureProviderTest, MaxGestureBoundsLength) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
@@ -2846,7 +2678,7 @@ TEST_F(GestureProviderTest, MaxGestureBoundsLength) {
GetMostRecentGestureEvent().details.bounding_box_f().height());
event =
- ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(kMaxGestureBoundsLength,
@@ -2858,19 +2690,19 @@ TEST_F(GestureProviderTest, MaxGestureBoundsLength) {
TEST_F(GestureProviderTest, ZeroRadiusBoundingBox) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 10, 20);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 10, 20);
event.SetTouchMajor(0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(gfx::RectF(10, 20, 0, 0),
GetMostRecentGestureEvent().details.bounding_box_f());
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_POINTER_DOWN, 10, 20, 110, 120);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::POINTER_DOWN, 10,
+ 20, 110, 120);
event.SetTouchMajor(0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(
- event_time, MotionEvent::ACTION_MOVE, 10, 20, 110, 150);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::MOVE, 10, 20, 110,
+ 150);
event.SetTouchMajor(0);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -2889,33 +2721,33 @@ TEST_F(GestureProviderTest, NoMinOrMaxGestureBoundsLengthWithStylusOrMouse) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetTouchMajor(0);
- event.SetToolType(0, MotionEvent::TOOL_TYPE_MOUSE);
+ event.SetToolType(0, MotionEvent::ToolType::MOUSE);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
- EXPECT_EQ(MotionEvent::TOOL_TYPE_MOUSE,
+ EXPECT_EQ(MotionEvent::ToolType::MOUSE,
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(0.f, GetMostRecentGestureEvent().details.bounding_box_f().width());
EXPECT_EQ(0.f, GetMostRecentGestureEvent().details.bounding_box_f().height());
event =
- ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::UP);
event.SetTouchMajor(1);
- event.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
+ event.SetToolType(0, MotionEvent::ToolType::STYLUS);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
- EXPECT_EQ(MotionEvent::TOOL_TYPE_STYLUS,
+ EXPECT_EQ(MotionEvent::ToolType::STYLUS,
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(0, GetMostRecentGestureEvent().details.bounding_box_f().width());
EXPECT_EQ(0, GetMostRecentGestureEvent().details.bounding_box_f().height());
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
event.SetTouchMajor(2.f * kMaxGestureBoundsLength);
- event.SetToolType(0, MotionEvent::TOOL_TYPE_MOUSE);
+ event.SetToolType(0, MotionEvent::ToolType::MOUSE);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_MOUSE,
+ EXPECT_EQ(MotionEvent::ToolType::MOUSE,
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(ET_GESTURE_TAP_DOWN, GetMostRecentGestureEventType());
EXPECT_EQ(2.f * kMaxGestureBoundsLength,
@@ -2924,12 +2756,12 @@ TEST_F(GestureProviderTest, NoMinOrMaxGestureBoundsLengthWithStylusOrMouse) {
GetMostRecentGestureEvent().details.bounding_box_f().height());
event =
- ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::UP);
event.SetTouchMajor(2.f * kMaxGestureBoundsLength);
- event.SetToolType(0, MotionEvent::TOOL_TYPE_ERASER);
+ event.SetToolType(0, MotionEvent::ToolType::ERASER);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
- EXPECT_EQ(MotionEvent::TOOL_TYPE_ERASER,
+ EXPECT_EQ(MotionEvent::ToolType::ERASER,
GetMostRecentGestureEvent().primary_tool_type);
EXPECT_EQ(2.f * kMaxGestureBoundsLength,
GetMostRecentGestureEvent().details.bounding_box_f().width());
@@ -2946,7 +2778,7 @@ TEST_F(GestureProviderTest, BoundingBoxForShowPressAndTapGesture) {
SetShowPressAndLongPressTimeout(showpress_timeout, longpress_timeout);
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, 10, 10);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, 10, 10);
event.SetTouchMajor(10);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
@@ -2955,12 +2787,12 @@ TEST_F(GestureProviderTest, BoundingBoxForShowPressAndTapGesture) {
EXPECT_EQ(gfx::RectF(5, 5, 10, 10),
GetMostRecentGestureEvent().details.bounding_box_f());
- event = ObtainMotionEvent(
- event_time + kOneMicrosecond, MotionEvent::ACTION_MOVE, 11, 9);
+ event = ObtainMotionEvent(event_time + kOneMicrosecond,
+ MotionEvent::Action::MOVE, 11, 9);
event.SetTouchMajor(20);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(
- event_time + kOneMicrosecond, MotionEvent::ACTION_MOVE, 8, 11);
+ event = ObtainMotionEvent(event_time + kOneMicrosecond,
+ MotionEvent::Action::MOVE, 8, 11);
event.SetTouchMajor(10);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
RunTasksAndWait(showpress_timeout + kOneMicrosecond);
@@ -2969,7 +2801,7 @@ TEST_F(GestureProviderTest, BoundingBoxForShowPressAndTapGesture) {
GetMostRecentGestureEvent().details.bounding_box_f());
event =
- ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::ACTION_UP);
+ ObtainMotionEvent(event_time + kOneMicrosecond, MotionEvent::Action::UP);
event.SetTouchMajor(30);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
@@ -2988,9 +2820,9 @@ TEST_F(GestureProviderTest, SingleTapRepeat) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
@@ -2998,9 +2830,9 @@ TEST_F(GestureProviderTest, SingleTapRepeat) {
// A second tap after the double-tap timeout window will not increment
// the tap count.
event_time += GetDoubleTapTimeout() + kOneMicrosecond;
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
@@ -3008,9 +2840,9 @@ TEST_F(GestureProviderTest, SingleTapRepeat) {
// A secondary tap within the tap repeat period should increment
// the tap count.
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(2, GetMostRecentGestureEvent().details.tap_count());
@@ -3018,19 +2850,19 @@ TEST_F(GestureProviderTest, SingleTapRepeat) {
// A secondary tap within the tap repeat location threshold should increment
// the tap count.
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, kFakeCoordX,
kFakeCoordY + GetTouchSlop() / 2);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(3, GetMostRecentGestureEvent().details.tap_count());
// The tap count should reset after hitting the repeat length.
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
@@ -3038,18 +2870,18 @@ TEST_F(GestureProviderTest, SingleTapRepeat) {
// If double-tap is enabled, the tap repeat count should always be 1.
gesture_provider_->SetDoubleTapSupportForPlatformEnabled(true);
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
RunTasksAndWait(GetDoubleTapTimeout());
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
RunTasksAndWait(GetDoubleTapTimeout());
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
@@ -3064,9 +2896,9 @@ TEST_F(GestureProviderTest, SingleTapRepeatLengthOfOne) {
base::TimeTicks event_time = base::TimeTicks::Now();
MockMotionEvent event =
- ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
gesture_provider_->OnTouchEvent(event);
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
@@ -3074,18 +2906,18 @@ TEST_F(GestureProviderTest, SingleTapRepeatLengthOfOne) {
// Repeated taps should still produce a tap count of 1 if the
// tap repeat length is 1.
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
event_time += GetValidDoubleTapDelay();
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_DOWN, kFakeCoordX,
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::DOWN, kFakeCoordX,
kFakeCoordY + GetTouchSlop() / 2);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
- event = ObtainMotionEvent(event_time, MotionEvent::ACTION_UP);
+ event = ObtainMotionEvent(event_time, MotionEvent::Action::UP);
EXPECT_TRUE(gesture_provider_->OnTouchEvent(event));
EXPECT_EQ(ET_GESTURE_TAP, GetMostRecentGestureEventType());
EXPECT_EQ(1, GetMostRecentGestureEvent().details.tap_count());
diff --git a/chromium/ui/events/gesture_detection/gesture_touch_uma_histogram.cc b/chromium/ui/events/gesture_detection/gesture_touch_uma_histogram.cc
index db52a8ae49b..7afcbf49bd3 100644
--- a/chromium/ui/events/gesture_detection/gesture_touch_uma_histogram.cc
+++ b/chromium/ui/events/gesture_detection/gesture_touch_uma_histogram.cc
@@ -22,19 +22,19 @@ void GestureTouchUMAHistogram::RecordGestureEvent(
}
void GestureTouchUMAHistogram::RecordTouchEvent(const MotionEvent& event) {
- if (event.GetAction() == MotionEvent::ACTION_DOWN) {
+ if (event.GetAction() == MotionEvent::Action::DOWN) {
start_time_ = event.GetEventTime();
start_touch_position_ = gfx::Point(event.GetX(), event.GetY());
is_single_finger_ = true;
max_distance_from_start_squared_ = 0;
- } else if (event.GetAction() == MotionEvent::ACTION_MOVE &&
+ } else if (event.GetAction() == MotionEvent::Action::MOVE &&
is_single_finger_) {
float cur_dist = (start_touch_position_ -
gfx::Point(event.GetX(), event.GetY())).LengthSquared();
if (cur_dist > max_distance_from_start_squared_)
max_distance_from_start_squared_ = cur_dist;
} else {
- if (event.GetAction() == MotionEvent::ACTION_UP && is_single_finger_) {
+ if (event.GetAction() == MotionEvent::Action::UP && is_single_finger_) {
UMA_HISTOGRAM_CUSTOM_COUNTS(
"Event.TouchMaxDistance",
static_cast<int>(sqrt(max_distance_from_start_squared_)),
diff --git a/chromium/ui/events/gesture_detection/motion_event.cc b/chromium/ui/events/gesture_detection/motion_event.cc
index 07ee9e125f2..a5c083b0782 100644
--- a/chromium/ui/events/gesture_detection/motion_event.cc
+++ b/chromium/ui/events/gesture_detection/motion_event.cc
@@ -59,4 +59,13 @@ std::unique_ptr<MotionEvent> MotionEvent::Cancel() const {
return MotionEventGeneric::CancelEvent(*this);
}
+std::ostream& operator<<(std::ostream& stream,
+ const MotionEvent::Action action) {
+ return stream << static_cast<int>(action);
+}
+std::ostream& operator<<(std::ostream& stream,
+ const MotionEvent::ToolType tool_type) {
+ return stream << static_cast<int>(tool_type);
+}
+
} // namespace ui
diff --git a/chromium/ui/events/gesture_detection/motion_event.h b/chromium/ui/events/gesture_detection/motion_event.h
index 05a3c55ee0f..383b23aa6eb 100644
--- a/chromium/ui/events/gesture_detection/motion_event.h
+++ b/chromium/ui/events/gesture_detection/motion_event.h
@@ -19,30 +19,23 @@ namespace ui {
// subset of Android's MotionEvent API used in gesture detection.
class GESTURE_DETECTION_EXPORT MotionEvent {
public:
- enum Action {
- ACTION_NONE,
- ACTION_DOWN,
- ACTION_UP,
- ACTION_MOVE,
- ACTION_CANCEL,
- ACTION_POINTER_DOWN,
- ACTION_POINTER_UP,
- ACTION_HOVER_ENTER,
- ACTION_HOVER_EXIT,
- ACTION_HOVER_MOVE,
- ACTION_BUTTON_PRESS,
- ACTION_BUTTON_RELEASE,
- ACTION_LAST = ACTION_BUTTON_RELEASE
+ enum class Action {
+ NONE,
+ DOWN,
+ UP,
+ MOVE,
+ CANCEL,
+ POINTER_DOWN,
+ POINTER_UP,
+ HOVER_ENTER,
+ HOVER_EXIT,
+ HOVER_MOVE,
+ BUTTON_PRESS,
+ BUTTON_RELEASE,
+ LAST = BUTTON_RELEASE
};
- enum ToolType {
- TOOL_TYPE_UNKNOWN,
- TOOL_TYPE_FINGER,
- TOOL_TYPE_STYLUS,
- TOOL_TYPE_MOUSE,
- TOOL_TYPE_ERASER,
- TOOL_TYPE_LAST = TOOL_TYPE_ERASER
- };
+ enum class ToolType { UNKNOWN, FINGER, STYLUS, MOUSE, ERASER, LAST = ERASER };
enum ButtonType {
BUTTON_PRIMARY = 1 << 0,
@@ -63,8 +56,8 @@ class GESTURE_DETECTION_EXPORT MotionEvent {
// An unique identifier this motion event.
virtual uint32_t GetUniqueEventId() const = 0;
virtual Action GetAction() const = 0;
- // Only valid if |GetAction()| returns ACTION_POINTER_UP or
- // ACTION_POINTER_DOWN.
+ // Only valid if |GetAction()| returns Action::POINTER_UP or
+ // Action::POINTER_DOWN.
virtual int GetActionIndex() const = 0;
virtual size_t GetPointerCount() const = 0;
virtual int GetPointerId(size_t pointer_index) const = 0;
@@ -139,6 +132,13 @@ class GESTURE_DETECTION_EXPORT MotionEvent {
std::unique_ptr<MotionEvent> Cancel() const;
};
+GESTURE_DETECTION_EXPORT std::ostream& operator<<(
+ std::ostream& stream,
+ const MotionEvent::Action action);
+GESTURE_DETECTION_EXPORT std::ostream& operator<<(
+ std::ostream& stream,
+ const MotionEvent::ToolType tool_type);
+
} // namespace ui
#endif // UI_EVENTS_GESTURE_DETECTION_MOTION_EVENT_H_
diff --git a/chromium/ui/events/gesture_detection/motion_event_buffer.cc b/chromium/ui/events/gesture_detection/motion_event_buffer.cc
index b2ce72f9ffc..596ca39403d 100644
--- a/chromium/ui/events/gesture_detection/motion_event_buffer.cc
+++ b/chromium/ui/events/gesture_detection/motion_event_buffer.cc
@@ -36,8 +36,8 @@ float Lerp(float a, float b, float alpha) {
}
bool CanAddSample(const MotionEvent& event0, const MotionEvent& event1) {
- DCHECK_EQ(event0.GetAction(), MotionEvent::ACTION_MOVE);
- if (event1.GetAction() != MotionEvent::ACTION_MOVE)
+ DCHECK_EQ(event0.GetAction(), MotionEvent::Action::MOVE);
+ if (event1.GetAction() != MotionEvent::Action::MOVE)
return false;
const size_t pointer_count = event0.GetPointerCount();
@@ -57,8 +57,8 @@ bool CanAddSample(const MotionEvent& event0, const MotionEvent& event1) {
}
bool ShouldResampleTool(MotionEvent::ToolType tool) {
- return tool == MotionEvent::TOOL_TYPE_UNKNOWN ||
- tool == MotionEvent::TOOL_TYPE_FINGER;
+ return tool == MotionEvent::ToolType::UNKNOWN ||
+ tool == MotionEvent::ToolType::FINGER;
}
// Splits a chunk of events from the front of the provided |batch| and returns
@@ -109,7 +109,7 @@ std::unique_ptr<MotionEventGeneric> ResampleMotionEvent(
const MotionEvent& event0,
const MotionEvent& event1,
base::TimeTicks resample_time) {
- DCHECK_EQ(MotionEvent::ACTION_MOVE, event0.GetAction());
+ DCHECK_EQ(MotionEvent::Action::MOVE, event0.GetAction());
DCHECK_EQ(event0.GetPointerCount(), event1.GetPointerCount());
const base::TimeTicks time0 = event0.GetEventTime();
@@ -130,8 +130,8 @@ std::unique_ptr<MotionEventGeneric> ResampleMotionEvent(
event0, event1, event0_i, static_cast<size_t>(event1_i), alpha);
if (event0_i == 0) {
- event.reset(new MotionEventGeneric(
- MotionEvent::ACTION_MOVE, resample_time, pointer));
+ event.reset(new MotionEventGeneric(MotionEvent::Action::MOVE,
+ resample_time, pointer));
} else {
event->PushPointer(pointer);
}
@@ -233,7 +233,7 @@ MotionEventBuffer::~MotionEventBuffer() {
void MotionEventBuffer::OnMotionEvent(const MotionEvent& event) {
DCHECK_EQ(0U, event.GetHistorySize());
- if (event.GetAction() != MotionEvent::ACTION_MOVE) {
+ if (event.GetAction() != MotionEvent::Action::MOVE) {
last_extrapolated_event_time_ = base::TimeTicks();
if (!buffered_events_.empty())
FlushWithoutResampling(std::move(buffered_events_));
diff --git a/chromium/ui/events/gesture_detection/motion_event_buffer_unittest.cc b/chromium/ui/events/gesture_detection/motion_event_buffer_unittest.cc
index b8090b2a82c..a6f78436309 100644
--- a/chromium/ui/events/gesture_detection/motion_event_buffer_unittest.cc
+++ b/chromium/ui/events/gesture_detection/motion_event_buffer_unittest.cc
@@ -83,8 +83,8 @@ class MotionEventBufferTest : public testing::Test,
const MotionEvent& b,
bool ignore_history) {
EXPECT_EQ(a.GetAction(), b.GetAction());
- if (a.GetAction() == MotionEvent::ACTION_POINTER_DOWN ||
- a.GetAction() == MotionEvent::ACTION_POINTER_UP) {
+ if (a.GetAction() == MotionEvent::Action::POINTER_DOWN ||
+ a.GetAction() == MotionEvent::Action::POINTER_UP) {
EXPECT_EQ(a.GetActionIndex(), b.GetActionIndex());
}
EXPECT_EQ(a.GetButtonState(), b.GetButtonState());
@@ -185,8 +185,8 @@ class MotionEventBufferTest : public testing::Test,
base::TimeDelta last_dt;
while (event_time < max_event_time) {
position += gfx::ScaleVector2d(velocity, event_time_delta.InSecondsF());
- MockMotionEvent move(
- MotionEvent::ACTION_MOVE, event_time, position.x(), position.y());
+ MockMotionEvent move(MotionEvent::Action::MOVE, event_time, position.x(),
+ position.y());
buffer.OnMotionEvent(move);
event_time += event_time_delta;
@@ -258,7 +258,7 @@ TEST_F(MotionEventBufferTest, BufferWithOneMoveNotResampled) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
- MockMotionEvent move(MotionEvent::ACTION_MOVE, event_time, 4.f, 4.f);
+ MockMotionEvent move(MotionEvent::Action::MOVE, event_time, 4.f, 4.f);
buffer.OnMotionEvent(move);
EXPECT_TRUE(GetAndResetNeedsFlush());
EXPECT_FALSE(GetLastEvent());
@@ -274,7 +274,7 @@ TEST_F(MotionEventBufferTest, BufferFlushedOnNonActionMove) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 1.f, 1.f);
buffer.OnMotionEvent(move0);
EXPECT_TRUE(GetAndResetNeedsFlush());
EXPECT_FALSE(GetLastEvent());
@@ -282,19 +282,19 @@ TEST_F(MotionEventBufferTest, BufferFlushedOnNonActionMove) {
event_time += base::TimeDelta::FromMilliseconds(5);
// The second move should remain buffered.
- MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 2.f, 2.f);
buffer.OnMotionEvent(move1);
EXPECT_FALSE(GetAndResetNeedsFlush());
EXPECT_FALSE(GetLastEvent());
// The third move should remain buffered.
- MockMotionEvent move2(MotionEvent::ACTION_MOVE, event_time, 3.f, 3.f);
+ MockMotionEvent move2(MotionEvent::Action::MOVE, event_time, 3.f, 3.f);
buffer.OnMotionEvent(move2);
EXPECT_FALSE(GetAndResetNeedsFlush());
EXPECT_FALSE(GetLastEvent());
// The up should flush the buffer.
- MockMotionEvent up(MotionEvent::ACTION_UP, event_time, 4.f, 4.f);
+ MockMotionEvent up(MotionEvent::Action::UP, event_time, 4.f, 4.f);
buffer.OnMotionEvent(up);
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -314,7 +314,7 @@ TEST_F(MotionEventBufferTest, BufferFlushedOnIncompatibleActionMove) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 1.f, 1.f);
buffer.OnMotionEvent(move0);
EXPECT_TRUE(GetAndResetNeedsFlush());
EXPECT_FALSE(GetLastEvent());
@@ -322,8 +322,8 @@ TEST_F(MotionEventBufferTest, BufferFlushedOnIncompatibleActionMove) {
event_time += base::TimeDelta::FromMilliseconds(5);
// The second move has a different pointer count, flushing the first.
- MockMotionEvent move1(
- MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f, 3.f, 3.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 2.f, 2.f, 3.f,
+ 3.f);
buffer.OnMotionEvent(move1);
EXPECT_FALSE(GetAndResetNeedsFlush());
ASSERT_TRUE(GetLastEvent());
@@ -333,7 +333,7 @@ TEST_F(MotionEventBufferTest, BufferFlushedOnIncompatibleActionMove) {
// The third move has differing tool types, flushing the second.
MockMotionEvent move2(move1);
- move2.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
+ move2.SetToolType(0, MotionEvent::ToolType::STYLUS);
buffer.OnMotionEvent(move2);
EXPECT_FALSE(GetAndResetNeedsFlush());
EXPECT_EVENT_EQ(move1, *GetLastEvent());
@@ -355,13 +355,13 @@ TEST_F(MotionEventBufferTest, BufferFlushedOnIncompatibleActionMove) {
pointer0.id = 1;
PointerProperties pointer1(10.f, 10.f, 2.f);
pointer1.id = 2;
- MotionEventGeneric move3(MotionEvent::ACTION_MOVE, event_time, pointer0);
+ MotionEventGeneric move3(MotionEvent::Action::MOVE, event_time, pointer0);
move3.PushPointer(pointer1);
buffer.OnMotionEvent(move3);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
- MotionEventGeneric move4(MotionEvent::ACTION_MOVE, event_time, pointer0);
+ MotionEventGeneric move4(MotionEvent::Action::MOVE, event_time, pointer0);
pointer1.id = 7;
move4.PushPointer(pointer1);
buffer.OnMotionEvent(move2);
@@ -374,7 +374,7 @@ TEST_F(MotionEventBufferTest, OnlyActionMoveBuffered) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
- MockMotionEvent down(MotionEvent::ACTION_DOWN, event_time, 1.f, 1.f);
+ MockMotionEvent down(MotionEvent::Action::DOWN, event_time, 1.f, 1.f);
buffer.OnMotionEvent(down);
EXPECT_FALSE(GetAndResetNeedsFlush());
ASSERT_TRUE(GetLastEvent());
@@ -382,7 +382,7 @@ TEST_F(MotionEventBufferTest, OnlyActionMoveBuffered) {
GetAndResetForwardedEvents();
- MockMotionEvent up(MotionEvent::ACTION_UP, event_time, 2.f, 2.f);
+ MockMotionEvent up(MotionEvent::Action::UP, event_time, 2.f, 2.f);
buffer.OnMotionEvent(up);
EXPECT_FALSE(GetAndResetNeedsFlush());
ASSERT_TRUE(GetLastEvent());
@@ -390,7 +390,7 @@ TEST_F(MotionEventBufferTest, OnlyActionMoveBuffered) {
GetAndResetForwardedEvents();
- MockMotionEvent cancel(MotionEvent::ACTION_CANCEL, event_time, 3.f, 3.f);
+ MockMotionEvent cancel(MotionEvent::Action::CANCEL, event_time, 3.f, 3.f);
buffer.OnMotionEvent(cancel);
EXPECT_FALSE(GetAndResetNeedsFlush());
ASSERT_TRUE(GetLastEvent());
@@ -398,7 +398,7 @@ TEST_F(MotionEventBufferTest, OnlyActionMoveBuffered) {
GetAndResetForwardedEvents();
- MockMotionEvent move(MotionEvent::ACTION_MOVE, event_time, 4.f, 4.f);
+ MockMotionEvent move(MotionEvent::Action::MOVE, event_time, 4.f, 4.f);
buffer.OnMotionEvent(move);
EXPECT_TRUE(GetAndResetNeedsFlush());
EXPECT_FALSE(GetLastEvent());
@@ -419,7 +419,7 @@ TEST_F(MotionEventBufferTest, OutOfOrderPointersBuffered) {
PointerProperties p1(2.f, 1.f, 0.5f);
p1.id = 2;
- MotionEventGeneric move0(MotionEvent::ACTION_MOVE, event_time, p0);
+ MotionEventGeneric move0(MotionEvent::Action::MOVE, event_time, p0);
move0.PushPointer(p1);
buffer.OnMotionEvent(move0);
EXPECT_TRUE(GetAndResetNeedsFlush());
@@ -429,7 +429,7 @@ TEST_F(MotionEventBufferTest, OutOfOrderPointersBuffered) {
// The second move should remain buffered even if the logical pointers are
// in a different order.
- MotionEventGeneric move1(MotionEvent::ACTION_MOVE, event_time, p1);
+ MotionEventGeneric move1(MotionEvent::Action::MOVE, event_time, p1);
move1.PushPointer(p0);
buffer.OnMotionEvent(move1);
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -452,14 +452,14 @@ TEST_F(MotionEventBufferTest, FlushedEventsNeverLaterThanFlushTime) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 1.f, 1.f);
buffer.OnMotionEvent(move0);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
// The second move should remain buffered.
event_time += LargeDelta();
- MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 2.f, 2.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -509,13 +509,13 @@ TEST_F(MotionEventBufferTest, NoResamplingWhenDisabled) {
MotionEventBuffer buffer(this, resampling_enabled);
// Queue two events.
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 5.f, 10.f);
buffer.OnMotionEvent(move0);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
event_time += base::TimeDelta::FromMilliseconds(5);
- MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 15.f, 30.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 15.f, 30.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -543,14 +543,14 @@ TEST_F(MotionEventBufferTest, NoResamplingWhenDisabled) {
GetAndResetForwardedEvents();
// Now queue two more events.
- move0 = MockMotionEvent(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
+ move0 = MockMotionEvent(MotionEvent::Action::MOVE, event_time, 5.f, 10.f);
buffer.OnMotionEvent(move0);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
// The second move should remain buffered.
event_time += base::TimeDelta::FromMilliseconds(5);
- move1 = MockMotionEvent(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
+ move1 = MockMotionEvent(MotionEvent::Action::MOVE, event_time, 10.f, 20.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -575,14 +575,14 @@ TEST_F(MotionEventBufferTest, NoResamplingWithOutOfOrderActionMove) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 5.f, 10.f);
buffer.OnMotionEvent(move0);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
// The second move should remain buffered.
event_time += base::TimeDelta::FromMilliseconds(10);
- MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 10.f, 20.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -609,14 +609,14 @@ TEST_F(MotionEventBufferTest, NoResamplingWithOutOfOrderActionMove) {
// Try enqueuing an event *after* the second event but *before* the
// extrapolated event. It should be dropped.
event_time = move1.GetEventTime() + base::TimeDelta::FromMilliseconds(1);
- MockMotionEvent move2(MotionEvent::ACTION_MOVE, event_time, 15.f, 25.f);
+ MockMotionEvent move2(MotionEvent::Action::MOVE, event_time, 15.f, 25.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
// Finally queue an event *after* the extrapolated event.
event_time = expected_time + base::TimeDelta::FromMilliseconds(1);
- MockMotionEvent move3(MotionEvent::ACTION_MOVE, event_time, 15.f, 25.f);
+ MockMotionEvent move3(MotionEvent::Action::MOVE, event_time, 15.f, 25.f);
buffer.OnMotionEvent(move3);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
@@ -637,14 +637,14 @@ TEST_F(MotionEventBufferTest, NoResamplingWithSmallTimeDeltaBetweenMoves) {
MotionEventBuffer buffer(this, true);
// The first move should be buffered.
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 1.f, 1.f);
buffer.OnMotionEvent(move0);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
// The second move should remain buffered.
event_time += SmallDelta();
- MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 2.f, 2.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -668,14 +668,14 @@ TEST_F(MotionEventBufferTest, NoResamplingWithMismatchBetweenMoves) {
MotionEventBuffer buffer(this, true);
// The first move should be buffered.
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 1.f, 1.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 1.f, 1.f);
buffer.OnMotionEvent(move0);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
// The second move should remain buffered.
event_time += SmallDelta();
- MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 2.f, 2.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 2.f, 2.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -698,14 +698,14 @@ TEST_F(MotionEventBufferTest, Interpolation) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 5.f, 10.f);
buffer.OnMotionEvent(move0);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
// The second move should remain buffered.
event_time += base::TimeDelta::FromMilliseconds(5);
- MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 15.f, 30.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 15.f, 30.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -723,8 +723,7 @@ TEST_F(MotionEventBufferTest, Interpolation) {
float alpha = (interpolated_time - move0.GetEventTime()).InMillisecondsF() /
(move1.GetEventTime() - move0.GetEventTime()).InMillisecondsF();
MockMotionEvent interpolated_event(
- MotionEvent::ACTION_MOVE,
- interpolated_time,
+ MotionEvent::Action::MOVE, interpolated_time,
move0.GetX(0) + (move1.GetX(0) - move0.GetX(0)) * alpha,
move0.GetY(0) + (move1.GetY(0) - move0.GetY(0)) * alpha);
std::vector<std::unique_ptr<MotionEvent>> events =
@@ -745,14 +744,14 @@ TEST_F(MotionEventBufferTest, Extrapolation) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 5.f, 10.f);
buffer.OnMotionEvent(move0);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
// The second move should remain buffered.
event_time += base::TimeDelta::FromMilliseconds(5);
- MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 10.f, 20.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -776,8 +775,7 @@ TEST_F(MotionEventBufferTest, Extrapolation) {
(expected_time - move0.GetEventTime()).InMillisecondsF() /
(move1.GetEventTime() - move0.GetEventTime()).InMillisecondsF();
MockMotionEvent extrapolated_event(
- MotionEvent::ACTION_MOVE,
- expected_time,
+ MotionEvent::Action::MOVE, expected_time,
move0.GetX(0) + (move1.GetX(0) - move0.GetX(0)) * expected_alpha,
move0.GetY(0) + (move1.GetY(0) - move0.GetY(0)) * expected_alpha);
std::vector<std::unique_ptr<MotionEvent>> events =
@@ -793,14 +791,14 @@ TEST_F(MotionEventBufferTest, ExtrapolationHorizonLimited) {
base::TimeTicks event_time = base::TimeTicks::Now();
MotionEventBuffer buffer(this, true);
- MockMotionEvent move0(MotionEvent::ACTION_MOVE, event_time, 5.f, 10.f);
+ MockMotionEvent move0(MotionEvent::Action::MOVE, event_time, 5.f, 10.f);
buffer.OnMotionEvent(move0);
ASSERT_FALSE(GetLastEvent());
EXPECT_TRUE(GetAndResetNeedsFlush());
// The second move should remain buffered.
event_time += base::TimeDelta::FromMilliseconds(24);
- MockMotionEvent move1(MotionEvent::ACTION_MOVE, event_time, 10.f, 20.f);
+ MockMotionEvent move1(MotionEvent::Action::MOVE, event_time, 10.f, 20.f);
buffer.OnMotionEvent(move1);
ASSERT_FALSE(GetLastEvent());
EXPECT_FALSE(GetAndResetNeedsFlush());
@@ -822,8 +820,7 @@ TEST_F(MotionEventBufferTest, ExtrapolationHorizonLimited) {
(expected_time - move0.GetEventTime()).InMillisecondsF() /
(move1.GetEventTime() - move0.GetEventTime()).InMillisecondsF();
MockMotionEvent extrapolated_event(
- MotionEvent::ACTION_MOVE,
- expected_time,
+ MotionEvent::Action::MOVE, expected_time,
move0.GetX(0) + (move1.GetX(0) - move0.GetX(0)) * expected_alpha,
move0.GetY(0) + (move1.GetY(0) - move0.GetY(0)) * expected_alpha);
std::vector<std::unique_ptr<MotionEvent>> events =
diff --git a/chromium/ui/events/gesture_detection/motion_event_generic.cc b/chromium/ui/events/gesture_detection/motion_event_generic.cc
index 07afcd6c9b9..293ea0b689a 100644
--- a/chromium/ui/events/gesture_detection/motion_event_generic.cc
+++ b/chromium/ui/events/gesture_detection/motion_event_generic.cc
@@ -20,7 +20,7 @@ PointerProperties::PointerProperties()
PointerProperties::PointerProperties(float x, float y, float touch_major)
: id(0),
- tool_type(MotionEvent::TOOL_TYPE_UNKNOWN),
+ tool_type(MotionEvent::ToolType::UNKNOWN),
x(x),
y(y),
raw_x(x),
@@ -119,7 +119,7 @@ MotionEvent::Action MotionEventGeneric::GetAction() const {
}
int MotionEventGeneric::GetActionIndex() const {
- DCHECK(action_ == ACTION_POINTER_DOWN || action_ == ACTION_POINTER_UP);
+ DCHECK(action_ == Action::POINTER_DOWN || action_ == Action::POINTER_UP);
DCHECK_GE(action_index_, 0);
DCHECK_LT(action_index_, static_cast<int>(pointers_->size()));
return action_index_;
@@ -244,7 +244,7 @@ std::unique_ptr<MotionEventGeneric> MotionEventGeneric::CancelEvent(
bool with_history = false;
std::unique_ptr<MotionEventGeneric> cancel_event(
new MotionEventGeneric(event, with_history));
- cancel_event->set_action(ACTION_CANCEL);
+ cancel_event->set_action(Action::CANCEL);
cancel_event->set_unique_event_id(ui::GetNextTouchEventId());
return cancel_event;
}
@@ -263,7 +263,7 @@ void MotionEventGeneric::RemovePointerAt(size_t index) {
void MotionEventGeneric::PushHistoricalEvent(
std::unique_ptr<MotionEvent> event) {
DCHECK(event);
- DCHECK_EQ(event->GetAction(), ACTION_MOVE);
+ DCHECK_EQ(event->GetAction(), Action::MOVE);
DCHECK_EQ(event->GetPointerCount(), GetPointerCount());
DCHECK_EQ(event->GetAction(), GetAction());
DCHECK_LE(event->GetEventTime(), GetEventTime());
@@ -271,11 +271,10 @@ void MotionEventGeneric::PushHistoricalEvent(
}
MotionEventGeneric::MotionEventGeneric()
- : action_(ACTION_NONE),
+ : action_(Action::NONE),
unique_event_id_(ui::GetNextTouchEventId()),
action_index_(-1),
- button_state_(0) {
-}
+ button_state_(0) {}
MotionEventGeneric::MotionEventGeneric(const MotionEvent& event,
bool with_history)
@@ -283,7 +282,7 @@ MotionEventGeneric::MotionEventGeneric(const MotionEvent& event,
event_time_(event.GetEventTime()),
unique_event_id_(event.GetUniqueEventId()),
action_index_(
- (action_ == ACTION_POINTER_UP || action_ == ACTION_POINTER_DOWN)
+ (action_ == Action::POINTER_UP || action_ == Action::POINTER_DOWN)
? event.GetActionIndex()
: 0),
button_state_(event.GetButtonState()),
@@ -299,7 +298,7 @@ MotionEventGeneric::MotionEventGeneric(const MotionEvent& event,
for (size_t h = 0; h < history_size; ++h) {
std::unique_ptr<MotionEventGeneric> historical_event(
new MotionEventGeneric());
- historical_event->set_action(ACTION_MOVE);
+ historical_event->set_action(Action::MOVE);
historical_event->set_event_time(event.GetHistoricalEventTime(h));
for (size_t i = 0; i < pointer_count; ++i) {
historical_event->PushPointer(
diff --git a/chromium/ui/events/gesture_detection/motion_event_generic_unittest.cc b/chromium/ui/events/gesture_detection/motion_event_generic_unittest.cc
index 0f5b2c5ee8e..c1eb7768249 100644
--- a/chromium/ui/events/gesture_detection/motion_event_generic_unittest.cc
+++ b/chromium/ui/events/gesture_detection/motion_event_generic_unittest.cc
@@ -15,8 +15,8 @@ namespace ui {
TEST(MotionEventGenericTest, Basic) {
base::TimeTicks event_time = base::TimeTicks::Now();
- MotionEventGeneric event(
- MotionEvent::ACTION_DOWN, event_time, PointerProperties());
+ MotionEventGeneric event(MotionEvent::Action::DOWN, event_time,
+ PointerProperties());
EXPECT_EQ(1U, event.GetPointerCount());
EXPECT_EQ(0U, event.GetHistorySize());
EXPECT_EQ(event_time, event.GetEventTime());
@@ -38,8 +38,8 @@ TEST(MotionEventGenericTest, Basic) {
event.pointer(0).id = 3;
EXPECT_EQ(3, event.GetPointerId(0));
- event.set_action(MotionEvent::ACTION_POINTER_DOWN);
- EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, event.GetAction());
+ event.set_action(MotionEvent::Action::POINTER_DOWN);
+ EXPECT_EQ(MotionEvent::Action::POINTER_DOWN, event.GetAction());
event_time += base::TimeDelta::FromMilliseconds(5);
event.set_event_time(event_time);
@@ -54,16 +54,15 @@ TEST(MotionEventGenericTest, Basic) {
event.set_action_index(1);
EXPECT_EQ(1, event.GetActionIndex());
- event.set_action(MotionEvent::ACTION_MOVE);
- EXPECT_EQ(MotionEvent::ACTION_MOVE, event.GetAction());
+ event.set_action(MotionEvent::Action::MOVE);
+ EXPECT_EQ(MotionEvent::Action::MOVE, event.GetAction());
PointerProperties historical_pointer0(1.2f, 2.4f, 1.f);
PointerProperties historical_pointer1(2.4f, 4.8f, 2.f);
PointerProperties historical_pointer2(4.8f, 9.6f, 3.f);
MotionEventGeneric historical_event(
- MotionEvent::ACTION_MOVE,
- event_time - base::TimeDelta::FromMilliseconds(5),
- historical_pointer0);
+ MotionEvent::Action::MOVE,
+ event_time - base::TimeDelta::FromMilliseconds(5), historical_pointer0);
historical_event.PushPointer(historical_pointer1);
historical_event.PushPointer(historical_pointer2);
@@ -83,8 +82,7 @@ TEST(MotionEventGenericTest, Basic) {
}
TEST(MotionEventGenericTest, Clone) {
- MotionEventGeneric event(MotionEvent::ACTION_DOWN,
- base::TimeTicks::Now(),
+ MotionEventGeneric event(MotionEvent::Action::DOWN, base::TimeTicks::Now(),
PointerProperties(8.3f, 4.7f, 2.f));
event.set_button_state(MotionEvent::BUTTON_PRIMARY);
@@ -100,11 +98,11 @@ TEST(MotionEventGenericTest, CloneWithHistory) {
event_time - base::TimeDelta::FromMilliseconds(5);
PointerProperties pointer(8.3f, 4.7f, 10.1f);
- MotionEventGeneric event(MotionEvent::ACTION_MOVE, event_time, pointer);
+ MotionEventGeneric event(MotionEvent::Action::MOVE, event_time, pointer);
PointerProperties historical_pointer(3.4f, -4.3f, 11.5);
std::unique_ptr<MotionEvent> historical_event(new MotionEventGeneric(
- MotionEvent::ACTION_MOVE, historical_event_time, historical_pointer));
+ MotionEvent::Action::MOVE, historical_event_time, historical_pointer));
event.PushHistoricalEvent(std::move(historical_event));
EXPECT_EQ(1U, event.GetHistorySize());
@@ -116,13 +114,12 @@ TEST(MotionEventGenericTest, CloneWithHistory) {
}
TEST(MotionEventGenericTest, Cancel) {
- MotionEventGeneric event(MotionEvent::ACTION_UP,
- base::TimeTicks::Now(),
+ MotionEventGeneric event(MotionEvent::Action::UP, base::TimeTicks::Now(),
PointerProperties(8.7f, 4.3f, 1.f));
event.set_button_state(MotionEvent::BUTTON_SECONDARY);
std::unique_ptr<MotionEvent> cancel = event.Cancel();
- event.set_action(MotionEvent::ACTION_CANCEL);
+ event.set_action(MotionEvent::Action::CANCEL);
ASSERT_TRUE(cancel);
EXPECT_NE(event.GetUniqueEventId(), cancel->GetUniqueEventId());
EXPECT_EQ(test::ToString(event), test::ToString(*cancel));
@@ -132,7 +129,7 @@ TEST(MotionEventGenericTest, FindPointerIndexOfId) {
base::TimeTicks event_time = base::TimeTicks::Now();
PointerProperties pointer;
pointer.id = 0;
- MotionEventGeneric event0(MotionEvent::ACTION_DOWN, event_time, pointer);
+ MotionEventGeneric event0(MotionEvent::Action::DOWN, event_time, pointer);
EXPECT_EQ(0, event0.FindPointerIndexOfId(0));
EXPECT_EQ(-1, event0.FindPointerIndexOfId(1));
EXPECT_EQ(-1, event0.FindPointerIndexOfId(-1));
@@ -159,7 +156,7 @@ TEST(MotionEventGenericTest, RemovePointerAt) {
base::TimeTicks event_time = base::TimeTicks::Now();
PointerProperties pointer;
pointer.id = 0;
- MotionEventGeneric event(MotionEvent::ACTION_DOWN, event_time, pointer);
+ MotionEventGeneric event(MotionEvent::Action::DOWN, event_time, pointer);
pointer.id = 7;
EXPECT_EQ(1u, event.PushPointer(pointer));
@@ -245,19 +242,19 @@ TEST(MotionEventGenericTest, ToString) {
pointer0.touch_major = 35;
pointer0.orientation = -1;
- MotionEventGeneric event(MotionEvent::ACTION_MOVE, event_time, pointer0);
+ MotionEventGeneric event(MotionEvent::Action::MOVE, event_time, pointer0);
event.PushPointer(pointer1);
pointer0.x += 50;
pointer1.x -= 50;
std::unique_ptr<MotionEventGeneric> historical_event0(new MotionEventGeneric(
- MotionEvent::ACTION_MOVE, historical_event_time0, pointer0));
+ MotionEvent::Action::MOVE, historical_event_time0, pointer0));
historical_event0->PushPointer(pointer1);
pointer0.x += 100;
pointer1.x -= 100;
std::unique_ptr<MotionEventGeneric> historical_event1(new MotionEventGeneric(
- MotionEvent::ACTION_MOVE, historical_event_time1, pointer0));
+ MotionEvent::Action::MOVE, historical_event_time1, pointer0));
historical_event1->PushPointer(pointer1);
event.PushHistoricalEvent(std::move(historical_event0));
diff --git a/chromium/ui/events/gesture_detection/scale_gesture_detector.cc b/chromium/ui/events/gesture_detection/scale_gesture_detector.cc
index 73beab48ec6..eace042b698 100644
--- a/chromium/ui/events/gesture_detection/scale_gesture_detector.cc
+++ b/chromium/ui/events/gesture_detection/scale_gesture_detector.cc
@@ -71,7 +71,7 @@ ScaleGestureDetector::~ScaleGestureDetector() {}
bool ScaleGestureDetector::OnTouchEvent(const MotionEvent& event) {
curr_time_ = event.GetEventTime();
- const int action = event.GetAction();
+ const MotionEvent::Action action = event.GetAction();
const int count = static_cast<int>(event.GetPointerCount());
const bool is_stylus_button_down =
@@ -82,11 +82,11 @@ bool ScaleGestureDetector::OnTouchEvent(const MotionEvent& event) {
!is_stylus_button_down;
const bool stream_complete =
- action == MotionEvent::ACTION_UP ||
- action == MotionEvent::ACTION_CANCEL || anchored_scale_cancelled ||
- (action == MotionEvent::ACTION_POINTER_DOWN && InAnchoredScaleMode());
+ action == MotionEvent::Action::UP ||
+ action == MotionEvent::Action::CANCEL || anchored_scale_cancelled ||
+ (action == MotionEvent::Action::POINTER_DOWN && InAnchoredScaleMode());
- if (action == MotionEvent::ACTION_DOWN || stream_complete) {
+ if (action == MotionEvent::Action::DOWN || stream_complete) {
// Reset any scale in progress with the listener.
// If it's an ACTION_DOWN we're beginning a new event stream.
// This means the app probably didn't give us all the events. Shame on it.
@@ -110,12 +110,12 @@ bool ScaleGestureDetector::OnTouchEvent(const MotionEvent& event) {
initial_span_ = 0;
}
- const bool config_changed = action == MotionEvent::ACTION_DOWN ||
- action == MotionEvent::ACTION_POINTER_UP ||
- action == MotionEvent::ACTION_POINTER_DOWN ||
+ const bool config_changed = action == MotionEvent::Action::DOWN ||
+ action == MotionEvent::Action::POINTER_UP ||
+ action == MotionEvent::Action::POINTER_DOWN ||
anchored_scale_cancelled;
- const bool pointer_up = action == MotionEvent::ACTION_POINTER_UP;
+ const bool pointer_up = action == MotionEvent::Action::POINTER_UP;
const int skip_index = pointer_up ? event.GetActionIndex() : -1;
// Determine focal point.
@@ -210,7 +210,7 @@ bool ScaleGestureDetector::OnTouchEvent(const MotionEvent& event) {
}
// Handle motion; focal point and span/scale factor are changing.
- if (action == MotionEvent::ACTION_MOVE) {
+ if (action == MotionEvent::Action::MOVE) {
curr_span_x_ = span_x;
curr_span_y_ = span_y;
curr_span_ = span;
diff --git a/chromium/ui/events/gesture_detection/scale_gesture_detector.h b/chromium/ui/events/gesture_detection/scale_gesture_detector.h
index 38038bd2538..9a407854205 100644
--- a/chromium/ui/events/gesture_detection/scale_gesture_detector.h
+++ b/chromium/ui/events/gesture_detection/scale_gesture_detector.h
@@ -50,8 +50,8 @@ class GESTURE_DETECTION_EXPORT ScaleGestureDetector {
//
// Note: Applications should pass a complete and consistent event stream to
// this method. A complete and consistent event stream involves all
- // MotionEvents from the initial ACTION_DOWN to the final ACTION_UP or
- // ACTION_CANCEL.
+ // MotionEvents from the initial Action::DOWN to the final Action::UP or
+ // Action::CANCEL.
//
// Returns true if the event was processed and the detector wants to receive
// the rest of the MotionEvents in this event stream.
diff --git a/chromium/ui/events/gesture_detection/snap_scroll_controller.cc b/chromium/ui/events/gesture_detection/snap_scroll_controller.cc
index b50971d3e8f..a393c2e349d 100644
--- a/chromium/ui/events/gesture_detection/snap_scroll_controller.cc
+++ b/chromium/ui/events/gesture_detection/snap_scroll_controller.cc
@@ -51,12 +51,12 @@ void SnapScrollController::SetSnapScrollMode(
const MotionEvent& event,
bool is_scale_gesture_detection_in_progress) {
switch (event.GetAction()) {
- case MotionEvent::ACTION_DOWN:
+ case MotionEvent::Action::DOWN:
mode_ = SNAP_PENDING;
down_position_.set_x(event.GetX());
down_position_.set_y(event.GetY());
break;
- case MotionEvent::ACTION_MOVE: {
+ case MotionEvent::Action::MOVE: {
if (is_scale_gesture_detection_in_progress)
break;
@@ -80,8 +80,8 @@ void SnapScrollController::SetSnapScrollMode(
if (mode_ == SNAP_PENDING && dx > kMaxSnapBound && dy > kMaxSnapBound)
mode_ = SNAP_NONE;
} break;
- case MotionEvent::ACTION_UP:
- case MotionEvent::ACTION_CANCEL:
+ case MotionEvent::Action::UP:
+ case MotionEvent::Action::CANCEL:
down_position_ = gfx::PointF();
accumulated_distance_ = gfx::Vector2dF();
break;
diff --git a/chromium/ui/events/gesture_detection/touch_disposition_gesture_filter.cc b/chromium/ui/events/gesture_detection/touch_disposition_gesture_filter.cc
index a23bc35a4e8..4490825b526 100644
--- a/chromium/ui/events/gesture_detection/touch_disposition_gesture_filter.cc
+++ b/chromium/ui/events/gesture_detection/touch_disposition_gesture_filter.cc
@@ -139,7 +139,7 @@ TouchDispositionGestureFilter::TouchDispositionGestureFilter(
TouchDispositionGestureFilterClient* client)
: client_(client),
ending_event_motion_event_id_(0),
- ending_event_primary_tool_type_(MotionEvent::TOOL_TYPE_UNKNOWN),
+ ending_event_primary_tool_type_(MotionEvent::ToolType::UNKNOWN),
needs_tap_ending_event_(false),
needs_show_press_event_(false),
needs_fling_ending_event_(false),
diff --git a/chromium/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc b/chromium/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
index 613cc75d0fd..c2c26616d0f 100644
--- a/chromium/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
+++ b/chromium/ui/events/gesture_detection/touch_disposition_gesture_filter_unittest.cc
@@ -275,7 +275,7 @@ class TouchDispositionGestureFilterTest
GestureEventDetails details(type);
details.set_device_type(GestureDeviceType::DEVICE_TOUCHSCREEN);
return GestureEventData(
- details, 0, MotionEvent::TOOL_TYPE_FINGER, base::TimeTicks(), x, y, 0,
+ details, 0, MotionEvent::ToolType::FINGER, base::TimeTicks(), x, y, 0,
0, 1,
gfx::RectF(x - diameter / 2, y - diameter / 2, diameter, diameter),
kDefaultEventFlags, 0U);
diff --git a/chromium/ui/events/gesture_detection/velocity_tracker.cc b/chromium/ui/events/gesture_detection/velocity_tracker.cc
index 4094525c2b6..b0f984026e4 100644
--- a/chromium/ui/events/gesture_detection/velocity_tracker.cc
+++ b/chromium/ui/events/gesture_detection/velocity_tracker.cc
@@ -36,16 +36,16 @@ namespace {
static_assert(MotionEvent::MAX_POINTER_ID < 32, "max pointer id too large");
-// Threshold between ACTION_MOVE events for determining that a pointer has
-// stopped moving. Some input devices do not send ACTION_MOVE events in the case
-// where a pointer has stopped. We need to detect this case so that we can
+// Threshold between Action::MOVE events for determining that a pointer has
+// stopped moving. Some input devices do not send Action::MOVE events in the
+// case where a pointer has stopped. We need to detect this case so that we can
// accurately predict the velocity after the pointer starts moving again.
const int kAssumePointerMoveStoppedTimeMs = 40;
-// Threshold between ACTION_MOVE and ACTION_{UP|POINTER_UP} events for
+// Threshold between Action::MOVE and Action::{UP|POINTER_UP} events for
// determining that a pointer has stopped moving. This is a larger threshold
// than |kAssumePointerMoveStoppedTimeMs|, as some devices may delay synthesis
-// of ACTION_{UP|POINTER_UP} to reduce risk of noisy release.
+// of Action::{UP|POINTER_UP} to reduce risk of noisy release.
const int kAssumePointerUpStoppedTimeMs = 80;
struct Position {
@@ -297,15 +297,13 @@ void VelocityTracker::AddMovement(const TimeTicks& event_time,
}
void VelocityTracker::AddMovement(const MotionEvent& event) {
- int32_t actionMasked = event.GetAction();
-
- switch (actionMasked) {
- case MotionEvent::ACTION_DOWN:
+ switch (event.GetAction()) {
+ case MotionEvent::Action::DOWN:
// case MotionEvent::HOVER_ENTER:
// Clear all pointers on down before adding the new movement.
Clear();
break;
- case MotionEvent::ACTION_POINTER_DOWN: {
+ case MotionEvent::Action::POINTER_DOWN: {
// Start a new movement trace for a pointer that just went down.
// We do this on down instead of on up because the client may want to
// query the final velocity for a pointer that just went up.
@@ -314,20 +312,20 @@ void VelocityTracker::AddMovement(const MotionEvent& event) {
ClearPointers(downIdBits);
break;
}
- case MotionEvent::ACTION_MOVE:
- // case MotionEvent::ACTION_HOVER_MOVE:
+ case MotionEvent::Action::MOVE:
+ // case MotionEvent::Action::HOVER_MOVE:
break;
- case MotionEvent::ACTION_UP:
- case MotionEvent::ACTION_POINTER_UP:
- // Note that ACTION_UP and ACTION_POINTER_UP always report the last known
- // position of the pointers that went up. ACTION_POINTER_UP does include
- // the new position of pointers that remained down but we will also
- // receive an ACTION_MOVE with this information if any of them actually
- // moved. Since we don't know how many pointers will be going up at once
- // it makes sense to just wait for the following ACTION_MOVE before adding
- // the movement. However, if the up event itself is delayed because of
- // (difficult albeit possible) prolonged stationary screen contact, assume
- // that motion has stopped.
+ case MotionEvent::Action::UP:
+ case MotionEvent::Action::POINTER_UP:
+ // Note that Action::UP and Action::POINTER_UP always report the last
+ // known position of the pointers that went up. Action::POINTER_UP does
+ // include the new position of pointers that remained down but we will
+ // also receive an Action::MOVE with this information if any of them
+ // actually moved. Since we don't know how many pointers will be going up
+ // at once it makes sense to just wait for the following Action::MOVE
+ // before adding the movement. However, if the up event itself is delayed
+ // because of (difficult albeit possible) prolonged stationary screen
+ // contact, assume that motion has stopped.
if ((event.GetEventTime() - last_event_time_) >=
base::TimeDelta::FromMilliseconds(kAssumePointerUpStoppedTimeMs))
strategy_->Clear();
diff --git a/chromium/ui/events/gesture_detection/velocity_tracker_unittest.cc b/chromium/ui/events/gesture_detection/velocity_tracker_unittest.cc
index a8e2880d3e4..e828d351afa 100644
--- a/chromium/ui/events/gesture_detection/velocity_tracker_unittest.cc
+++ b/chromium/ui/events/gesture_detection/velocity_tracker_unittest.cc
@@ -68,9 +68,9 @@ class VelocityTrackerTest : public testing::Test {
if (!samples)
return;
const base::TimeDelta dt = t / samples;
- state->AddMovement(Sample(MotionEvent::ACTION_DOWN, p0, t0, v, dt * 0));
+ state->AddMovement(Sample(MotionEvent::Action::DOWN, p0, t0, v, dt * 0));
ApplyMovement(state, p0, v, t0, t, samples);
- state->AddMovement(Sample(MotionEvent::ACTION_UP, p0, t0, v, t));
+ state->AddMovement(Sample(MotionEvent::Action::UP, p0, t0, v, t));
}
static void ApplyMovement(VelocityTrackerState* state,
@@ -84,7 +84,7 @@ class VelocityTrackerTest : public testing::Test {
return;
const base::TimeDelta dt = t / samples;
for (size_t i = 0; i < samples; ++i)
- state->AddMovement(Sample(MotionEvent::ACTION_MOVE, p0, t0, v, dt * i));
+ state->AddMovement(Sample(MotionEvent::Action::MOVE, p0, t0, v, dt * i));
}
};
@@ -159,7 +159,7 @@ TEST_F(VelocityTrackerTest, VaryingVelocity) {
base::TimeTicks t0 = base::TimeTicks::Now();
base::TimeDelta dt = kTenMillis * 10;
state.AddMovement(
- Sample(MotionEvent::ACTION_DOWN, p0, t0, vFast, base::TimeDelta()));
+ Sample(MotionEvent::Action::DOWN, p0, t0, vFast, base::TimeDelta()));
// Apply some fast movement and compute the velocity.
gfx::PointF pCurr = p0;
@@ -202,7 +202,7 @@ TEST_F(VelocityTrackerTest, DelayedActionUp) {
VelocityTrackerState state(VelocityTracker::Strategy::LSQ2);
state.AddMovement(
- Sample(MotionEvent::ACTION_DOWN, p0, t0, v, base::TimeDelta()));
+ Sample(MotionEvent::Action::DOWN, p0, t0, v, base::TimeDelta()));
// Apply the movement and verify a (non-zero) velocity.
ApplyMovement(&state, p0, v, t0, dt, samples);
@@ -210,11 +210,11 @@ TEST_F(VelocityTrackerTest, DelayedActionUp) {
EXPECT_NEAR(-1000, state.GetXVelocity(0), kEpsilson);
EXPECT_NEAR(1000, state.GetYVelocity(0), kEpsilson);
- // Apply the delayed ACTION_UP.
+ // Apply the delayed Action::UP.
const gfx::PointF p1 = p0 + ScaleVector2d(v, dt.InSecondsF());
const base::TimeTicks t1 = t0 + dt + kTenMillis * 10;
- state.AddMovement(Sample(
- MotionEvent::ACTION_UP, p1, t1, v, base::TimeDelta()));
+ state.AddMovement(
+ Sample(MotionEvent::Action::UP, p1, t1, v, base::TimeDelta()));
// The tracked velocity should have been reset.
state.ComputeCurrentVelocity(1000, 1000);
@@ -234,14 +234,14 @@ TEST_F(VelocityTrackerTest, NoDirectionReversal) {
gfx::PointF p(0, 0);
- MockMotionEvent m1(MotionEvent::ACTION_DOWN, t0, p.x(), p.y());
+ MockMotionEvent m1(MotionEvent::Action::DOWN, t0, p.x(), p.y());
state_unrestricted.AddMovement(m1);
state_restricted.AddMovement(m1);
for (size_t i = 0; i < samples; ++i) {
if (i < 50)
p.set_y(p.y() + 10);
- MockMotionEvent mi(MotionEvent::ACTION_MOVE, t0 + dt * i, p.x(), p.y());
+ MockMotionEvent mi(MotionEvent::Action::MOVE, t0 + dt * i, p.x(), p.y());
state_unrestricted.AddMovement(mi);
state_restricted.AddMovement(mi);
}
diff --git a/chromium/ui/events/gesture_event_details.cc b/chromium/ui/events/gesture_event_details.cc
index 8f422cbfc6f..2de5edbbbc6 100644
--- a/chromium/ui/events/gesture_event_details.cc
+++ b/chromium/ui/events/gesture_event_details.cc
@@ -79,6 +79,7 @@ GestureEventDetails::GestureEventDetails(ui::EventType type,
// allowed as an exception.
if (other.type() == ui::ET_GESTURE_PINCH_BEGIN)
break;
+ FALLTHROUGH;
case ui::ET_GESTURE_SCROLL_UPDATE:
case ui::ET_SCROLL_FLING_START:
case ui::ET_GESTURE_SWIPE:
diff --git a/chromium/ui/events/gestures/blink/web_gesture_curve_impl.cc b/chromium/ui/events/gestures/blink/web_gesture_curve_impl.cc
index 65f680e7f83..b2aec0cbeb1 100644
--- a/chromium/ui/events/gestures/blink/web_gesture_curve_impl.cc
+++ b/chromium/ui/events/gestures/blink/web_gesture_curve_impl.cc
@@ -24,6 +24,10 @@
#include "ui/events/android/scroller.h"
#endif
+#if !defined(OS_ANDROID) && defined(CHROMECAST_BUILD)
+#include "ui/events/chromecast/scroller.h"
+#endif
+
using blink::WebGestureCurve;
namespace ui {
@@ -37,7 +41,7 @@ std::unique_ptr<GestureCurve> CreateDefaultPlatformCurve(
base::TimeTicks());
}
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(CHROMECAST_BUILD)
auto scroller = std::make_unique<Scroller>(Scroller::Config());
scroller->Fling(0,
0,
diff --git a/chromium/ui/events/gestures/motion_event_aura.cc b/chromium/ui/events/gestures/motion_event_aura.cc
index 50032936b65..12acaec437a 100644
--- a/chromium/ui/events/gestures/motion_event_aura.cc
+++ b/chromium/ui/events/gestures/motion_event_aura.cc
@@ -14,18 +14,18 @@ MotionEvent::ToolType EventPointerTypeToMotionEventToolType(
EventPointerType type) {
switch (type) {
case EventPointerType::POINTER_TYPE_UNKNOWN:
- return MotionEvent::TOOL_TYPE_UNKNOWN;
+ return MotionEvent::ToolType::UNKNOWN;
case EventPointerType::POINTER_TYPE_MOUSE:
- return MotionEvent::TOOL_TYPE_MOUSE;
+ return MotionEvent::ToolType::MOUSE;
case EventPointerType::POINTER_TYPE_PEN:
- return MotionEvent::TOOL_TYPE_STYLUS;
+ return MotionEvent::ToolType::STYLUS;
case EventPointerType::POINTER_TYPE_TOUCH:
- return MotionEvent::TOOL_TYPE_FINGER;
+ return MotionEvent::ToolType::FINGER;
case EventPointerType::POINTER_TYPE_ERASER:
- return MotionEvent::TOOL_TYPE_ERASER;
+ return MotionEvent::ToolType::ERASER;
}
- return MotionEvent::TOOL_TYPE_UNKNOWN;
+ return MotionEvent::ToolType::UNKNOWN;
}
PointerProperties GetPointerPropertiesFromTouchEvent(const TouchEvent& touch) {
@@ -96,6 +96,7 @@ bool MotionEventAura::OnTouch(const TouchEvent& touch) {
case ET_TOUCH_PRESSED:
if (!AddTouch(touch))
return false;
+ FALLTHROUGH;
case ET_TOUCH_RELEASED:
case ET_TOUCH_CANCELLED:
// Removing these touch points needs to be postponed until after the
@@ -127,7 +128,7 @@ void MotionEventAura::CleanupRemovedTouchPoints(const TouchEvent& event) {
DCHECK(GetPointerCount());
int index_to_delete = GetIndexFromId(event.pointer_details().id);
set_action_index(-1);
- set_action(MotionEvent::ACTION_NONE);
+ set_action(MotionEvent::Action::NONE);
pointer(index_to_delete) = pointer(GetPointerCount() - 1);
PopPointer();
}
@@ -155,25 +156,25 @@ void MotionEventAura::UpdateCachedAction(const TouchEvent& touch) {
switch (touch.type()) {
case ET_TOUCH_PRESSED:
if (GetPointerCount() == 1) {
- set_action(ACTION_DOWN);
+ set_action(Action::DOWN);
} else {
- set_action(ACTION_POINTER_DOWN);
+ set_action(Action::POINTER_DOWN);
set_action_index(GetIndexFromId(touch.pointer_details().id));
}
break;
case ET_TOUCH_RELEASED:
if (GetPointerCount() == 1) {
- set_action(ACTION_UP);
+ set_action(Action::UP);
} else {
- set_action(ACTION_POINTER_UP);
+ set_action(Action::POINTER_UP);
set_action_index(GetIndexFromId(touch.pointer_details().id));
}
break;
case ET_TOUCH_CANCELLED:
- set_action(ACTION_CANCEL);
+ set_action(Action::CANCEL);
break;
case ET_TOUCH_MOVED:
- set_action(ACTION_MOVE);
+ set_action(Action::MOVE);
break;
default:
NOTREACHED();
diff --git a/chromium/ui/events/gestures/motion_event_aura_unittest.cc b/chromium/ui/events/gestures/motion_event_aura_unittest.cc
index 534013d9cfa..276876f2059 100644
--- a/chromium/ui/events/gestures/motion_event_aura_unittest.cc
+++ b/chromium/ui/events/gestures/motion_event_aura_unittest.cc
@@ -257,7 +257,7 @@ TEST(MotionEventAuraTest, TapParams) {
EXPECT_FLOAT_EQ(radius_y, event.GetTouchMinor(0) / 2);
EXPECT_FLOAT_EQ(rotation_angle, gfx::RadToDeg(event.GetOrientation(0)) + 90);
EXPECT_FLOAT_EQ(pressure, event.GetPressure(0));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(0));
+ EXPECT_EQ(MotionEvent::ToolType::FINGER, event.GetToolType(0));
// Test case: radius_x < radius_y, rotation_angle < 90
radius_x = 67.89f;
@@ -273,7 +273,7 @@ TEST(MotionEventAuraTest, TapParams) {
EXPECT_FLOAT_EQ(radius_x, event.GetTouchMinor(1) / 2);
EXPECT_FLOAT_EQ(rotation_angle, gfx::RadToDeg(event.GetOrientation(1)));
EXPECT_FLOAT_EQ(pressure, event.GetPressure(1));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(1));
+ EXPECT_EQ(MotionEvent::ToolType::FINGER, event.GetToolType(1));
// Test cloning of tap params
// TODO(mustaq): Make a separate clone test, crbug.com/450655
@@ -285,7 +285,7 @@ TEST(MotionEventAuraTest, TapParams) {
EXPECT_FLOAT_EQ(radius_x, clone->GetTouchMinor(1) / 2);
EXPECT_FLOAT_EQ(rotation_angle, gfx::RadToDeg(clone->GetOrientation(1)));
EXPECT_FLOAT_EQ(pressure, clone->GetPressure(1));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, clone->GetToolType(1));
+ EXPECT_EQ(MotionEvent::ToolType::FINGER, clone->GetToolType(1));
// TODO(mustaq): The move test seems out-of-scope here, crbug.com/450655
radius_x = 76.98f;
@@ -302,7 +302,7 @@ TEST(MotionEventAuraTest, TapParams) {
EXPECT_FLOAT_EQ(radius_x, event.GetTouchMinor(1) / 2);
EXPECT_FLOAT_EQ(rotation_angle, gfx::RadToDeg(event.GetOrientation(1)));
EXPECT_FLOAT_EQ(pressure, event.GetPressure(1));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(1));
+ EXPECT_EQ(MotionEvent::ToolType::FINGER, event.GetToolType(1));
// Test case: radius_x > radius_y, rotation_angle > 90
radius_x = 123.45f;
@@ -318,7 +318,7 @@ TEST(MotionEventAuraTest, TapParams) {
EXPECT_FLOAT_EQ(radius_y, event.GetTouchMinor(2) / 2);
EXPECT_FLOAT_EQ(rotation_angle, gfx::RadToDeg(event.GetOrientation(2)) + 90);
EXPECT_FLOAT_EQ(pressure, event.GetPressure(2));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(2));
+ EXPECT_EQ(MotionEvent::ToolType::FINGER, event.GetToolType(2));
// Test case: radius_x < radius_y, rotation_angle > 90
radius_x = 67.89f;
@@ -334,7 +334,7 @@ TEST(MotionEventAuraTest, TapParams) {
EXPECT_FLOAT_EQ(radius_x, event.GetTouchMinor(3) / 2);
EXPECT_FLOAT_EQ(rotation_angle, gfx::RadToDeg(event.GetOrientation(3)) + 180);
EXPECT_FLOAT_EQ(pressure, event.GetPressure(3));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(3));
+ EXPECT_EQ(MotionEvent::ToolType::FINGER, event.GetToolType(3));
}
TEST(MotionEventAuraTest, Timestamps) {
@@ -371,36 +371,36 @@ TEST(MotionEventAuraTest, CachedAction) {
TouchEvent press0 = TouchWithType(ET_TOUCH_PRESSED, ids[0]);
EXPECT_TRUE(event.OnTouch(press0));
- EXPECT_EQ(MotionEvent::ACTION_DOWN, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::DOWN, event.GetAction());
EXPECT_EQ(1U, event.GetPointerCount());
TouchEvent press1 = TouchWithType(ET_TOUCH_PRESSED, ids[1]);
EXPECT_TRUE(event.OnTouch(press1));
- EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::POINTER_DOWN, event.GetAction());
EXPECT_EQ(1, event.GetActionIndex());
EXPECT_EQ(2U, event.GetPointerCount());
// Test cloning of CachedAction information.
std::unique_ptr<MotionEvent> clone = event.Clone();
- EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, clone->GetAction());
+ EXPECT_EQ(MotionEvent::Action::POINTER_DOWN, clone->GetAction());
EXPECT_EQ(1, clone->GetActionIndex());
TouchEvent move0 = TouchWithType(ET_TOUCH_MOVED, ids[0]);
move0.set_location(gfx::Point(10, 12));
EXPECT_TRUE(event.OnTouch(move0));
- EXPECT_EQ(MotionEvent::ACTION_MOVE, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::MOVE, event.GetAction());
EXPECT_EQ(2U, event.GetPointerCount());
TouchEvent release0 = TouchWithType(ET_TOUCH_RELEASED, ids[0]);
EXPECT_TRUE(event.OnTouch(release0));
- EXPECT_EQ(MotionEvent::ACTION_POINTER_UP, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::POINTER_UP, event.GetAction());
EXPECT_EQ(2U, event.GetPointerCount());
event.CleanupRemovedTouchPoints(release0);
EXPECT_EQ(1U, event.GetPointerCount());
TouchEvent release1 = TouchWithType(ET_TOUCH_RELEASED, ids[1]);
EXPECT_TRUE(event.OnTouch(release1));
- EXPECT_EQ(MotionEvent::ACTION_UP, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::UP, event.GetAction());
EXPECT_EQ(1U, event.GetPointerCount());
event.CleanupRemovedTouchPoints(release1);
EXPECT_EQ(0U, event.GetPointerCount());
@@ -412,17 +412,17 @@ TEST(MotionEventAuraTest, Cancel) {
TouchEvent press0 = TouchWithType(ET_TOUCH_PRESSED, ids[0]);
EXPECT_TRUE(event.OnTouch(press0));
- EXPECT_EQ(MotionEvent::ACTION_DOWN, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::DOWN, event.GetAction());
EXPECT_EQ(1U, event.GetPointerCount());
TouchEvent press1 = TouchWithType(ET_TOUCH_PRESSED, ids[1]);
EXPECT_TRUE(event.OnTouch(press1));
- EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::POINTER_DOWN, event.GetAction());
EXPECT_EQ(1, event.GetActionIndex());
EXPECT_EQ(2U, event.GetPointerCount());
std::unique_ptr<MotionEvent> cancel = event.Cancel();
- EXPECT_EQ(MotionEvent::ACTION_CANCEL, cancel->GetAction());
+ EXPECT_EQ(MotionEvent::Action::CANCEL, cancel->GetAction());
EXPECT_EQ(2U, cancel->GetPointerCount());
}
@@ -431,7 +431,7 @@ TEST(MotionEventAuraTest, ToolType) {
TouchEvent touch_event = TouchWithType(ET_TOUCH_PRESSED, 7);
EXPECT_TRUE(event.OnTouch(touch_event));
ASSERT_EQ(1U, event.GetPointerCount());
- EXPECT_EQ(MotionEvent::TOOL_TYPE_FINGER, event.GetToolType(0));
+ EXPECT_EQ(MotionEvent::ToolType::FINGER, event.GetToolType(0));
touch_event = TouchWithType(ET_TOUCH_RELEASED, 7);
PointerDetails pointer_details(EventPointerType::POINTER_TYPE_PEN,
@@ -441,7 +441,7 @@ TEST(MotionEventAuraTest, ToolType) {
/* force */ 1.0f);
touch_event.SetPointerDetailsForTest(pointer_details);
EXPECT_TRUE(event.OnTouch(touch_event));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_STYLUS, event.GetToolType(0));
+ EXPECT_EQ(MotionEvent::ToolType::STYLUS, event.GetToolType(0));
}
TEST(MotionEventAuraTest, Flags) {
@@ -501,13 +501,13 @@ TEST(MotionEventAuraTest, UniqueEventID) {
TouchEvent press0 = TouchWithType(ET_TOUCH_PRESSED, 3);
EXPECT_TRUE(event.OnTouch(press0));
- EXPECT_EQ(MotionEvent::ACTION_DOWN, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::DOWN, event.GetAction());
ASSERT_EQ(1U, event.GetPointerCount());
EXPECT_EQ(event.GetUniqueEventId(), press0.unique_event_id());
TouchEvent press1 = TouchWithType(ET_TOUCH_PRESSED, 6);
EXPECT_TRUE(event.OnTouch(press1));
- EXPECT_EQ(MotionEvent::ACTION_POINTER_DOWN, event.GetAction());
+ EXPECT_EQ(MotionEvent::Action::POINTER_DOWN, event.GetAction());
EXPECT_EQ(2U, event.GetPointerCount());
EXPECT_EQ(event.GetUniqueEventId(), press1.unique_event_id());
}
@@ -543,7 +543,7 @@ TEST(MotionEventAuraTest, PenRadiusDefault) {
ET_TOUCH_PRESSED, gfx::Point(0, 0), base::TimeTicks(),
ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_PEN, 7));
EXPECT_TRUE(event.OnTouch(touch_event));
- EXPECT_EQ(MotionEvent::TOOL_TYPE_STYLUS, event.GetToolType(0));
+ EXPECT_EQ(MotionEvent::ToolType::STYLUS, event.GetToolType(0));
EXPECT_EQ(1u, event.GetTouchMajor(0));
EXPECT_EQ(1u, event.GetTouchMinor(0));
}
diff --git a/chromium/ui/events/keyboard_hook.h b/chromium/ui/events/keyboard_hook.h
new file mode 100644
index 00000000000..32f05492772
--- /dev/null
+++ b/chromium/ui/events/keyboard_hook.h
@@ -0,0 +1,40 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_EVENTS_KEYBOARD_HOOK_H_
+#define UI_EVENTS_KEYBOARD_HOOK_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/containers/flat_set.h"
+#include "base/optional.h"
+#include "ui/events/events_export.h"
+
+namespace ui {
+
+class KeyEvent;
+
+// Intercepts keyboard events typically handled by the OS or browser.
+// Destroying the instance will unregister and clean up the keyboard hook.
+class EVENTS_EXPORT KeyboardHook {
+ public:
+ using KeyEventCallback = base::RepeatingCallback<void(KeyEvent* event)>;
+
+ virtual ~KeyboardHook() = default;
+
+ // Creates a platform specific implementation.
+ // |native_key_codes| is the set of key codes which will be intercepted, if
+ // it is empty, this class will attempt to intercept all keys.
+ // |callback| is called for each key which is intercepted.
+ // Returns a valid instance if the hook was created and successfully
+ // registered otherwise nullptr.
+ static std::unique_ptr<KeyboardHook> Create(
+ base::Optional<base::flat_set<int>> native_key_codes,
+ KeyEventCallback callback);
+};
+
+} // namespace ui
+
+#endif // UI_EVENTS_KEYBOARD_HOOK_H_
diff --git a/chromium/ui/events/keyboard_hook_base.cc b/chromium/ui/events/keyboard_hook_base.cc
new file mode 100644
index 00000000000..d9a7938ff30
--- /dev/null
+++ b/chromium/ui/events/keyboard_hook_base.cc
@@ -0,0 +1,34 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/keyboard_hook_base.h"
+
+#include <utility>
+
+#include "base/macros.h"
+#include "base/stl_util.h"
+#include "ui/events/event.h"
+
+namespace ui {
+
+KeyboardHookBase::KeyboardHookBase(
+ base::Optional<base::flat_set<int>> native_key_codes,
+ KeyEventCallback callback)
+ : key_event_callback_(std::move(callback)),
+ key_codes_(std::move(native_key_codes)) {
+ DCHECK(key_event_callback_);
+}
+
+KeyboardHookBase::~KeyboardHookBase() = default;
+
+bool KeyboardHookBase::ShouldCaptureKeyEvent(int key_code) const {
+ return !key_codes_ || base::ContainsKey(key_codes_.value(), key_code);
+}
+
+void KeyboardHookBase::ForwardCapturedKeyEvent(
+ std::unique_ptr<KeyEvent> event) {
+ key_event_callback_.Run(event.get());
+}
+
+} // namespace ui
diff --git a/chromium/ui/events/keyboard_hook_base.h b/chromium/ui/events/keyboard_hook_base.h
new file mode 100644
index 00000000000..428c24fa077
--- /dev/null
+++ b/chromium/ui/events/keyboard_hook_base.h
@@ -0,0 +1,42 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_EVENTS_KEYBOARD_HOOK_BASE_H_
+#define UI_EVENTS_KEYBOARD_HOOK_BASE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "ui/events/keyboard_hook.h"
+
+namespace ui {
+
+class KeyEvent;
+
+class KeyboardHookBase : public KeyboardHook {
+ public:
+ KeyboardHookBase(base::Optional<base::flat_set<int>> native_key_codes,
+ KeyEventCallback callback);
+ ~KeyboardHookBase() override;
+
+ protected:
+ // Indicates whether |key_code| should be intercepted by the keyboard hook.
+ bool ShouldCaptureKeyEvent(int key_code) const;
+
+ // Forwards the key event using |key_event_callback_|.
+ void ForwardCapturedKeyEvent(std::unique_ptr<KeyEvent> event);
+
+ private:
+ // Used to forward key events.
+ KeyEventCallback key_event_callback_;
+
+ // The set of keys which should be intercepted by the keyboard hook.
+ base::Optional<base::flat_set<int>> key_codes_;
+
+ DISALLOW_COPY_AND_ASSIGN(KeyboardHookBase);
+};
+
+} // namespace ui
+
+#endif // UI_EVENTS_KEYBOARD_HOOK_BASE_H_
diff --git a/chromium/ui/events/keycodes/keyboard_code_conversion_android.cc b/chromium/ui/events/keycodes/keyboard_code_conversion_android.cc
index 5baef1990a9..f65db2b5e08 100644
--- a/chromium/ui/events/keycodes/keyboard_code_conversion_android.cc
+++ b/chromium/ui/events/keycodes/keyboard_code_conversion_android.cc
@@ -284,7 +284,7 @@ DomKey GetDomKeyFromAndroidKeycode(int keycode) {
case AKEYCODE_KATAKANA_HIRAGANA:
return DomKey::HIRAGANA_KATAKANA;
case AKEYCODE_KANA:
- return DomKey::KANA_MODE;
+ return DomKey::KANJI_MODE;
case AKEYCODE_BRIGHTNESS_DOWN:
return DomKey::BRIGHTNESS_DOWN;
case AKEYCODE_BRIGHTNESS_UP:
@@ -379,6 +379,8 @@ DomKey GetDomKeyFromAndroidKeycode(int keycode) {
return DomKey::COPY;
case AKEYCODE_PASTE:
return DomKey::PASTE;
+ case AKEYCODE_DVR:
+ return DomKey::DVR;
// The following codes should already be handled as printable
// character mapping.
@@ -479,7 +481,6 @@ DomKey GetDomKeyFromAndroidKeycode(int keycode) {
// case AKEYCODE_BUTTON_SELECT:
// case AKEYCODE_BUTTON_MODE:
// case AKEYCODE_WINDOW:
- // case AKEYCODE_DVR:
// case AKEYCODE_BUTTON_1:
// case AKEYCODE_BUTTON_2:
// case AKEYCODE_BUTTON_3:
diff --git a/chromium/ui/events/keycodes/keyboard_code_conversion_xkb.cc b/chromium/ui/events/keycodes/keyboard_code_conversion_xkb.cc
index 836f7829fff..4b95e75a497 100644
--- a/chromium/ui/events/keycodes/keyboard_code_conversion_xkb.cc
+++ b/chromium/ui/events/keycodes/keyboard_code_conversion_xkb.cc
@@ -110,8 +110,10 @@ DomKey NonPrintableXKeySymToDomKey(xkb_keysym_t keysym) {
return DomKey::END;
case XKB_KEY_Select:
return DomKey::SELECT;
+ // Treat Print/PrintScreen as PrintScreen https://crbug.com/683097.
case XKB_KEY_Print:
- return DomKey::PRINT;
+ case XKB_KEY_3270_PrintScreen:
+ return DomKey::PRINT_SCREEN;
case XKB_KEY_Execute:
return DomKey::EXECUTE;
case XKB_KEY_Insert:
@@ -357,8 +359,6 @@ DomKey NonPrintableXKeySymToDomKey(xkb_keysym_t keysym) {
return DomKey::EX_SEL;
case XKB_KEY_3270_CursorSelect:
return DomKey::CR_SEL;
- case XKB_KEY_3270_PrintScreen:
- return DomKey::PRINT_SCREEN;
case XKB_KEY_ISO_Level3_Shift:
return DomKey::ALT_GRAPH;
case XKB_KEY_ISO_Level3_Latch:
diff --git a/chromium/ui/events/keycodes/platform_key_map_win.cc b/chromium/ui/events/keycodes/platform_key_map_win.cc
index bd1dfcc7549..d7ecacc8553 100644
--- a/chromium/ui/events/keycodes/platform_key_map_win.cc
+++ b/chromium/ui/events/keycodes/platform_key_map_win.cc
@@ -65,10 +65,6 @@ bool HasControlAndAlt(int flags) {
return (flags & kControlAndAltFlags) == kControlAndAltFlags;
}
-int SetControlAndAltToAltGraph(int flags) {
- return (flags & ~kControlAndAltFlags) | EF_ALTGR_DOWN;
-}
-
int ReplaceAltGraphWithControlAndAlt(int flags) {
return (flags & EF_ALTGR_DOWN)
? ((flags & ~EF_ALTGR_DOWN) | kControlAndAltFlags)
@@ -322,12 +318,10 @@ DomKey PlatformKeyMap::DomKeyFromKeyboardCodeImpl(KeyboardCode key_code,
if (it != printable_keycode_to_key_.end()) {
key = it->second;
if (key != DomKey::NONE) {
- // TODO(25503): Map Ctrl+Alt to AltGraph if new behaviour is enabled.
- if (HasControlAndAlt(try_flags) &&
- base::FeatureList::IsEnabled(kFixAltGraphModifier)) {
- // Printable character generated via Control+Alt means AltGraph.
- *flags = SetControlAndAltToAltGraph(*flags);
- }
+ // If we find a character with |try_flags| including Control and Alt
+ // then this is an AltGraph-shifted event.
+ if (HasControlAndAlt(try_flags))
+ *flags = ReplaceControlAndAltWithAltGraph(*flags);
return key;
}
}
@@ -362,6 +356,15 @@ DomKey PlatformKeyMap::DomKeyFromKeyboardCode(KeyboardCode key_code,
}
// static
+int PlatformKeyMap::ReplaceControlAndAltWithAltGraph(int flags) {
+ if (!HasControlAndAlt(flags))
+ return flags;
+ if (!IsFixAltGraphEnabled())
+ return flags;
+ return (flags & ~kControlAndAltFlags) | EF_ALTGR_DOWN;
+}
+
+// static
bool PlatformKeyMap::UsesAltGraph() {
base::ThreadLocalStorage::Slot* platform_key_map_tls =
g_platform_key_map_tls_lazy.Pointer();
diff --git a/chromium/ui/events/keycodes/platform_key_map_win.h b/chromium/ui/events/keycodes/platform_key_map_win.h
index 7b9871fef6c..53e13ba090f 100644
--- a/chromium/ui/events/keycodes/platform_key_map_win.h
+++ b/chromium/ui/events/keycodes/platform_key_map_win.h
@@ -11,6 +11,7 @@
#include "base/event_types.h"
#include "base/hash.h"
+#include "ui/events/event.h"
#include "ui/events/events_export.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_codes_win.h"
@@ -25,15 +26,20 @@ class EVENTS_EXPORT PlatformKeyMap {
~PlatformKeyMap();
// Returns the DOM KeyboardEvent key from |KeyboardCode|+|EventFlags| and
- // the keyboard layout of current thread.
+ // the keyboard layout of current thread. If this is an AltGraph modified
+ // key then |flags| will have Control+Alt removed, and AltGraph set.
// Updates a per-thread key map cache whenever the layout changes.
- // If |flags| includes both Control and Alt modifiers, they will be replaced
- // by AltGraph if the key generates a printable character with them.
static DomKey DomKeyFromKeyboardCode(KeyboardCode key_code, int* flags);
// Returns true if the currently-active keymap uses AltGraph shift.
static bool UsesAltGraph();
+ // If the supplied event has both Control and Alt modifiers set, then they
+ // are replaced by AltGraph. This should only ever be applied to the flags
+ // for printable-character events.
+ // TODO(crbug.com/25503): Has no effect if FixAltGraph is not enabled.
+ static int ReplaceControlAndAltWithAltGraph(int flags);
+
// TODO(crbug.com/25503): Returns true if we disambiguate AltGraph.
static bool IsFixAltGraphEnabled();
diff --git a/chromium/ui/events/keycodes/platform_key_map_win_unittest.cc b/chromium/ui/events/keycodes/platform_key_map_win_unittest.cc
index 814d5a35ddb..7424bfe8f86 100644
--- a/chromium/ui/events/keycodes/platform_key_map_win_unittest.cc
+++ b/chromium/ui/events/keycodes/platform_key_map_win_unittest.cc
@@ -6,6 +6,7 @@
#include "base/macros.h"
#include "base/strings/string16.h"
+#include "base/test/scoped_feature_list.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/dom/dom_code.h"
@@ -29,6 +30,11 @@ struct TestKey {
const char* altgr_capslock;
};
+struct DomKeyAndFlags {
+ DomKey key;
+ int flags;
+};
+
} // anonymous namespace
class PlatformKeyMapTest : public testing::Test {
@@ -87,6 +93,16 @@ class PlatformKeyMapTest : public testing::Test {
return keymap.DomKeyFromKeyboardCodeImpl(key_code, &flags);
}
+ // Returns the DomKey and |flags| in a struct, for use in tests verifying
+ // that the API correctly modifies the |flags| in/out parameter.
+ DomKeyAndFlags DomKeyAndFlagsFromKeyboardCode(const PlatformKeyMap& keymap,
+ KeyboardCode key_code,
+ int flags) {
+ DomKeyAndFlags result = {DomKey(), flags};
+ result.key = keymap.DomKeyFromKeyboardCodeImpl(key_code, &result.flags);
+ return result;
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(PlatformKeyMapTest);
};
@@ -326,7 +342,7 @@ TEST_F(PlatformKeyMapTest, JapaneseSpecificKeys) {
}
}
-TEST_F(PlatformKeyMapTest, AltGraph) {
+TEST_F(PlatformKeyMapTest, AltGraphDomKey) {
PlatformKeyMap us_keymap(
GetPlatformKeyboardLayout(KEYBOARD_LAYOUT_ENGLISH_US));
EXPECT_EQ(DomKey::ALT,
@@ -343,4 +359,75 @@ TEST_F(PlatformKeyMapTest, AltGraph) {
EF_ALTGR_DOWN | EF_IS_EXTENDED_KEY));
}
+namespace {
+
+const struct AltGraphModifierTestCase {
+ // Test-case Virtual Keycode and modifier flags.
+ KeyboardCode key_code;
+ int flags;
+
+ // Whether or not this case generates an AltGraph-shifted key under FR-fr
+ // layout.
+ bool expect_alt_graph;
+} kAltGraphModifierTestCases[] = {
+ {VKEY_C, EF_NONE, false},
+ {VKEY_C, EF_ALTGR_DOWN, false},
+ {VKEY_C, EF_CONTROL_DOWN | EF_ALT_DOWN, false},
+ {VKEY_C, EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN, false},
+ {VKEY_E, EF_NONE, false},
+ {VKEY_E, EF_ALTGR_DOWN, true},
+ {VKEY_E, EF_CONTROL_DOWN | EF_ALT_DOWN, true},
+ {VKEY_E, EF_CONTROL_DOWN | EF_ALT_DOWN | EF_ALTGR_DOWN, true},
+};
+
+class AltGraphModifierTest
+ : public PlatformKeyMapTest,
+ public testing::WithParamInterface<KeyboardLayout> {
+ public:
+ AltGraphModifierTest() : keymap_(GetPlatformKeyboardLayout(GetParam())) {}
+
+ protected:
+ base::test::ScopedFeatureList feature_list_;
+ PlatformKeyMap keymap_;
+};
+
+TEST_P(AltGraphModifierTest, OldAltGraphModifierBehaviour) {
+ feature_list_.InitFromCommandLine("", "FixAltGraph");
+
+ // Regardless of the keyboard layout, modifier flags should be unchanged.
+ for (const auto& test_case : kAltGraphModifierTestCases) {
+ DomKeyAndFlags result = DomKeyAndFlagsFromKeyboardCode(
+ keymap_, test_case.key_code, test_case.flags);
+ EXPECT_EQ(test_case.flags, result.flags)
+ << " for key_code=" << test_case.key_code;
+ }
+}
+
+TEST_P(AltGraphModifierTest, AltGraphModifierBehaviour) {
+ feature_list_.InitFromCommandLine("FixAltGraph", "");
+
+ // If the key generates a character under AltGraph then |result| should
+ // report AltGraph, but not Control or Alt.
+ for (const auto& test_case : kAltGraphModifierTestCases) {
+ DomKeyAndFlags result = DomKeyAndFlagsFromKeyboardCode(
+ keymap_, test_case.key_code, test_case.flags);
+ if (GetParam() == KEYBOARD_LAYOUT_FRENCH && test_case.expect_alt_graph) {
+ EXPECT_EQ(EF_ALTGR_DOWN, result.flags)
+ << " for key_code=" << test_case.key_code
+ << " flags=" << test_case.flags;
+ } else {
+ EXPECT_EQ(test_case.flags, result.flags)
+ << " for key_code=" << test_case.key_code
+ << " flags=" << test_case.flags;
+ }
+ }
+}
+
+INSTANTIATE_TEST_CASE_P(VerifyAltGraph,
+ AltGraphModifierTest,
+ ::testing::Values(KEYBOARD_LAYOUT_ENGLISH_US,
+ KEYBOARD_LAYOUT_FRENCH));
+
+} // namespace
+
} // namespace ui
diff --git a/chromium/ui/events/ozone/BUILD.gn b/chromium/ui/events/ozone/BUILD.gn
index 613d448ce7e..f9a33289569 100644
--- a/chromium/ui/events/ozone/BUILD.gn
+++ b/chromium/ui/events/ozone/BUILD.gn
@@ -33,6 +33,8 @@ if (use_ozone) {
"device/udev/device_manager_udev.cc",
"device/udev/device_manager_udev.h",
"events_ozone_export.h",
+ "keyboard/event_auto_repeat_handler.cc",
+ "keyboard/event_auto_repeat_handler.h",
]
deps = [
diff --git a/chromium/ui/events/ozone/evdev/input_device_factory_evdev.cc b/chromium/ui/events/ozone/evdev/input_device_factory_evdev.cc
index 5242dc7f55c..4cc71e34d38 100644
--- a/chromium/ui/events/ozone/evdev/input_device_factory_evdev.cc
+++ b/chromium/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -10,6 +10,7 @@
#include <utility>
+#include "base/bind.h"
#include "base/files/scoped_file.h"
#include "base/memory/ptr_util.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -509,6 +510,16 @@ void InputDeviceFactoryEvdev::EnablePalmSuppression(bool enabled) {
return;
palm_suppression_enabled_ = enabled;
+ // This function can be called while disabling pen devices, so don't disable
+ // inline here.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindOnce(&InputDeviceFactoryEvdev::EnableDevices,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void InputDeviceFactoryEvdev::EnableDevices() {
+ // TODO(spang): Fix the UI to not dismiss menus when we use
+ // ApplyInputDeviceSettings() instead of this function.
for (const auto& it : converters_)
it.second->SetEnabled(IsDeviceEnabled(it.second.get()));
}
diff --git a/chromium/ui/events/ozone/evdev/input_device_factory_evdev.h b/chromium/ui/events/ozone/evdev/input_device_factory_evdev.h
index 3c20987b281..567fbc35b28 100644
--- a/chromium/ui/events/ozone/evdev/input_device_factory_evdev.h
+++ b/chromium/ui/events/ozone/evdev/input_device_factory_evdev.h
@@ -63,8 +63,6 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev {
base::WeakPtr<InputDeviceFactoryEvdev> GetWeakPtr();
- void EnablePalmSuppression(bool enabled);
-
private:
// Open device at path & starting processing events.
void AttachInputDevice(std::unique_ptr<EventConverterEvdev> converter);
@@ -94,6 +92,8 @@ class EVENTS_OZONE_EVDEV_EXPORT InputDeviceFactoryEvdev {
void SetBoolPropertyForOneType(const EventDeviceType type,
const std::string& name,
bool value);
+ void EnablePalmSuppression(bool enabled);
+ void EnableDevices();
// Task runner for our thread.
scoped_refptr<base::TaskRunner> task_runner_;
diff --git a/chromium/ui/events/ozone/evdev/input_injector_evdev.cc b/chromium/ui/events/ozone/evdev/input_injector_evdev.cc
index b69dc04508b..f6976d717db 100644
--- a/chromium/ui/events/ozone/evdev/input_injector_evdev.cc
+++ b/chromium/ui/events/ozone/evdev/input_injector_evdev.cc
@@ -42,6 +42,7 @@ void InputInjectorEvdev::InjectMouseButton(EventFlags button, bool down) {
break;
case EF_MIDDLE_MOUSE_BUTTON:
code = BTN_MIDDLE;
+ break;
default:
LOG(WARNING) << "Invalid flag: " << button << " for the button parameter";
return;
diff --git a/chromium/ui/events/ozone/evdev/input_injector_evdev_unittest.cc b/chromium/ui/events/ozone/evdev/input_injector_evdev_unittest.cc
index 6c8b86ca0b6..737bce2125e 100644
--- a/chromium/ui/events/ozone/evdev/input_injector_evdev_unittest.cc
+++ b/chromium/ui/events/ozone/evdev/input_injector_evdev_unittest.cc
@@ -174,6 +174,12 @@ TEST_F(InputInjectorEvdevTest, RightClick) {
run_loop_.RunUntilIdle();
}
+TEST_F(InputInjectorEvdevTest, MiddleClick) {
+ ExpectClick(12, 13, EF_MIDDLE_MOUSE_BUTTON, 1);
+ SimulateMouseClick(12, 13, EF_MIDDLE_MOUSE_BUTTON, 1);
+ run_loop_.RunUntilIdle();
+}
+
TEST_F(InputInjectorEvdevTest, DoubleClick) {
ExpectClick(12, 13, EF_LEFT_MOUSE_BUTTON, 2);
SimulateMouseClick(12, 13, EF_LEFT_MOUSE_BUTTON, 2);
diff --git a/chromium/ui/events/ozone/evdev/keyboard_evdev.cc b/chromium/ui/events/ozone/evdev/keyboard_evdev.cc
index 23b738d9b63..a0f5420b0ed 100644
--- a/chromium/ui/events/ozone/evdev/keyboard_evdev.cc
+++ b/chromium/ui/events/ozone/evdev/keyboard_evdev.cc
@@ -19,23 +19,14 @@
namespace ui {
-namespace {
-
-const int kRepeatDelayMs = 500;
-const int kRepeatIntervalMs = 50;
-
-} // namespace
-
KeyboardEvdev::KeyboardEvdev(EventModifiers* modifiers,
KeyboardLayoutEngine* keyboard_layout_engine,
const EventDispatchCallback& callback)
: callback_(callback),
modifiers_(modifiers),
keyboard_layout_engine_(keyboard_layout_engine),
- weak_ptr_factory_(this) {
- repeat_delay_ = base::TimeDelta::FromMilliseconds(kRepeatDelayMs);
- repeat_interval_ = base::TimeDelta::FromMilliseconds(kRepeatIntervalMs);
-}
+ auto_repeat_handler_(this),
+ weak_ptr_factory_(this) {}
KeyboardEvdev::~KeyboardEvdev() {
}
@@ -54,7 +45,8 @@ void KeyboardEvdev::OnKeyChange(unsigned int key,
return; // Key already released.
key_state_.set(key, down);
- UpdateKeyRepeat(key, down, suppress_auto_repeat, device_id);
+ auto_repeat_handler_.UpdateKeyRepeat(key, down, suppress_auto_repeat,
+ device_id);
DispatchKey(key, down, is_repeat, timestamp, device_id);
}
@@ -67,23 +59,21 @@ bool KeyboardEvdev::IsCapsLockEnabled() {
}
bool KeyboardEvdev::IsAutoRepeatEnabled() {
- return auto_repeat_enabled_;
+ return auto_repeat_handler_.IsAutoRepeatEnabled();
}
void KeyboardEvdev::SetAutoRepeatEnabled(bool enabled) {
- auto_repeat_enabled_ = enabled;
+ auto_repeat_handler_.SetAutoRepeatEnabled(enabled);
}
void KeyboardEvdev::SetAutoRepeatRate(const base::TimeDelta& delay,
const base::TimeDelta& interval) {
- repeat_delay_ = delay;
- repeat_interval_ = interval;
+ auto_repeat_handler_.SetAutoRepeatRate(delay, interval);
}
void KeyboardEvdev::GetAutoRepeatRate(base::TimeDelta* delay,
base::TimeDelta* interval) {
- *delay = repeat_delay_;
- *interval = repeat_interval_;
+ auto_repeat_handler_.GetAutoRepeatRate(delay, interval);
}
bool KeyboardEvdev::SetCurrentLayoutByName(const std::string& layout_name) {
@@ -92,6 +82,13 @@ bool KeyboardEvdev::SetCurrentLayoutByName(const std::string& layout_name) {
return result;
}
+void KeyboardEvdev::FlushInput(base::OnceClosure closure) {
+ // Post a task behind any pending key releases in the message loop
+ // FIFO. This ensures there's no spurious repeats during periods of UI
+ // thread jank.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, std::move(closure));
+}
+
void KeyboardEvdev::UpdateModifier(int modifier_flag, bool down) {
if (modifier_flag == EF_NONE)
return;
@@ -135,62 +132,6 @@ void KeyboardEvdev::RefreshModifiers() {
}
}
-void KeyboardEvdev::UpdateKeyRepeat(unsigned int key,
- bool down,
- bool suppress_auto_repeat,
- int device_id) {
- if (!auto_repeat_enabled_ || suppress_auto_repeat)
- StopKeyRepeat();
- else if (key != repeat_key_ && down)
- StartKeyRepeat(key, device_id);
- else if (key == repeat_key_ && !down)
- StopKeyRepeat();
-}
-
-void KeyboardEvdev::StartKeyRepeat(unsigned int key, int device_id) {
- repeat_key_ = key;
- repeat_device_id_ = device_id;
- repeat_sequence_++;
-
- ScheduleKeyRepeat(repeat_delay_);
-}
-
-void KeyboardEvdev::StopKeyRepeat() {
- repeat_key_ = KEY_RESERVED;
- repeat_sequence_++;
-}
-
-void KeyboardEvdev::ScheduleKeyRepeat(const base::TimeDelta& delay) {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE,
- base::BindOnce(&KeyboardEvdev::OnRepeatTimeout,
- weak_ptr_factory_.GetWeakPtr(), repeat_sequence_),
- delay);
-}
-
-void KeyboardEvdev::OnRepeatTimeout(unsigned int sequence) {
- if (repeat_sequence_ != sequence)
- return;
-
- // Post a task behind any pending key releases in the message loop
- // FIFO. This ensures there's no spurious repeats during periods of UI
- // thread jank.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::BindOnce(&KeyboardEvdev::OnRepeatCommit,
- weak_ptr_factory_.GetWeakPtr(), repeat_sequence_));
-}
-
-void KeyboardEvdev::OnRepeatCommit(unsigned int sequence) {
- if (repeat_sequence_ != sequence)
- return;
-
- DispatchKey(repeat_key_, true /* down */, true /* repeat */,
- EventTimeForNow(), repeat_device_id_);
-
- ScheduleKeyRepeat(repeat_interval_);
-}
-
void KeyboardEvdev::DispatchKey(unsigned int key,
bool down,
bool repeat,
diff --git a/chromium/ui/events/ozone/evdev/keyboard_evdev.h b/chromium/ui/events/ozone/evdev/keyboard_evdev.h
index 4a6f59bf11d..eba0dc0fe07 100644
--- a/chromium/ui/events/ozone/evdev/keyboard_evdev.h
+++ b/chromium/ui/events/ozone/evdev/keyboard_evdev.h
@@ -15,6 +15,7 @@
#include "ui/events/ozone/evdev/event_device_util.h"
#include "ui/events/ozone/evdev/event_dispatch_callback.h"
#include "ui/events/ozone/evdev/events_ozone_evdev_export.h"
+#include "ui/events/ozone/keyboard/event_auto_repeat_handler.h"
#include "ui/events/ozone/layout/keyboard_layout_engine.h"
namespace ui {
@@ -28,7 +29,8 @@ enum class DomCode;
// one logical keyboard, applying modifiers & implementing key repeat.
//
// It also currently also applies the layout.
-class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev {
+class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev
+ : public EventAutoRepeatHandler::Delegate {
public:
KeyboardEvdev(EventModifiers* modifiers,
KeyboardLayoutEngine* keyboard_layout_engine,
@@ -65,20 +67,14 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev {
void UpdateModifier(int modifier_flag, bool down);
void RefreshModifiers();
void UpdateCapsLockLed();
- void UpdateKeyRepeat(unsigned int key,
- bool down,
- bool suppress_auto_repeat,
- int device_id);
- void StartKeyRepeat(unsigned int key, int device_id);
- void StopKeyRepeat();
- void ScheduleKeyRepeat(const base::TimeDelta& delay);
- void OnRepeatTimeout(unsigned int sequence);
- void OnRepeatCommit(unsigned int sequence);
+
+ // EventAutoRepeatHandler::Delegate
+ void FlushInput(base::OnceClosure closure) override;
void DispatchKey(unsigned int key,
bool down,
bool repeat,
base::TimeTicks timestamp,
- int device_id);
+ int device_id) override;
// Aggregated key state. There is only one bit of state per key; we do not
// attempt to count presses of the same key on multiple keyboards.
@@ -98,13 +94,8 @@ class EVENTS_OZONE_EVDEV_EXPORT KeyboardEvdev {
// Shared layout engine.
KeyboardLayoutEngine* keyboard_layout_engine_;
- // Key repeat state.
- bool auto_repeat_enabled_ = true;
- unsigned int repeat_key_ = KEY_RESERVED;
- unsigned int repeat_sequence_ = 0;
- int repeat_device_id_ = 0;
- base::TimeDelta repeat_delay_;
- base::TimeDelta repeat_interval_;
+ // Key repeat handler.
+ EventAutoRepeatHandler auto_repeat_handler_;
base::WeakPtrFactory<KeyboardEvdev> weak_ptr_factory_;
diff --git a/chromium/ui/events/ozone/evdev/touch_evdev_types.h b/chromium/ui/events/ozone/evdev/touch_evdev_types.h
index 22d2345148b..cf0c58e83e2 100644
--- a/chromium/ui/events/ozone/evdev/touch_evdev_types.h
+++ b/chromium/ui/events/ozone/evdev/touch_evdev_types.h
@@ -58,12 +58,7 @@ struct EVENTS_OZONE_EVDEV_EXPORT InProgressTouchEvdev {
float tilt_y = 0;
ui::EventPointerType reported_tool_type =
ui::EventPointerType::POINTER_TYPE_TOUCH;
-
- struct ButtonState {
- bool down = false;
- bool changed = false;
- };
- ButtonState btn_stylus;
+ bool stylus_button = false;
};
} // namespace ui
diff --git a/chromium/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/chromium/ui/events/ozone/evdev/touch_event_converter_evdev.cc
index 33455714618..7141819c6d4 100644
--- a/chromium/ui/events/ozone/evdev/touch_event_converter_evdev.cc
+++ b/chromium/ui/events/ozone/evdev/touch_event_converter_evdev.cc
@@ -228,6 +228,7 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
MT_TOOL_FINGER);
events_[i].tool_type = tool_type;
events_[i].major = touch_major;
+ events_[i].stylus_button = false;
if (events_[i].cancelled)
cancelled_state = true;
}
@@ -264,8 +265,6 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
}
void TouchEventConverterEvdev::Reinitialize() {
- ReleaseButtons();
-
EventDeviceInfo info;
if (!info.Initialize(fd_, path_)) {
LOG(ERROR) << "Failed to synchronize state for touch device: "
@@ -297,7 +296,6 @@ void TouchEventConverterEvdev::OnEnabled() {
void TouchEventConverterEvdev::OnDisabled() {
ReleaseTouches();
- ReleaseButtons();
if (enable_palm_suppression_callback_) {
enable_palm_suppression_callback_.Run(false);
}
@@ -391,8 +389,7 @@ void TouchEventConverterEvdev::EmulateMultitouchEvent(
void TouchEventConverterEvdev::ProcessKey(const input_event& input) {
switch (input.code) {
case BTN_STYLUS:
- events_[current_slot_].btn_stylus.down = input.value;
- events_[current_slot_].btn_stylus.changed = true;
+ events_[current_slot_].stylus_button = input.value;
events_[current_slot_].altered = true;
break;
case BTN_TOOL_PEN:
@@ -520,7 +517,7 @@ void TouchEventConverterEvdev::ReportTouchEvent(
ui::PointerDetails details(event.reported_tool_type, /* pointer_id*/ 0,
event.radius_x, event.radius_y, event.pressure,
/* twist */ 0, event.tilt_x, event.tilt_y);
- int flags = event.btn_stylus.down ? ui::EventFlags::EF_LEFT_MOUSE_BUTTON : 0;
+ int flags = event.stylus_button ? ui::EventFlags::EF_LEFT_MOUSE_BUTTON : 0;
dispatcher_->DispatchTouchEvent(TouchEventParams(
input_device_.id, event.slot, event_type, gfx::PointF(event.x, event.y),
details, timestamp, flags));
@@ -587,7 +584,6 @@ void TouchEventConverterEvdev::ReportEvents(base::TimeTicks timestamp) {
event->was_touching = event->touching;
event->was_delayed = event->delayed;
event->altered = false;
- event->btn_stylus.changed = false;
}
}
@@ -609,6 +605,7 @@ void TouchEventConverterEvdev::UpdateTrackingId(int slot, int tracking_id) {
void TouchEventConverterEvdev::ReleaseTouches() {
for (size_t slot = 0; slot < events_.size(); slot++) {
+ events_[slot].stylus_button = false;
events_[slot].cancelled = true;
events_[slot].altered = true;
}
@@ -616,19 +613,6 @@ void TouchEventConverterEvdev::ReleaseTouches() {
ReportEvents(EventTimeForNow());
}
-void TouchEventConverterEvdev::ReleaseButtons() {
- for (size_t slot = 0; slot < events_.size(); slot++) {
- InProgressTouchEvdev* event = &events_[slot];
-
- if (event->btn_stylus.down) {
- event->btn_stylus.down = false;
- event->btn_stylus.changed = true;
- }
- }
-
- ReportEvents(EventTimeForNow());
-}
-
float TouchEventConverterEvdev::ScalePressure(int32_t value) {
float pressure = value - pressure_min_;
if (pressure_max_ - pressure_min_)
diff --git a/chromium/ui/events/ozone/evdev/touch_event_converter_evdev.h b/chromium/ui/events/ozone/evdev/touch_event_converter_evdev.h
index 905902448fa..7e5c6c0756e 100644
--- a/chromium/ui/events/ozone/evdev/touch_event_converter_evdev.h
+++ b/chromium/ui/events/ozone/evdev/touch_event_converter_evdev.h
@@ -90,7 +90,6 @@ class EVENTS_OZONE_EVDEV_EXPORT TouchEventConverterEvdev
void UpdateTrackingId(int slot, int tracking_id);
void ReleaseTouches();
- void ReleaseButtons();
void CancelAllTouches();
bool IsPalm(const InProgressTouchEvdev& touch);
// Normalize pressure value to [0, 1].
diff --git a/chromium/ui/events/ozone/keyboard/event_auto_repeat_handler.cc b/chromium/ui/events/ozone/keyboard/event_auto_repeat_handler.cc
new file mode 100644
index 00000000000..3eea5cf5efa
--- /dev/null
+++ b/chromium/ui/events/ozone/keyboard/event_auto_repeat_handler.cc
@@ -0,0 +1,103 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/ozone/keyboard/event_auto_repeat_handler.h"
+
+#include "base/threading/thread_task_runner_handle.h"
+#include "ui/events/base_event_utils.h"
+
+namespace ui {
+
+namespace {
+
+constexpr int kRepeatDelayMs = 500;
+constexpr int kRepeatIntervalMs = 50;
+
+} // namespace
+
+EventAutoRepeatHandler::EventAutoRepeatHandler(Delegate* delegate)
+ : repeat_delay_(base::TimeDelta::FromMilliseconds(kRepeatDelayMs)),
+ repeat_interval_(base::TimeDelta::FromMilliseconds(kRepeatIntervalMs)),
+ delegate_(delegate),
+ weak_ptr_factory_(this) {
+ DCHECK(delegate_);
+}
+
+EventAutoRepeatHandler::~EventAutoRepeatHandler() {}
+
+bool EventAutoRepeatHandler::IsAutoRepeatEnabled() {
+ return auto_repeat_enabled_;
+}
+
+void EventAutoRepeatHandler::SetAutoRepeatEnabled(bool enabled) {
+ auto_repeat_enabled_ = enabled;
+}
+
+void EventAutoRepeatHandler::SetAutoRepeatRate(
+ const base::TimeDelta& delay,
+ const base::TimeDelta& interval) {
+ repeat_delay_ = delay;
+ repeat_interval_ = interval;
+}
+
+void EventAutoRepeatHandler::GetAutoRepeatRate(base::TimeDelta* delay,
+ base::TimeDelta* interval) {
+ *delay = repeat_delay_;
+ *interval = repeat_interval_;
+}
+
+void EventAutoRepeatHandler::UpdateKeyRepeat(unsigned int key,
+ bool down,
+ bool suppress_auto_repeat,
+ int device_id) {
+ if (!auto_repeat_enabled_ || suppress_auto_repeat)
+ StopKeyRepeat();
+ else if (key != repeat_key_ && down)
+ StartKeyRepeat(key, device_id);
+ else if (key == repeat_key_ && !down)
+ StopKeyRepeat();
+}
+
+void EventAutoRepeatHandler::StartKeyRepeat(unsigned int key, int device_id) {
+ repeat_key_ = key;
+ repeat_device_id_ = device_id;
+ repeat_sequence_++;
+
+ ScheduleKeyRepeat(repeat_delay_);
+}
+
+void EventAutoRepeatHandler::StopKeyRepeat() {
+ repeat_key_ = KEY_RESERVED;
+ repeat_sequence_++;
+}
+
+void EventAutoRepeatHandler::ScheduleKeyRepeat(const base::TimeDelta& delay) {
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&EventAutoRepeatHandler::OnRepeatTimeout,
+ weak_ptr_factory_.GetWeakPtr(), repeat_sequence_),
+ delay);
+}
+
+void EventAutoRepeatHandler::OnRepeatTimeout(unsigned int sequence) {
+ if (repeat_sequence_ != sequence)
+ return;
+
+ base::OnceClosure commit =
+ base::BindOnce(&EventAutoRepeatHandler::OnRepeatCommit,
+ weak_ptr_factory_.GetWeakPtr(), repeat_sequence_);
+ delegate_->FlushInput(std::move(commit));
+}
+
+void EventAutoRepeatHandler::OnRepeatCommit(unsigned int sequence) {
+ if (repeat_sequence_ != sequence)
+ return;
+
+ delegate_->DispatchKey(repeat_key_, true /* down */, true /* repeat */,
+ EventTimeForNow(), repeat_device_id_);
+
+ ScheduleKeyRepeat(repeat_interval_);
+}
+
+} // namespace ui
diff --git a/chromium/ui/events/ozone/keyboard/event_auto_repeat_handler.h b/chromium/ui/events/ozone/keyboard/event_auto_repeat_handler.h
new file mode 100644
index 00000000000..f95430b3730
--- /dev/null
+++ b/chromium/ui/events/ozone/keyboard/event_auto_repeat_handler.h
@@ -0,0 +1,71 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_EVENTS_OZONE_KEYBOARD_EVENT_AUTO_REPEAT_HANDLER_H
+#define UI_EVENTS_OZONE_KEYBOARD_EVENT_AUTO_REPEAT_HANDLER_H
+
+#include <linux/input.h>
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "ui/events/ozone/events_ozone_export.h"
+
+namespace ui {
+
+class EVENTS_OZONE_EXPORT EventAutoRepeatHandler {
+ public:
+ class Delegate {
+ public:
+ // Gives the client a chance to flush the input queue
+ // cancelling possible spurios auto repeat keys.
+ // Useful under janky situations.
+ virtual void FlushInput(base::OnceClosure closure) = 0;
+ virtual void DispatchKey(unsigned int key,
+ bool down,
+ bool repeat,
+ base::TimeTicks timestamp,
+ int device_id) = 0;
+ };
+
+ explicit EventAutoRepeatHandler(Delegate* delegate);
+ ~EventAutoRepeatHandler();
+
+ void UpdateKeyRepeat(unsigned int key,
+ bool down,
+ bool suppress_auto_repeat,
+ int device_id);
+ void StopKeyRepeat();
+
+ // Configuration for key repeat.
+ bool IsAutoRepeatEnabled();
+ void SetAutoRepeatEnabled(bool enabled);
+ void SetAutoRepeatRate(const base::TimeDelta& delay,
+ const base::TimeDelta& interval);
+ void GetAutoRepeatRate(base::TimeDelta* delay, base::TimeDelta* interval);
+
+ private:
+ void StartKeyRepeat(unsigned int key, int device_id);
+ void ScheduleKeyRepeat(const base::TimeDelta& delay);
+ void OnRepeatTimeout(unsigned int sequence);
+ void OnRepeatCommit(unsigned int sequence);
+
+ // Key repeat state.
+ bool auto_repeat_enabled_ = true;
+ unsigned int repeat_key_ = KEY_RESERVED;
+ unsigned int repeat_sequence_ = 0;
+ int repeat_device_id_ = 0;
+ base::TimeDelta repeat_delay_;
+ base::TimeDelta repeat_interval_;
+
+ Delegate* delegate_ = nullptr;
+
+ base::WeakPtrFactory<EventAutoRepeatHandler> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(EventAutoRepeatHandler);
+};
+
+} // namespace ui
+
+#endif // UI_EVENTS_OZONE_KEYBOARD_EVENT_AUTO_REPEAT_HANDLER_H
diff --git a/chromium/ui/events/win/keyboard_hook_win.cc b/chromium/ui/events/win/keyboard_hook_win.cc
new file mode 100644
index 00000000000..8f92cd5ec72
--- /dev/null
+++ b/chromium/ui/events/win/keyboard_hook_win.cc
@@ -0,0 +1,131 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/keyboard_hook_base.h"
+
+#include <utility>
+
+#include <windows.h>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/optional.h"
+#include "base/threading/thread_checker.h"
+#include "ui/events/event.h"
+
+namespace ui {
+
+namespace {
+
+// These keys interfere with the return value of ::GetKeyState() as observing
+// them directly in LowLevelKeyboardProc will cause their key combinations to be
+// ignored. As an example, the KeyF event in an Alt + F combination will result
+// in a missing alt-down flag. Since a regular application can successfully
+// receive these keys without using LowLevelKeyboardProc, they can be ignored.
+bool IsOSReservedKey(DWORD vk) {
+ return vk == VK_SHIFT || vk == VK_LSHIFT || vk == VK_RSHIFT ||
+ vk == VK_CONTROL || vk == VK_LCONTROL || vk == VK_RCONTROL ||
+ vk == VK_MENU || vk == VK_LMENU || vk == VK_RMENU || vk == VK_LWIN ||
+ vk == VK_RWIN || vk == VK_CAPITAL || vk == VK_NUMLOCK ||
+ vk == VK_SCROLL;
+}
+
+class KeyboardHookWin : public KeyboardHookBase {
+ public:
+ KeyboardHookWin(base::Optional<base::flat_set<int>> native_key_codes,
+ KeyEventCallback callback);
+ ~KeyboardHookWin() override;
+
+ bool Register();
+
+ private:
+ static LRESULT CALLBACK ProcessKeyEvent(int code,
+ WPARAM w_param,
+ LPARAM l_param);
+ static KeyboardHookWin* instance_;
+
+ THREAD_CHECKER(thread_checker_);
+
+ HHOOK hook_ = nullptr;
+
+ DISALLOW_COPY_AND_ASSIGN(KeyboardHookWin);
+};
+
+// static
+KeyboardHookWin* KeyboardHookWin::instance_ = nullptr;
+
+KeyboardHookWin::KeyboardHookWin(base::Optional<base::flat_set<int>> key_codes,
+ KeyEventCallback callback)
+ : KeyboardHookBase(std::move(key_codes), std::move(callback)) {}
+
+KeyboardHookWin::~KeyboardHookWin() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ DCHECK_EQ(instance_, this);
+ instance_ = nullptr;
+
+ if (!UnhookWindowsHookEx(hook_))
+ DPLOG(ERROR) << "UnhookWindowsHookEx failed";
+}
+
+bool KeyboardHookWin::Register() {
+ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+ // Only one instance of this class can be registered at a time.
+ DCHECK(!instance_);
+ instance_ = this;
+
+ // Per MSDN this Hook procedure will be called in the context of the thread
+ // which installed it.
+ hook_ = SetWindowsHookEx(
+ WH_KEYBOARD_LL,
+ reinterpret_cast<HOOKPROC>(&KeyboardHookWin::ProcessKeyEvent),
+ /*hMod=*/nullptr,
+ /*dwThreadId=*/0);
+ DPLOG_IF(ERROR, !hook_) << "SetWindowsHookEx failed";
+
+ return hook_ != nullptr;
+}
+
+// static
+LRESULT CALLBACK KeyboardHookWin::ProcessKeyEvent(int code,
+ WPARAM w_param,
+ LPARAM l_param) {
+ // If there is an error unhooking, this method could be called with a null
+ // |instance_|. Ensure we have a valid instance and that |code| is correct
+ // before proceeding.
+ if (!instance_ || code != HC_ACTION)
+ return CallNextHookEx(nullptr, code, w_param, l_param);
+
+ DCHECK_CALLED_ON_VALID_THREAD(instance_->thread_checker_);
+
+ KBDLLHOOKSTRUCT* ll_hooks = reinterpret_cast<KBDLLHOOKSTRUCT*>(l_param);
+ if (!IsOSReservedKey(ll_hooks->vkCode) &&
+ instance_->ShouldCaptureKeyEvent(ll_hooks->vkCode)) {
+ MSG msg = {nullptr, w_param, ll_hooks->vkCode,
+ (ll_hooks->scanCode << 16) | (ll_hooks->flags & 0xFFFF),
+ ll_hooks->time};
+ instance_->ForwardCapturedKeyEvent(std::make_unique<KeyEvent>(msg));
+ return 1;
+ }
+ return CallNextHookEx(nullptr, code, w_param, l_param);
+}
+
+} // namespace
+
+// static
+std::unique_ptr<KeyboardHook> KeyboardHook::Create(
+ base::Optional<base::flat_set<int>> key_codes,
+ KeyEventCallback callback) {
+ std::unique_ptr<KeyboardHookWin> keyboard_hook =
+ std::make_unique<KeyboardHookWin>(std::move(key_codes),
+ std::move(callback));
+
+ if (!keyboard_hook->Register())
+ return nullptr;
+
+ return keyboard_hook;
+}
+
+} // namespace ui
diff --git a/chromium/ui/events/x/events_x_unittest.cc b/chromium/ui/events/x/events_x_unittest.cc
index fa0291e44b1..0022b7f180f 100644
--- a/chromium/ui/events/x/events_x_unittest.cc
+++ b/chromium/ui/events/x/events_x_unittest.cc
@@ -12,6 +12,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
+#include "base/test/simple_test_tick_clock.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/devices/x11/device_data_manager_x11.h"
@@ -548,30 +549,22 @@ base::TimeTicks TimeTicksFromMillis(int64_t millis) {
return base::TimeTicks() + base::TimeDelta::FromMilliseconds(millis);
}
-class MockTickClock : public base::TickClock {
- public:
- explicit MockTickClock(int64_t milliseconds)
- : ticks_(TimeTicksFromMillis(milliseconds)) {}
- base::TimeTicks NowTicks() override { return ticks_; }
-
- private:
- base::TimeTicks ticks_;
-};
-
} // namespace
TEST_F(EventsXTest, TimestampRolloverAndAdjustWhenDecreasing) {
XEvent event;
InitButtonEvent(&event, true, gfx::Point(5, 10), 1, 0);
- ResetTimestampRolloverCountersForTesting(
- std::make_unique<MockTickClock>(0x100000001));
+ base::SimpleTestTickClock clock;
+ clock.SetNowTicks(TimeTicksFromMillis(0x100000001));
+ SetEventTickClockForTesting(&clock);
+ ResetTimestampRolloverCountersForTesting();
event.xbutton.time = 0xFFFFFFFF;
EXPECT_EQ(TimeTicksFromMillis(0xFFFFFFFF), ui::EventTimeFromNative(&event));
- ResetTimestampRolloverCountersForTesting(
- std::make_unique<MockTickClock>(0x100000007));
+ clock.SetNowTicks(TimeTicksFromMillis(0x100000007));
+ ResetTimestampRolloverCountersForTesting();
event.xbutton.time = 3;
EXPECT_EQ(TimeTicksFromMillis(0x100000000 + 3),
@@ -582,15 +575,18 @@ TEST_F(EventsXTest, NoTimestampRolloverWhenMonotonicIncreasing) {
XEvent event;
InitButtonEvent(&event, true, gfx::Point(5, 10), 1, 0);
- ResetTimestampRolloverCountersForTesting(std::make_unique<MockTickClock>(10));
+ base::SimpleTestTickClock clock;
+ clock.SetNowTicks(TimeTicksFromMillis(10));
+ SetEventTickClockForTesting(&clock);
+ ResetTimestampRolloverCountersForTesting();
event.xbutton.time = 6;
EXPECT_EQ(TimeTicksFromMillis(6), ui::EventTimeFromNative(&event));
event.xbutton.time = 7;
EXPECT_EQ(TimeTicksFromMillis(7), ui::EventTimeFromNative(&event));
- ResetTimestampRolloverCountersForTesting(
- std::make_unique<MockTickClock>(0x100000005));
+ clock.SetNowTicks(TimeTicksFromMillis(0x100000005));
+ ResetTimestampRolloverCountersForTesting();
event.xbutton.time = 0xFFFFFFFF;
EXPECT_EQ(TimeTicksFromMillis(0xFFFFFFFF), ui::EventTimeFromNative(&event));
diff --git a/chromium/ui/events/x/events_x_utils.cc b/chromium/ui/events/x/events_x_utils.cc
index 4106f41d517..6ad9ba9e9aa 100644
--- a/chromium/ui/events/x/events_x_utils.cc
+++ b/chromium/ui/events/x/events_x_utils.cc
@@ -635,6 +635,7 @@ int GetChangedMouseButtonFlagsFromXEvent(const XEvent& xev) {
default:
break;
}
+ break;
}
default:
break;
@@ -818,11 +819,9 @@ bool IsAltPressed() {
return XModifierStateWatcher::GetInstance()->state() & Mod1Mask;
}
-void ResetTimestampRolloverCountersForTesting(
- std::unique_ptr<base::TickClock> tick_clock) {
+void ResetTimestampRolloverCountersForTesting() {
g_last_seen_timestamp_ms = 0;
g_rollover_ms = 0;
- SetEventTickClockForTesting(std::move(tick_clock));
}
} // namespace ui
diff --git a/chromium/ui/events/x/events_x_utils.h b/chromium/ui/events/x/events_x_utils.h
index 4d5e754441a..64814e87715 100644
--- a/chromium/ui/events/x/events_x_utils.h
+++ b/chromium/ui/events/x/events_x_utils.h
@@ -89,8 +89,7 @@ EVENTS_X_EXPORT bool GetFlingDataFromXEvent(const XEvent& xev,
// Uses the XModifierStateWatcher to determine if alt is pressed or not.
EVENTS_X_EXPORT bool IsAltPressed();
-EVENTS_X_EXPORT void ResetTimestampRolloverCountersForTesting(
- std::unique_ptr<base::TickClock> tick_clock = nullptr);
+EVENTS_X_EXPORT void ResetTimestampRolloverCountersForTesting();
} // namespace ui
diff --git a/chromium/ui/events/x/keyboard_hook_posix.cc b/chromium/ui/events/x/keyboard_hook_posix.cc
new file mode 100644
index 00000000000..17c59bdcd2f
--- /dev/null
+++ b/chromium/ui/events/x/keyboard_hook_posix.cc
@@ -0,0 +1,43 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/events/keyboard_hook_base.h"
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/optional.h"
+#include "ui/events/event.h"
+
+namespace ui {
+
+namespace {
+
+// A default implementation for POSIX platforms.
+class KeyboardHookPosix : public KeyboardHookBase {
+ public:
+ KeyboardHookPosix(base::Optional<base::flat_set<int>> native_key_codes,
+ KeyEventCallback callback);
+ ~KeyboardHookPosix() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(KeyboardHookPosix);
+};
+
+KeyboardHookPosix::KeyboardHookPosix(
+ base::Optional<base::flat_set<int>> key_codes,
+ KeyEventCallback callback)
+ : KeyboardHookBase(std::move(key_codes), std::move(callback)) {}
+
+KeyboardHookPosix::~KeyboardHookPosix() = default;
+
+} // namespace
+
+// static
+std::unique_ptr<KeyboardHook> KeyboardHook::Create(
+ base::Optional<base::flat_set<int>> native_key_codes,
+ KeyboardHook::KeyEventCallback callback) {
+ return nullptr;
+}
+
+} // namespace ui
diff --git a/chromium/ui/gfx/BUILD.gn b/chromium/ui/gfx/BUILD.gn
index 580b686cf4b..9c38caf3ba8 100644
--- a/chromium/ui/gfx/BUILD.gn
+++ b/chromium/ui/gfx/BUILD.gn
@@ -172,8 +172,6 @@ jumbo_component("gfx") {
"utf16_indexing.h",
"vsync_provider.cc",
"vsync_provider.h",
- "win/direct_manipulation.cc",
- "win/direct_manipulation.h",
"win/direct_write.cc",
"win/direct_write.h",
"win/hwnd_util.cc",
@@ -624,6 +622,12 @@ static_library("test_support") {
"//ui/gfx/geometry",
]
+ if (!is_ios) {
+ sources += [ "render_text_test_api.h" ]
+
+ deps += [ "//third_party:freetype_harfbuzz" ]
+ }
+
if (is_linux) {
deps += [ "//third_party/fontconfig" ]
}
diff --git a/chromium/ui/gfx/animation/slide_animation.h b/chromium/ui/gfx/animation/slide_animation.h
index 221c8ffaba7..4105970d196 100644
--- a/chromium/ui/gfx/animation/slide_animation.h
+++ b/chromium/ui/gfx/animation/slide_animation.h
@@ -55,9 +55,11 @@ class ANIMATION_EXPORT SlideAnimation : public LinearAnimation {
virtual void Reset(double value);
// Begin a showing animation or reverse a hiding animation in progress.
+ // Animates |GetCurrentValue()| towards 1.
virtual void Show();
// Begin a hiding animation or reverse a showing animation in progress.
+ // Animates |GetCurrentValue()| towards 0.
virtual void Hide();
// Sets the time a slide will take. Note that this isn't actually
diff --git a/chromium/ui/gfx/buffer_format_util.cc b/chromium/ui/gfx/buffer_format_util.cc
index 9c4837029ef..f72941f5258 100644
--- a/chromium/ui/gfx/buffer_format_util.cc
+++ b/chromium/ui/gfx/buffer_format_util.cc
@@ -11,17 +11,26 @@
namespace gfx {
namespace {
-const BufferFormat kBufferFormats[] = {
- BufferFormat::ATC, BufferFormat::ATCIA,
- BufferFormat::DXT1, BufferFormat::DXT5,
- BufferFormat::ETC1, BufferFormat::R_8,
- BufferFormat::R_16, BufferFormat::RG_88,
- BufferFormat::BGR_565, BufferFormat::RGBA_4444,
- BufferFormat::RGBX_8888, BufferFormat::RGBA_8888,
- BufferFormat::BGRX_8888, BufferFormat::BGRX_1010102,
- BufferFormat::BGRA_8888, BufferFormat::RGBA_F16,
- BufferFormat::UYVY_422, BufferFormat::YUV_420_BIPLANAR,
- BufferFormat::YVU_420};
+const BufferFormat kBufferFormats[] = {BufferFormat::ATC,
+ BufferFormat::ATCIA,
+ BufferFormat::DXT1,
+ BufferFormat::DXT5,
+ BufferFormat::ETC1,
+ BufferFormat::R_8,
+ BufferFormat::R_16,
+ BufferFormat::RG_88,
+ BufferFormat::BGR_565,
+ BufferFormat::RGBA_4444,
+ BufferFormat::RGBX_8888,
+ BufferFormat::RGBA_8888,
+ BufferFormat::BGRX_8888,
+ BufferFormat::BGRX_1010102,
+ BufferFormat::RGBX_1010102,
+ BufferFormat::BGRA_8888,
+ BufferFormat::RGBA_F16,
+ BufferFormat::UYVY_422,
+ BufferFormat::YUV_420_BIPLANAR,
+ BufferFormat::YVU_420};
static_assert(arraysize(kBufferFormats) ==
(static_cast<int>(BufferFormat::LAST) + 1),
@@ -63,6 +72,7 @@ bool RowSizeForBufferFormatChecked(
return true;
case BufferFormat::BGRX_8888:
case BufferFormat::BGRX_1010102:
+ case BufferFormat::RGBX_1010102:
case BufferFormat::RGBX_8888:
case BufferFormat::RGBA_8888:
case BufferFormat::BGRA_8888:
@@ -113,6 +123,7 @@ size_t NumberOfPlanesForBufferFormat(BufferFormat format) {
case BufferFormat::RGBA_8888:
case BufferFormat::BGRX_8888:
case BufferFormat::BGRX_1010102:
+ case BufferFormat::RGBX_1010102:
case BufferFormat::BGRA_8888:
case BufferFormat::RGBA_F16:
case BufferFormat::UYVY_422:
@@ -142,6 +153,7 @@ size_t SubsamplingFactorForBufferFormat(BufferFormat format, size_t plane) {
case BufferFormat::RGBA_8888:
case BufferFormat::BGRX_8888:
case BufferFormat::BGRX_1010102:
+ case BufferFormat::RGBX_1010102:
case BufferFormat::BGRA_8888:
case BufferFormat::RGBA_F16:
case BufferFormat::UYVY_422:
@@ -216,6 +228,7 @@ size_t BufferOffsetForBufferFormat(const Size& size,
case BufferFormat::RGBA_8888:
case BufferFormat::BGRX_8888:
case BufferFormat::BGRX_1010102:
+ case BufferFormat::RGBX_1010102:
case BufferFormat::BGRA_8888:
case BufferFormat::RGBA_F16:
case BufferFormat::UYVY_422:
@@ -267,6 +280,8 @@ const char* BufferFormatToString(BufferFormat format) {
return "BGRX_8888";
case BufferFormat::BGRX_1010102:
return "BGRX_1010102";
+ case BufferFormat::RGBX_1010102:
+ return "RGBX_1010102";
case BufferFormat::BGRA_8888:
return "BGRA_8888";
case BufferFormat::RGBA_F16:
diff --git a/chromium/ui/gfx/buffer_types.h b/chromium/ui/gfx/buffer_types.h
index 53f4518d498..cd16f2ee83f 100644
--- a/chromium/ui/gfx/buffer_types.h
+++ b/chromium/ui/gfx/buffer_types.h
@@ -26,6 +26,7 @@ enum class BufferFormat {
RGBA_8888,
BGRX_8888,
BGRX_1010102,
+ RGBX_1010102,
BGRA_8888,
RGBA_F16,
YVU_420,
diff --git a/chromium/ui/gfx/canvas_unittest.cc b/chromium/ui/gfx/canvas_unittest.cc
index 837518a1aab..25bc3148741 100644
--- a/chromium/ui/gfx/canvas_unittest.cc
+++ b/chromium/ui/gfx/canvas_unittest.cc
@@ -72,12 +72,11 @@ TEST_F(CanvasTest, ClipRectWithScaling) {
}
// Line height is only supported on Skia.
-#if defined(OS_MACOSX) || defined(OS_ANDROID)
+#if defined(OS_ANDROID)
#define MAYBE_StringSizeWithLineHeight DISABLED_StringSizeWithLineHeight
#else
#define MAYBE_StringSizeWithLineHeight StringSizeWithLineHeight
#endif
-
TEST_F(CanvasTest, MAYBE_StringSizeWithLineHeight) {
gfx::Size one_line_size = SizeStringInt("Q", 0, 0);
gfx::Size four_line_size = SizeStringInt("Q\nQ\nQ\nQ", 1000000, 1000);
diff --git a/chromium/ui/gfx/canvas_unittest_mac.mm b/chromium/ui/gfx/canvas_unittest_mac.mm
index 99b25708464..78d0487ceba 100644
--- a/chromium/ui/gfx/canvas_unittest_mac.mm
+++ b/chromium/ui/gfx/canvas_unittest_mac.mm
@@ -49,8 +49,8 @@ class CanvasTestMac : public testing::Test {
float canvas_width = kReallyLargeNumber;
float canvas_height = kReallyLargeNumber;
- Canvas::SizeStringFloat(
- text16, font_list, &canvas_width, &canvas_height, 0, 0);
+ Canvas::SizeStringFloat(text16, font_list, &canvas_width, &canvas_height, 0,
+ 0, Typesetter::NATIVE);
EXPECT_NE(kReallyLargeNumber, mac_width) << "no width for " << text;
EXPECT_NE(kReallyLargeNumber, mac_height) << "no height for " << text;
@@ -64,10 +64,9 @@ class CanvasTestMac : public testing::Test {
Font font_;
};
- // Tests that Canvas' SizeStringFloat yields result consistent with a native
- // implementation.
-// Disabled for the typesetter migration. http://crbug.com/803354.
-TEST_F(CanvasTestMac, DISABLED_StringSizeIdenticalForSkia) {
+// Tests that Canvas' SizeStringFloat yields result consistent with a native
+// implementation when using Typesetter::NATIVE.
+TEST_F(CanvasTestMac, StringSizeIdenticalForSkia) {
CompareSizes("");
CompareSizes("Foo");
CompareSizes("Longword");
@@ -80,8 +79,8 @@ TEST_F(CanvasTestMac, FractionalWidth) {
float height = kReallyLargeNumber;
FontList font_list;
- Canvas::SizeStringFloat(
- base::UTF8ToUTF16("Test"), font_list, &width, &height, 0, 0);
+ Canvas::SizeStringFloat(base::UTF8ToUTF16("Test"), font_list, &width, &height,
+ 0, 0, Typesetter::NATIVE);
EXPECT_GT(width, static_cast<int>(width));
}
diff --git a/chromium/ui/gfx/color_palette.h b/chromium/ui/gfx/color_palette.h
index 767f2d2c18b..3c77e6a68c9 100644
--- a/chromium/ui/gfx/color_palette.h
+++ b/chromium/ui/gfx/color_palette.h
@@ -13,24 +13,35 @@ namespace gfx {
// as a visual flag for misbehaving code.
constexpr SkColor kPlaceholderColor = SK_ColorRED;
-const SkColor kChromeIconGrey = SkColorSetRGB(0x5A, 0x5A, 0x5A);
+constexpr SkColor kChromeIconGrey = SkColorSetRGB(0x5A, 0x5A, 0x5A);
// The number refers to the shade of darkness. Each color in the MD
// palette ranges from 100-900.
-const SkColor kGoogleBlue300 = SkColorSetRGB(0x7B, 0xAA, 0xF7);
-const SkColor kGoogleBlue500 = SkColorSetRGB(0x42, 0x85, 0xF4);
-const SkColor kGoogleBlue700 = SkColorSetRGB(0x33, 0x67, 0xD6);
-const SkColor kGoogleBlue900 = SkColorSetRGB(0x1C, 0x3A, 0xA9);
-const SkColor kGoogleRed300 = SkColorSetRGB(0xE6, 0x7C, 0x73);
-const SkColor kGoogleRed700 = SkColorSetRGB(0xC5, 0x39, 0x29);
-const SkColor kGoogleGreen300 = SkColorSetRGB(0x57, 0xBB, 0x8A);
-const SkColor kGoogleGreen700 = SkColorSetRGB(0x0B, 0x80, 0x43);
-const SkColor kGoogleYellow300 = SkColorSetRGB(0xF7, 0xCB, 0x4D);
-const SkColor kGoogleYellow700 = SkColorSetRGB(0xF0, 0x93, 0x00);
+constexpr SkColor kGoogleBlue300 = SkColorSetRGB(0x8A, 0xB4, 0xF8);
+constexpr SkColor kGoogleBlue500 = SkColorSetRGB(0x42, 0x85, 0xF4);
+constexpr SkColor kGoogleBlue600 = SkColorSetRGB(0x1A, 0x73, 0xE8);
+constexpr SkColor kGoogleBlue700 = SkColorSetRGB(0x19, 0x67, 0xD2);
+constexpr SkColor kGoogleBlue900 = SkColorSetRGB(0x17, 0x4E, 0xA6);
+constexpr SkColor kGoogleRed300 = SkColorSetRGB(0xF2, 0x8B, 0xB2);
+constexpr SkColor kGoogleRed600 = SkColorSetRGB(0xD9, 0x30, 0x25);
+constexpr SkColor kGoogleRed700 = SkColorSetRGB(0xC5, 0x22, 0x1F);
+constexpr SkColor kGoogleRed800 = SkColorSetRGB(0xB3, 0x14, 0x12);
+constexpr SkColor kGoogleRedDark600 = SkColorSetRGB(0xD3, 0x3B, 0x30);
+constexpr SkColor kGoogleRedDark800 = SkColorSetRGB(0xB4, 0x1B, 0x1A);
+constexpr SkColor kGoogleGreen300 = SkColorSetRGB(0x81, 0xC9, 0x95);
+constexpr SkColor kGoogleGreen700 = SkColorSetRGB(0x18, 0x80, 0x38);
+constexpr SkColor kGoogleYellow300 = SkColorSetRGB(0xFD, 0xD6, 0x63);
+constexpr SkColor kGoogleYellow700 = SkColorSetRGB(0xF2, 0x99, 0x00);
+constexpr SkColor kGoogleYellow900 = SkColorSetRGB(0xE3, 0x74, 0x00);
+constexpr SkColor kGoogleGrey100 = SkColorSetRGB(0xF1, 0xF3, 0xF4);
+constexpr SkColor kGoogleGrey400 = SkColorSetRGB(0xBD, 0xC1, 0xC6);
+constexpr SkColor kGoogleGrey700 = SkColorSetRGB(0x5F, 0x63, 0x68);
+constexpr SkColor kGoogleGrey800 = SkColorSetRGB(0x3C, 0x40, 0x43);
+constexpr SkColor kGoogleGrey900 = SkColorSetRGB(0x20, 0x21, 0x24);
// An alpha value for designating a control's disabled state. In specs this is
// sometimes listed as 0.38a.
-const SkAlpha kDisabledControlAlpha = 0x61;
+constexpr SkAlpha kDisabledControlAlpha = 0x61;
} // namespace gfx
diff --git a/chromium/ui/gfx/color_space.cc b/chromium/ui/gfx/color_space.cc
index 1c79c47e5c9..77458c930c6 100644
--- a/chromium/ui/gfx/color_space.cc
+++ b/chromium/ui/gfx/color_space.cc
@@ -8,6 +8,7 @@
#include <map>
#include <sstream>
+#include "base/atomic_sequence_num.h"
#include "base/containers/mru_cache.h"
#include "base/lazy_instance.h"
#include "base/synchronization/lock.h"
@@ -21,6 +22,8 @@ namespace gfx {
namespace {
+base::AtomicSequenceNumber g_color_space_id;
+
// See comments in ToSkColorSpace about this cache. This cache may only be
// accessed while holding g_sk_color_space_cache_lock.
static const size_t kMaxCachedSkColorSpaces = 16;
@@ -183,6 +186,11 @@ ColorSpace ColorSpace::CreateREC709() {
RangeID::LIMITED);
}
+// static
+int ColorSpace::GetNextId() {
+ return g_color_space_id.GetNext();
+}
+
bool ColorSpace::operator==(const ColorSpace& other) const {
if (primaries_ != other.primaries_ || transfer_ != other.transfer_ ||
matrix_ != other.matrix_ || range_ != other.range_ ||
diff --git a/chromium/ui/gfx/color_space.h b/chromium/ui/gfx/color_space.h
index 8e6cff172b1..561cbc74e2a 100644
--- a/chromium/ui/gfx/color_space.h
+++ b/chromium/ui/gfx/color_space.h
@@ -152,6 +152,9 @@ class COLOR_SPACE_EXPORT ColorSpace {
static ColorSpace CreateREC601();
static ColorSpace CreateREC709();
+ // Generates a process global unique ID that can be used to key a color space.
+ static int GetNextId();
+
bool operator==(const ColorSpace& other) const;
bool operator!=(const ColorSpace& other) const;
bool operator<(const ColorSpace& other) const;
diff --git a/chromium/ui/gfx/color_transform.cc b/chromium/ui/gfx/color_transform.cc
index 548a9636678..cf3aa80546e 100644
--- a/chromium/ui/gfx/color_transform.cc
+++ b/chromium/ui/gfx/color_transform.cc
@@ -621,9 +621,14 @@ class ColorTransformToLinear : public ColorTransformPerChannelTransferFn {
" float c1 = 3424.0 / 4096.0;\n"
" float c2 = (2413.0 / 4096.0) * 32.0;\n"
" float c3 = (2392.0 / 4096.0) * 32.0;\n"
- " v = pow(max(pow(v, 1.0 / m2) - c1, 0.0) /\n"
- " (c2 - c3 * pow(v, 1.0 / m2)), 1.0 / m1);\n"
- " v *= 10000.0 / 80.0;\n"
+ " #ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+ " highp float v2 = v;\n"
+ " #else\n"
+ " float v2 = v;\n"
+ " #endif\n"
+ " v2 = pow(max(pow(v2, 1.0 / m2) - c1, 0.0) /\n"
+ " (c2 - c3 * pow(v2, 1.0 / m2)), 1.0 / m1);\n"
+ " v = v2 * 10000.0 / 80.0;\n"
" return v;\n";
return;
case ColorSpace::TransferID::SMPTEST2084_NON_HDR:
diff --git a/chromium/ui/gfx/font_list_unittest.cc b/chromium/ui/gfx/font_list_unittest.cc
index 0d8bda77938..e2bcf215ecd 100644
--- a/chromium/ui/gfx/font_list_unittest.cc
+++ b/chromium/ui/gfx/font_list_unittest.cc
@@ -299,9 +299,9 @@ TEST(FontListTest, MAYBE_Fonts_DeriveWithSizeDelta) {
#endif
TEST(FontListTest, MAYBE_Fonts_GetHeight_GetBaseline) {
// If a font list has only one font, the height and baseline must be the same.
- Font font1("Arial", 16);
- ASSERT_EQ("arial", base::ToLowerASCII(font1.GetActualFontNameForTesting()));
- FontList font_list1("Arial, 16px");
+ Font font1("Verdana", 16);
+ ASSERT_EQ("verdana", base::ToLowerASCII(font1.GetActualFontNameForTesting()));
+ FontList font_list1("Verdana, 16px");
EXPECT_EQ(font1.GetHeight(), font_list1.GetHeight());
EXPECT_EQ(font1.GetBaseline(), font_list1.GetBaseline());
diff --git a/chromium/ui/gfx/font_names_testing.cc b/chromium/ui/gfx/font_names_testing.cc
index 941852a330a..09ec558cd7b 100644
--- a/chromium/ui/gfx/font_names_testing.cc
+++ b/chromium/ui/gfx/font_names_testing.cc
@@ -15,7 +15,7 @@ const char kSymbolFontName[] = "Symbol";
#endif
#if defined(OS_LINUX)
-const char kCJKFontName[] = "Kochi Mincho";
+const char kCJKFontName[] = "IPAMincho";
#elif defined(OS_MACOSX)
const char kCJKFontName[] = "Heiti SC";
#else
diff --git a/chromium/ui/gfx/geometry/mojo/BUILD.gn b/chromium/ui/gfx/geometry/mojo/BUILD.gn
index f6cda9d3beb..2d0e1efbcfd 100644
--- a/chromium/ui/gfx/geometry/mojo/BUILD.gn
+++ b/chromium/ui/gfx/geometry/mojo/BUILD.gn
@@ -10,6 +10,8 @@ mojom("mojo") {
sources = [
"geometry.mojom",
]
+
+ check_includes_blink = false
}
mojom("test_interfaces") {
diff --git a/chromium/ui/gfx/geometry/vector2d.h b/chromium/ui/gfx/geometry/vector2d.h
index 4b45667adf5..d9964532f51 100644
--- a/chromium/ui/gfx/geometry/vector2d.h
+++ b/chromium/ui/gfx/geometry/vector2d.h
@@ -39,6 +39,9 @@ class GFX_EXPORT Vector2d {
// Subtract the components of the |other| vector from the current vector.
void Subtract(const Vector2d& other);
+ constexpr bool operator==(const Vector2d& other) const {
+ return x_ == other.x_ && y_ == other.y_;
+ }
void operator+=(const Vector2d& other) { Add(other); }
void operator-=(const Vector2d& other) { Subtract(other); }
@@ -70,11 +73,7 @@ class GFX_EXPORT Vector2d {
int y_;
};
-inline bool operator==(const Vector2d& lhs, const Vector2d& rhs) {
- return lhs.x() == rhs.x() && lhs.y() == rhs.y();
-}
-
-inline Vector2d operator-(const Vector2d& v) {
+inline constexpr Vector2d operator-(const Vector2d& v) {
return Vector2d(-v.x(), -v.y());
}
diff --git a/chromium/ui/gfx/geometry/vector2d_f.h b/chromium/ui/gfx/geometry/vector2d_f.h
index 92f7f877531..7e40ea881fc 100644
--- a/chromium/ui/gfx/geometry/vector2d_f.h
+++ b/chromium/ui/gfx/geometry/vector2d_f.h
@@ -67,15 +67,15 @@ class GFX_EXPORT Vector2dF {
float y_;
};
-inline bool operator==(const Vector2dF& lhs, const Vector2dF& rhs) {
+inline constexpr bool operator==(const Vector2dF& lhs, const Vector2dF& rhs) {
return lhs.x() == rhs.x() && lhs.y() == rhs.y();
}
-inline bool operator!=(const Vector2dF& lhs, const Vector2dF& rhs) {
+inline constexpr bool operator!=(const Vector2dF& lhs, const Vector2dF& rhs) {
return !(lhs == rhs);
}
-inline Vector2dF operator-(const Vector2dF& v) {
+inline constexpr Vector2dF operator-(const Vector2dF& v) {
return Vector2dF(-v.x(), -v.y());
}
diff --git a/chromium/ui/gfx/ipc/color/BUILD.gn b/chromium/ui/gfx/ipc/color/BUILD.gn
index a2e66760411..496398dd77a 100644
--- a/chromium/ui/gfx/ipc/color/BUILD.gn
+++ b/chromium/ui/gfx/ipc/color/BUILD.gn
@@ -19,6 +19,6 @@ jumbo_component("color") {
public_deps = [
"//base",
"//ipc",
- "//ui/gfx:gfx",
+ "//ui/gfx:color_space",
]
}
diff --git a/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.cc b/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.cc
index ead0d23554b..dc58b2a48e1 100644
--- a/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.cc
+++ b/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.cc
@@ -7,57 +7,64 @@
#include <string>
#include "base/pickle.h"
+#include "ipc/ipc_message_utils.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkImageInfo.h"
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits_macros.h"
#include "ui/gfx/transform.h"
-namespace {
-
-struct SkBitmap_Data {
- // The color type for the bitmap (bits per pixel, etc).
- SkColorType color_type;
+// Generate param traits write methods.
+#include "ipc/param_traits_write_macros.h"
+namespace IPC {
+#undef UI_GFX_IPC_SKIA_GFX_SKIA_PARAM_TRAITS_MACROS_H_
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits_macros.h"
+} // namespace IPC
- // The alpha type for the bitmap (opaque, premul, unpremul).
- SkAlphaType alpha_type;
+// Generate param traits read methods.
+#include "ipc/param_traits_read_macros.h"
+namespace IPC {
+#undef UI_GFX_IPC_SKIA_GFX_SKIA_PARAM_TRAITS_MACROS_H_
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits_macros.h"
+} // namespace IPC
- // The width of the bitmap in pixels.
- uint32_t width;
+// Generate param traits log methods.
+#include "ipc/param_traits_log_macros.h"
+namespace IPC {
+#undef UI_GFX_IPC_SKIA_GFX_SKIA_PARAM_TRAITS_MACROS_H_
+#include "ui/gfx/ipc/skia/gfx_skia_param_traits_macros.h"
+} // namespace IPC
- // The height of the bitmap in pixels.
- uint32_t height;
+namespace IPC {
- void InitSkBitmapDataForTransfer(const SkBitmap& bitmap) {
- const SkImageInfo& info = bitmap.info();
- color_type = info.colorType();
- alpha_type = info.alphaType();
- width = info.width();
- height = info.height();
- }
+void ParamTraits<SkImageInfo>::Write(base::Pickle* m, const SkImageInfo& p) {
+ WriteParam(m, p.colorType());
+ WriteParam(m, p.alphaType());
+ WriteParam(m, p.width());
+ WriteParam(m, p.height());
+}
- // Returns whether |bitmap| successfully initialized.
- bool InitSkBitmapFromData(SkBitmap* bitmap,
- const char* pixels,
- size_t pixels_size) const {
- if (!bitmap->tryAllocPixels(
- SkImageInfo::Make(width, height, color_type, alpha_type)))
- return false;
- if (pixels_size != bitmap->computeByteSize())
- return false;
- memcpy(bitmap->getPixels(), pixels, pixels_size);
- return true;
+bool ParamTraits<SkImageInfo>::Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ SkImageInfo* r) {
+ SkColorType color_type;
+ SkAlphaType alpha_type;
+ uint32_t width;
+ uint32_t height;
+ if (!ReadParam(m, iter, &color_type) || !ReadParam(m, iter, &alpha_type) ||
+ !ReadParam(m, iter, &width) || !ReadParam(m, iter, &height)) {
+ return false;
}
-};
-} // namespace
+ *r = SkImageInfo::Make(width, height, color_type, alpha_type);
+ return true;
+}
-namespace IPC {
+void ParamTraits<SkImageInfo>::Log(const SkImageInfo& p, std::string* l) {
+ l->append("<SkImageInfo>");
+}
void ParamTraits<SkBitmap>::Write(base::Pickle* m, const SkBitmap& p) {
- size_t fixed_size = sizeof(SkBitmap_Data);
- SkBitmap_Data bmp_data;
- bmp_data.InitSkBitmapDataForTransfer(p);
- m->WriteData(reinterpret_cast<const char*>(&bmp_data),
- static_cast<int>(fixed_size));
+ WriteParam(m, p.info());
size_t pixel_size = p.computeByteSize();
m->WriteData(reinterpret_cast<const char*>(p.getPixels()),
static_cast<int>(pixel_size));
@@ -66,28 +73,28 @@ void ParamTraits<SkBitmap>::Write(base::Pickle* m, const SkBitmap& p) {
bool ParamTraits<SkBitmap>::Read(const base::Pickle* m,
base::PickleIterator* iter,
SkBitmap* r) {
- const char* fixed_data;
- int fixed_data_size = 0;
- if (!iter->ReadData(&fixed_data, &fixed_data_size) ||
- (fixed_data_size <= 0)) {
+ SkImageInfo image_info;
+ if (!ReadParam(m, iter, &image_info))
return false;
- }
- if (fixed_data_size != sizeof(SkBitmap_Data))
- return false; // Message is malformed.
- const char* variable_data;
- int variable_data_size = 0;
- if (!iter->ReadData(&variable_data, &variable_data_size) ||
- (variable_data_size < 0)) {
+ const char* bitmap_data;
+ int bitmap_data_size = 0;
+ if (!iter->ReadData(&bitmap_data, &bitmap_data_size))
return false;
- }
- const SkBitmap_Data* bmp_data =
- reinterpret_cast<const SkBitmap_Data*>(fixed_data);
- return bmp_data->InitSkBitmapFromData(r, variable_data, variable_data_size);
+ // ReadData() only returns true if bitmap_data_size >= 0.
+
+ if (!r->tryAllocPixels(image_info))
+ return false;
+
+ if (static_cast<size_t>(bitmap_data_size) != r->computeByteSize())
+ return false;
+ memcpy(r->getPixels(), bitmap_data, bitmap_data_size);
+ return true;
}
void ParamTraits<SkBitmap>::Log(const SkBitmap& p, std::string* l) {
l->append("<SkBitmap>");
+ LogParam(p.info(), l);
}
void ParamTraits<gfx::Transform>::Write(base::Pickle* m, const param_type& p) {
diff --git a/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.h b/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.h
index d3acc930865..3b0d4a82cd3 100644
--- a/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.h
+++ b/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits.h
@@ -12,6 +12,7 @@
#include "ui/gfx/ipc/skia/gfx_skia_ipc_export.h"
class SkBitmap;
+struct SkImageInfo;
namespace base {
class Pickle;
@@ -25,6 +26,16 @@ class Transform;
namespace IPC {
template <>
+struct GFX_SKIA_IPC_EXPORT ParamTraits<SkImageInfo> {
+ using param_type = SkImageInfo;
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m,
+ base::PickleIterator* iter,
+ param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template <>
struct GFX_SKIA_IPC_EXPORT ParamTraits<SkBitmap> {
using param_type = SkBitmap;
static void Write(base::Pickle* m, const param_type& p);
diff --git a/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits_macros.h b/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits_macros.h
new file mode 100644
index 00000000000..e48af3f0aab
--- /dev/null
+++ b/chromium/ui/gfx/ipc/skia/gfx_skia_param_traits_macros.h
@@ -0,0 +1,16 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GFX_IPC_SKIA_GFX_SKIA_PARAM_TRAITS_MACROS_H_
+#define UI_GFX_IPC_SKIA_GFX_SKIA_PARAM_TRAITS_MACROS_H_
+
+#include <stdint.h>
+
+#include "ipc/ipc_message_macros.h"
+#include "third_party/skia/include/core/SkImageInfo.h"
+
+IPC_ENUM_TRAITS_VALIDATE(SkColorType, kLastEnum_SkColorType);
+IPC_ENUM_TRAITS_VALIDATE(SkAlphaType, kLastEnum_SkAlphaType);
+
+#endif // UI_GFX_IPC_SKIA_GFX_SKIA_PARAM_TRAITS_MACROS_H_
diff --git a/chromium/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc b/chromium/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc
index b86d8efeb86..a9fd8622ef5 100644
--- a/chromium/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc
+++ b/chromium/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
#include "ui/gfx/native_pixmap_handle.h"
#if defined(OS_CHROMEOS)
@@ -64,10 +65,19 @@ class ClientNativePixmapFactoryDmabuf : public ClientNativePixmapFactory {
return format == gfx::BufferFormat::BGRX_8888 ||
format == gfx::BufferFormat::RGBX_8888;
case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE:
- return format == gfx::BufferFormat::BGRX_8888 ||
- format == gfx::BufferFormat::BGRA_8888 ||
- format == gfx::BufferFormat::RGBX_8888 ||
- format == gfx::BufferFormat::RGBA_8888;
+ return
+#if defined(ARCH_CPU_X86_FAMILY)
+ // Currently only Intel driver (i.e. minigbm and Mesa) supports R_8
+ // RG_88 and NV12. https://crbug.com/356871
+ format == gfx::BufferFormat::R_8 ||
+ format == gfx::BufferFormat::RG_88 ||
+ format == gfx::BufferFormat::YUV_420_BIPLANAR ||
+#endif
+
+ format == gfx::BufferFormat::BGRX_8888 ||
+ format == gfx::BufferFormat::BGRA_8888 ||
+ format == gfx::BufferFormat::RGBX_8888 ||
+ format == gfx::BufferFormat::RGBA_8888;
case gfx::BufferUsage::SCANOUT_VDA_WRITE:
return false;
case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE:
diff --git a/chromium/ui/gfx/mac/io_surface.cc b/chromium/ui/gfx/mac/io_surface.cc
index 4fe0ddd3f87..bf6111f0387 100644
--- a/chromium/ui/gfx/mac/io_surface.cc
+++ b/chromium/ui/gfx/mac/io_surface.cc
@@ -60,6 +60,7 @@ int32_t BytesPerElement(gfx::BufferFormat format, int plane) {
case gfx::BufferFormat::BGR_565:
case gfx::BufferFormat::RGBA_4444:
case gfx::BufferFormat::RGBX_8888:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::YVU_420:
NOTREACHED();
return 0;
@@ -74,7 +75,7 @@ int32_t PixelFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::R_8:
return 'L008';
case gfx::BufferFormat::BGRX_1010102:
- return 'R10k';
+ return 'l10r'; // little-endian ARGB2101010 full-range ARGB
case gfx::BufferFormat::BGRA_8888:
case gfx::BufferFormat::BGRX_8888:
case gfx::BufferFormat::RGBA_8888:
@@ -95,6 +96,9 @@ int32_t PixelFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::BGR_565:
case gfx::BufferFormat::RGBA_4444:
case gfx::BufferFormat::RGBX_8888:
+ case gfx::BufferFormat::RGBX_1010102:
+ // Technically RGBX_1010102 should be accepted as 'R10k', but then it won't
+ // be supported by CGLTexImageIOSurface2D(), so it's best to reject it here.
case gfx::BufferFormat::YVU_420:
NOTREACHED();
return 0;
@@ -209,7 +213,7 @@ IOSurfaceRef CreateIOSurface(const gfx::Size& size,
}
void IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
- const gfx::ColorSpace& color_space) {
+ const ColorSpace& color_space) {
// Retrieve the ICC profile data that created this profile, if it exists.
ICCProfile icc_profile = ICCProfile::FromCacheMac(color_space);
@@ -218,9 +222,25 @@ void IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
icc_profile =
ICCProfile::FromParametricColorSpace(color_space.GetAsFullRangeRGB());
}
-
- // If that fails, we can't use this color space.
if (!icc_profile.IsValid()) {
+ if (__builtin_available(macos 10.12, *)) {
+ static const ColorSpace kBt2020(ColorSpace::PrimaryID::BT2020,
+ ColorSpace::TransferID::SMPTEST2084,
+ ColorSpace::MatrixID::BT2020_NCL,
+ ColorSpace::RangeID::LIMITED);
+ if (color_space == kBt2020) {
+ base::ScopedCFTypeRef<CGColorSpaceRef> cg_color_space(
+ CGColorSpaceCreateWithName(kCGColorSpaceITUR_2020));
+ DCHECK(cg_color_space);
+
+ base::ScopedCFTypeRef<CFDataRef> cf_data_icc_profile(
+ CGColorSpaceCopyICCData(cg_color_space));
+ DCHECK(cf_data_icc_profile);
+ IOSurfaceSetValue(io_surface, CFSTR("IOSurfaceColorSpace"),
+ cf_data_icc_profile);
+ return;
+ }
+ }
DLOG(ERROR) << "Failed to set color space for IOSurface: no ICC profile: "
<< color_space.ToString();
return;
diff --git a/chromium/ui/gfx/mojo/buffer_types.mojom b/chromium/ui/gfx/mojo/buffer_types.mojom
index b197b50cdbd..0708aeb0cd3 100644
--- a/chromium/ui/gfx/mojo/buffer_types.mojom
+++ b/chromium/ui/gfx/mojo/buffer_types.mojom
@@ -20,6 +20,7 @@ enum BufferFormat {
RGBA_8888,
BGRX_8888,
BGRX_1010102,
+ RGBX_1010102,
BGRA_8888,
RGBA_F16,
YVU_420,
diff --git a/chromium/ui/gfx/mojo/buffer_types_struct_traits.h b/chromium/ui/gfx/mojo/buffer_types_struct_traits.h
index eb83ec07149..51957398716 100644
--- a/chromium/ui/gfx/mojo/buffer_types_struct_traits.h
+++ b/chromium/ui/gfx/mojo/buffer_types_struct_traits.h
@@ -42,6 +42,8 @@ struct EnumTraits<gfx::mojom::BufferFormat, gfx::BufferFormat> {
return gfx::mojom::BufferFormat::BGRX_8888;
case gfx::BufferFormat::BGRX_1010102:
return gfx::mojom::BufferFormat::BGRX_1010102;
+ case gfx::BufferFormat::RGBX_1010102:
+ return gfx::mojom::BufferFormat::RGBX_1010102;
case gfx::BufferFormat::BGRA_8888:
return gfx::mojom::BufferFormat::BGRA_8888;
case gfx::BufferFormat::RGBA_F16:
@@ -96,6 +98,9 @@ struct EnumTraits<gfx::mojom::BufferFormat, gfx::BufferFormat> {
case gfx::mojom::BufferFormat::BGRX_1010102:
*out = gfx::BufferFormat::BGRX_1010102;
return true;
+ case gfx::mojom::BufferFormat::RGBX_1010102:
+ *out = gfx::BufferFormat::RGBX_1010102;
+ return true;
case gfx::mojom::BufferFormat::RGBA_8888:
*out = gfx::BufferFormat::RGBA_8888;
return true;
diff --git a/chromium/ui/gfx/mojo/ca_layer_params.mojom b/chromium/ui/gfx/mojo/ca_layer_params.mojom
index bdb8ef65b2a..7bf73564354 100644
--- a/chromium/ui/gfx/mojo/ca_layer_params.mojom
+++ b/chromium/ui/gfx/mojo/ca_layer_params.mojom
@@ -6,13 +6,17 @@ module gfx.mojom;
import "ui/gfx/geometry/mojo/geometry.mojom";
+union CALayerContent {
+ uint32 ca_context_id;
+ handle io_surface_mach_port;
+};
+
// gfx::CALayerParams
struct CALayerParams {
// TODO(676224): Use preprocessor to restrict platform-specific members to
// desired platform.
bool is_empty;
- uint32 ca_context_id;
- handle? io_surface_mach_port;
+ CALayerContent content;
gfx.mojom.Size pixel_size;
float scale_factor;
};
diff --git a/chromium/ui/gfx/mojo/ca_layer_params_struct_traits.cc b/chromium/ui/gfx/mojo/ca_layer_params_struct_traits.cc
index a2cb2a99b30..dd553996b5c 100644
--- a/chromium/ui/gfx/mojo/ca_layer_params_struct_traits.cc
+++ b/chromium/ui/gfx/mojo/ca_layer_params_struct_traits.cc
@@ -10,33 +10,48 @@
namespace mojo {
-mojo::ScopedHandle
-StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams>::
- io_surface_mach_port(const gfx::CALayerParams& ca_layer_params) {
+gfx::mojom::CALayerContentPtr
+StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams>::content(
+ const gfx::CALayerParams& ca_layer_params) {
#if defined(OS_MACOSX) && !defined(OS_IOS)
- return mojo::WrapMachPort(ca_layer_params.io_surface_mach_port.get());
-#else
- return mojo::ScopedHandle();
+ if (ca_layer_params.io_surface_mach_port) {
+ DCHECK(!ca_layer_params.ca_context_id);
+ return gfx::mojom::CALayerContent::NewIoSurfaceMachPort(
+ mojo::WrapMachPort(ca_layer_params.io_surface_mach_port.get()));
+ }
#endif
+ return gfx::mojom::CALayerContent::NewCaContextId(
+ ca_layer_params.ca_context_id);
}
bool StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams>::Read(
gfx::mojom::CALayerParamsDataView data,
gfx::CALayerParams* out) {
out->is_empty = data.is_empty();
- out->ca_context_id = data.ca_context_id();
+ gfx::mojom::CALayerContentDataView content_data;
+ data.GetContentDataView(&content_data);
+ switch (content_data.tag()) {
+ case gfx::mojom::CALayerContentDataView::Tag::CA_CONTEXT_ID:
+ out->ca_context_id = content_data.ca_context_id();
+ break;
+ case gfx::mojom::CALayerContentDataView::Tag::IO_SURFACE_MACH_PORT:
#if defined(OS_MACOSX) && !defined(OS_IOS)
- mach_port_t io_surface_mach_port;
- MojoResult unwrap_result =
- mojo::UnwrapMachPort(data.TakeIoSurfaceMachPort(), &io_surface_mach_port);
- if (unwrap_result != MOJO_RESULT_OK)
- return false;
- out->io_surface_mach_port.reset(io_surface_mach_port);
+ mach_port_t io_surface_mach_port;
+ MojoResult unwrap_result = mojo::UnwrapMachPort(
+ content_data.TakeIoSurfaceMachPort(), &io_surface_mach_port);
+ if (unwrap_result != MOJO_RESULT_OK)
+ return false;
+ out->io_surface_mach_port.reset(io_surface_mach_port);
+#else
+ return false;
#endif
+ break;
+ }
if (!data.ReadPixelSize(&out->pixel_size))
return false;
+
out->scale_factor = data.scale_factor();
return true;
}
diff --git a/chromium/ui/gfx/mojo/ca_layer_params_struct_traits.h b/chromium/ui/gfx/mojo/ca_layer_params_struct_traits.h
index 59a947cbfbe..94127a0d5b5 100644
--- a/chromium/ui/gfx/mojo/ca_layer_params_struct_traits.h
+++ b/chromium/ui/gfx/mojo/ca_layer_params_struct_traits.h
@@ -16,13 +16,6 @@ struct StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams> {
return ca_layer_params.is_empty;
}
- static uint32_t ca_context_id(const gfx::CALayerParams& ca_layer_params) {
- return ca_layer_params.ca_context_id;
- }
-
- static mojo::ScopedHandle io_surface_mach_port(
- const gfx::CALayerParams& ca_layer_params);
-
static gfx::Size pixel_size(const gfx::CALayerParams& ca_layer_params) {
return ca_layer_params.pixel_size;
}
@@ -31,6 +24,9 @@ struct StructTraits<gfx::mojom::CALayerParamsDataView, gfx::CALayerParams> {
return ca_layer_params.scale_factor;
}
+ static gfx::mojom::CALayerContentPtr content(
+ const gfx::CALayerParams& ca_layer_params);
+
static bool Read(gfx::mojom::CALayerParamsDataView data,
gfx::CALayerParams* out);
};
diff --git a/chromium/ui/gfx/paint_vector_icon.cc b/chromium/ui/gfx/paint_vector_icon.cc
index 7761ec11b10..b9832d0f231 100644
--- a/chromium/ui/gfx/paint_vector_icon.cc
+++ b/chromium/ui/gfx/paint_vector_icon.cc
@@ -562,6 +562,14 @@ void PaintVectorIcon(Canvas* canvas,
SkColor color,
const base::TimeDelta& elapsed_time) {
DCHECK(!icon.is_empty());
+ if (icon.path) {
+ DCHECK(icon.path_size > 0);
+ DCHECK_EQ(END, icon.path[icon.path_size - 1].command) << icon.name;
+ }
+ if (icon.path_1x) {
+ DCHECK(icon.path_1x_size > 0);
+ DCHECK_EQ(END, icon.path_1x[icon.path_1x_size - 1].command) << icon.name;
+ }
const PathElement* path =
(canvas->image_scale() == 1.f && icon.path_1x) ? icon.path_1x : icon.path;
PaintPath(canvas, path, dip_size, color, elapsed_time);
diff --git a/chromium/ui/gfx/paint_vector_icon_unittest.cc b/chromium/ui/gfx/paint_vector_icon_unittest.cc
index bc4a4327b47..6570dc52d8b 100644
--- a/chromium/ui/gfx/paint_vector_icon_unittest.cc
+++ b/chromium/ui/gfx/paint_vector_icon_unittest.cc
@@ -51,7 +51,7 @@ TEST(VectorIconTest, RelativeMoveToAfterClose) {
R_LINE_TO, 50, 51,
END,
};
- const VectorIcon icon = {elements, nullptr};
+ const VectorIcon icon = {elements, arraysize(elements)};
PaintVectorIcon(&canvas, icon, 100, SK_ColorMAGENTA);
sk_sp<cc::PaintRecord> record = recorder.finishRecordingAsPicture();
@@ -88,7 +88,7 @@ TEST(VectorIconTest, FlipsInRtl) {
CLOSE,
END,
};
- const VectorIcon icon = {elements, nullptr};
+ const VectorIcon icon = {elements, arraysize(elements)};
PaintVectorIcon(&canvas, icon, canvas_size, color);
// Count the number of pixels in the canvas.
diff --git a/chromium/ui/gfx/platform_font_win.cc b/chromium/ui/gfx/platform_font_win.cc
index 759caf4ccc2..187ffbdaa03 100644
--- a/chromium/ui/gfx/platform_font_win.cc
+++ b/chromium/ui/gfx/platform_font_win.cc
@@ -24,7 +24,7 @@
#include "base/win/scoped_gdi_object.h"
#include "base/win/scoped_hdc.h"
#include "base/win/scoped_select_object.h"
-#include "base/win/win_util.h"
+#include "base/win/win_client_metrics.h"
#include "third_party/skia/include/core/SkFontLCDConfig.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkTypeface.h"
diff --git a/chromium/ui/gfx/render_text.cc b/chromium/ui/gfx/render_text.cc
index b5f58764ecb..3d706df56ee 100644
--- a/chromium/ui/gfx/render_text.cc
+++ b/chromium/ui/gfx/render_text.cc
@@ -250,12 +250,16 @@ void SkiaTextRenderer::DrawPosText(const SkPoint* pos,
0, 0, flags_);
}
-void SkiaTextRenderer::DrawUnderline(int x, int y, int width) {
+void SkiaTextRenderer::DrawUnderline(int x,
+ int y,
+ int width,
+ SkScalar thickness_factor) {
SkScalar x_scalar = SkIntToScalar(x);
const SkScalar text_size = flags_.getTextSize();
SkRect r = SkRect::MakeLTRB(
x_scalar, y + text_size * kUnderlineOffset, x_scalar + width,
- y + (text_size * (kUnderlineOffset + kLineThicknessFactor)));
+ y + (text_size *
+ (kUnderlineOffset + (thickness_factor * kLineThicknessFactor))));
canvas_skia_->drawRect(r, flags_);
}
@@ -431,6 +435,7 @@ void RenderText::SetFontList(const FontList& font_list) {
weights_.SetValue(font_list.GetFontWeight());
styles_[ITALIC].SetValue((font_style & Font::ITALIC) != 0);
styles_[UNDERLINE].SetValue((font_style & Font::UNDERLINE) != 0);
+ styles_[HEAVY_UNDERLINE].SetValue(false);
baseline_ = kInvalidBaseline;
cached_bounds_and_offset_valid_ = false;
OnLayoutTextAttributeChanged(false);
@@ -913,11 +918,6 @@ SelectionModel RenderText::GetSelectionModelForSelectionStart() const {
sel.is_reversed() ? CURSOR_BACKWARD : CURSOR_FORWARD);
}
-std::vector<Rect> RenderText::GetSubstringBoundsForTesting(
- const gfx::Range& range) {
- return GetSubstringBounds(range);
-}
-
const Vector2d& RenderText::GetUpdatedDisplayOffset() {
UpdateCachedBoundsAndOffset();
return display_offset_;
@@ -1177,11 +1177,11 @@ void RenderText::ApplyCompositionAndSelectionStyles() {
// Save the underline and color breaks to undo the temporary styles later.
DCHECK(!composition_and_selection_styles_applied_);
saved_colors_ = colors_;
- saved_underlines_ = styles_[UNDERLINE];
+ saved_underlines_ = styles_[HEAVY_UNDERLINE];
// Apply an underline to the composition range in |underlines|.
if (composition_range_.IsValid() && !composition_range_.is_empty())
- styles_[UNDERLINE].ApplyValue(true, composition_range_);
+ styles_[HEAVY_UNDERLINE].ApplyValue(true, composition_range_);
// Apply the selected text color to the [un-reversed] selection range.
if (!selection().is_empty() && focused()) {
@@ -1195,7 +1195,7 @@ void RenderText::UndoCompositionAndSelectionStyles() {
// Restore the underline and color breaks to undo the temporary styles.
DCHECK(composition_and_selection_styles_applied_);
colors_ = saved_colors_;
- styles_[UNDERLINE] = saved_underlines_;
+ styles_[HEAVY_UNDERLINE] = saved_underlines_;
composition_and_selection_styles_applied_ = false;
}
@@ -1728,4 +1728,18 @@ Range RenderText::ExpandRangeToWordBoundary(const Range& range) const {
: Range(range_min, range_max);
}
+internal::TextRunList* RenderText::GetRunList() {
+ NOTREACHED();
+ return nullptr;
+}
+
+const internal::TextRunList* RenderText::GetRunList() const {
+ NOTREACHED();
+ return nullptr;
+}
+
+void RenderText::SetGlyphWidthForTest(float test_width) {
+ NOTREACHED();
+}
+
} // namespace gfx
diff --git a/chromium/ui/gfx/render_text.h b/chromium/ui/gfx/render_text.h
index 0b8b82a2bc8..47fa4c605ce 100644
--- a/chromium/ui/gfx/render_text.h
+++ b/chromium/ui/gfx/render_text.h
@@ -50,6 +50,8 @@ class Font;
namespace internal {
+class TextRunList;
+
// Internal helper class used by derived classes to draw text through Skia.
class GFX_EXPORT SkiaTextRenderer {
public:
@@ -68,7 +70,7 @@ class GFX_EXPORT SkiaTextRenderer {
virtual void DrawPosText(const SkPoint* pos,
const uint16_t* glyphs,
size_t glyph_count);
- void DrawUnderline(int x, int y, int width);
+ void DrawUnderline(int x, int y, int width, SkScalar thickness_factor = 1.0);
void DrawStrike(int x, int y, int width, SkScalar thickness_factor);
private:
@@ -478,8 +480,13 @@ class GFX_EXPORT RenderText {
// chosen.
virtual std::vector<FontSpan> GetFontSpansForTesting() = 0;
- // Helper function to be used in tests for retrieving the substring bounds.
- std::vector<Rect> GetSubstringBoundsForTesting(const gfx::Range& range);
+ // Get the visual bounds containing the logical substring within the |range|.
+ // If |range| is empty, the result is empty. These bounds could be visually
+ // discontinuous if the substring is split by a LTR/RTL level change.
+ // These bounds are in local coordinates, but may be outside the visible
+ // region if the text is longer than the textfield. Subsequent text, cursor,
+ // or bounds changes may invalidate returned values.
+ virtual std::vector<Rect> GetSubstringBounds(const Range& range) = 0;
// Gets the horizontal span (relative to the left of the text, not the view)
// of the sequence of glyphs in |text_range|, over which the cursor will
@@ -585,14 +592,6 @@ class GFX_EXPORT RenderText {
// Sets the selection model, |model| is assumed to be valid.
void SetSelectionModel(const SelectionModel& model);
- // Get the visual bounds containing the logical substring within the |range|.
- // If |range| is empty, the result is empty. These bounds could be visually
- // discontinuous if the substring is split by a LTR/RTL level change.
- // These bounds are in local coordinates, but may be outside the visible
- // region if the text is longer than the textfield. Subsequent text, cursor,
- // or bounds changes may invalidate returned values.
- virtual std::vector<Rect> GetSubstringBounds(const Range& range) = 0;
-
// Convert between indices into |text_| and indices into
// GetDisplayText(), which differ when the text is obscured,
// truncated or elided. Regardless of whether or not the text is
@@ -704,11 +703,20 @@ class GFX_EXPORT RenderText {
// range. Maintains directionality of |range|.
Range ExpandRangeToWordBoundary(const Range& range) const;
+ // Returns an implementation-specific run list, if implemented.
+ virtual internal::TextRunList* GetRunList();
+ virtual const internal::TextRunList* GetRunList() const;
+
// Returns the decorated text corresponding to |range|. Returns false if the
// text cannot be retrieved, e.g. if the text is obscured.
virtual bool GetDecoratedTextForRange(const Range& range,
DecoratedText* decorated_text) = 0;
+ // Specify the width of a glyph for test. The width of glyphs is very
+ // platform-dependent and environment-dependent. Otherwise multiline text
+ // will become really flaky.
+ virtual void SetGlyphWidthForTest(float test_width);
+
// Logical UTF-16 string data to be drawn.
base::string16 text_;
diff --git a/chromium/ui/gfx/render_text_harfbuzz.cc b/chromium/ui/gfx/render_text_harfbuzz.cc
index 79a7a863cd1..9178adbe330 100644
--- a/chromium/ui/gfx/render_text_harfbuzz.cc
+++ b/chromium/ui/gfx/render_text_harfbuzz.cc
@@ -674,7 +674,8 @@ TextRunHarfBuzz::TextRunHarfBuzz(const Font& template_font)
italic(false),
weight(Font::Weight::NORMAL),
strike(false),
- underline(false) {}
+ underline(false),
+ heavy_underline(false) {}
TextRunHarfBuzz::~TextRunHarfBuzz() {}
@@ -1130,61 +1131,27 @@ SelectionModel RenderTextHarfBuzz::AdjacentWordSelectionModel(
if (!success)
return selection;
- // Match OS specific word break behavior.
-#if defined(OS_WIN)
- size_t pos;
- if (direction == CURSOR_RIGHT) {
- pos = std::min(selection.caret_pos() + 1, text().length());
- while (iter.Advance()) {
- pos = iter.pos();
- if (iter.IsWord() && pos > selection.caret_pos()) {
- // In Windows, word move advances past any characters separating the
- // end of the current word from the next word.
- while (iter.Advance() && !iter.IsWord())
- pos = iter.pos();
- break;
- }
- }
- } else { // direction == CURSOR_LEFT
- // Notes: We always iterate words from the beginning.
- // This is probably fast enough for our usage, but we may
- // want to modify WordIterator so that it can start from the
- // middle of string and advance backwards.
- pos = std::max<int>(selection.caret_pos() - 1, 0);
- while (iter.Advance()) {
- if (iter.IsWord()) {
- size_t begin = iter.pos() - iter.GetString().length();
- if (begin == selection.caret_pos()) {
- // The cursor is at the beginning of a word.
- // Move to previous word.
- break;
- } else if (iter.pos() >= selection.caret_pos()) {
- // The cursor is in the middle or at the end of a word.
- // Move to the top of current word.
- pos = begin;
- break;
- }
- pos = iter.pos() - iter.GetString().length();
- }
- }
- }
- return SelectionModel(pos, CURSOR_FORWARD);
-#else
internal::TextRunList* run_list = GetRunList();
- SelectionModel cur(selection);
+ SelectionModel current(selection);
for (;;) {
- cur = AdjacentCharSelectionModel(cur, direction);
- size_t run = GetRunContainingCaret(cur);
+ current = AdjacentCharSelectionModel(current, direction);
+ size_t run = GetRunContainingCaret(current);
if (run == run_list->size())
break;
+ size_t cursor = current.caret_pos();
+#if defined(OS_WIN)
+ // Windows generally advances to the start of a word in either direction.
+ // TODO: Break on the end of a word when the neighboring text is puctuation.
+ if (iter.IsStartOfWord(cursor))
+ break;
+#else
const bool is_forward =
run_list->runs()[run]->is_rtl == (direction == CURSOR_LEFT);
- size_t cursor = cur.caret_pos();
if (is_forward ? iter.IsEndOfWord(cursor) : iter.IsStartOfWord(cursor))
break;
+#endif // defined(OS_WIN)
}
- return cur;
-#endif
+ return current;
}
std::vector<Rect> RenderTextHarfBuzz::GetSubstringBounds(const Range& range) {
@@ -1367,7 +1334,9 @@ void RenderTextHarfBuzz::DrawVisualText(internal::SkiaTextRenderer* renderer) {
? (SkFloatToScalar(segment.width()) + preceding_segment_widths +
SkIntToScalar(origin.x()))
: positions[colored_glyphs.end() - glyphs_range.start()].x());
- if (run.underline)
+ if (run.heavy_underline)
+ renderer->DrawUnderline(start_x, origin.y(), end_x - start_x, 2.0);
+ else if (run.underline)
renderer->DrawUnderline(start_x, origin.y(), end_x - start_x);
if (run.strike)
renderer->DrawStrike(start_x, origin.y(), end_x - start_x,
@@ -1456,6 +1425,7 @@ void RenderTextHarfBuzz::ItemizeTextToRuns(
run->baseline_type = style.baseline();
run->strike = style.style(STRIKE);
run->underline = style.style(UNDERLINE);
+ run->heavy_underline = style.style(HEAVY_UNDERLINE);
run->weight = style.weight();
int32_t script_item_break = 0;
bidi_iterator.GetLogicalRun(run_break, &script_item_break, &run->level);
@@ -1739,6 +1709,8 @@ void RenderTextHarfBuzz::EnsureLayoutRunList() {
}
}
+// Returns the current run list, |display_run_list_| if the text is elided, or
+// |layout_run_list_| otherwise.
internal::TextRunList* RenderTextHarfBuzz::GetRunList() {
DCHECK(!update_layout_run_list_);
DCHECK(!update_display_run_list_);
@@ -1771,7 +1743,7 @@ bool RenderTextHarfBuzz::GetDecoratedTextForRange(
int style = Font::NORMAL;
if (run.italic)
style |= Font::ITALIC;
- if (run.underline)
+ if (run.underline || run.heavy_underline)
style |= Font::UNDERLINE;
// Get range relative to the decorated text.
@@ -1787,4 +1759,8 @@ bool RenderTextHarfBuzz::GetDecoratedTextForRange(
return true;
}
+void RenderTextHarfBuzz::SetGlyphWidthForTest(float test_width) {
+ glyph_width_for_test_ = test_width;
+}
+
} // namespace gfx
diff --git a/chromium/ui/gfx/render_text_harfbuzz.h b/chromium/ui/gfx/render_text_harfbuzz.h
index b883e84fddf..983b225548d 100644
--- a/chromium/ui/gfx/render_text_harfbuzz.h
+++ b/chromium/ui/gfx/render_text_harfbuzz.h
@@ -91,6 +91,7 @@ struct GFX_EXPORT TextRunHarfBuzz {
Font::Weight weight;
bool strike;
bool underline;
+ bool heavy_underline;
private:
DISALLOW_COPY_AND_ASSIGN(TextRunHarfBuzz);
@@ -193,13 +194,6 @@ class GFX_EXPORT RenderTextHarfBuzz : public RenderText {
friend class test::RenderTextTestApi;
friend class RenderTextHarfBuzzTest;
- // Specify the width of a glyph for test. The width of glyphs is very
- // platform-dependent and environment-dependent. Otherwise multiline test
- // will become really flaky.
- void set_glyph_width_for_test(float test_width) {
- glyph_width_for_test_ = test_width;
- }
-
// Return the run index that contains the argument; or the length of the
// |runs_| vector if argument exceeds the text length or width.
size_t GetRunContainingCaret(const SelectionModel& caret);
@@ -245,14 +239,12 @@ class GFX_EXPORT RenderTextHarfBuzz : public RenderText {
// Makes sure that text runs for layout text are shaped.
void EnsureLayoutRunList();
- // Returns the current run list, |display_run_list_| if the text is
- // elided, or |layout_run_list_| otherwise.
- internal::TextRunList* GetRunList();
- const internal::TextRunList* GetRunList() const;
-
// RenderText:
+ internal::TextRunList* GetRunList() override;
+ const internal::TextRunList* GetRunList() const override;
bool GetDecoratedTextForRange(const Range& range,
DecoratedText* decorated_text) override;
+ void SetGlyphWidthForTest(float test_width) override;
// Text run list for |layout_text_| and |display_text_|.
// |display_run_list_| is created only when the text is elided.
diff --git a/chromium/ui/gfx/render_text_mac.mm b/chromium/ui/gfx/render_text_mac.mm
index c6f256d01c1..bf162b3ddfc 100644
--- a/chromium/ui/gfx/render_text_mac.mm
+++ b/chromium/ui/gfx/render_text_mac.mm
@@ -360,8 +360,10 @@ base::ScopedCFTypeRef<CFMutableArrayRef> RenderTextMac::ApplyStyles(
kCTForegroundColorAttributeName, foreground);
CFArrayAppendValue(attributes, foreground);
- if (style.style(UNDERLINE)) {
- CTUnderlineStyle value = kCTUnderlineStyleSingle;
+ if (style.style(UNDERLINE) || style.style(HEAVY_UNDERLINE)) {
+ CTUnderlineStyle value = style.style(HEAVY_UNDERLINE)
+ ? kCTUnderlineStyleThick
+ : kCTUnderlineStyleSingle;
base::ScopedCFTypeRef<CFNumberRef> underline_value(
CFNumberCreate(NULL, kCFNumberSInt32Type, &value));
CFAttributedStringSetAttribute(
diff --git a/chromium/ui/gfx/render_text_test_api.h b/chromium/ui/gfx/render_text_test_api.h
new file mode 100644
index 00000000000..dbb6c4436e6
--- /dev/null
+++ b/chromium/ui/gfx/render_text_test_api.h
@@ -0,0 +1,87 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/macros.h"
+#include "ui/gfx/break_list.h"
+#include "ui/gfx/geometry/vector2d.h"
+#include "ui/gfx/render_text.h"
+#include "ui/gfx/selection_model.h"
+
+namespace gfx {
+namespace test {
+
+class RenderTextTestApi {
+ public:
+ RenderTextTestApi(RenderText* render_text) : render_text_(render_text) {}
+
+ static cc::PaintFlags& GetRendererPaint(
+ internal::SkiaTextRenderer* renderer) {
+ return renderer->flags_;
+ }
+
+ // Callers must ensure that the associated RenderText object is a
+ // RenderTextHarfBuzz instance.
+ const internal::TextRunList* GetHarfBuzzRunList() const {
+ return render_text_->GetRunList();
+ }
+
+ void DrawVisualText(internal::SkiaTextRenderer* renderer) {
+ render_text_->EnsureLayout();
+ render_text_->DrawVisualText(renderer);
+ }
+
+ const BreakList<SkColor>& colors() const { return render_text_->colors(); }
+
+ const BreakList<BaselineStyle>& baselines() const {
+ return render_text_->baselines();
+ }
+
+ const BreakList<Font::Weight>& weights() const {
+ return render_text_->weights();
+ }
+
+ const std::vector<BreakList<bool>>& styles() const {
+ return render_text_->styles();
+ }
+
+ const std::vector<internal::Line>& lines() const {
+ return render_text_->lines();
+ }
+
+ SelectionModel EdgeSelectionModel(VisualCursorDirection direction) {
+ return render_text_->EdgeSelectionModel(direction);
+ }
+
+ size_t TextIndexToDisplayIndex(size_t index) {
+ return render_text_->TextIndexToDisplayIndex(index);
+ }
+
+ size_t DisplayIndexToTextIndex(size_t index) {
+ return render_text_->DisplayIndexToTextIndex(index);
+ }
+
+ void EnsureLayout() { render_text_->EnsureLayout(); }
+
+ Vector2d GetAlignmentOffset(size_t line_number) {
+ return render_text_->GetAlignmentOffset(line_number);
+ }
+
+ int GetDisplayTextBaseline() {
+ return render_text_->GetDisplayTextBaseline();
+ }
+
+ // Callers must ensure that the underlying RenderText object is a
+ // RenderTextHarfBuzz instance.
+ void SetGlyphWidth(float test_width) {
+ render_text_->SetGlyphWidthForTest(test_width);
+ }
+
+ private:
+ RenderText* render_text_;
+
+ DISALLOW_COPY_AND_ASSIGN(RenderTextTestApi);
+};
+
+} // namespace test
+} // namespace gfx
diff --git a/chromium/ui/gfx/render_text_unittest.cc b/chromium/ui/gfx/render_text_unittest.cc
index ea11f5453ed..5a47cee1adf 100644
--- a/chromium/ui/gfx/render_text_unittest.cc
+++ b/chromium/ui/gfx/render_text_unittest.cc
@@ -39,6 +39,7 @@
#include "ui/gfx/range/range.h"
#include "ui/gfx/range/range_f.h"
#include "ui/gfx/render_text_harfbuzz.h"
+#include "ui/gfx/render_text_test_api.h"
#include "ui/gfx/switches.h"
#include "ui/gfx/text_utils.h"
@@ -58,77 +59,6 @@ using base::UTF8ToUTF16;
using base::WideToUTF16;
namespace gfx {
-namespace test {
-
-class RenderTextTestApi {
- public:
- RenderTextTestApi(RenderText* render_text) : render_text_(render_text) {}
-
- static cc::PaintFlags& GetRendererPaint(
- internal::SkiaTextRenderer* renderer) {
- return renderer->flags_;
- }
-
- // Callers should ensure that the associated RenderText object is a
- // RenderTextHarfBuzz instance.
- const internal::TextRunList* GetHarfBuzzRunList() const {
- RenderTextHarfBuzz* render_text =
- static_cast<RenderTextHarfBuzz*>(render_text_);
- return render_text->GetRunList();
- }
-
- void DrawVisualText(internal::SkiaTextRenderer* renderer) {
- render_text_->EnsureLayout();
- render_text_->DrawVisualText(renderer);
- }
-
- const BreakList<SkColor>& colors() const { return render_text_->colors(); }
-
- const BreakList<BaselineStyle>& baselines() const {
- return render_text_->baselines();
- }
-
- const BreakList<Font::Weight>& weights() const {
- return render_text_->weights();
- }
-
- const std::vector<BreakList<bool>>& styles() const {
- return render_text_->styles();
- }
-
- const std::vector<internal::Line>& lines() const {
- return render_text_->lines();
- }
-
- SelectionModel EdgeSelectionModel(VisualCursorDirection direction) {
- return render_text_->EdgeSelectionModel(direction);
- }
-
- size_t TextIndexToDisplayIndex(size_t index) {
- return render_text_->TextIndexToDisplayIndex(index);
- }
-
- size_t DisplayIndexToTextIndex(size_t index) {
- return render_text_->DisplayIndexToTextIndex(index);
- }
-
- void EnsureLayout() { render_text_->EnsureLayout(); }
-
- Vector2d GetAlignmentOffset(size_t line_number) {
- return render_text_->GetAlignmentOffset(line_number);
- }
-
- int GetDisplayTextBaseline() {
- return render_text_->GetDisplayTextBaseline();
- }
-
- private:
- RenderText* render_text_;
-
- DISALLOW_COPY_AND_ASSIGN(RenderTextTestApi);
-};
-
-} // namespace test
namespace {
@@ -533,8 +463,7 @@ class RenderTextTest : public testing::Test,
#endif
Rect GetSubstringBoundsUnion(const Range& range) {
- const std::vector<Rect> bounds =
- render_text_->GetSubstringBoundsForTesting(range);
+ const std::vector<Rect> bounds = render_text_->GetSubstringBounds(range);
return std::accumulate(bounds.begin(), bounds.end(), Rect(), UnionRects);
}
@@ -616,7 +545,7 @@ class RenderTextHarfBuzzTest : public RenderTextTest {
protected:
void SetGlyphWidth(float test_width) {
- GetRenderTextHarfBuzz()->set_glyph_width_for_test(test_width);
+ test_api()->SetGlyphWidth(test_width);
}
bool ShapeRunWithFont(const base::string16& text,
@@ -1479,6 +1408,102 @@ TEST_P(RenderTextHarfBuzzTest, MoveCursor_Word) {
SELECTION_EXTEND, &expected);
}
+// TODO(asvitkine): RenderTextMac cursor movements. http://crbug.com/131618
+TEST_P(RenderTextHarfBuzzTest, MoveCursor_Word_RTL) {
+ RenderText* render_text = GetRenderText();
+ render_text->SetText(UTF8ToUTF16("אבג דהו זחט"));
+ std::vector<Range> expected;
+
+ // SELECTION_NONE.
+ render_text->SelectRange(Range(6));
+
+ // Move right twice.
+ expected.push_back(Range(4));
+ expected.push_back(Range(0));
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_RIGHT,
+ SELECTION_NONE, &expected);
+
+ // Move left twice.
+#if defined(OS_WIN) // Move word left includes space/punctuation.
+ expected.push_back(Range(4));
+ expected.push_back(Range(8));
+#else // Non-Windows: move word left does NOT include space/punctuation.
+ expected.push_back(Range(3));
+ expected.push_back(Range(7));
+#endif
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_LEFT,
+ SELECTION_NONE, &expected);
+
+ // SELECTION_CARET.
+ render_text->SelectRange(Range(6));
+
+ // Move right.
+ expected.push_back(Range(6, 4));
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_RIGHT,
+ SELECTION_CARET, &expected);
+
+ // Move left twice.
+ expected.push_back(Range(6));
+#if defined(OS_WIN) // Select word left includes space/punctuation.
+ expected.push_back(Range(6, 8));
+#else // Non-Windows: select word left does NOT include space/punctuation.
+ expected.push_back(Range(6, 7));
+#endif
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_LEFT,
+ SELECTION_CARET, &expected);
+
+ // Move right.
+ expected.push_back(Range(6));
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_RIGHT,
+ SELECTION_CARET, &expected);
+
+ // SELECTION_RETAIN.
+ render_text->SelectRange(Range(6));
+
+ // Move right.
+ expected.push_back(Range(6, 4));
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_RIGHT,
+ SELECTION_RETAIN, &expected);
+
+ // Move left twice.
+#if defined(OS_WIN) // Select word left includes space/punctuation.
+ expected.push_back(Range(6, 8));
+#else // Non-Windows: select word left does NOT include space/punctuation.
+ expected.push_back(Range(6, 7));
+#endif
+ expected.push_back(Range(6, 11));
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_LEFT,
+ SELECTION_RETAIN, &expected);
+
+ // Move right.
+ expected.push_back(Range(6, 8));
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_RIGHT,
+ SELECTION_RETAIN, &expected);
+
+ // SELECTION_EXTEND.
+ render_text->SelectRange(Range(6));
+
+ // Move right.
+ expected.push_back(Range(6, 4));
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_RIGHT,
+ SELECTION_EXTEND, &expected);
+
+ // Move left twice.
+#if defined(OS_WIN) // Select word left includes space/punctuation.
+ expected.push_back(Range(4, 8));
+#else // Non-Windows: select word left does NOT include space/punctuation.
+ expected.push_back(Range(4, 7));
+#endif
+ expected.push_back(Range(4, 11));
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_LEFT,
+ SELECTION_EXTEND, &expected);
+
+ // Move right.
+ expected.push_back(Range(4, 8));
+ RunMoveCursorTestAndClearExpectations(render_text, WORD_BREAK, CURSOR_RIGHT,
+ SELECTION_EXTEND, &expected);
+}
+
TEST_P(RenderTextTest, MoveCursor_Line) {
RenderText* render_text = GetRenderText();
render_text->SetText(UTF8ToUTF16("123 456 789"));
@@ -2477,25 +2502,26 @@ TEST_P(RenderTextTest, StringSizeEmptyString) {
}
TEST_P(RenderTextTest, StringSizeRespectsFontListMetrics) {
- // Check that Arial and the CJK font have different font metrics.
- Font arial_font("Arial", 16);
- ASSERT_EQ("arial",
- base::ToLowerASCII(arial_font.GetActualFontNameForTesting()));
+ // Check that Verdana and the CJK font have different font metrics.
+ Font verdana_font("Verdana", 16);
+ ASSERT_EQ("verdana",
+ base::ToLowerASCII(verdana_font.GetActualFontNameForTesting()));
Font cjk_font(kCJKFontName, 16);
ASSERT_EQ(base::ToLowerASCII(kCJKFontName),
base::ToLowerASCII(cjk_font.GetActualFontNameForTesting()));
- EXPECT_NE(arial_font.GetHeight(), cjk_font.GetHeight());
- EXPECT_NE(arial_font.GetBaseline(), cjk_font.GetBaseline());
- // "a" should be rendered with Arial, not with the CJK font.
- const char* arial_font_text = "a";
- // "円" (U+5168 Han character YEN) should render with the CJK font, not Arial.
+ EXPECT_NE(verdana_font.GetHeight(), cjk_font.GetHeight());
+ EXPECT_NE(verdana_font.GetBaseline(), cjk_font.GetBaseline());
+ // "a" should be rendered with Verdana, not with the CJK font.
+ const char* verdana_font_text = "a";
+ // "円" (U+5168 Han character YEN) should render with the CJK font, not
+ // Verdana.
const char* cjk_font_text = "\u5168";
- Font smaller_font = arial_font;
+ Font smaller_font = verdana_font;
Font larger_font = cjk_font;
- const char* smaller_font_text = arial_font_text;
+ const char* smaller_font_text = verdana_font_text;
const char* larger_font_text = cjk_font_text;
- if (cjk_font.GetHeight() < arial_font.GetHeight() &&
- cjk_font.GetBaseline() < arial_font.GetBaseline()) {
+ if (cjk_font.GetHeight() < verdana_font.GetHeight() &&
+ cjk_font.GetBaseline() < verdana_font.GetBaseline()) {
std::swap(smaller_font, larger_font);
std::swap(smaller_font_text, larger_font_text);
}
diff --git a/chromium/ui/gfx/sequential_id_generator_unittest.cc b/chromium/ui/gfx/sequential_id_generator_unittest.cc
index 049ed7ac556..c4f98b795b6 100644
--- a/chromium/ui/gfx/sequential_id_generator_unittest.cc
+++ b/chromium/ui/gfx/sequential_id_generator_unittest.cc
@@ -44,4 +44,5 @@ TEST(SequentialIDGeneratorTest, MaybeRemoveNumbers) {
EXPECT_FALSE(generator.HasGeneratedIDFor(42));
generator.ReleaseNumber(42);
}
+
} // namespace ui
diff --git a/chromium/ui/gfx/shadow_value.cc b/chromium/ui/gfx/shadow_value.cc
index 9f177974801..ba552bace1b 100644
--- a/chromium/ui/gfx/shadow_value.cc
+++ b/chromium/ui/gfx/shadow_value.cc
@@ -10,6 +10,7 @@
#include "base/strings/stringprintf.h"
#include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/safe_integer_conversions.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
namespace gfx {
@@ -28,8 +29,7 @@ Insets GetInsets(const ShadowValues& shadows, bool include_inner_blur) {
double blur = shadow.blur();
if (!include_inner_blur)
blur /= 2;
- // Add 0.5 to round up to the next integer.
- int blur_length = static_cast<int>(blur + 0.5);
+ int blur_length = ToRoundedInt(blur);
left = std::max(left, blur_length - shadow.x());
top = std::max(top, blur_length - shadow.y());
@@ -42,16 +42,6 @@ Insets GetInsets(const ShadowValues& shadows, bool include_inner_blur) {
} // namespace
-ShadowValue::ShadowValue() : blur_(0), color_(0) {}
-
-ShadowValue::ShadowValue(const gfx::Vector2d& offset,
- double blur,
- SkColor color)
- : offset_(offset), blur_(blur), color_(color) {
-}
-
-ShadowValue::~ShadowValue() {}
-
ShadowValue ShadowValue::Scale(float scale) const {
gfx::Vector2d scaled_offset =
gfx::ToFlooredVector2d(gfx::ScaleVector2d(offset_, scale));
diff --git a/chromium/ui/gfx/shadow_value.h b/chromium/ui/gfx/shadow_value.h
index 7723a8b1e07..d212678ff29 100644
--- a/chromium/ui/gfx/shadow_value.h
+++ b/chromium/ui/gfx/shadow_value.h
@@ -6,6 +6,7 @@
#define UI_GFX_SHADOW_VALUE_H_
#include <string>
+#include <tuple>
#include <vector>
#include "third_party/skia/include/core/SkColor.h"
@@ -23,15 +24,20 @@ typedef std::vector<ShadowValue> ShadowValues;
// shadow's offset, blur amount and color.
class GFX_EXPORT ShadowValue {
public:
- ShadowValue();
- ShadowValue(const gfx::Vector2d& offset, double blur, SkColor color);
- ~ShadowValue();
+ constexpr ShadowValue() = default;
+ constexpr ShadowValue(const gfx::Vector2d& offset, double blur, SkColor color)
+ : offset_(offset), blur_(blur), color_(color) {}
- int x() const { return offset_.x(); }
- int y() const { return offset_.y(); }
- const gfx::Vector2d& offset() const { return offset_; }
- double blur() const { return blur_; }
- SkColor color() const { return color_; }
+ constexpr int x() const { return offset_.x(); }
+ constexpr int y() const { return offset_.y(); }
+ constexpr const gfx::Vector2d& offset() const { return offset_; }
+ constexpr double blur() const { return blur_; }
+ constexpr SkColor color() const { return color_; }
+
+ constexpr bool operator==(const ShadowValue& other) const {
+ return offset_ == other.offset_ && blur_ == other.blur_ &&
+ color_ == other.color_;
+ }
ShadowValue Scale(float scale) const;
@@ -63,16 +69,11 @@ class GFX_EXPORT ShadowValue {
// amount of 4.0 means to have a blurry shadow edge of 4 pixels that
// transitions from full shadow color to fully transparent and with 2 pixels
// inside the shadow and 2 pixels goes beyond the edge.
- double blur_;
+ double blur_ = 0.;
- SkColor color_;
+ SkColor color_ = SK_ColorTRANSPARENT;
};
-inline bool operator==(const ShadowValue& lhs, const ShadowValue& rhs) {
- return lhs.offset() == rhs.offset() && lhs.blur() == rhs.blur() &&
- lhs.color() == rhs.color();
-}
-
} // namespace gfx
#endif // UI_GFX_SHADOW_VALUE_H_
diff --git a/chromium/ui/gfx/shadow_value_unittest.cc b/chromium/ui/gfx/shadow_value_unittest.cc
index fb065b82e21..d93e0967bbf 100644
--- a/chromium/ui/gfx/shadow_value_unittest.cc
+++ b/chromium/ui/gfx/shadow_value_unittest.cc
@@ -13,45 +13,49 @@
namespace gfx {
TEST(ShadowValueTest, GetMargin) {
- const struct TestCase {
+ constexpr struct TestCase {
Insets expected_margin;
size_t shadow_count;
ShadowValue shadows[2];
} kTestCases[] = {
- {
- Insets(), 0, {},
- },
- {
- Insets(-2, -2, -2, -2),
- 1,
- { ShadowValue(gfx::Vector2d(0, 0), 4, 0), },
- },
- {
- Insets(0, -1, -4, -3),
- 1,
- { ShadowValue(gfx::Vector2d(1, 2), 4, 0), },
- },
- {
- Insets(-4, -3, 0, -1),
- 1,
- { ShadowValue(gfx::Vector2d(-1, -2), 4, 0), },
- },
- {
- Insets(0, -1, -5, -4),
- 2,
{
- ShadowValue(gfx::Vector2d(1, 2), 4, 0),
- ShadowValue(gfx::Vector2d(2, 3), 4, 0),
+ Insets(), 0, {},
},
- },
- {
- Insets(-4, -3, -5, -4),
- 2,
{
- ShadowValue(gfx::Vector2d(-1, -2), 4, 0),
- ShadowValue(gfx::Vector2d(2, 3), 4, 0),
+ Insets(-2, -2, -2, -2),
+ 1,
+ {
+ {gfx::Vector2d(0, 0), 4, 0},
+ },
+ },
+ {
+ Insets(0, -1, -4, -3),
+ 1,
+ {
+ {gfx::Vector2d(1, 2), 4, 0},
+ },
+ },
+ {
+ Insets(-4, -3, 0, -1),
+ 1,
+ {
+ {gfx::Vector2d(-1, -2), 4, 0},
+ },
+ },
+ {
+ Insets(0, -1, -5, -4),
+ 2,
+ {
+ {gfx::Vector2d(1, 2), 4, 0}, {gfx::Vector2d(2, 3), 4, 0},
+ },
+ },
+ {
+ Insets(-4, -3, -5, -4),
+ 2,
+ {
+ {gfx::Vector2d(-1, -2), 4, 0}, {gfx::Vector2d(2, 3), 4, 0},
+ },
},
- },
};
for (size_t i = 0; i < arraysize(kTestCases); ++i) {
diff --git a/chromium/ui/gfx/skia_paint_util.cc b/chromium/ui/gfx/skia_paint_util.cc
index 3c126e73566..df9dcded399 100644
--- a/chromium/ui/gfx/skia_paint_util.cc
+++ b/chromium/ui/gfx/skia_paint_util.cc
@@ -40,8 +40,9 @@ sk_sp<cc::PaintShader> CreateImageRepShaderForScale(
return cc::PaintShader::MakeImage(
cc::PaintImageBuilder::WithDefault()
- .set_id(cc::PaintImage::kNonLazyStableId)
- .set_image(SkImage::MakeFromBitmap(image_rep.sk_bitmap()))
+ .set_id(cc::PaintImage::GetNextId())
+ .set_image(SkImage::MakeFromBitmap(image_rep.sk_bitmap()),
+ cc::PaintImage::GetNextContentId())
.TakePaintImage(),
tile_mode, tile_mode, &shader_scale);
}
diff --git a/chromium/ui/gfx/text_constants.h b/chromium/ui/gfx/text_constants.h
index 431195c7707..0ca89b1f228 100644
--- a/chromium/ui/gfx/text_constants.h
+++ b/chromium/ui/gfx/text_constants.h
@@ -81,6 +81,7 @@ enum TextStyle {
ITALIC = 0,
STRIKE,
UNDERLINE,
+ HEAVY_UNDERLINE,
NUM_TEXT_STYLES,
};
diff --git a/chromium/ui/gfx/text_utils.cc b/chromium/ui/gfx/text_utils.cc
index 9dbc32b2662..d462b678c9e 100644
--- a/chromium/ui/gfx/text_utils.cc
+++ b/chromium/ui/gfx/text_utils.cc
@@ -7,6 +7,7 @@
#include <stdint.h>
#include "base/i18n/char_iterator.h"
+#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "third_party/icu/source/common/unicode/uchar.h"
@@ -108,4 +109,13 @@ size_t FindValidBoundaryAfter(const base::string16& text, size_t index) {
return static_cast<size_t>(text_index);
}
+HorizontalAlignment MaybeFlipForRTL(HorizontalAlignment alignment) {
+ if (base::i18n::IsRTL() &&
+ (alignment == gfx::ALIGN_LEFT || alignment == gfx::ALIGN_RIGHT)) {
+ alignment =
+ (alignment == gfx::ALIGN_LEFT) ? gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
+ }
+ return alignment;
+}
+
} // namespace gfx
diff --git a/chromium/ui/gfx/text_utils.h b/chromium/ui/gfx/text_utils.h
index 010c7cab062..462d7690dd7 100644
--- a/chromium/ui/gfx/text_utils.h
+++ b/chromium/ui/gfx/text_utils.h
@@ -47,6 +47,9 @@ FindValidBoundaryBefore(const base::string16& text, size_t index);
GFX_EXPORT size_t
FindValidBoundaryAfter(const base::string16& text, size_t index);
+// If the UI layout is right-to-left, flip the alignment direction.
+GFX_EXPORT HorizontalAlignment MaybeFlipForRTL(HorizontalAlignment alignment);
+
} // namespace gfx
#endif // UI_GFX_TEXT_UTILS_H_
diff --git a/chromium/ui/gfx/vector_icon_types.h b/chromium/ui/gfx/vector_icon_types.h
index d1cba9b3e7d..fae6871dffb 100644
--- a/chromium/ui/gfx/vector_icon_types.h
+++ b/chromium/ui/gfx/vector_icon_types.h
@@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// This file provides defines needed by PaintVectorIcon and is implemented
-// by the generated file vector_icons.cc.
-
#ifndef UI_GFX_VECTOR_ICON_TYPES_H_
#define UI_GFX_VECTOR_ICON_TYPES_H_
@@ -66,7 +63,8 @@ enum CommandType {
// Parameters are delay (ms), duration (ms), and tween type
// (gfx::Tween::Type).
TRANSITION_END,
- // Marks the end of the list of commands.
+ // Marks the end of the list of commands. TODO(estade): remove this sentinel
+ // value and rely on VectorIcon::path_size.
END
};
@@ -86,8 +84,20 @@ struct VectorIcon {
bool is_empty() const { return !path; }
- const gfx::PathElement* path;
- const gfx::PathElement* path_1x;
+ const gfx::PathElement* path = nullptr;
+ // The length of |path|.
+ size_t path_size = 0u;
+
+ const gfx::PathElement* path_1x = nullptr;
+ // The length of |path_1x|.
+ size_t path_1x_size = 0u;
+
+ // A human-readable name, useful for debugging, derived from the name of the
+ // icon file. This can also be used as an identifier, but vector icon targets
+ // should be careful to ensure this is unique.
+ const char* name = nullptr;
+
+ bool operator<(const VectorIcon& other) const;
private:
DISALLOW_COPY_AND_ASSIGN(VectorIcon);
diff --git a/chromium/ui/gfx/vsync_provider.cc b/chromium/ui/gfx/vsync_provider.cc
index d54ffe8c060..6276b7f3d0a 100644
--- a/chromium/ui/gfx/vsync_provider.cc
+++ b/chromium/ui/gfx/vsync_provider.cc
@@ -19,8 +19,12 @@ bool FixedVSyncProvider::GetVSyncParametersIfAvailable(
return true;
}
-bool FixedVSyncProvider::SupportGetVSyncParametersIfAvailable() {
+bool FixedVSyncProvider::SupportGetVSyncParametersIfAvailable() const {
return true;
}
+bool FixedVSyncProvider::IsHWClock() const {
+ return false;
+}
+
} // namespace gfx
diff --git a/chromium/ui/gfx/vsync_provider.h b/chromium/ui/gfx/vsync_provider.h
index a1c1098d185..e8aa0fe7028 100644
--- a/chromium/ui/gfx/vsync_provider.h
+++ b/chromium/ui/gfx/vsync_provider.h
@@ -33,7 +33,10 @@ class GFX_EXPORT VSyncProvider {
base::TimeDelta* interval) = 0;
// Returns true, if GetVSyncParametersIfAvailable is supported.
- virtual bool SupportGetVSyncParametersIfAvailable() = 0;
+ virtual bool SupportGetVSyncParametersIfAvailable() const = 0;
+
+ // Returns true, if VSyncProvider gets VSync timebase from HW.
+ virtual bool IsHWClock() const = 0;
};
// Provides a constant timebase and interval.
@@ -48,7 +51,8 @@ class GFX_EXPORT FixedVSyncProvider : public VSyncProvider {
void GetVSyncParameters(const UpdateVSyncCallback& callback) override;
bool GetVSyncParametersIfAvailable(base::TimeTicks* timebase,
base::TimeDelta* interval) override;
- bool SupportGetVSyncParametersIfAvailable() override;
+ bool SupportGetVSyncParametersIfAvailable() const override;
+ bool IsHWClock() const override;
private:
base::TimeTicks timebase_;
diff --git a/chromium/ui/gfx/win/rendering_window_manager.cc b/chromium/ui/gfx/win/rendering_window_manager.cc
index 4f2cbfb7b90..5c7261f5a36 100644
--- a/chromium/ui/gfx/win/rendering_window_manager.cc
+++ b/chromium/ui/gfx/win/rendering_window_manager.cc
@@ -22,6 +22,12 @@ void RenderingWindowManager::RegisterParent(HWND parent) {
info_.emplace(parent, EmeddingInfo());
}
+void SetParentAndMoveToBottom(HWND child, HWND parent) {
+ ::SetParent(child, parent);
+ // Move D3D window behind Chrome's window to avoid losing some messages.
+ ::SetWindowPos(child, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+}
+
bool RenderingWindowManager::RegisterChild(HWND parent, HWND child) {
if (!child)
return false;
@@ -44,7 +50,7 @@ bool RenderingWindowManager::RegisterChild(HWND parent, HWND child) {
if (info.call_set_parent) {
base::PostTaskWithTraits(
FROM_HERE, {base::TaskPriority::USER_BLOCKING},
- base::BindOnce(base::IgnoreResult(&::SetParent), child, parent));
+ base::BindOnce(&SetParentAndMoveToBottom, child, parent));
}
return true;
@@ -64,14 +70,14 @@ void RenderingWindowManager::DoSetParentOnChild(HWND parent) {
DCHECK(!info.call_set_parent);
info.call_set_parent = true;
- // Call ::SetParent() once RegisterChild() is called.
+ // Call SetParentAndMoveToBottom() once RegisterChild() is called.
if (!info.child)
return;
child = info.child;
}
- ::SetParent(child, parent);
+ SetParentAndMoveToBottom(child, parent);
}
void RenderingWindowManager::UnregisterParent(HWND parent) {
diff --git a/chromium/ui/gfx/x/x11.h b/chromium/ui/gfx/x/x11.h
index 979ad844ee5..eb53d6dd906 100644
--- a/chromium/ui/gfx/x/x11.h
+++ b/chromium/ui/gfx/x/x11.h
@@ -80,25 +80,40 @@ extern "C" {
// in the x11 namespace below. This is the main purpose of this header
// file.
-// Not redefining common words is extra important for jumbo builds
+// Not using common words is extra important for jumbo builds
// where cc files are merged. Those merged filed get to see many more
// headers than initially expected, including system headers like
// those from X11.
-#undef None // Defined by X11/X.h to 0L
#undef Status // Defined by X11/Xlib.h to int
-#undef True // Defined by X11/Xlib.h to 1
-#undef False // Defined by X11/Xlib.h to 0
#undef Bool // Defined by X11/Xlib.h to int
#undef RootWindow // Defined by X11/Xlib.h
-#undef CurrentTime // Defined by X11/X.h to 0L
-#undef Success // Defined by X11/X.h to 0
#undef DestroyAll // Defined by X11/X.h to 0
#undef COUNT // Defined by X11/extensions/XI.h to 0
#undef CREATE // Defined by X11/extensions/XI.h to 1
#undef DeviceAdded // Defined by X11/extensions/XI.h to 0
#undef DeviceMode // Defined by X11/extensions/XI.h to 1
#undef DeviceRemoved // Defined by X11/extensions/XI.h to 1
+
+// The constants below are made available in the x11 namespace with
+// their original values so we double check that the value is what we
+// expect using static_assert.
+static_assert(FocusIn == 9 && FocusOut == 10, "Unexpected focus constants");
+#undef FocusIn // Defined by X.h to 9
+#undef FocusOut // Defined by X.h to 10
+
+static_assert(None == 0, "Unexpected value for X11 constant 'None'");
+#undef None // Defined by X11/X.h to 0L
+
+static_assert(True == 1 && False == 0, "Unexpected X11 truth values");
+#undef True // Defined by X11/Xlib.h to 1
+#undef False // Defined by X11/Xlib.h to 0
+
+static_assert(CurrentTime == 0, "Unexpected value for X11 'CurrentTime'");
+#undef CurrentTime // Defined by X11/X.h to 0L
+
+static_assert(Success == 0, "Unexpected value for X11 'Success'");
+#undef Success // Defined by X11/X.h to 0
}
// The x11 namespace allows to scope X11 constants and types that
@@ -109,6 +124,8 @@ static const long CurrentTime = 0L;
static const int False = 0;
static const int True = 1;
static const int Success = 0;
+static const int FocusIn = 9;
+static const int FocusOut = 10;
typedef int Bool;
typedef int Status;
} // namespace x11
diff --git a/chromium/ui/gfx/x/x11_types.cc b/chromium/ui/gfx/x/x11_types.cc
index 7540f8ae288..502589f3ec8 100644
--- a/chromium/ui/gfx/x/x11_types.cc
+++ b/chromium/ui/gfx/x/x11_types.cc
@@ -149,17 +149,17 @@ void PutARGBImage(XDisplay* display,
for (int y = 0; y < data_height; ++y) {
for (int x = 0; x < data_width; ++x) {
const uint32_t pixel = *(bitmap_in++);
- uint16_t out_pixel = ((pixel >> 8) & 0xf800) |
- ((pixel >> 5) & 0x07e0) |
- ((pixel >> 3) & 0x001f);
+ uint16_t out_pixel = ((pixel >> 8) & 0b1111100000000000) |
+ ((pixel >> 5) & 0b0000011111100000) |
+ ((pixel >> 3) & 0b0000000000011111);
*(bitmap16++) = out_pixel;
}
}
image.data = reinterpret_cast<char*>(orig_bitmap16);
- image.red_mask = 0xf800;
- image.green_mask = 0x07e0;
- image.blue_mask = 0x001f;
+ image.red_mask = 0b1111100000000000;
+ image.green_mask = 0b0000011111100000;
+ image.blue_mask = 0b0000000000011111;
XPutImage(display, pixmap, static_cast<GC>(pixmap_gc), &image,
src_x, src_y, dst_x, dst_y,
diff --git a/chromium/ui/gl/BUILD.gn b/chromium/ui/gl/BUILD.gn
index 6e476ff9f23..238df5099a5 100644
--- a/chromium/ui/gl/BUILD.gn
+++ b/chromium/ui/gl/BUILD.gn
@@ -16,7 +16,6 @@ declare_args() {
(target_cpu == "x86" || target_cpu == "x64")
}
-use_egl = is_win || is_android || is_linux || is_fuchsia
use_glx = use_x11 || ozone_platform_x11
if (is_android) {
@@ -28,6 +27,7 @@ buildflag_header("gl_features") {
header = "gl_features.h"
flags = [
"ENABLE_SWIFTSHADER=$enable_swiftshader",
+ "USE_EGL_ON_MAC=$use_egl_on_mac",
"USE_STATIC_ANGLE=$use_static_angle",
]
}
@@ -155,6 +155,7 @@ component("gl") {
public_configs = [ "//third_party/khronos:khronos_headers" ]
deps = [
+ ":gl_features",
"//base/third_party/dynamic_annotations",
# Remove after fixing crbug.com/724999.
@@ -239,6 +240,7 @@ component("gl") {
deps += [ "//ui/base/x" ]
+ assert(use_egl)
data_deps += [
"//third_party/angle:libEGL",
"//third_party/angle:libGLESv2",
@@ -291,6 +293,7 @@ component("gl") {
libs = [ "dwmapi.lib" ]
ldflags = [ "/DELAYLOAD:dwmapi.dll" ]
+ assert(use_egl)
data_deps += [
"//third_party/angle:libEGL",
"//third_party/angle:libGLESv2",
@@ -318,6 +321,18 @@ component("gl") {
"OpenGL.framework",
"Quartz.framework",
]
+
+ if (use_egl) {
+ sources += [
+ "gl_image_io_surface_egl.h",
+ "gl_image_io_surface_egl.mm",
+ ]
+
+ data_deps += [
+ "//third_party/angle:libEGL",
+ "//third_party/angle:libGLESv2",
+ ]
+ }
}
if (is_android) {
sources += [
diff --git a/chromium/ui/gl/features.gni b/chromium/ui/gl/features.gni
index 7e948472f4e..75a55a3a095 100644
--- a/chromium/ui/gl/features.gni
+++ b/chromium/ui/gl/features.gni
@@ -6,4 +6,12 @@ declare_args() {
# Whether ANGLE should be linked statically
# False by default, enabling currently supported only on Android
use_static_angle = false
+
+ # Whether experimental support for ANGLE on Mac should be enabled.
+ # False by default since it is experimental
+ use_egl_on_mac = false
}
+
+# Should EGL support be compiled
+use_egl =
+ is_win || is_android || is_linux || is_fuchsia || (is_mac && use_egl_on_mac)
diff --git a/chromium/ui/gl/gl_bindings.h b/chromium/ui/gl/gl_bindings.h
index 2fc96618dfe..4e7c09b173b 100644
--- a/chromium/ui/gl/gl_bindings.h
+++ b/chromium/ui/gl/gl_bindings.h
@@ -99,6 +99,7 @@
#define GL_ALPHA8_EXT 0x803C
#define GL_LUMINANCE8_EXT 0x8040
#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_RGB10_A2_EXT 0x8059
#define GL_RGBA32F_EXT 0x8814
#define GL_RGB32F_EXT 0x8815
#define GL_ALPHA32F_EXT 0x8816
@@ -106,13 +107,13 @@
#define GL_LUMINANCE_ALPHA32F_EXT 0x8819
#define GL_RGBA16F_EXT 0x881A
#define GL_RGB16F_EXT 0x881B
-#define GL_RG16F_EXT 0x822F
-#define GL_R16F_EXT 0x822D
+#define GL_RG16F_EXT 0x822F
+#define GL_R16F_EXT 0x822D
#define GL_ALPHA16F_EXT 0x881C
#define GL_LUMINANCE16F_EXT 0x881E
#define GL_LUMINANCE_ALPHA16F_EXT 0x881F
-#define GL_R32F_EXT 0x822E
-#define GL_RG32F_EXT 0x8230
+#define GL_R32F_EXT 0x822E
+#define GL_RG32F_EXT 0x8230
#define GL_BGRA8_EXT 0x93A1
// GL_ANGLE_instanced_arrays
diff --git a/chromium/ui/gl/gl_fence_android_native_fence_sync.cc b/chromium/ui/gl/gl_fence_android_native_fence_sync.cc
index 3c46d4b77ff..ae1b0aa33c2 100644
--- a/chromium/ui/gl/gl_fence_android_native_fence_sync.cc
+++ b/chromium/ui/gl/gl_fence_android_native_fence_sync.cc
@@ -61,7 +61,7 @@ std::unique_ptr<gfx::GpuFence> GLFenceAndroidNativeFenceSync::GetGpuFence() {
handle.type = gfx::GpuFenceHandleType::kAndroidNativeFenceSync;
handle.native_fd = base::FileDescriptor(sync_fd, /*auto_close=*/true);
- return base::MakeUnique<gfx::GpuFence>(handle);
+ return std::make_unique<gfx::GpuFence>(handle);
}
} // namespace gl
diff --git a/chromium/ui/gl/gl_gl_api_implementation.cc b/chromium/ui/gl/gl_gl_api_implementation.cc
index 22d51ae8a6d..250bb1c2909 100644
--- a/chromium/ui/gl/gl_gl_api_implementation.cc
+++ b/chromium/ui/gl/gl_gl_api_implementation.cc
@@ -31,21 +31,8 @@ static bool g_debug_bindings_enabled = false;
namespace {
-static inline GLenum GetInternalFormat(const GLVersionInfo* version,
- GLenum internal_format) {
- if (!version->is_es) {
- if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT)
- return GL_RGBA8;
- }
- if (version->is_es3 && version->is_mesa) {
- // Mesa bug workaround: Mipmapping does not work when using GL_BGRA_EXT
- if (internal_format == GL_BGRA_EXT)
- return GL_RGBA;
- }
- return internal_format;
-}
-
-// TODO(epenner): Could the above function be merged into this and removed?
+// TODO(epenner): Could the above function be merged into GetInternalFormat and
+// removed?
static inline GLenum GetTexInternalFormat(const GLVersionInfo* version,
GLenum internal_format,
GLenum format,
@@ -244,6 +231,19 @@ static inline GLenum GetPixelType(const GLVersionInfo* version,
} // anonymous namespace
+GLenum GetInternalFormat(const GLVersionInfo* version, GLenum internal_format) {
+ if (!version->is_es) {
+ if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT)
+ return GL_RGBA8;
+ }
+ if (version->is_es3 && version->is_mesa) {
+ // Mesa bug workaround: Mipmapping does not work when using GL_BGRA_EXT
+ if (internal_format == GL_BGRA_EXT)
+ return GL_RGBA;
+ }
+ return internal_format;
+}
+
void InitializeStaticGLBindingsGL() {
g_current_gl_context_tls = new base::ThreadLocalPointer<CurrentGL>;
g_no_context_current_gl = new CurrentGL;
diff --git a/chromium/ui/gl/gl_gl_api_implementation.h b/chromium/ui/gl/gl_gl_api_implementation.h
index 6d6c7f5489d..6fd49e028c8 100644
--- a/chromium/ui/gl/gl_gl_api_implementation.h
+++ b/chromium/ui/gl/gl_gl_api_implementation.h
@@ -17,6 +17,9 @@ namespace gl {
struct GLVersionInfo;
+GL_EXPORT GLenum GetInternalFormat(const GLVersionInfo* version,
+ GLenum internal_format);
+
GL_EXPORT void InitializeStaticGLBindingsGL();
GL_EXPORT void ClearBindingsGL();
diff --git a/chromium/ui/gl/gl_image_io_surface.h b/chromium/ui/gl/gl_image_io_surface.h
index eba2ee3722e..fd9741d9f08 100644
--- a/chromium/ui/gl/gl_image_io_surface.h
+++ b/chromium/ui/gl/gl_image_io_surface.h
@@ -85,10 +85,9 @@ class GL_EXPORT GLImageIOSurface : public GLImage {
static GLImageIOSurface* FromGLImage(GLImage* image);
protected:
- ~GLImageIOSurface() override;
-
- private:
GLImageIOSurface(const gfx::Size& size, unsigned internalformat);
+ ~GLImageIOSurface() override;
+ virtual bool BindTexImageImpl(unsigned internalformat);
Type GetType() const override;
class RGBConverter;
diff --git a/chromium/ui/gl/gl_image_io_surface.mm b/chromium/ui/gl/gl_image_io_surface.mm
index da406da75c1..12bb7790c11 100644
--- a/chromium/ui/gl/gl_image_io_surface.mm
+++ b/chromium/ui/gl/gl_image_io_surface.mm
@@ -18,9 +18,16 @@
#include "ui/gfx/mac/io_surface.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_enums.h"
+#include "ui/gl/gl_features.h"
+#include "ui/gl/gl_version_info.h"
#include "ui/gl/scoped_binders.h"
#include "ui/gl/yuv_to_rgb_converter.h"
+#if BUILDFLAG(USE_EGL_ON_MAC)
+#include "ui/gl/gl_image_io_surface_egl.h"
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
+
// Note that this must be included after gl_bindings.h to avoid conflicts.
#include <OpenGL/CGLIOSurface.h>
#include <Quartz/Quartz.h>
@@ -38,6 +45,7 @@ bool ValidInternalFormat(unsigned internalformat) {
case GL_RG:
case GL_BGRA_EXT:
case GL_RGB:
+ case GL_RGB10_A2_EXT:
case GL_RGB_YCBCR_420V_CHROMIUM:
case GL_RGB_YCBCR_422_CHROMIUM:
case GL_RGBA:
@@ -68,6 +76,7 @@ bool ValidFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::BGR_565:
case gfx::BufferFormat::RGBA_4444:
case gfx::BufferFormat::RGBX_8888:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::YVU_420:
return false;
}
@@ -85,7 +94,7 @@ GLenum TextureFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::RG_88:
return GL_RG;
case gfx::BufferFormat::BGRA_8888:
- case gfx::BufferFormat::BGRX_8888:
+ case gfx::BufferFormat::BGRX_8888: // See https://crbug.com/595948.
case gfx::BufferFormat::RGBA_8888:
case gfx::BufferFormat::RGBA_F16:
return GL_RGBA;
@@ -93,8 +102,9 @@ GLenum TextureFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::YUV_420_BIPLANAR:
return GL_RGB_YCBCR_420V_CHROMIUM;
case gfx::BufferFormat::BGRX_1010102:
- // CGLTexImageIOSurface2D() (and OpenGL ES 3.0, for the case) support only
- // GL_RGBA despite the hardware ignoring it.
+ // Technically we should use GL_RGB but CGLTexImageIOSurface2D() (and
+ // OpenGL ES 3.0, for the case) support only GL_RGBA (the hardware ignores
+ // the alpha channel anyway), see https://crbug.com/797347.
return GL_RGBA;
case gfx::BufferFormat::ATC:
case gfx::BufferFormat::ATCIA:
@@ -104,6 +114,7 @@ GLenum TextureFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::BGR_565:
case gfx::BufferFormat::RGBA_4444:
case gfx::BufferFormat::RGBX_8888:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::YVU_420:
NOTREACHED();
return 0;
@@ -123,7 +134,7 @@ GLenum DataFormat(gfx::BufferFormat format) {
return GL_RG;
case gfx::BufferFormat::BGRA_8888:
case gfx::BufferFormat::BGRX_8888:
- case gfx::BufferFormat::RGBA_8888:
+ case gfx::BufferFormat::RGBA_8888: // See https://crbug.com/533677#c6.
case gfx::BufferFormat::BGRX_1010102:
return GL_BGRA;
case gfx::BufferFormat::RGBA_F16:
@@ -138,9 +149,10 @@ GLenum DataFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::BGR_565:
case gfx::BufferFormat::RGBA_4444:
case gfx::BufferFormat::RGBX_8888:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
- NOTREACHED();
+ NOTREACHED() << gfx::BufferFormatToString(format);
return 0;
}
@@ -173,9 +185,10 @@ GLenum DataType(gfx::BufferFormat format) {
case gfx::BufferFormat::BGR_565:
case gfx::BufferFormat::RGBA_4444:
case gfx::BufferFormat::RGBX_8888:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
- NOTREACHED();
+ NOTREACHED() << gfx::BufferFormatToString(format);
return 0;
}
@@ -186,7 +199,7 @@ GLenum DataType(gfx::BufferFormat format) {
// When an IOSurface is bound to a texture with internalformat "GL_RGB", many
// OpenGL operations are broken. Therefore, don't allow an IOSurface to be bound
// with GL_RGB unless overridden via BindTexImageWithInternalformat.
-// crbug.com/595948, crbug.com/699566.
+// https://crbug.com/595948, https://crbug.com/699566.
GLenum ConvertRequestedInternalFormat(GLenum internalformat) {
if (internalformat == GL_RGB)
return GL_RGBA;
@@ -198,6 +211,12 @@ GLenum ConvertRequestedInternalFormat(GLenum internalformat) {
// static
GLImageIOSurface* GLImageIOSurface::Create(const gfx::Size& size,
unsigned internalformat) {
+#if BUILDFLAG(USE_EGL_ON_MAC)
+ if (GLContext::GetCurrent()->GetVersionInfo()->is_angle) {
+ return new GLImageIOSurfaceEGL(size, internalformat);
+ }
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
+
return new GLImageIOSurface(size, internalformat);
}
@@ -217,9 +236,14 @@ bool GLImageIOSurface::Initialize(IOSurfaceRef io_surface,
gfx::BufferFormat format) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!io_surface_);
+ if (!io_surface) {
+ LOG(ERROR) << "Invalid IOSurface";
+ return false;
+ }
if (!ValidInternalFormat(internalformat_)) {
- LOG(ERROR) << "Invalid internalformat: " << internalformat_;
+ LOG(ERROR) << "Invalid internalformat: "
+ << GLEnums::GetStringEnum(internalformat_);
return false;
}
@@ -282,24 +306,33 @@ bool GLImageIOSurface::BindTexImageWithInternalformat(unsigned target,
return false;
}
+ DCHECK(io_surface_);
+
+ if (!BindTexImageImpl(internalformat)) {
+ return false;
+ }
+
+ UMA_HISTOGRAM_TIMES("GPU.IOSurface.TexImageTime",
+ base::TimeTicks::Now() - start_time);
+ return true;
+}
+
+bool GLImageIOSurface::BindTexImageImpl(unsigned internalformat) {
CGLContextObj cgl_context =
static_cast<CGLContextObj>(GLContext::GetCurrent()->GetHandle());
- DCHECK(io_surface_);
-
GLenum texture_format =
internalformat ? internalformat : TextureFormat(format_);
CGLError cgl_error = CGLTexImageIOSurface2D(
- cgl_context, target, texture_format, size_.width(), size_.height(),
- DataFormat(format_), DataType(format_), io_surface_.get(), 0);
+ cgl_context, GL_TEXTURE_RECTANGLE_ARB, texture_format, size_.width(),
+ size_.height(), DataFormat(format_), DataType(format_), io_surface_.get(),
+ 0);
if (cgl_error != kCGLNoError) {
LOG(ERROR) << "Error in CGLTexImageIOSurface2D: "
<< CGLErrorString(cgl_error);
return false;
}
- UMA_HISTOGRAM_TIMES("GPU.IOSurface.TexImageTime",
- base::TimeTicks::Now() - start_time);
return true;
}
diff --git a/chromium/ui/gl/gl_image_io_surface_egl.h b/chromium/ui/gl/gl_image_io_surface_egl.h
new file mode 100644
index 00000000000..17d96825ec4
--- /dev/null
+++ b/chromium/ui/gl/gl_image_io_surface_egl.h
@@ -0,0 +1,35 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_GL_GL_IMAGE_IO_SURFACE_EGL_H_
+#define UI_GL_GL_IMAGE_IO_SURFACE_EGL_H_
+
+#include "ui/gl/gl_image_io_surface.h"
+
+#include <egl/EGL.h>
+
+namespace gl {
+
+// Implements a IOSurface-backed GLImage that uses the
+// EGL_ANGLE_iosurface_client_buffer extension to bind the IOSurface to textures
+class GL_EXPORT GLImageIOSurfaceEGL : public GLImageIOSurface {
+ public:
+ GLImageIOSurfaceEGL(const gfx::Size& size, unsigned internalformat);
+
+ void ReleaseTexImage(unsigned target) override;
+
+ protected:
+ ~GLImageIOSurfaceEGL() override;
+ bool BindTexImageImpl(unsigned internalformat) override;
+
+ private:
+ EGLDisplay display_;
+ EGLSurface pbuffer_;
+ EGLConfig dummy_config_;
+ bool texture_bound_;
+};
+
+} // namespace gl
+
+#endif // UI_GL_GL_IMAGE_IO_SURFACE_EGL_H_
diff --git a/chromium/ui/gl/gl_image_io_surface_egl.mm b/chromium/ui/gl/gl_image_io_surface_egl.mm
new file mode 100644
index 00000000000..787870d540a
--- /dev/null
+++ b/chromium/ui/gl/gl_image_io_surface_egl.mm
@@ -0,0 +1,154 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/gl/gl_image_io_surface_egl.h"
+
+#include "ui/gl/gl_surface_egl.h"
+
+// Enums for the EGL_ANGLE_iosurface_client_buffer extension
+#define EGL_IOSURFACE_ANGLE 0x3454
+#define EGL_IOSURFACE_PLANE_ANGLE 0x345A
+#define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
+#define EGL_TEXTURE_TYPE_ANGLE 0x345C
+#define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
+
+namespace gl {
+
+namespace {
+
+struct InternalFormatType {
+ InternalFormatType(GLenum format, GLenum type) : format(format), type(type) {}
+
+ GLenum format;
+ GLenum type;
+};
+
+// Convert a gfx::BufferFormat to a (internal format, type) combination from the
+// EGL_ANGLE_iosurface_client_buffer extension spec.
+InternalFormatType BufferFormatToInternalFormatType(gfx::BufferFormat format) {
+ switch (format) {
+ case gfx::BufferFormat::R_8:
+ return {GL_RED, GL_UNSIGNED_BYTE};
+ case gfx::BufferFormat::R_16:
+ return {GL_RED_INTEGER, GL_UNSIGNED_SHORT};
+ case gfx::BufferFormat::RG_88:
+ return {GL_RG, GL_UNSIGNED_BYTE};
+ case gfx::BufferFormat::BGRA_8888:
+ case gfx::BufferFormat::BGRX_8888: // See https://crbug.com/595948.
+ case gfx::BufferFormat::RGBA_8888:
+ return {GL_BGRA_EXT, GL_UNSIGNED_BYTE};
+ case gfx::BufferFormat::RGBA_F16:
+ return {GL_RGBA, GL_HALF_FLOAT};
+ case gfx::BufferFormat::UYVY_422:
+ case gfx::BufferFormat::YUV_420_BIPLANAR:
+ case gfx::BufferFormat::BGRX_1010102:
+ NOTIMPLEMENTED();
+ return {GL_NONE, GL_NONE};
+ case gfx::BufferFormat::ATC:
+ case gfx::BufferFormat::ATCIA:
+ case gfx::BufferFormat::DXT1:
+ case gfx::BufferFormat::DXT5:
+ case gfx::BufferFormat::ETC1:
+ case gfx::BufferFormat::BGR_565:
+ case gfx::BufferFormat::RGBA_4444:
+ case gfx::BufferFormat::RGBX_8888:
+ case gfx::BufferFormat::YVU_420:
+ NOTREACHED();
+ return {GL_NONE, GL_NONE};
+ }
+
+ NOTREACHED();
+ return {GL_NONE, GL_NONE};
+}
+
+} // anonymous namespace
+
+GLImageIOSurfaceEGL::GLImageIOSurfaceEGL(const gfx::Size& size,
+ unsigned internalformat)
+ : GLImageIOSurface(size, internalformat),
+ display_(GLSurfaceEGL::GetHardwareDisplay()),
+ pbuffer_(EGL_NO_SURFACE),
+ dummy_config_(nullptr),
+ texture_bound_(false) {
+ DCHECK(display_ != EGL_NO_DISPLAY);
+
+ // When creating a pbuffer we need to supply an EGLConfig. On ANGLE and
+ // Swiftshader on Mac, there's only ever one config. Query it from EGL.
+ EGLint numConfigs = 0;
+ EGLBoolean result =
+ eglChooseConfig(display_, nullptr, &dummy_config_, 1, &numConfigs);
+ DCHECK(result == EGL_TRUE);
+ DCHECK(numConfigs = 1);
+ DCHECK(dummy_config_ != nullptr);
+}
+
+GLImageIOSurfaceEGL::~GLImageIOSurfaceEGL() {
+ if (pbuffer_ != EGL_NO_SURFACE) {
+ EGLBoolean result = eglDestroySurface(display_, pbuffer_);
+ DCHECK(result == EGL_TRUE);
+ }
+}
+
+void GLImageIOSurfaceEGL::ReleaseTexImage(unsigned target) {
+ DCHECK(target == GL_TEXTURE_RECTANGLE_ARB);
+ DCHECK(pbuffer_ != EGL_NO_SURFACE);
+ DCHECK(texture_bound_);
+
+ EGLBoolean result = eglReleaseTexImage(display_, pbuffer_, EGL_BACK_BUFFER);
+ DCHECK(result == EGL_TRUE);
+ texture_bound_ = false;
+}
+
+bool GLImageIOSurfaceEGL::BindTexImageImpl(unsigned internalformat) {
+ // TODO(cwallez@chromium.org): internalformat is used by Blink's
+ // DrawingBuffer::SetupRGBEmulationForBlitFramebuffer to bind an RGBA
+ // IOSurface as RGB. We should support this.
+ if (internalformat != 0) {
+ LOG(ERROR) << "GLImageIOSurfaceEGL doesn't support binding with a custom "
+ "internal format yet.";
+ return false;
+ }
+
+ // Create the pbuffer representing this IOSurface lazily because we don't know
+ // in the constructor if we're going to be used to bind plane 0 to a texture,
+ // or to transform YUV to RGB.
+ if (pbuffer_ == EGL_NO_SURFACE) {
+ InternalFormatType formatType = BufferFormatToInternalFormatType(format_);
+
+ // clang-format off
+ const EGLint attribs[] = {
+ EGL_WIDTH, size_.width(),
+ EGL_HEIGHT, size_.height(),
+ EGL_IOSURFACE_PLANE_ANGLE, 0,
+ EGL_TEXTURE_TARGET, EGL_TEXTURE_RECTANGLE_ANGLE,
+ EGL_TEXTURE_INTERNAL_FORMAT_ANGLE, formatType.format,
+ EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA,
+ EGL_TEXTURE_TYPE_ANGLE, formatType.type,
+ EGL_NONE, EGL_NONE,
+ };
+ // clang-format off
+
+ pbuffer_ = eglCreatePbufferFromClientBuffer(display_, EGL_IOSURFACE_ANGLE,
+ io_surface_.get(), dummy_config_, attribs);
+ if (pbuffer_ == EGL_NO_SURFACE) {
+ LOG(ERROR) << "eglCreatePbufferFromClientBuffer failed, EGL error is "
+ << eglGetError();
+ return false;
+ }
+ }
+
+ DCHECK(!texture_bound_);
+ EGLBoolean result = eglBindTexImage(display_, pbuffer_, EGL_BACK_BUFFER);
+
+ if (result != EGL_TRUE) {
+ LOG(ERROR) << "eglBindTexImage failed, EGL error is "
+ << eglGetError();
+ return false;
+ }
+
+ texture_bound_ = true;
+ return true;
+}
+
+} // namespace gl
diff --git a/chromium/ui/gl/gl_image_io_surface_unittest.cc b/chromium/ui/gl/gl_image_io_surface_unittest.cc
index 1b7c837ed16..3ec385e7496 100644
--- a/chromium/ui/gl/gl_image_io_surface_unittest.cc
+++ b/chromium/ui/gl/gl_image_io_surface_unittest.cc
@@ -5,6 +5,7 @@
#include <stddef.h>
#include <stdint.h>
+#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gfx/mac/io_surface.h"
@@ -36,13 +37,27 @@ class GLImageIOSurfaceTestDelegate : public GLImageTestDelegateBase {
IOSurfaceRef surface_ref = gfx::CreateIOSurface(size, format);
IOReturn status = IOSurfaceLock(surface_ref, 0, nullptr);
EXPECT_NE(status, kIOReturnCannotLock);
+
+ uint8_t corrected_color[4];
+ if (format == gfx::BufferFormat::RGBA_8888) {
+ // GL_RGBA is not supported by CGLTexImageIOSurface2D(), so we pretend it
+ // is GL_BGRA, (see https://crbug.com/533677#c6) swizzle the channels for
+ // the purpose of this test.
+ corrected_color[0] = color[2];
+ corrected_color[1] = color[1];
+ corrected_color[2] = color[0];
+ corrected_color[3] = color[3];
+ } else {
+ memcpy(corrected_color, color, arraysize(corrected_color));
+ }
+
for (size_t plane = 0; plane < NumberOfPlanesForBufferFormat(format);
++plane) {
void* data = IOSurfaceGetBaseAddressOfPlane(surface_ref, plane);
GLImageTestSupport::SetBufferDataToColor(
size.width(), size.height(),
IOSurfaceGetBytesPerRowOfPlane(surface_ref, plane), plane, format,
- color, static_cast<uint8_t*>(data));
+ corrected_color, static_cast<uint8_t*>(data));
}
IOSurfaceUnlock(surface_ref, 0, nullptr);
@@ -55,7 +70,18 @@ class GLImageIOSurfaceTestDelegate : public GLImageTestDelegateBase {
unsigned GetTextureTarget() const { return GL_TEXTURE_RECTANGLE_ARB; }
- const uint8_t* GetImageColor() { return kImageColor; }
+ const uint8_t* GetImageColor() {
+ if (format != gfx::BufferFormat::BGRX_8888)
+ return kImageColor;
+
+ // BGRX_8888 is actually treated as BGRA because many operations are broken
+ // when binding an IOSurface as GL_RGB, see https://crbug.com/595948. This
+ // makes the alpha value comparison fail, because we expect 0xFF but are
+ // actually writing something (0xAA). Correct the alpha value for the test.
+ static uint8_t bgrx_image_color[] = {kImageColor[0], kImageColor[1],
+ kImageColor[2], 0xAA};
+ return bgrx_image_color;
+ }
int GetAdmissibleError() const {
return format == gfx::BufferFormat::YUV_420_BIPLANAR ? 1 : 0;
@@ -65,6 +91,7 @@ class GLImageIOSurfaceTestDelegate : public GLImageTestDelegateBase {
using GLImageTestTypes = testing::Types<
GLImageIOSurfaceTestDelegate<gfx::BufferFormat::RGBA_8888>,
GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRA_8888>,
+ GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRX_8888>,
GLImageIOSurfaceTestDelegate<gfx::BufferFormat::RGBA_F16>,
GLImageIOSurfaceTestDelegate<gfx::BufferFormat::YUV_420_BIPLANAR>,
GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRX_1010102>>;
@@ -74,6 +101,7 @@ INSTANTIATE_TYPED_TEST_CASE_P(GLImageIOSurface, GLImageTest, GLImageTestTypes);
using GLImageRGBTestTypes = testing::Types<
GLImageIOSurfaceTestDelegate<gfx::BufferFormat::RGBA_8888>,
GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRA_8888>,
+ GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRX_8888>,
GLImageIOSurfaceTestDelegate<gfx::BufferFormat::RGBA_F16>,
GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRX_1010102>>;
@@ -82,8 +110,11 @@ INSTANTIATE_TYPED_TEST_CASE_P(GLImageIOSurface,
GLImageRGBTestTypes);
using GLImageBindTestTypes = testing::Types<
- // TODO(mcasas): enable BGRX_1010102 entry, https://crbug.com/803473.
- GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRA_8888>>;
+ GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRA_8888>,
+ GLImageIOSurfaceTestDelegate<gfx::BufferFormat::RGBA_8888>,
+ GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRX_8888>,
+ GLImageIOSurfaceTestDelegate<gfx::BufferFormat::RGBA_F16>,
+ GLImageIOSurfaceTestDelegate<gfx::BufferFormat::BGRX_1010102>>;
INSTANTIATE_TYPED_TEST_CASE_P(GLImageIOSurface,
GLImageBindTest,
diff --git a/chromium/ui/gl/gl_image_memory.cc b/chromium/ui/gl/gl_image_memory.cc
index 87a5c1df395..1f5b76838bd 100644
--- a/chromium/ui/gl/gl_image_memory.cc
+++ b/chromium/ui/gl/gl_image_memory.cc
@@ -12,6 +12,7 @@
#include "ui/gfx/buffer_format_util.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_enums.h"
#include "ui/gl/gl_version_info.h"
using gfx::BufferFormat;
@@ -30,6 +31,7 @@ bool ValidInternalFormat(unsigned internalformat) {
case GL_RG:
case GL_RGB:
case GL_RGBA:
+ case GL_RGB10_A2_EXT:
case GL_BGRA_EXT:
return true;
default:
@@ -52,10 +54,11 @@ bool ValidFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::RGBX_8888:
case gfx::BufferFormat::RGBA_8888:
case gfx::BufferFormat::BGRX_8888:
+ case gfx::BufferFormat::BGRX_1010102:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::BGRA_8888:
case gfx::BufferFormat::RGBA_F16:
return true;
- case gfx::BufferFormat::BGRX_1010102:
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
case gfx::BufferFormat::UYVY_422:
@@ -82,10 +85,11 @@ bool IsCompressedFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::RGBX_8888:
case gfx::BufferFormat::RGBA_8888:
case gfx::BufferFormat::BGRX_8888:
+ case gfx::BufferFormat::BGRX_1010102:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::BGRA_8888:
case gfx::BufferFormat::RGBA_F16:
return false;
- case gfx::BufferFormat::BGRX_1010102:
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
case gfx::BufferFormat::UYVY_422:
@@ -126,6 +130,10 @@ GLenum TextureFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::BGRX_8888:
return GL_RGB;
case gfx::BufferFormat::BGRX_1010102:
+ case gfx::BufferFormat::RGBX_1010102:
+ // Technically speaking we should use an opaque format, but neither
+ // OpenGLES nor OpenGL supports the hypothetical GL_RGB10_EXT.
+ return GL_RGB10_A2_EXT;
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
case gfx::BufferFormat::UYVY_422:
@@ -140,8 +148,10 @@ GLenum TextureFormat(gfx::BufferFormat format) {
GLenum DataFormat(gfx::BufferFormat format) {
switch (format) {
case gfx::BufferFormat::RGBX_8888:
+ case gfx::BufferFormat::RGBX_1010102:
return GL_RGBA;
case gfx::BufferFormat::BGRX_8888:
+ case gfx::BufferFormat::BGRX_1010102:
return GL_BGRA_EXT;
case gfx::BufferFormat::BGR_565:
case gfx::BufferFormat::RGBA_4444:
@@ -157,7 +167,6 @@ GLenum DataFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::DXT5:
case gfx::BufferFormat::ETC1:
return TextureFormat(format);
- case gfx::BufferFormat::BGRX_1010102:
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
case gfx::BufferFormat::UYVY_422:
@@ -186,12 +195,14 @@ GLenum DataType(gfx::BufferFormat format) {
return GL_UNSIGNED_SHORT;
case gfx::BufferFormat::RGBA_F16:
return GL_HALF_FLOAT_OES;
+ case gfx::BufferFormat::BGRX_1010102:
+ case gfx::BufferFormat::RGBX_1010102:
+ return GL_UNSIGNED_INT_2_10_10_10_REV;
case gfx::BufferFormat::ATC:
case gfx::BufferFormat::ATCIA:
case gfx::BufferFormat::DXT1:
case gfx::BufferFormat::DXT5:
case gfx::BufferFormat::ETC1:
- case gfx::BufferFormat::BGRX_1010102:
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
case gfx::BufferFormat::UYVY_422:
@@ -213,6 +224,8 @@ GLint DataRowLength(size_t stride, gfx::BufferFormat format) {
case gfx::BufferFormat::RGBX_8888:
case gfx::BufferFormat::RGBA_8888:
case gfx::BufferFormat::BGRX_8888:
+ case gfx::BufferFormat::BGRX_1010102:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::BGRA_8888:
return base::checked_cast<GLint>(stride) / 4;
case gfx::BufferFormat::RGBA_F16:
@@ -224,7 +237,6 @@ GLint DataRowLength(size_t stride, gfx::BufferFormat format) {
case gfx::BufferFormat::DXT1:
case gfx::BufferFormat::DXT5:
case gfx::BufferFormat::ETC1:
- case gfx::BufferFormat::BGRX_1010102:
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
case gfx::BufferFormat::UYVY_422:
@@ -330,6 +342,8 @@ std::unique_ptr<uint8_t[]> GLES2Data(const gfx::Size& size,
data_format, data_type, data_row_length);
case gfx::BufferFormat::RGBA_4444:
case gfx::BufferFormat::RGBA_8888:
+ case gfx::BufferFormat::BGRX_1010102:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::BGRA_8888:
case gfx::BufferFormat::RGBA_F16:
case gfx::BufferFormat::R_8:
@@ -356,11 +370,10 @@ std::unique_ptr<uint8_t[]> GLES2Data(const gfx::Size& size,
case gfx::BufferFormat::DXT5:
case gfx::BufferFormat::ETC1:
return nullptr; // No data conversion needed
- case gfx::BufferFormat::BGRX_1010102:
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
case gfx::BufferFormat::UYVY_422:
- NOTREACHED();
+ NOTREACHED() << gfx::BufferFormatToString(format);
return nullptr;
}
@@ -390,12 +403,13 @@ bool GLImageMemory::Initialize(const unsigned char* memory,
gfx::BufferFormat format,
size_t stride) {
if (!ValidInternalFormat(internalformat_)) {
- LOG(ERROR) << "Invalid internalformat: " << internalformat_;
+ LOG(ERROR) << "Invalid internalformat: "
+ << GLEnums::GetStringEnum(internalformat_);
return false;
}
if (!ValidFormat(format)) {
- LOG(ERROR) << "Invalid format: " << static_cast<int>(format);
+ LOG(ERROR) << "Invalid format: " << gfx::BufferFormatToString(format);
return false;
}
diff --git a/chromium/ui/gl/gl_image_native_pixmap.cc b/chromium/ui/gl/gl_image_native_pixmap.cc
index 2c397340386..a917940b89b 100644
--- a/chromium/ui/gl/gl_image_native_pixmap.cc
+++ b/chromium/ui/gl/gl_image_native_pixmap.cc
@@ -24,6 +24,7 @@
#define DRM_FORMAT_XRGB8888 FOURCC('X', 'R', '2', '4')
#define DRM_FORMAT_XBGR8888 FOURCC('X', 'B', '2', '4')
#define DRM_FORMAT_XRGB2101010 FOURCC('X', 'R', '3', '0')
+#define DRM_FORMAT_XBGR2101010 FOURCC('X', 'B', '3', '0')
#define DRM_FORMAT_YVU420 FOURCC('Y', 'V', '1', '2')
#define DRM_FORMAT_NV12 FOURCC('N', 'V', '1', '2')
@@ -42,9 +43,11 @@ bool ValidInternalFormat(unsigned internalformat, gfx::BufferFormat format) {
case GL_RGB_YCBCR_420V_CHROMIUM:
return format == gfx::BufferFormat::YUV_420_BIPLANAR;
case GL_RGBA:
- return format == gfx::BufferFormat::RGBA_8888;
+ return format == gfx::BufferFormat::RGBA_8888 ||
+ format == gfx::BufferFormat::RGBX_1010102;
case GL_BGRA_EXT:
- return format == gfx::BufferFormat::BGRA_8888;
+ return format == gfx::BufferFormat::BGRA_8888 ||
+ format == gfx::BufferFormat::BGRX_1010102;
case GL_RED_EXT:
return format == gfx::BufferFormat::R_8;
case GL_R16_EXT:
@@ -67,6 +70,7 @@ bool ValidFormat(gfx::BufferFormat format) {
case gfx::BufferFormat::BGRA_8888:
case gfx::BufferFormat::BGRX_8888:
case gfx::BufferFormat::BGRX_1010102:
+ case gfx::BufferFormat::RGBX_1010102:
case gfx::BufferFormat::YVU_420:
case gfx::BufferFormat::YUV_420_BIPLANAR:
return true;
@@ -105,6 +109,8 @@ EGLint FourCC(gfx::BufferFormat format) {
return DRM_FORMAT_XRGB8888;
case gfx::BufferFormat::BGRX_1010102:
return DRM_FORMAT_XRGB2101010;
+ case gfx::BufferFormat::RGBX_1010102:
+ return DRM_FORMAT_XBGR2101010;
case gfx::BufferFormat::YVU_420:
return DRM_FORMAT_YVU420;
case gfx::BufferFormat::YUV_420_BIPLANAR:
@@ -141,6 +147,8 @@ gfx::BufferFormat GetBufferFormatFromFourCCFormat(int format) {
return gfx::BufferFormat::BGRX_8888;
case DRM_FORMAT_XRGB2101010:
return gfx::BufferFormat::BGRX_1010102;
+ case DRM_FORMAT_XBGR2101010:
+ return gfx::BufferFormat::RGBX_1010102;
case DRM_FORMAT_RGB565:
return gfx::BufferFormat::BGR_565;
case DRM_FORMAT_NV12:
@@ -412,10 +420,12 @@ unsigned GLImageNativePixmap::GetInternalFormatForTesting(
case gfx::BufferFormat::BGR_565:
case gfx::BufferFormat::RGBX_8888:
case gfx::BufferFormat::BGRX_8888:
- case gfx::BufferFormat::BGRX_1010102:
return GL_RGB;
case gfx::BufferFormat::RGBA_8888:
return GL_RGBA;
+ case gfx::BufferFormat::BGRX_1010102:
+ case gfx::BufferFormat::RGBX_1010102:
+ return GL_RGB10_A2_EXT;
case gfx::BufferFormat::BGRA_8888:
return GL_BGRA_EXT;
case gfx::BufferFormat::YVU_420:
diff --git a/chromium/ui/gl/gl_image_shared_memory_unittest.cc b/chromium/ui/gl/gl_image_shared_memory_unittest.cc
index fdef8d937c8..e48ed75c8f0 100644
--- a/chromium/ui/gl/gl_image_shared_memory_unittest.cc
+++ b/chromium/ui/gl/gl_image_shared_memory_unittest.cc
@@ -7,6 +7,7 @@
#include "base/memory/shared_memory.h"
#include "base/sys_info.h"
+#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_image_shared_memory.h"
#include "ui/gl/test/gl_image_test_template.h"
@@ -50,6 +51,13 @@ using GLImageTestTypes = testing::Types<
GLImageSharedMemoryTestDelegate<gfx::BufferFormat::RGBX_8888>,
GLImageSharedMemoryTestDelegate<gfx::BufferFormat::RGBA_8888>,
GLImageSharedMemoryTestDelegate<gfx::BufferFormat::BGRX_8888>,
+#if defined(OS_LINUX)
+ // Fails on Win nVidia and linux android: the test writes nothing (we read
+ // back the color used to clear the buffer).
+ // TODO(mcasas): enable those paltforms https://crbug.com/803451.
+ GLImageSharedMemoryTestDelegate<gfx::BufferFormat::BGRX_1010102>,
+ GLImageSharedMemoryTestDelegate<gfx::BufferFormat::RGBX_1010102>,
+#endif
GLImageSharedMemoryTestDelegate<gfx::BufferFormat::BGRA_8888>>;
INSTANTIATE_TYPED_TEST_CASE_P(GLImageSharedMemory,
diff --git a/chromium/ui/gl/gl_surface_egl.cc b/chromium/ui/gl/gl_surface_egl.cc
index 67255b5f33a..f1413f215a3 100644
--- a/chromium/ui/gl/gl_surface_egl.cc
+++ b/chromium/ui/gl/gl_surface_egl.cc
@@ -29,6 +29,7 @@
#include "ui/gl/gl_context_egl.h"
#include "ui/gl/gl_image.h"
#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface_presentation_helper.h"
#include "ui/gl/gl_surface_stub.h"
#include "ui/gl/gl_utils.h"
#include "ui/gl/scoped_make_current.h"
@@ -198,6 +199,8 @@ class EGLSyncControlVSyncProvider : public SyncControlVSyncProvider {
return false;
}
+ bool IsHWClock() const override { return true; }
+
private:
EGLSurface surface_;
@@ -981,7 +984,8 @@ bool NativeViewGLSurfaceEGL::Initialize(GLSurfaceFormat format) {
vsync_provider_internal_ =
std::make_unique<EGLSyncControlVSyncProvider>(surface_);
}
-
+ presentation_helper_ =
+ std::make_unique<GLSurfacePresentationHelper>(GetVSyncProvider());
return true;
}
@@ -1034,11 +1038,16 @@ void NativeViewGLSurfaceEGL::SetEnableSwapTimestamps() {
use_egl_timestamps_ = !supported_egl_timestamps_.empty();
}
+bool NativeViewGLSurfaceEGL::SupportsPresentationCallback() {
+ return true;
+}
+
bool NativeViewGLSurfaceEGL::InitializeNativeWindow() {
return true;
}
void NativeViewGLSurfaceEGL::Destroy() {
+ presentation_helper_ = nullptr;
vsync_provider_internal_ = nullptr;
if (surface_) {
@@ -1056,7 +1065,6 @@ bool NativeViewGLSurfaceEGL::IsOffscreen() {
gfx::SwapResult NativeViewGLSurfaceEGL::SwapBuffers(
const PresentationCallback& callback) {
- // TODO(penghuang): Provide presentation feedback. https://crbug.com/776877
TRACE_EVENT2("gpu", "NativeViewGLSurfaceEGL:RealSwapBuffers",
"width", GetSize().width(),
"height", GetSize().height());
@@ -1073,17 +1081,16 @@ gfx::SwapResult NativeViewGLSurfaceEGL::SwapBuffers(
!!eglGetNextFrameIdANDROID(GetDisplay(), surface_, &newFrameId);
}
+ GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
+ presentation_helper_.get(), callback);
if (!eglSwapBuffers(GetDisplay(), surface_)) {
DVLOG(1) << "eglSwapBuffers failed with error "
<< GetLastEGLErrorString();
- return gfx::SwapResult::SWAP_FAILED;
- }
-
- if (use_egl_timestamps_) {
+ scoped_swap_buffers.set_result(gfx::SwapResult::SWAP_FAILED);
+ } else if (use_egl_timestamps_) {
UpdateSwapEvents(newFrameId, newFrameIdIsValid);
}
-
- return gfx::SwapResult::SWAP_ACK;
+ return scoped_swap_buffers.result();
}
void NativeViewGLSurfaceEGL::UpdateSwapEvents(EGLuint64KHR newFrameId,
@@ -1271,21 +1278,22 @@ bool NativeViewGLSurfaceEGL::BuffersFlipped() const {
gfx::SwapResult NativeViewGLSurfaceEGL::SwapBuffersWithDamage(
const std::vector<int>& rects,
const PresentationCallback& callback) {
- // TODO(penghuang): Provide presentation feedback. https://crbug.com/776877
DCHECK(supports_swap_buffer_with_damage_);
if (!CommitAndClearPendingOverlays()) {
DVLOG(1) << "Failed to commit pending overlay planes.";
return gfx::SwapResult::SWAP_FAILED;
}
+ GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
+ presentation_helper_.get(), callback);
if (!eglSwapBuffersWithDamageKHR(GetDisplay(), surface_,
const_cast<EGLint*>(rects.data()),
static_cast<EGLint>(rects.size() / 4))) {
DVLOG(1) << "eglSwapBuffersWithDamageKHR failed with error "
<< GetLastEGLErrorString();
- return gfx::SwapResult::SWAP_FAILED;
+ scoped_swap_buffers.set_result(gfx::SwapResult::SWAP_FAILED);
}
- return gfx::SwapResult::SWAP_ACK;
+ return scoped_swap_buffers.result();
}
gfx::SwapResult NativeViewGLSurfaceEGL::PostSubBuffer(
@@ -1294,7 +1302,6 @@ gfx::SwapResult NativeViewGLSurfaceEGL::PostSubBuffer(
int width,
int height,
const PresentationCallback& callback) {
- // TODO(penghuang): Provide presentation feedback. https://crbug.com/776877
DCHECK(supports_post_sub_buffer_);
if (!CommitAndClearPendingOverlays()) {
DVLOG(1) << "Failed to commit pending overlay planes.";
@@ -1306,12 +1313,15 @@ gfx::SwapResult NativeViewGLSurfaceEGL::PostSubBuffer(
// bottom left.
y = GetSize().height() - y - height;
}
+
+ GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
+ presentation_helper_.get(), callback);
if (!eglPostSubBufferNV(GetDisplay(), surface_, x, y, width, height)) {
DVLOG(1) << "eglPostSubBufferNV failed with error "
<< GetLastEGLErrorString();
- return gfx::SwapResult::SWAP_FAILED;
+ scoped_swap_buffers.set_result(gfx::SwapResult::SWAP_FAILED);
}
- return gfx::SwapResult::SWAP_ACK;
+ return scoped_swap_buffers.result();
}
bool NativeViewGLSurfaceEGL::SupportsCommitOverlayPlanes() {
@@ -1324,13 +1334,21 @@ bool NativeViewGLSurfaceEGL::SupportsCommitOverlayPlanes() {
gfx::SwapResult NativeViewGLSurfaceEGL::CommitOverlayPlanes(
const PresentationCallback& callback) {
- // TODO(penghuang): Provide presentation feedback. https://crbug.com/776877
DCHECK(SupportsCommitOverlayPlanes());
// Here we assume that the overlays scheduled on this surface will display
// themselves to the screen right away in |CommitAndClearPendingOverlays|,
// rather than being queued and waiting for a "swap" signal.
- return CommitAndClearPendingOverlays() ? gfx::SwapResult::SWAP_ACK
- : gfx::SwapResult::SWAP_FAILED;
+ GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
+ presentation_helper_.get(), callback);
+ if (!CommitAndClearPendingOverlays())
+ scoped_swap_buffers.set_result(gfx::SwapResult::SWAP_FAILED);
+ return scoped_swap_buffers.result();
+}
+
+bool NativeViewGLSurfaceEGL::OnMakeCurrent(GLContext* context) {
+ if (presentation_helper_)
+ presentation_helper_->OnMakeCurrent(context, this);
+ return GLSurfaceEGL::OnMakeCurrent(context);
}
gfx::VSyncProvider* NativeViewGLSurfaceEGL::GetVSyncProvider() {
@@ -1367,9 +1385,13 @@ bool NativeViewGLSurfaceEGL::CommitAndClearPendingOverlays() {
return true;
bool success = true;
+#if defined(OS_ANDROID)
for (const auto& overlay : pending_overlays_)
success &= overlay.ScheduleOverlayPlane(window_);
pending_overlays_.clear();
+#else
+ NOTIMPLEMENTED();
+#endif
return success;
}
diff --git a/chromium/ui/gl/gl_surface_egl.h b/chromium/ui/gl/gl_surface_egl.h
index 30a71969d2b..1e8cb17097c 100644
--- a/chromium/ui/gl/gl_surface_egl.h
+++ b/chromium/ui/gl/gl_surface_egl.h
@@ -28,6 +28,8 @@
namespace gl {
+class GLSurfacePresentationHelper;
+
// If adding a new type, also add it to EGLDisplayType in
// tools/metrics/histograms/histograms.xml. Don't remove or reorder entries.
enum DisplayType {
@@ -104,10 +106,10 @@ class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL {
std::unique_ptr<gfx::VSyncProvider> vsync_provider);
// Implement GLSurface.
- using GLSurfaceEGL::Initialize;
bool Initialize(GLSurfaceFormat format) override;
bool SupportsSwapTimestamps() const override;
void SetEnableSwapTimestamps() override;
+ bool SupportsPresentationCallback() override;
void Destroy() override;
bool Resize(const gfx::Size& size,
float scale_factor,
@@ -127,6 +129,7 @@ class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL {
bool SupportsCommitOverlayPlanes() override;
gfx::SwapResult CommitOverlayPlanes(
const PresentationCallback& callback) override;
+ bool OnMakeCurrent(GLContext* context) override;
gfx::VSyncProvider* GetVSyncProvider() override;
bool ScheduleOverlayPlane(int z_order,
gfx::OverlayTransform transform,
@@ -180,6 +183,8 @@ class GL_EXPORT NativeViewGLSurfaceEGL : public GLSurfaceEGL {
base::queue<SwapInfo> swap_info_queue_;
+ std::unique_ptr<GLSurfacePresentationHelper> presentation_helper_;
+
DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceEGL);
};
diff --git a/chromium/ui/gl/gl_surface_glx.cc b/chromium/ui/gl/gl_surface_glx.cc
index ba10ace1d50..fb426317082 100644
--- a/chromium/ui/gl/gl_surface_glx.cc
+++ b/chromium/ui/gl/gl_surface_glx.cc
@@ -168,6 +168,8 @@ class OMLSyncControlVSyncProvider : public SyncControlVSyncProvider {
return true;
}
+ bool IsHWClock() const override { return true; }
+
private:
GLXWindow glx_window_;
@@ -344,8 +346,8 @@ class SGIVideoSyncVSyncProvider
const gfx::VSyncProvider::UpdateVSyncCallback& callback) override {
// Only one outstanding request per surface.
if (!pending_callback_) {
- pending_callback_.reset(
- new gfx::VSyncProvider::UpdateVSyncCallback(callback));
+ pending_callback_ =
+ std::make_unique<gfx::VSyncProvider::UpdateVSyncCallback>(callback);
vsync_thread_->task_runner()->PostTask(
FROM_HERE,
base::BindOnce(&SGIVideoSyncProviderThreadShim::GetVSyncParameters,
@@ -361,7 +363,8 @@ class SGIVideoSyncVSyncProvider
return false;
}
- bool SupportGetVSyncParametersIfAvailable() override { return false; }
+ bool SupportGetVSyncParametersIfAvailable() const override { return false; }
+ bool IsHWClock() const override { return false; }
private:
void PendingCallbackRunner(const base::TimeTicks timebase,
@@ -475,6 +478,10 @@ bool GLSurfaceGLX::InitializeExtensionSettingsOneOff() {
if (!g_glx_get_msc_rate_oml_supported && g_glx_sgi_video_sync_supported) {
Display* video_sync_display = gfx::OpenNewXDisplay();
+ if (!video_sync_display) {
+ LOG(ERROR) << "Could not open video sync display";
+ return false;
+ }
if (!CreateDummyWindow(video_sync_display)) {
LOG(ERROR) << "CreateDummyWindow(video_sync_display) failed";
return false;
@@ -609,13 +616,15 @@ bool NativeViewGLSurfaceGLX::Initialize(GLSurfaceFormat format) {
}
if (g_glx_oml_sync_control_supported) {
- vsync_provider_.reset(new OMLSyncControlVSyncProvider(glx_window_));
- presentation_helper_ = std::make_unique<GLSurfacePresentationHelper>(
- vsync_provider_.get(), true);
+ vsync_provider_ =
+ std::make_unique<OMLSyncControlVSyncProvider>(glx_window_);
+ presentation_helper_ =
+ std::make_unique<GLSurfacePresentationHelper>(vsync_provider_.get());
} else if (g_glx_sgi_video_sync_supported) {
- vsync_provider_.reset(new SGIVideoSyncVSyncProvider(parent_window_));
- presentation_helper_ = std::make_unique<GLSurfacePresentationHelper>(
- vsync_provider_.get(), false);
+ vsync_provider_ =
+ std::make_unique<SGIVideoSyncVSyncProvider>(parent_window_);
+ presentation_helper_ =
+ std::make_unique<GLSurfacePresentationHelper>(vsync_provider_.get());
} else {
// Assume a refresh rate of 59.9 Hz, which will cause us to skip
// 1 frame every 10 seconds on a 60Hz monitor, but will prevent us
@@ -625,8 +634,8 @@ bool NativeViewGLSurfaceGLX::Initialize(GLSurfaceFormat format) {
const base::TimeTicks kDefaultTimebase;
const base::TimeDelta kDefaultInterval =
base::TimeDelta::FromSeconds(1) / 59.9;
- vsync_provider_.reset(
- new gfx::FixedVSyncProvider(kDefaultTimebase, kDefaultInterval));
+ vsync_provider_ = std::make_unique<gfx::FixedVSyncProvider>(
+ kDefaultTimebase, kDefaultInterval);
presentation_helper_ = std::make_unique<GLSurfacePresentationHelper>(
kDefaultTimebase, kDefaultInterval);
}
@@ -668,10 +677,10 @@ gfx::SwapResult NativeViewGLSurfaceGLX::SwapBuffers(
const PresentationCallback& callback) {
TRACE_EVENT2("gpu", "NativeViewGLSurfaceGLX:RealSwapBuffers", "width",
GetSize().width(), "height", GetSize().height());
- presentation_helper_->PreSwapBuffers(callback);
+ GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
+ presentation_helper_.get(), callback);
glXSwapBuffers(g_display, GetDrawableHandle());
- presentation_helper_->PostSwapBuffers();
- return gfx::SwapResult::SWAP_ACK;
+ return scoped_swap_buffers.result();
}
gfx::Size NativeViewGLSurfaceGLX::GetSize() {
@@ -711,10 +720,11 @@ gfx::SwapResult NativeViewGLSurfaceGLX::PostSubBuffer(
int height,
const PresentationCallback& callback) {
DCHECK(g_driver_glx.ext.b_GLX_MESA_copy_sub_buffer);
- presentation_helper_->PreSwapBuffers(callback);
+
+ GLSurfacePresentationHelper::ScopedSwapBuffers scoped_swap_buffers(
+ presentation_helper_.get(), callback);
glXCopySubBufferMESA(g_display, GetDrawableHandle(), x, y, width, height);
- presentation_helper_->PostSwapBuffers();
- return gfx::SwapResult::SWAP_ACK;
+ return scoped_swap_buffers.result();
}
bool NativeViewGLSurfaceGLX::OnMakeCurrent(GLContext* context) {
diff --git a/chromium/ui/gl/gl_surface_presentation_helper.cc b/chromium/ui/gl/gl_surface_presentation_helper.cc
index 41acab425f3..6825fda6a77 100644
--- a/chromium/ui/gl/gl_surface_presentation_helper.cc
+++ b/chromium/ui/gl/gl_surface_presentation_helper.cc
@@ -11,6 +11,19 @@
namespace gl {
+GLSurfacePresentationHelper::ScopedSwapBuffers::ScopedSwapBuffers(
+ GLSurfacePresentationHelper* helper,
+ const GLSurface::PresentationCallback& callback)
+ : helper_(helper) {
+ if (helper_)
+ helper_->PreSwapBuffers(callback);
+}
+
+GLSurfacePresentationHelper::ScopedSwapBuffers::~ScopedSwapBuffers() {
+ if (helper_)
+ helper_->PostSwapBuffers(result_);
+}
+
GLSurfacePresentationHelper::Frame::Frame(Frame&& other) = default;
GLSurfacePresentationHelper::Frame::Frame(
@@ -24,19 +37,13 @@ GLSurfacePresentationHelper::Frame& GLSurfacePresentationHelper::Frame::
operator=(Frame&& other) = default;
GLSurfacePresentationHelper::GLSurfacePresentationHelper(
- gfx::VSyncProvider* vsync_provider,
- bool hw_clock)
- : vsync_provider_(vsync_provider),
- hw_clock_(hw_clock),
- weak_ptr_factory_(this) {
- DCHECK(vsync_provider_);
-}
+ gfx::VSyncProvider* vsync_provider)
+ : vsync_provider_(vsync_provider), weak_ptr_factory_(this) {}
GLSurfacePresentationHelper::GLSurfacePresentationHelper(
base::TimeTicks timebase,
base::TimeDelta interval)
: vsync_provider_(nullptr),
- hw_clock_(false),
vsync_timebase_(timebase),
vsync_interval_(interval),
weak_ptr_factory_(this) {}
@@ -88,9 +95,21 @@ void GLSurfacePresentationHelper::PreSwapBuffers(
pending_frames_.push_back(Frame(std::move(timer), callback));
}
-void GLSurfacePresentationHelper::PostSwapBuffers() {
- if (!waiting_for_vsync_parameters_)
- CheckPendingFrames();
+void GLSurfacePresentationHelper::PostSwapBuffers(gfx::SwapResult result) {
+ DCHECK(!pending_frames_.empty());
+ if (result == gfx::SwapResult::SWAP_ACK && gpu_timing_client_) {
+ if (!waiting_for_vsync_parameters_)
+ CheckPendingFrames();
+ return;
+ }
+
+ auto frame = std::move(pending_frames_.back());
+ pending_frames_.pop_back();
+ if (frame.timer) {
+ bool has_context = gl_context_ && gl_context_->IsCurrent(surface_);
+ frame.timer->Destroy(has_context);
+ }
+ frame.callback.Run(gfx::PresentationFeedback());
}
void GLSurfacePresentationHelper::CheckPendingFrames() {
@@ -113,7 +132,8 @@ void GLSurfacePresentationHelper::CheckPendingFrames() {
if (gl_context_ && !gl_context_->IsCurrent(surface_)) {
gpu_timing_client_ = nullptr;
for (auto& frame : pending_frames_) {
- frame.timer->Destroy(false /* has_context */);
+ if (frame.timer)
+ frame.timer->Destroy(false /* has_context */);
frame.callback.Run(gfx::PresentationFeedback());
}
pending_frames_.clear();
@@ -155,6 +175,7 @@ void GLSurfacePresentationHelper::CheckPendingFrames() {
};
const bool fixed_vsync = !vsync_provider_;
+ const bool hw_clock = vsync_provider_ && vsync_provider_->IsHWClock();
if (vsync_interval_.is_zero() || fixed_vsync) {
// If VSync parameters are fixed or not avaliable, we just run
// presentation callbacks with timestamp from GPUTimers.
@@ -170,7 +191,7 @@ void GLSurfacePresentationHelper::CheckPendingFrames() {
// The |vsync_timebase_| is the closest VSync's timestamp after the GPU
// finished renderering.
timestamp = vsync_timebase_;
- if (hw_clock_)
+ if (hw_clock)
flags |= gfx::PresentationFeedback::kHWClock;
} else {
// The |vsync_timebase_| isn't the closest VSync's timestamp after the
diff --git a/chromium/ui/gl/gl_surface_presentation_helper.h b/chromium/ui/gl/gl_surface_presentation_helper.h
index b00f6e94ea3..6baf88fafcb 100644
--- a/chromium/ui/gl/gl_surface_presentation_helper.h
+++ b/chromium/ui/gl/gl_surface_presentation_helper.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
+#include "ui/gfx/swap_result.h"
#include "ui/gl/gl_export.h"
#include "ui/gl/gl_surface.h"
@@ -26,8 +27,24 @@ class GPUTimer;
// implementations.
class GL_EXPORT GLSurfacePresentationHelper {
public:
- GLSurfacePresentationHelper(gfx::VSyncProvider* vsync_provider,
- bool hw_clock);
+ class GL_EXPORT ScopedSwapBuffers {
+ public:
+ ScopedSwapBuffers(GLSurfacePresentationHelper* helper,
+ const GLSurface::PresentationCallback& callback);
+ ~ScopedSwapBuffers();
+
+ void set_result(gfx::SwapResult result) { result_ = result; }
+ gfx::SwapResult result() const { return result_; }
+
+ private:
+ GLSurfacePresentationHelper* const helper_;
+ gfx::SwapResult result_ = gfx::SwapResult::SWAP_ACK;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedSwapBuffers);
+ };
+
+ explicit GLSurfacePresentationHelper(gfx::VSyncProvider* vsync_provider);
+
// For using fixed VSync provider.
GLSurfacePresentationHelper(const base::TimeTicks timebase,
const base::TimeDelta interval);
@@ -35,7 +52,7 @@ class GL_EXPORT GLSurfacePresentationHelper {
void OnMakeCurrent(GLContext* context, GLSurface* surface);
void PreSwapBuffers(const GLSurface::PresentationCallback& callback);
- void PostSwapBuffers();
+ void PostSwapBuffers(gfx::SwapResult result);
private:
struct Frame {
@@ -58,7 +75,6 @@ class GL_EXPORT GLSurfacePresentationHelper {
const base::TimeDelta interval);
gfx::VSyncProvider* const vsync_provider_;
- const bool hw_clock_;
scoped_refptr<GLContext> gl_context_;
GLSurface* surface_ = nullptr;
scoped_refptr<GPUTimingClient> gpu_timing_client_;
diff --git a/chromium/ui/gl/init/BUILD.gn b/chromium/ui/gl/init/BUILD.gn
index 3400ef6be17..d55a06bf481 100644
--- a/chromium/ui/gl/init/BUILD.gn
+++ b/chromium/ui/gl/init/BUILD.gn
@@ -26,6 +26,7 @@ jumbo_component("init") {
deps = [
"//base",
"//ui/gfx",
+ "//ui/gl:gl_features",
]
public_deps = [
@@ -37,7 +38,6 @@ jumbo_component("init") {
"gl_factory_android.cc",
"gl_initializer_android.cc",
]
- deps += [ "//ui/gl:gl_features" ]
} else if (is_win) {
sources += [
"gl_factory_win.cc",
@@ -46,7 +46,6 @@ jumbo_component("init") {
libs = [ "dwmapi.lib" ]
ldflags = [ "/DELAYLOAD:dwmapi.dll" ]
- deps += [ "//ui/gl:gl_features" ]
} else if (is_mac) {
sources += [
"gl_factory_mac.cc",
@@ -60,10 +59,7 @@ jumbo_component("init") {
"gl_initializer_x11.cc",
]
- deps += [
- "//ui/gfx/x",
- "//ui/gl:gl_features",
- ]
+ deps += [ "//ui/gfx/x" ]
} else if (use_ozone) {
sources += [
"gl_factory_ozone.cc",
diff --git a/chromium/ui/gl/init/create_gr_gl_interface.cc b/chromium/ui/gl/init/create_gr_gl_interface.cc
index e7b1c6e7afe..283dd1f028f 100644
--- a/chromium/ui/gl/init/create_gr_gl_interface.cc
+++ b/chromium/ui/gl/init/create_gr_gl_interface.cc
@@ -487,14 +487,6 @@ sk_sp<const GrGLInterface> CreateGrGLInterface(
functions->fWaitSync = gl->glWaitSyncFn;
functions->fDeleteSync = gl->glDeleteSyncFn;
- functions->fBindImageTexture = gl->glBindImageTextureEXTFn;
- // TODO(piman): skia type is wrong.
- functions->fMemoryBarrier =
- reinterpret_cast<GrGLMemoryBarrierProc>(gl->glMemoryBarrierEXTFn);
-
- // GL 4.5 or GL_ARB_ES3_1_compatibility or ES 3.1
- // functions->fMemoryBarrierByRegion = gl->glMemoryBarrierByRegionFn;
-
functions->fGetInternalformativ = gl->glGetInternalformativFn;
interface->fStandard = standard;
diff --git a/chromium/ui/gl/init/gl_factory_mac.cc b/chromium/ui/gl/init/gl_factory_mac.cc
index 72037d428e0..52544651c31 100644
--- a/chromium/ui/gl/init/gl_factory_mac.cc
+++ b/chromium/ui/gl/init/gl_factory_mac.cc
@@ -11,6 +11,7 @@
#include "ui/gl/gl_context_cgl.h"
#include "ui/gl/gl_context_osmesa.h"
#include "ui/gl/gl_context_stub.h"
+#include "ui/gl/gl_features.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_share_group.h"
#include "ui/gl/gl_surface.h"
@@ -18,6 +19,11 @@
#include "ui/gl/gl_surface_stub.h"
#include "ui/gl/gl_switches.h"
+#if BUILDFLAG(USE_EGL_ON_MAC)
+#include "ui/gl/gl_context_egl.h"
+#include "ui/gl/gl_surface_egl.h"
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
+
namespace gl {
namespace init {
@@ -59,6 +65,9 @@ class NoOpGLSurface : public GLSurface {
std::vector<GLImplementation> GetAllowedGLImplementations() {
std::vector<GLImplementation> impls;
impls.push_back(kGLImplementationDesktopGLCoreProfile);
+#if BUILDFLAG(USE_EGL_ON_MAC)
+ impls.push_back(kGLImplementationEGLGLES2);
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
impls.push_back(kGLImplementationDesktopGL);
impls.push_back(kGLImplementationAppleGL);
impls.push_back(kGLImplementationOSMesaGL);
@@ -77,12 +86,13 @@ scoped_refptr<GLContext> CreateGLContext(GLShareGroup* share_group,
case kGLImplementationDesktopGL:
case kGLImplementationDesktopGLCoreProfile:
case kGLImplementationAppleGL:
- // Note that with virtualization we might still be able to make current
- // a different onscreen surface with this context later. But we should
- // always be creating the context with an offscreen surface first.
- DCHECK(compatible_surface->IsOffscreen());
return InitializeGLContext(new GLContextCGL(share_group),
compatible_surface, attribs);
+#if BUILDFLAG(USE_EGL_ON_MAC)
+ case kGLImplementationEGLGLES2:
+ return InitializeGLContext(new GLContextEGL(share_group),
+ compatible_surface, attribs);
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
case kGLImplementationOSMesaGL:
return InitializeGLContext(new GLContextOSMesa(share_group),
compatible_surface, attribs);
@@ -105,7 +115,8 @@ scoped_refptr<GLSurface> CreateViewGLSurface(gfx::AcceleratedWidget window) {
switch (GetGLImplementation()) {
case kGLImplementationDesktopGL:
case kGLImplementationDesktopGLCoreProfile:
- case kGLImplementationAppleGL: {
+ case kGLImplementationAppleGL:
+ case kGLImplementationEGLGLES2: {
NOTIMPLEMENTED() << "No onscreen support on Mac.";
return nullptr;
}
@@ -134,6 +145,16 @@ scoped_refptr<GLSurface> CreateOffscreenGLSurfaceWithFormat(
case kGLImplementationAppleGL:
return InitializeGLSurfaceWithFormat(
new NoOpGLSurface(size), format);
+#if BUILDFLAG(USE_EGL_ON_MAC)
+ case kGLImplementationEGLGLES2:
+ if (GLSurfaceEGL::IsEGLSurfacelessContextSupported() &&
+ size.width() == 0 && size.height() == 0) {
+ return InitializeGLSurfaceWithFormat(new SurfacelessEGL(size), format);
+ } else {
+ return InitializeGLSurfaceWithFormat(new PbufferGLSurfaceEGL(size),
+ format);
+ }
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
case kGLImplementationMockGL:
case kGLImplementationStubGL:
return new GLSurfaceStub;
diff --git a/chromium/ui/gl/init/gl_initializer_mac.cc b/chromium/ui/gl/init/gl_initializer_mac.cc
index 828ce9bb013..3ca3b88be3f 100644
--- a/chromium/ui/gl/init/gl_initializer_mac.cc
+++ b/chromium/ui/gl/init/gl_initializer_mac.cc
@@ -17,12 +17,18 @@
#include "base/threading/thread_restrictions.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_features.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_implementation.h"
#include "ui/gl/gl_osmesa_api_implementation.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gpu_switching_manager.h"
+#if BUILDFLAG(USE_EGL_ON_MAC)
+#include "ui/gl/gl_egl_api_implementation.h"
+#include "ui/gl/gl_surface_egl.h"
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
+
namespace gl {
namespace init {
@@ -127,6 +133,56 @@ bool InitializeStaticCGLInternal(GLImplementation implementation) {
return true;
}
+#if BUILDFLAG(USE_EGL_ON_MAC)
+const char kGLESv2ANGLELibraryName[] = "libGLESv2.dylib";
+const char kEGLANGLELibraryName[] = "libEGL.dylib";
+
+bool InitializeStaticEGLInternal(GLImplementation implementation) {
+ if (implementation == kGLImplementationSwiftShaderGL) {
+ return false;
+ }
+
+ base::FilePath module_path;
+ if (!PathService::Get(base::DIR_MODULE, &module_path)) {
+ return false;
+ }
+
+ base::FilePath glesv2_path = module_path.Append(kGLESv2ANGLELibraryName);
+ base::NativeLibrary gles_library = LoadLibraryAndPrintError(glesv2_path);
+ if (!gles_library) {
+ return false;
+ }
+
+ base::FilePath egl_path = module_path.Append(kEGLANGLELibraryName);
+ base::NativeLibrary egl_library = LoadLibraryAndPrintError(egl_path);
+ if (!egl_library) {
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ GLGetProcAddressProc get_proc_address =
+ reinterpret_cast<GLGetProcAddressProc>(
+ base::GetFunctionPointerFromNativeLibrary(egl_library,
+ "eglGetProcAddress"));
+ if (!get_proc_address) {
+ LOG(ERROR) << "eglGetProcAddress not found.";
+ base::UnloadNativeLibrary(egl_library);
+ base::UnloadNativeLibrary(gles_library);
+ return false;
+ }
+
+ SetGLGetProcAddressProc(get_proc_address);
+ AddGLNativeLibrary(egl_library);
+ AddGLNativeLibrary(gles_library);
+ SetGLImplementation(kGLImplementationEGLGLES2);
+
+ InitializeStaticGLBindingsGL();
+ InitializeStaticGLBindingsEGL();
+
+ return true;
+}
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
+
} // namespace
bool InitializeGLOneOffPlatform() {
@@ -139,6 +195,14 @@ bool InitializeGLOneOffPlatform() {
return false;
}
return true;
+#if BUILDFLAG(USE_EGL_ON_MAC)
+ case kGLImplementationEGLGLES2:
+ if (!GLSurfaceEGL::InitializeOneOff(0)) {
+ LOG(ERROR) << "GLSurfaceEGL::InitializeOneOff failed.";
+ return false;
+ }
+ return true;
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
default:
return true;
}
@@ -163,6 +227,10 @@ bool InitializeStaticGLBindings(GLImplementation implementation) {
case kGLImplementationDesktopGLCoreProfile:
case kGLImplementationAppleGL:
return InitializeStaticCGLInternal(implementation);
+#if BUILDFLAG(USE_EGL_ON_MAC)
+ case kGLImplementationEGLGLES2:
+ return InitializeStaticEGLInternal(implementation);
+#endif // BUILDFLAG(USE_EGL_ON_MAC)
case kGLImplementationMockGL:
case kGLImplementationStubGL:
SetGLImplementation(implementation);
diff --git a/chromium/ui/gl/init/ozone_util.h b/chromium/ui/gl/init/ozone_util.h
index 02360ee291f..11c04d0c7e7 100644
--- a/chromium/ui/gl/init/ozone_util.h
+++ b/chromium/ui/gl/init/ozone_util.h
@@ -20,7 +20,7 @@ inline ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() {
// Returns true if there is an GLOzone for the specified GL implementation.
inline bool HasGLOzone(GLImplementation impl) {
- return GetSurfaceFactoryOzone()->GetGLOzone(impl) != nullptr;
+ return GetSurfaceFactoryOzone() && GetSurfaceFactoryOzone()->GetGLOzone(impl);
}
// Returns true if there is an GLOzone for the set GL implementation.
diff --git a/chromium/ui/gl/sync_control_vsync_provider.cc b/chromium/ui/gl/sync_control_vsync_provider.cc
index 7f9c6c01aec..2b94e43a57d 100644
--- a/chromium/ui/gl/sync_control_vsync_provider.cc
+++ b/chromium/ui/gl/sync_control_vsync_provider.cc
@@ -65,13 +65,9 @@ bool SyncControlVSyncProvider::GetVSyncParametersIfAvailable(
// Both Intel and Mali drivers will return TRUE for GetSyncValues
// but a value of 0 for MSC if they cannot access the CRTC data structure
// associated with the surface. crbug.com/231945
- bool prev_invalid_msc = invalid_msc_;
invalid_msc_ = (media_stream_counter == 0);
- if (invalid_msc_) {
- LOG_IF(ERROR, !prev_invalid_msc) << "glXGetSyncValuesOML "
- "should not return TRUE with a media stream counter of 0.";
+ if (invalid_msc_)
return false;
- }
struct timespec real_time;
clock_gettime(CLOCK_REALTIME, &real_time);
@@ -164,7 +160,7 @@ bool SyncControlVSyncProvider::GetVSyncParametersIfAvailable(
#endif // defined(OS_LINUX)
}
-bool SyncControlVSyncProvider::SupportGetVSyncParametersIfAvailable() {
+bool SyncControlVSyncProvider::SupportGetVSyncParametersIfAvailable() const {
#if defined(OS_LINUX)
return true;
#else
diff --git a/chromium/ui/gl/sync_control_vsync_provider.h b/chromium/ui/gl/sync_control_vsync_provider.h
index 7612e60a0fc..735d7ee61c9 100644
--- a/chromium/ui/gl/sync_control_vsync_provider.h
+++ b/chromium/ui/gl/sync_control_vsync_provider.h
@@ -23,7 +23,7 @@ class SyncControlVSyncProvider : public gfx::VSyncProvider {
void GetVSyncParameters(const UpdateVSyncCallback& callback) override;
bool GetVSyncParametersIfAvailable(base::TimeTicks* timebase,
base::TimeDelta* interval) override;
- bool SupportGetVSyncParametersIfAvailable() override;
+ bool SupportGetVSyncParametersIfAvailable() const override;
static constexpr bool IsSupported() {
#if defined(OS_LINUX)
diff --git a/chromium/ui/gl/vsync_provider_win.cc b/chromium/ui/gl/vsync_provider_win.cc
index 041cdd7b395..34dc007783f 100644
--- a/chromium/ui/gl/vsync_provider_win.cc
+++ b/chromium/ui/gl/vsync_provider_win.cc
@@ -122,7 +122,11 @@ bool VSyncProviderWin::GetVSyncParametersIfAvailable(
return true;
}
-bool VSyncProviderWin::SupportGetVSyncParametersIfAvailable() {
+bool VSyncProviderWin::SupportGetVSyncParametersIfAvailable() const {
+ return true;
+}
+
+bool VSyncProviderWin::IsHWClock() const {
return true;
}
diff --git a/chromium/ui/gl/vsync_provider_win.h b/chromium/ui/gl/vsync_provider_win.h
index 0ec5644276c..3ee9a29856b 100644
--- a/chromium/ui/gl/vsync_provider_win.h
+++ b/chromium/ui/gl/vsync_provider_win.h
@@ -22,7 +22,8 @@ class GL_EXPORT VSyncProviderWin : public gfx::VSyncProvider {
void GetVSyncParameters(const UpdateVSyncCallback& callback) override;
bool GetVSyncParametersIfAvailable(base::TimeTicks* timebase,
base::TimeDelta* interval) override;
- bool SupportGetVSyncParametersIfAvailable() override;
+ bool SupportGetVSyncParametersIfAvailable() const override;
+ bool IsHWClock() const override;
private:
gfx::AcceleratedWidget window_;
diff --git a/chromium/ui/keyboard/BUILD.gn b/chromium/ui/keyboard/BUILD.gn
index 3b2816104d8..ccf79d43925 100644
--- a/chromium/ui/keyboard/BUILD.gn
+++ b/chromium/ui/keyboard/BUILD.gn
@@ -35,6 +35,8 @@ jumbo_component("keyboard") {
"keyboard_util.h",
"notification_manager.cc",
"notification_manager.h",
+ "queued_container_type.cc",
+ "queued_container_type.h",
]
defines = [ "KEYBOARD_IMPLEMENTATION" ]
diff --git a/chromium/ui/keyboard/container_behavior.h b/chromium/ui/keyboard/container_behavior.h
index e6224c3552d..d641d88bff6 100644
--- a/chromium/ui/keyboard/container_behavior.h
+++ b/chromium/ui/keyboard/container_behavior.h
@@ -60,9 +60,11 @@ class KEYBOARD_EXPORT ContainerBehavior {
virtual bool IsDragHandle(const gfx::Vector2d& offset,
const gfx::Size& keyboard_size) const = 0;
- virtual void SavePosition(const gfx::Point& position) = 0;
+ virtual void SavePosition(const gfx::Rect& keyboard_bounds,
+ const gfx::Size& screen_size) = 0;
- virtual void HandlePointerEvent(const ui::LocatedEvent& event) = 0;
+ virtual void HandlePointerEvent(const ui::LocatedEvent& event,
+ const gfx::Rect& display_bounds) = 0;
virtual ContainerType GetType() const = 0;
diff --git a/chromium/ui/keyboard/container_floating_behavior.cc b/chromium/ui/keyboard/container_floating_behavior.cc
index 9d93d393baf..855cdc202cf 100644
--- a/chromium/ui/keyboard/container_floating_behavior.cc
+++ b/chromium/ui/keyboard/container_floating_behavior.cc
@@ -69,7 +69,7 @@ const gfx::Rect ContainerFloatingBehavior::AdjustSetBoundsRequest(
const gfx::Rect& requested_bounds) {
gfx::Rect keyboard_bounds = requested_bounds;
- if (UseDefaultPosition()) {
+ if (!default_position_) {
// If the keyboard hasn't been shown yet, ignore the request and use
// default.
gfx::Point default_location =
@@ -80,18 +80,39 @@ const gfx::Rect ContainerFloatingBehavior::AdjustSetBoundsRequest(
// the screen.
keyboard_bounds =
ContainKeyboardToScreenBounds(keyboard_bounds, display_bounds);
+ SavePosition(keyboard_bounds, display_bounds.size());
}
return keyboard_bounds;
}
+void ContainerFloatingBehavior::SavePosition(const gfx::Rect& keyboard_bounds,
+ const gfx::Size& screen_size) {
+ int left_distance = keyboard_bounds.x();
+ int right_distance = screen_size.width() - (keyboard_bounds.right());
+ int top_distance = keyboard_bounds.y();
+ int bottom_distance = screen_size.height() - (keyboard_bounds.bottom());
+
+ double available_width = left_distance + right_distance;
+ double available_height = top_distance + bottom_distance;
+
+ if (!default_position_) {
+ default_position_ = std::make_unique<KeyboardPosition>();
+ }
+
+ default_position_->left_padding_allotment_ratio =
+ left_distance / available_width;
+ default_position_->top_padding_allotment_ratio =
+ top_distance / available_height;
+}
+
gfx::Rect ContainerFloatingBehavior::ContainKeyboardToScreenBounds(
const gfx::Rect& keyboard_bounds,
const gfx::Rect& display_bounds) const {
int left = keyboard_bounds.x();
int top = keyboard_bounds.y();
- int right = left + keyboard_bounds.width();
- int bottom = top + keyboard_bounds.height();
+ int right = keyboard_bounds.right();
+ int bottom = keyboard_bounds.bottom();
// Prevent keyboard from appearing off screen or overlapping with the edge.
if (left < 0) {
@@ -118,37 +139,36 @@ bool ContainerFloatingBehavior::IsOverscrollAllowed() const {
return false;
}
-bool ContainerFloatingBehavior::UseDefaultPosition() const {
- // (-1, -1) is used as a sentinel unset value.
- return default_position_.x() == -1;
-}
-
gfx::Point ContainerFloatingBehavior::GetPositionForShowingKeyboard(
const gfx::Size& keyboard_size,
const gfx::Rect& display_bounds) const {
// Start with the last saved position
- gfx::Point position = default_position_;
- if (UseDefaultPosition()) {
+ gfx::Point top_left_offset;
+ KeyboardPosition* position = default_position_.get();
+ if (position == nullptr) {
// If there is none, center the keyboard along the bottom of the screen.
- position.set_x(display_bounds.width() - keyboard_size.width() -
- kDefaultDistanceFromScreenRight);
- position.set_y(display_bounds.height() - keyboard_size.height() -
- kDefaultDistanceFromScreenBottom);
+ top_left_offset.set_x(display_bounds.width() - keyboard_size.width() -
+ kDefaultDistanceFromScreenRight);
+ top_left_offset.set_y(display_bounds.height() - keyboard_size.height() -
+ kDefaultDistanceFromScreenBottom);
+ } else {
+ double left = (display_bounds.width() - keyboard_size.width()) *
+ position->left_padding_allotment_ratio;
+ double top = (display_bounds.height() - keyboard_size.height()) *
+ position->top_padding_allotment_ratio;
+ top_left_offset.set_x((int)left);
+ top_left_offset.set_y((int)top);
}
// Make sure that this location is valid according to the current size of the
// screen.
- gfx::Rect keyboard_bounds = gfx::Rect(position, keyboard_size);
+ gfx::Rect keyboard_bounds = gfx::Rect(top_left_offset, keyboard_size);
gfx::Rect valid_keyboard_bounds =
ContainKeyboardToScreenBounds(keyboard_bounds, display_bounds);
return valid_keyboard_bounds.origin();
}
-void ContainerFloatingBehavior::SavePosition(const gfx::Point& position) {
- default_position_ = position;
-}
-
bool ContainerFloatingBehavior::IsDragHandle(
const gfx::Vector2d& offset,
const gfx::Size& keyboard_size) const {
@@ -156,7 +176,8 @@ bool ContainerFloatingBehavior::IsDragHandle(
}
void ContainerFloatingBehavior::HandlePointerEvent(
- const ui::LocatedEvent& event) {
+ const ui::LocatedEvent& event,
+ const gfx::Rect& display_bounds) {
// Cannot call UI-backed operations without a KeyboardController
DCHECK(controller_);
auto kb_offset = gfx::Vector2d(event.x(), event.y());
@@ -205,7 +226,7 @@ void ContainerFloatingBehavior::HandlePointerEvent(
const gfx::Rect new_bounds =
gfx::Rect(new_keyboard_location, keyboard_bounds.size());
controller_->MoveKeyboard(new_bounds);
- SavePosition(container->bounds().origin());
+ SavePosition(container->bounds(), display_bounds.size());
handle_drag = true;
}
if (!handle_drag && drag_descriptor_) {
@@ -219,9 +240,10 @@ void ContainerFloatingBehavior::SetCanonicalBounds(
const gfx::Rect& display_bounds) {
gfx::Point keyboard_location =
GetPositionForShowingKeyboard(container->bounds().size(), display_bounds);
- SavePosition(keyboard_location);
- container->SetBounds(
- gfx::Rect(keyboard_location, container->bounds().size()));
+ gfx::Rect keyboard_bounds =
+ gfx::Rect(keyboard_location, container->bounds().size());
+ SavePosition(keyboard_bounds, display_bounds.size());
+ container->SetBounds(keyboard_bounds);
}
bool ContainerFloatingBehavior::TextBlurHidesKeyboard() const {
diff --git a/chromium/ui/keyboard/container_floating_behavior.h b/chromium/ui/keyboard/container_floating_behavior.h
index 89124dfa9a4..6ea2b2abfde 100644
--- a/chromium/ui/keyboard/container_floating_behavior.h
+++ b/chromium/ui/keyboard/container_floating_behavior.h
@@ -23,6 +23,11 @@ namespace keyboard {
constexpr int kDefaultDistanceFromScreenBottom = 20;
constexpr int kDefaultDistanceFromScreenRight = 20;
+struct KeyboardPosition {
+ double left_padding_allotment_ratio;
+ double top_padding_allotment_ratio;
+};
+
class KEYBOARD_EXPORT ContainerFloatingBehavior : public ContainerBehavior {
public:
ContainerFloatingBehavior(KeyboardController* controller);
@@ -42,8 +47,10 @@ class KEYBOARD_EXPORT ContainerFloatingBehavior : public ContainerBehavior {
bool IsOverscrollAllowed() const override;
bool IsDragHandle(const gfx::Vector2d& offset,
const gfx::Size& keyboard_size) const override;
- void SavePosition(const gfx::Point& position) override;
- void HandlePointerEvent(const ui::LocatedEvent& event) override;
+ void SavePosition(const gfx::Rect& keyboard_bounds,
+ const gfx::Size& screen_size) override;
+ void HandlePointerEvent(const ui::LocatedEvent& event,
+ const gfx::Rect& display_bounds) override;
void SetCanonicalBounds(aura::Window* container,
const gfx::Rect& display_bounds) override;
ContainerType GetType() const override;
@@ -52,6 +59,11 @@ class KEYBOARD_EXPORT ContainerFloatingBehavior : public ContainerBehavior {
bool BoundsAffectWorkspaceLayout() const override;
bool SetDraggableArea(const gfx::Rect& rect) override;
+ // Calculate the position of the keyboard for when it is being shown.
+ gfx::Point GetPositionForShowingKeyboard(
+ const gfx::Size& keyboard_size,
+ const gfx::Rect& display_bounds) const;
+
private:
// Ensures that the keyboard is neither off the screen nor overlapping an
// edge.
@@ -62,19 +74,11 @@ class KEYBOARD_EXPORT ContainerFloatingBehavior : public ContainerBehavior {
// Saves the current keyboard location for use the next time it is displayed.
void UpdateLastPoint(const gfx::Point& position);
- // Returns true if the keyboard has not been display/moved yet and the default
- // position should be used.
- bool UseDefaultPosition() const;
-
- // Calculate the position of the keyboard for when it is being shown.
- gfx::Point GetPositionForShowingKeyboard(
- const gfx::Size& keyboard_size,
- const gfx::Rect& display_bounds) const;
-
KeyboardController* controller_;
// TODO(blakeo): cache the default_position_ on a per-display basis.
- gfx::Point default_position_ = gfx::Point(-1, -1);
+ std::unique_ptr<struct keyboard::KeyboardPosition> default_position_ =
+ nullptr;
// Current state of a cursor drag to move the keyboard, if one exists.
// Otherwise nullptr.
diff --git a/chromium/ui/keyboard/container_floating_behavior_unittest.cc b/chromium/ui/keyboard/container_floating_behavior_unittest.cc
index c3e81c710f4..6db3b404566 100644
--- a/chromium/ui/keyboard/container_floating_behavior_unittest.cc
+++ b/chromium/ui/keyboard/container_floating_behavior_unittest.cc
@@ -32,7 +32,8 @@ TEST(ContainerFloatingBehaviorTest, AdjustSetBoundsRequest) {
keyboard_height);
// Save an arbitrary position so that default location will not be used.
- floating_behavior.SavePosition(gfx::Point(0, 0));
+ floating_behavior.SavePosition(
+ gfx::Rect(0, 0, keyboard_width, keyboard_height), workspace.size());
gfx::Rect result =
floating_behavior.AdjustSetBoundsRequest(workspace, center);
@@ -49,6 +50,69 @@ TEST(ContainerFloatingBehaviorTest, AdjustSetBoundsRequest) {
result);
}
+TEST(ContainerFloatingBehaviorTest, AdjustSetBoundsRequestVariousSides) {
+ ContainerFloatingBehavior floating_behavior(nullptr);
+
+ const int keyboard_width = 100;
+ const int keyboard_height = 100;
+ gfx::Size keyboard_size = gfx::Size(keyboard_width, keyboard_height);
+ gfx::Rect workspace_wide(0, 0, 1000, 500);
+ gfx::Rect workspace_tall(0, 0, 500, 1000);
+ gfx::Rect top_left(0, 0, keyboard_width, keyboard_height);
+ gfx::Rect top_right(900, 0, keyboard_width, keyboard_height);
+ gfx::Rect bottom_left(0, 400, keyboard_width, keyboard_height);
+ gfx::Rect bottom_right(900, 400, keyboard_width, keyboard_height);
+ gfx::Rect bottomish_center(450, 390, keyboard_width, keyboard_height);
+
+ // Save an arbitrary position so that default location will not be used.
+ floating_behavior.SavePosition(
+ gfx::Rect(0, 0, keyboard_width, keyboard_height), workspace_wide.size());
+
+ floating_behavior.AdjustSetBoundsRequest(workspace_wide, top_left);
+ gfx::Point result = floating_behavior.GetPositionForShowingKeyboard(
+ keyboard_size, workspace_wide);
+ ASSERT_EQ(gfx::Point(0, 0), result);
+ result = floating_behavior.GetPositionForShowingKeyboard(keyboard_size,
+ workspace_tall);
+ ASSERT_EQ(gfx::Point(0, 0), result);
+
+ floating_behavior.AdjustSetBoundsRequest(workspace_wide, top_right);
+ result = floating_behavior.GetPositionForShowingKeyboard(keyboard_size,
+ workspace_wide);
+ ASSERT_EQ(gfx::Point(900, 0), result);
+ result = floating_behavior.GetPositionForShowingKeyboard(keyboard_size,
+ workspace_tall);
+ ASSERT_EQ(gfx::Point(400, 0), result);
+
+ floating_behavior.AdjustSetBoundsRequest(workspace_wide, bottom_left);
+ result = floating_behavior.GetPositionForShowingKeyboard(keyboard_size,
+ workspace_wide);
+ ASSERT_EQ(gfx::Point(0, 400), result);
+ result = floating_behavior.GetPositionForShowingKeyboard(keyboard_size,
+ workspace_tall);
+ ASSERT_EQ(gfx::Point(0, 900), result);
+
+ floating_behavior.AdjustSetBoundsRequest(workspace_wide, bottom_right);
+ result = floating_behavior.GetPositionForShowingKeyboard(keyboard_size,
+ workspace_wide);
+ ASSERT_EQ(gfx::Point(900, 400), result);
+ result = floating_behavior.GetPositionForShowingKeyboard(keyboard_size,
+ workspace_tall);
+ ASSERT_EQ(gfx::Point(400, 900), result);
+
+ floating_behavior.AdjustSetBoundsRequest(workspace_wide, bottomish_center);
+ result = floating_behavior.GetPositionForShowingKeyboard(keyboard_size,
+ workspace_wide);
+ ASSERT_EQ(gfx::Point(450, 390), result);
+ result = floating_behavior.GetPositionForShowingKeyboard(keyboard_size,
+ workspace_tall);
+
+ // rather than 400:0 for the vertical padding, use 390:10
+ // with 900 pixels available this ratio results in 877.5, which is truncated.
+ // 390 / 400 * 900 = 877.5
+ ASSERT_EQ(gfx::Point(200, 877), result);
+}
+
TEST(ContainerFloatingBehaviorTest, DontSaveCoordinatesUntilKeyboardMoved) {
ContainerFloatingBehavior floating_behavior(nullptr);
@@ -77,7 +141,8 @@ TEST(ContainerFloatingBehaviorTest, DontSaveCoordinatesUntilKeyboardMoved) {
// Simulate the user clicking and moving the keyboard to some arbitrary
// location (it doesn't matter where). Now that the coordinate is known to be
// user-determined.
- floating_behavior.SavePosition(gfx::Point(10, 10));
+ floating_behavior.SavePosition(
+ gfx::Rect(10, 10, keyboard_width, keyboard_height), workspace.size());
// Move the keyboard somewhere else. The coordinates should be taken as-is
// without being adjusted.
diff --git a/chromium/ui/keyboard/container_full_width_behavior.cc b/chromium/ui/keyboard/container_full_width_behavior.cc
index 15cbf04698c..2dca9c087ec 100644
--- a/chromium/ui/keyboard/container_full_width_behavior.cc
+++ b/chromium/ui/keyboard/container_full_width_behavior.cc
@@ -82,7 +82,8 @@ bool ContainerFullWidthBehavior::IsOverscrollAllowed() const {
return controller_ && !controller_->keyboard_locked();
}
-void ContainerFullWidthBehavior::SavePosition(const gfx::Point& position) {
+void ContainerFullWidthBehavior::SavePosition(const gfx::Rect& keyboard_bounds,
+ const gfx::Size& screen_size) {
// No-op. Nothing to save.
}
@@ -93,7 +94,8 @@ bool ContainerFullWidthBehavior::IsDragHandle(
}
void ContainerFullWidthBehavior::HandlePointerEvent(
- const ui::LocatedEvent& event) {
+ const ui::LocatedEvent& event,
+ const gfx::Rect& display_bounds) {
// No-op. Nothing special to do for pointer events.
}
diff --git a/chromium/ui/keyboard/container_full_width_behavior.h b/chromium/ui/keyboard/container_full_width_behavior.h
index 5a5d1a493d7..077d3b92eb6 100644
--- a/chromium/ui/keyboard/container_full_width_behavior.h
+++ b/chromium/ui/keyboard/container_full_width_behavior.h
@@ -39,8 +39,10 @@ class KEYBOARD_EXPORT ContainerFullWidthBehavior : public ContainerBehavior {
bool IsOverscrollAllowed() const override;
bool IsDragHandle(const gfx::Vector2d& offset,
const gfx::Size& keyboard_size) const override;
- void SavePosition(const gfx::Point& position) override;
- void HandlePointerEvent(const ui::LocatedEvent& event) override;
+ void SavePosition(const gfx::Rect& keyboard_bounds,
+ const gfx::Size& screen_size) override;
+ void HandlePointerEvent(const ui::LocatedEvent& event,
+ const gfx::Rect& display_bounds) override;
void SetCanonicalBounds(aura::Window* container,
const gfx::Rect& display_bounds) override;
ContainerType GetType() const override;
diff --git a/chromium/ui/keyboard/keyboard_controller.cc b/chromium/ui/keyboard/keyboard_controller.cc
index 76a576bfe09..b9ba7f519ef 100644
--- a/chromium/ui/keyboard/keyboard_controller.cc
+++ b/chromium/ui/keyboard/keyboard_controller.cc
@@ -12,6 +12,7 @@
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
@@ -25,6 +26,7 @@
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/display/types/display_constants.h"
+#include "ui/events/base_event_utils.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/path.h"
@@ -36,6 +38,7 @@
#include "ui/keyboard/keyboard_ui.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/keyboard/notification_manager.h"
+#include "ui/keyboard/queued_container_type.h"
#include "ui/wm/core/window_animations.h"
#if defined(OS_CHROMEOS)
@@ -51,6 +54,13 @@ constexpr int kHideKeyboardDelayMs = 100;
// intermediate state for more than 5 seconds.
constexpr int kReportLingeringStateDelayMs = 5000;
+// Delay threshold after the keyboard enters the WILL_HIDE state. If text focus
+// is regained during this threshold, the keyboard will show again, even if it
+// is an asynchronous event. This is for the benefit of things like login flow
+// where the password field may get text focus after an animation that plays
+// after the user enters their username.
+constexpr int kTransientBlurThresholdMs = 3500;
+
// State transition diagram (document linked from crbug.com/719905)
bool isAllowedStateTransition(keyboard::KeyboardControllerState from,
keyboard::KeyboardControllerState to) {
@@ -202,12 +212,11 @@ KeyboardController::KeyboardController(std::unique_ptr<KeyboardUI> ui,
show_on_content_update_(false),
keyboard_locked_(false),
state_(KeyboardControllerState::UNKNOWN),
- enqueued_container_type_(ContainerType::FULL_WIDTH),
weak_factory_report_lingering_state_(this),
weak_factory_will_hide_(this) {
ui_->GetInputMethod()->AddObserver(this);
ui_->SetController(this);
- SetContainerBehaviorInternal(enqueued_container_type_);
+ SetContainerBehaviorInternal(ContainerType::FULL_WIDTH);
ChangeState(KeyboardControllerState::INITIAL);
}
@@ -385,11 +394,8 @@ void KeyboardController::HideKeyboard(HideReason reason) {
}
void KeyboardController::HideAnimationFinished() {
- if (state_ != KeyboardControllerState::HIDDEN)
- return;
-
- if (enqueued_container_type_ != container_behavior_->GetType()) {
- SetContainerBehaviorInternal(enqueued_container_type_);
+ if (state_ == KeyboardControllerState::HIDDEN && queued_container_type_) {
+ SetContainerBehaviorInternal(queued_container_type_->container_type());
ShowKeyboard(false /* lock */);
}
}
@@ -498,17 +504,36 @@ void KeyboardController::OnTextInputStateChanged(
return;
}
} else {
- // Abort a pending keyboard hide.
- if (WillHideKeyboard())
- ChangeState(KeyboardControllerState::SHOWN);
+ switch (state_) {
+ case KeyboardControllerState::WILL_HIDE:
+ // Abort a pending keyboard hide.
+ ChangeState(KeyboardControllerState::SHOWN);
+ return;
+ case KeyboardControllerState::HIDDEN:
+ if (focused)
+ ShowKeyboardIfWithinTransientBlurThreshold();
+ return;
+ default:
+ break;
+ }
// Do not explicitly show the Virtual keyboard unless it is in the process
- // of hiding. Instead, the virtual keyboard is shown in response to a user
- // gesture (mouse or touch) that is received while an element has input
- // focus. Showing the keyboard requires an explicit call to
- // OnShowImeIfNeeded.
+ // of hiding or the hide duration was very short (transient blur). Instead,
+ // the virtual keyboard is shown in response to a user gesture (mouse or
+ // touch) that is received while an element has input focus. Showing the
+ // keyboard requires an explicit call to OnShowImeIfNeeded.
}
}
+void KeyboardController::ShowKeyboardIfWithinTransientBlurThreshold() {
+ static const base::TimeDelta kTransientBlurThreshold =
+ base::TimeDelta::FromMilliseconds(kTransientBlurThresholdMs);
+
+ const base::Time now = base::Time::Now();
+ const base::TimeDelta time_since_last_blur = now - time_of_last_blur_;
+ if (time_since_last_blur < kTransientBlurThreshold)
+ ShowKeyboard(false);
+}
+
void KeyboardController::OnShowImeIfNeeded() {
// Calling |ShowKeyboardInternal| may move the keyboard to another display.
if (IsKeyboardEnabled() && !keyboard_locked())
@@ -624,6 +649,10 @@ void KeyboardController::PopulateKeyboardContent(int64_t display_id,
container_behavior_->DoShowingAnimation(container_.get(), &settings);
+ // the queued container behavior will notify JS to change layout when it
+ // gets destroyed.
+ queued_container_type_ = nullptr;
+
ChangeState(KeyboardControllerState::SHOWN);
NotifyKeyboardBoundsChangingAndEnsureCaretInWorkArea();
}
@@ -678,6 +707,8 @@ void KeyboardController::ChangeState(KeyboardControllerState state) {
if (state_ == state)
return;
+ KeyboardControllerState original_state = state_;
+
state_ = state;
if (state != KeyboardControllerState::WILL_HIDE)
@@ -691,11 +722,16 @@ void KeyboardController::ChangeState(KeyboardControllerState state) {
switch (state_) {
case KeyboardControllerState::LOADING_EXTENSION:
case KeyboardControllerState::WILL_HIDE:
+ if (state_ == KeyboardControllerState::WILL_HIDE &&
+ original_state == KeyboardControllerState::SHOWN) {
+ time_of_last_blur_ = base::Time::Now();
+ }
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&KeyboardController::ReportLingeringState,
weak_factory_report_lingering_state_.GetWeakPtr()),
base::TimeDelta::FromMilliseconds(kReportLingeringStateDelayMs));
+
break;
default:
// Do nothing
@@ -737,18 +773,31 @@ bool KeyboardController::IsOverscrollAllowed() const {
}
void KeyboardController::HandlePointerEvent(const ui::LocatedEvent& event) {
- container_behavior_->HandlePointerEvent(event);
+ container_behavior_->HandlePointerEvent(
+ event, container_->GetRootWindow()->bounds());
}
-void KeyboardController::SetContainerType(const ContainerType type) {
- if (container_behavior_->GetType() == type)
+
+void KeyboardController::SetContainerType(
+ const ContainerType type,
+ base::OnceCallback<void(bool)> callback) {
+ if (container_behavior_->GetType() == type) {
+ std::move(callback).Run(false);
return;
+ }
- enqueued_container_type_ = type;
if (state_ == KeyboardControllerState::SHOWN) {
+ // Keyboard is already shown. Hiding the keyboard at first then switching
+ // container type.
+ queued_container_type_ =
+ std::make_unique<QueuedContainerType>(this, type, std::move(callback));
HideKeyboard(HIDE_REASON_AUTOMATIC);
} else {
+ // Keyboard is hidden. Switching the container type immediately and invoking
+ // the passed callback now.
SetContainerBehaviorInternal(type);
+ DCHECK(GetActiveContainerType() == type);
+ std::move(callback).Run(true /* change_successful */);
}
}
diff --git a/chromium/ui/keyboard/keyboard_controller.h b/chromium/ui/keyboard/keyboard_controller.h
index c702b72940b..ef9356317a4 100644
--- a/chromium/ui/keyboard/keyboard_controller.h
+++ b/chromium/ui/keyboard/keyboard_controller.h
@@ -9,6 +9,7 @@
#include "base/macros.h"
#include "base/observer_list.h"
+#include "base/time/time.h"
#include "ui/aura/window_observer.h"
#include "ui/base/ime/input_method_observer.h"
#include "ui/base/ime/text_input_type.h"
@@ -22,6 +23,7 @@
#include "ui/keyboard/keyboard_layout_delegate.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/keyboard/notification_manager.h"
+#include "ui/keyboard/queued_container_type.h"
namespace aura {
class Window;
@@ -152,6 +154,10 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver,
KeyboardControllerState GetStateForTest() const { return state_; }
+ ContainerType GetActiveContainerType() const {
+ return container_behavior_->GetType();
+ }
+
const gfx::Rect AdjustSetBoundsRequest(
const gfx::Rect& display_bounds,
const gfx::Rect& requested_bounds) const;
@@ -170,7 +176,8 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver,
// Sets the active container type. If the keyboard is currently shown, this
// will trigger a hide animation and a subsequent show animation. Otherwise
// the ContainerBehavior change is synchronous.
- void SetContainerType(const ContainerType type);
+ void SetContainerType(const ContainerType type,
+ base::OnceCallback<void(bool)> callback);
// Sets floating keyboard drggable rect.
bool SetDraggableArea(const gfx::Rect& rect);
@@ -240,6 +247,10 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver,
// Reports error histogram in case lingering in an intermediate state.
void ReportLingeringState();
+ // Shows the keyboard if the last time the keyboard was hidden was a small
+ // time ago.
+ void ShowKeyboardIfWithinTransientBlurThreshold();
+
void SetContainerBehaviorInternal(const ContainerType type);
std::unique_ptr<KeyboardUI> ui_;
@@ -252,6 +263,8 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver,
// Current active visual behavior for the keyboard container.
std::unique_ptr<ContainerBehavior> container_behavior_;
+ std::unique_ptr<QueuedContainerType> queued_container_type_;
+
// If true, show the keyboard window when keyboard UI content updates.
bool show_on_content_update_;
@@ -268,10 +281,10 @@ class KEYBOARD_EXPORT KeyboardController : public ui::InputMethodObserver,
KeyboardControllerState state_;
- ContainerType enqueued_container_type_;
-
NotificationManager notification_manager_;
+ base::Time time_of_last_blur_ = base::Time::UnixEpoch();
+
static KeyboardController* instance_;
base::WeakPtrFactory<KeyboardController> weak_factory_report_lingering_state_;
diff --git a/chromium/ui/keyboard/keyboard_controller_observer.h b/chromium/ui/keyboard/keyboard_controller_observer.h
index bdaa053ac8d..822d07a3a1e 100644
--- a/chromium/ui/keyboard/keyboard_controller_observer.h
+++ b/chromium/ui/keyboard/keyboard_controller_observer.h
@@ -30,26 +30,26 @@ class KEYBOARD_EXPORT KeyboardControllerObserver {
virtual ~KeyboardControllerObserver() {}
// Called when the keyboard is shown or closed.
- virtual void OnKeyboardAvailabilityChanging(const bool is_available) {}
+ virtual void OnKeyboardAvailabilityChanged(const bool is_available) {}
// Called when the keyboard bounds are changing.
- virtual void OnKeyboardVisibleBoundsChanging(const gfx::Rect& new_bounds) {}
+ virtual void OnKeyboardVisibleBoundsChanged(const gfx::Rect& new_bounds) {}
// Called when the keyboard bounds have changed in a way that should affect
// the usable region of the workspace.
- virtual void OnKeyboardWorkspaceOccludedBoundsChanging(
+ virtual void OnKeyboardWorkspaceOccludedBoundsChanged(
const gfx::Rect& new_bounds) {}
// Called when the keyboard bounds have changed in a way that affects how the
// workspace should change to not take up the screen space occupied by the
// keyboard.
- virtual void OnKeyboardWorkspaceDisplacingBoundsChanging(
+ virtual void OnKeyboardWorkspaceDisplacingBoundsChanged(
const gfx::Rect& new_bounds){};
// Redundant with other various notification methods. Use this if the state of
// multiple properties need to be conveyed simultaneously to observer
// implementations without the need to track multiple stateful properties.
- virtual void OnKeyboardAppearanceChanging(
+ virtual void OnKeyboardAppearanceChanged(
const KeyboardStateDescriptor& state){};
// Called when the keyboard was closed.
diff --git a/chromium/ui/keyboard/keyboard_controller_unittest.cc b/chromium/ui/keyboard/keyboard_controller_unittest.cc
index fad8f1e77a7..8ecafe94069 100644
--- a/chromium/ui/keyboard/keyboard_controller_unittest.cc
+++ b/chromium/ui/keyboard/keyboard_controller_unittest.cc
@@ -14,7 +14,7 @@
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/client/focus_client.h"
-#include "ui/aura/test/aura_test_helper.h"
+#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/base/ime/dummy_text_input_client.h"
@@ -176,15 +176,39 @@ class TestKeyboardLayoutDelegate : public KeyboardLayoutDelegate {
DISALLOW_COPY_AND_ASSIGN(TestKeyboardLayoutDelegate);
};
+class SetModeCallbackInvocationCounter {
+ public:
+ SetModeCallbackInvocationCounter() : weak_factory_invoke_(this) {}
+
+ void Invoke(bool status) {
+ if (status)
+ invocation_count_success_++;
+ else
+ invocation_count_failure_++;
+ }
+
+ base::OnceCallback<void(bool)> GetInvocationCallback() {
+ return base::BindOnce(&SetModeCallbackInvocationCounter::Invoke,
+ weak_factory_invoke_.GetWeakPtr());
+ }
+
+ int invocation_count_for_status(bool status) {
+ return status ? invocation_count_success_ : invocation_count_failure_;
+ }
+
+ private:
+ int invocation_count_success_ = 0;
+ int invocation_count_failure_ = 0;
+ base::WeakPtrFactory<SetModeCallbackInvocationCounter> weak_factory_invoke_;
+};
+
} // namespace
-class KeyboardControllerTest : public testing::Test,
+class KeyboardControllerTest : public aura::test::AuraTestBase,
public KeyboardControllerObserver {
public:
KeyboardControllerTest()
- : scoped_task_environment_(
- base::test::ScopedTaskEnvironment::MainThreadType::UI),
- visible_bounds_number_of_calls_(0),
+ : visible_bounds_number_of_calls_(0),
occluding_bounds_number_of_calls_(0),
is_available_number_of_calls_(0),
is_available_(false),
@@ -192,24 +216,14 @@ class KeyboardControllerTest : public testing::Test,
~KeyboardControllerTest() override {}
void SetUp() override {
- // The ContextFactory must exist before any Compositors are created.
- bool enable_pixel_output = false;
- ui::ContextFactory* context_factory = nullptr;
- ui::ContextFactoryPrivate* context_factory_private = nullptr;
-
- ui::InitializeContextFactoryForTests(enable_pixel_output, &context_factory,
- &context_factory_private);
-
ui::SetUpInputMethodFactoryForTesting();
- aura_test_helper_.reset(new aura::test::AuraTestHelper());
- aura_test_helper_->SetUp(context_factory, context_factory_private);
- new wm::DefaultActivationClient(aura_test_helper_->root_window());
+ aura::test::AuraTestBase::SetUp();
+ new wm::DefaultActivationClient(root_window());
focus_controller_.reset(new TestFocusController(root_window()));
layout_delegate_.reset(new TestKeyboardLayoutDelegate());
- controller_.reset(
- new KeyboardController(std::make_unique<TestKeyboardUI>(
- aura_test_helper_->host()->GetInputMethod()),
- layout_delegate_.get()));
+ controller_.reset(new KeyboardController(
+ std::make_unique<TestKeyboardUI>(host()->GetInputMethod()),
+ layout_delegate_.get()));
controller()->AddObserver(this);
}
@@ -218,11 +232,9 @@ class KeyboardControllerTest : public testing::Test,
controller()->RemoveObserver(this);
controller_.reset();
focus_controller_.reset();
- aura_test_helper_->TearDown();
- ui::TerminateContextFactoryForTests();
+ aura::test::AuraTestBase::TearDown();
}
- aura::Window* root_window() { return aura_test_helper_->root_window(); }
KeyboardUI* ui() { return controller_->ui(); }
KeyboardController* controller() { return controller_.get(); }
@@ -240,16 +252,16 @@ class KeyboardControllerTest : public testing::Test,
protected:
// KeyboardControllerObserver overrides
- void OnKeyboardVisibleBoundsChanging(const gfx::Rect& new_bounds) override {
+ void OnKeyboardVisibleBoundsChanged(const gfx::Rect& new_bounds) override {
visible_bounds_ = new_bounds;
visible_bounds_number_of_calls_++;
}
- void OnKeyboardWorkspaceOccludedBoundsChanging(
+ void OnKeyboardWorkspaceOccludedBoundsChanged(
const gfx::Rect& new_bounds) override {
occluding_bounds_ = new_bounds;
occluding_bounds_number_of_calls_++;
}
- void OnKeyboardAvailabilityChanging(bool is_available) override {
+ void OnKeyboardAvailabilityChanged(bool is_available) override {
is_available_ = is_available;
is_available_number_of_calls_++;
}
@@ -271,6 +283,15 @@ class KeyboardControllerTest : public testing::Test,
bool IsKeyboardClosed() { return keyboard_closed_; }
+ void SetProgrammaticFocus(ui::TextInputClient* client) {
+ controller_->OnTextInputStateChanged(client);
+ }
+
+ void AddTimeToTransientBlurCounter(double seconds) {
+ controller_->time_of_last_blur_ -=
+ base::TimeDelta::FromMilliseconds((int)(1000 * seconds));
+ }
+
void SetFocus(ui::TextInputClient* client) {
ui::InputMethod* input_method = ui()->GetInputMethod();
input_method->SetFocusedTextInputClient(client);
@@ -308,8 +329,6 @@ class KeyboardControllerTest : public testing::Test,
run_loop->Run();
}
- base::test::ScopedTaskEnvironment scoped_task_environment_;
- std::unique_ptr<aura::test::AuraTestHelper> aura_test_helper_;
std::unique_ptr<TestFocusController> focus_controller_;
private:
@@ -449,6 +468,82 @@ TEST_F(KeyboardControllerTest, ClickDoesNotFocusKeyboard) {
keyboard_container->RemovePreTargetHandler(&observer);
}
+// Tests that blur-then-focus that occur in less than the transient threshold
+// cause the keyboard to re-show.
+TEST_F(KeyboardControllerTest, TransientBlurShortDelay) {
+ ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
+ ui::DummyTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT);
+ ui::DummyTextInputClient no_input_client(ui::TEXT_INPUT_TYPE_NONE);
+ base::RunLoop run_loop;
+ aura::Window* keyboard_container(controller()->GetContainerWindow());
+ std::unique_ptr<KeyboardContainerObserver> keyboard_container_observer(
+ new KeyboardContainerObserver(keyboard_container, &run_loop));
+ root_window()->AddChild(keyboard_container);
+
+ // Keyboard is hidden
+ EXPECT_FALSE(keyboard_container->IsVisible());
+
+ // Set programmatic focus to the text field. Nothing happens
+ SetProgrammaticFocus(&input_client);
+ EXPECT_FALSE(keyboard_container->IsVisible());
+
+ // Click it for real. Keyboard starts to appear.
+ SetFocus(&input_client);
+ EXPECT_TRUE(keyboard_container->IsVisible());
+
+ // Focus a non text field
+ SetFocus(&no_input_client);
+
+ // It waits 100 ms and then hides. Wait for this routine to finish.
+ EXPECT_TRUE(WillHideKeyboard());
+ RunLoop(&run_loop);
+ EXPECT_FALSE(keyboard_container->IsVisible());
+
+ // Virtually wait half a second
+ AddTimeToTransientBlurCounter(0.5);
+ // Apply programmatic focus to the text field.
+ SetProgrammaticFocus(&input_client);
+ EXPECT_TRUE(keyboard_container->IsVisible());
+ EXPECT_FALSE(WillHideKeyboard());
+}
+
+// Tests that blur-then-focus that occur past the transient threshold do not
+// cause the keyboard to re-show.
+TEST_F(KeyboardControllerTest, TransientBlurLongDelay) {
+ ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
+ ui::DummyTextInputClient input_client(ui::TEXT_INPUT_TYPE_TEXT);
+ ui::DummyTextInputClient no_input_client(ui::TEXT_INPUT_TYPE_NONE);
+ base::RunLoop run_loop;
+ aura::Window* keyboard_container(controller()->GetContainerWindow());
+ std::unique_ptr<KeyboardContainerObserver> keyboard_container_observer(
+ new KeyboardContainerObserver(keyboard_container, &run_loop));
+ root_window()->AddChild(keyboard_container);
+
+ // Keyboard is hidden
+ EXPECT_FALSE(keyboard_container->IsVisible());
+
+ // Set programmatic focus to the text field. Nothing happens
+ SetProgrammaticFocus(&input_client);
+ EXPECT_FALSE(keyboard_container->IsVisible());
+
+ // Click it for real. Keyboard starts to appear.
+ SetFocus(&input_client);
+ EXPECT_TRUE(keyboard_container->IsVisible());
+
+ // Focus a non text field
+ SetFocus(&no_input_client);
+
+ // It waits 100 ms and then hides. Wait for this routine to finish.
+ EXPECT_TRUE(WillHideKeyboard());
+ RunLoop(&run_loop);
+ EXPECT_FALSE(keyboard_container->IsVisible());
+
+ // Wait 5 seconds and then set programmatic focus to a text field
+ AddTimeToTransientBlurCounter(5.0);
+ SetProgrammaticFocus(&input_client);
+ EXPECT_FALSE(keyboard_container->IsVisible());
+}
+
TEST_F(KeyboardControllerTest, VisibilityChangeWithTextInputTypeChange) {
ScopedAccessibilityKeyboardEnabler scoped_keyboard_enabler;
ui::DummyTextInputClient input_client_0(ui::TEXT_INPUT_TYPE_TEXT);
@@ -655,13 +750,27 @@ TEST_F(KeyboardControllerAnimationTest, ContainerAnimation) {
EXPECT_EQ(gfx::Rect(), notified_occluding_bounds());
EXPECT_FALSE(notified_is_available());
- controller()->SetContainerType(ContainerType::FLOATING);
+ SetModeCallbackInvocationCounter invocation_counter;
+ controller()->SetContainerType(ContainerType::FLOATING,
+ invocation_counter.GetInvocationCallback());
+ EXPECT_EQ(1, invocation_counter.invocation_count_for_status(true));
+ EXPECT_EQ(0, invocation_counter.invocation_count_for_status(false));
ShowKeyboard();
RunAnimationForLayer(layer);
+ EXPECT_EQ(1, invocation_counter.invocation_count_for_status(true));
+ EXPECT_EQ(0, invocation_counter.invocation_count_for_status(false));
// Visible bounds and occluding bounds are now different.
EXPECT_EQ(keyboard_container()->bounds(), notified_visible_bounds());
EXPECT_EQ(gfx::Rect(), notified_occluding_bounds());
EXPECT_TRUE(notified_is_available());
+
+ // callback should do nothing when container mode is set to the current active
+ // container type. An unnecessary call gets registered synchronously as a
+ // failure status to the callback.
+ controller()->SetContainerType(ContainerType::FLOATING,
+ invocation_counter.GetInvocationCallback());
+ EXPECT_EQ(1, invocation_counter.invocation_count_for_status(true));
+ EXPECT_EQ(1, invocation_counter.invocation_count_for_status(false));
}
// Show keyboard during keyboard hide animation should abort the hide animation
diff --git a/chromium/ui/keyboard/keyboard_util.cc b/chromium/ui/keyboard/keyboard_util.cc
index 356253966e7..35b70957c3a 100644
--- a/chromium/ui/keyboard/keyboard_util.cc
+++ b/chromium/ui/keyboard/keyboard_util.cc
@@ -18,6 +18,7 @@
#include "ui/base/ime/input_method_base.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/base/ime/text_input_flags.h"
+#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/events/event_sink.h"
#include "ui/events/event_utils.h"
@@ -245,12 +246,14 @@ bool SendKeyEvent(const std::string type,
if (!input_method)
return false;
+ // This can be null if no text input field is not focused.
ui::TextInputClient* tic = input_method->GetTextInputClient();
SendProcessKeyEvent(ui::ET_KEY_PRESSED, host);
ui::KeyEvent char_event(key_value, code, ui::EF_NONE);
- tic->InsertChar(char_event);
+ if (tic)
+ tic->InsertChar(char_event);
SendProcessKeyEvent(ui::ET_KEY_RELEASED, host);
}
} else {
diff --git a/chromium/ui/keyboard/notification_manager.cc b/chromium/ui/keyboard/notification_manager.cc
index 5ef18d8da2a..4838d2b3fc2 100644
--- a/chromium/ui/keyboard/notification_manager.cc
+++ b/chromium/ui/keyboard/notification_manager.cc
@@ -59,20 +59,20 @@ void NotificationManager::SendNotifications(
for (KeyboardControllerObserver& observer : observers) {
if (send_availability_notification)
- observer.OnKeyboardAvailabilityChanging(is_available);
+ observer.OnKeyboardAvailabilityChanged(is_available);
if (send_visual_bounds_notification)
- observer.OnKeyboardVisibleBoundsChanging(bounds);
+ observer.OnKeyboardVisibleBoundsChanged(bounds);
if (send_occluded_bounds_notification)
- observer.OnKeyboardWorkspaceOccludedBoundsChanging(occluded_region);
+ observer.OnKeyboardWorkspaceOccludedBoundsChanged(occluded_region);
if (send_displaced_bounds_notification) {
- observer.OnKeyboardWorkspaceDisplacingBoundsChanging(
+ observer.OnKeyboardWorkspaceDisplacingBoundsChanged(
workspace_layout_offset_region);
}
- observer.OnKeyboardAppearanceChanging(state);
+ observer.OnKeyboardAppearanceChanged(state);
}
}
diff --git a/chromium/ui/keyboard/queued_container_type.cc b/chromium/ui/keyboard/queued_container_type.cc
new file mode 100644
index 00000000000..2cf7b882e24
--- /dev/null
+++ b/chromium/ui/keyboard/queued_container_type.cc
@@ -0,0 +1,24 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/bind.h"
+#include "ui/keyboard/keyboard_controller.h"
+
+namespace keyboard {
+
+QueuedContainerType::QueuedContainerType(
+ KeyboardController* controller,
+ ContainerType container_type,
+ base::OnceCallback<void(bool success)> callback)
+ : controller_(controller),
+ container_type_(container_type),
+ callback_(std::move(callback)){};
+
+QueuedContainerType::~QueuedContainerType() {
+ bool change_successful =
+ controller_->GetActiveContainerType() == container_type_;
+ std::move(callback_).Run(change_successful);
+};
+
+} // namespace keyboard
diff --git a/chromium/ui/keyboard/queued_container_type.h b/chromium/ui/keyboard/queued_container_type.h
new file mode 100644
index 00000000000..ce58d930e28
--- /dev/null
+++ b/chromium/ui/keyboard/queued_container_type.h
@@ -0,0 +1,37 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_KEYBOARD_QUEUED_CONTAINER_TYPE_H_
+#define UI_KEYBOARD_QUEUED_CONTAINER_TYPE_H_
+
+#include "base/bind.h"
+#include "ui/keyboard/container_type.h"
+
+namespace keyboard {
+
+class KeyboardController;
+
+// Tracks a queued ContainerType change request. Couples a container type with a
+// callback to invoke once the necessary animation and container changes are
+// complete.
+// The callback will be invoked once this object goes out of scope. Success
+// is defined as the KeyboardController's current container behavior matching
+// the same container type as the queued container type.
+class QueuedContainerType {
+ public:
+ QueuedContainerType(KeyboardController* controller,
+ ContainerType container_type,
+ base::OnceCallback<void(bool success)> callback);
+ ~QueuedContainerType();
+ ContainerType container_type() { return container_type_; }
+
+ private:
+ KeyboardController* controller_;
+ ContainerType container_type_;
+ base::OnceCallback<void(bool success)> callback_;
+};
+
+} // namespace keyboard
+
+#endif // UI_KEYBOARD_QUEUED_CONTAINER_TYPE_H_
diff --git a/chromium/ui/keyboard/resources/inputview_adapter.js b/chromium/ui/keyboard/resources/inputview_adapter.js
index cbafd012b8b..eedf5648d8e 100644
--- a/chromium/ui/keyboard/resources/inputview_adapter.js
+++ b/chromium/ui/keyboard/resources/inputview_adapter.js
@@ -163,7 +163,8 @@ function registerInputviewApi() {
NONE: 0,
ALT: 8,
CONTROL: 4,
- SHIFT: 2
+ SHIFT: 2,
+ CAPSLOCK: 256
};
// Mapping from keyName to keyCode (see ui::KeyEvent).
@@ -295,8 +296,10 @@ function registerInputviewApi() {
event.modifiers |= Modifier.ALT;
if (data.ctrlKey)
event.modifiers |= Modifier.CONTROL;
- if (data.shiftKey || data.capsLock)
+ if (data.shiftKey)
event.modifiers |= Modifier.SHIFT;
+ if (data.capsLock)
+ event.modifiers |= Modifier.CAPSLOCK;
chrome.virtualKeyboardPrivate.sendKeyEvent(event, logIfError_);
});
diff --git a/chromium/ui/latency/latency_tracker.cc b/chromium/ui/latency/latency_tracker.cc
index 6b50846afd6..85e25920566 100644
--- a/chromium/ui/latency/latency_tracker.cc
+++ b/chromium/ui/latency/latency_tracker.cc
@@ -104,13 +104,6 @@ void LatencyTracker::OnGpuSwapBuffersCompleted(const LatencyInfo& latency) {
}
}
-void LatencyTracker::ReportRapporScrollLatency(
- const std::string& name,
- const LatencyInfo::LatencyComponent& start_component,
- const LatencyInfo::LatencyComponent& end_component) {
- // Only supported by RenderWidgetHostLatencyTracker.
-}
-
void LatencyTracker::ReportUkmScrollLatency(
const InputMetricEvent& metric_event,
const LatencyInfo::LatencyComponent& start_component,
@@ -193,10 +186,6 @@ void LatencyTracker::ComputeEndToEndLatencyHistograms(
original_component, gpu_swap_begin_component);
}
- ReportRapporScrollLatency("Event.Latency.ScrollBegin." + input_modality +
- ".TimeToScrollUpdateSwapBegin2",
- original_component, gpu_swap_begin_component);
-
} else if (latency.FindLatency(
ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT,
&original_component)) {
@@ -215,10 +204,6 @@ void LatencyTracker::ComputeEndToEndLatencyHistograms(
original_component, gpu_swap_begin_component);
}
- ReportRapporScrollLatency("Event.Latency.ScrollUpdate." + input_modality +
- ".TimeToScrollUpdateSwapBegin2",
- original_component, gpu_swap_begin_component);
-
} else if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0,
&original_component)) {
if (latency.source_event_type() == SourceEventType::KEY_PRESS) {
diff --git a/chromium/ui/latency/latency_tracker.h b/chromium/ui/latency/latency_tracker.h
index f0180ebc45d..24397fc4ba6 100644
--- a/chromium/ui/latency/latency_tracker.h
+++ b/chromium/ui/latency/latency_tracker.h
@@ -29,11 +29,6 @@ class LatencyTracker {
protected:
ukm::SourceId ukm_source_id() const { return ukm_source_id_; }
- virtual void ReportRapporScrollLatency(
- const std::string& name,
- const LatencyInfo::LatencyComponent& start_component,
- const LatencyInfo::LatencyComponent& end_component);
-
private:
enum class InputMetricEvent {
SCROLL_BEGIN_TOUCH = 0,
diff --git a/chromium/ui/login/account_picker/md_user_pod_template.css b/chromium/ui/login/account_picker/md_user_pod_template.css
index 7b5d8f189f9..96794332ac3 100644
--- a/chromium/ui/login/account_picker/md_user_pod_template.css
+++ b/chromium/ui/login/account_picker/md_user_pod_template.css
@@ -13,3 +13,28 @@
text-transform: none;
z-index: 6;
}
+
+/* TODO(crbug.com/814922): Merge most of these with the default values. */
+pin-keyboard {
+ --pin-keyboard-backspace-opacity: 1;
+ --pin-keyboard-backspace-color: #FFF;
+ --pin-keyboard-backspace-paper-ripple-offset: 9px;
+ --pin-keyboard-digit-button: {
+ margin: 15px;
+ opacity: 1;
+ width: 48px;
+ };
+
+ --pin-keyboard-letter-color: rgba(255, 255, 255, .34);
+ --pin-keyboard-number-color: #FFF;
+
+ --pin-keyboard-paper-ripple: {
+ border-radius: 50%;
+ color: rgba(0, 0, 0, .34);
+ height: 60px;
+ left: -6px;
+ position: absolute;
+ top: -6px;
+ width: 60px;
+ };
+}
diff --git a/chromium/ui/login/display_manager.js b/chromium/ui/login/display_manager.js
index b1bededb799..3102fbfef19 100644
--- a/chromium/ui/login/display_manager.js
+++ b/chromium/ui/login/display_manager.js
@@ -56,6 +56,7 @@
/** @const */ var ACCELERATOR_APP_LAUNCH_NETWORK_CONFIG =
'app_launch_network_config';
/** @const */ var ACCELERATOR_BOOTSTRAPPING_SLAVE = "bootstrapping_slave";
+/** @const */ var ACCELERATOR_DEMO_MODE = "demo_mode";
/* Signin UI state constants. Used to control header bar UI. */
/** @const */ var SIGNIN_UI_STATE = {
@@ -91,7 +92,8 @@
USER_ADDING: 'user-adding',
APP_LAUNCH_SPLASH: 'app-launch-splash',
ARC_KIOSK_SPLASH: 'arc-kiosk-splash',
- DESKTOP_USER_MANAGER: 'login-add-user'
+ DESKTOP_USER_MANAGER: 'login-add-user',
+ GAIA_SIGNIN: 'gaia-signin'
};
/* Possible lock screen enabled app activity state. */
@@ -186,6 +188,15 @@ cr.define('cr.ui.login', function() {
SCREEN_OOBE_RESET,
];
+ /**
+ * Group of screens (screen IDs) where demo mode setup invocation is
+ * available.
+ * @type Array<string>
+ * @const
+ */
+ var DEMO_MODE_SETUP_AVAILABLE_SCREEN_GROUP = [
+ SCREEN_GAIA_SIGNIN,
+ ];
/**
* OOBE screens group index.
@@ -297,10 +308,17 @@ cr.define('cr.ui.login', function() {
loadTimeData.getString('showViewsLock') == 'on' &&
(this.displayType_ == DISPLAY_TYPE.LOCK ||
this.displayType_ == DISPLAY_TYPE.USER_ADDING);
- var showingViewsLogin = loadTimeData.valueExists('showViewsLogin') &&
+ return showingViewsLock || this.showingViewsLogin;
+ },
+
+ /**
+ * Returns true if we are showing views based login screen.
+ * @return {boolean}
+ */
+ get showingViewsLogin() {
+ return loadTimeData.valueExists('showViewsLogin') &&
loadTimeData.getString('showViewsLogin') == 'on' &&
- (this.displayType_ == DISPLAY_TYPE.LOGIN);
- return showingViewsLock || showingViewsLogin;
+ (this.displayType_ == DISPLAY_TYPE.GAIA_SIGNIN);
},
/**
@@ -423,6 +441,11 @@ cr.define('cr.ui.login', function() {
chrome.send('networkConfigRequest');
} else if (name == ACCELERATOR_BOOTSTRAPPING_SLAVE) {
chrome.send('setOobeBootstrappingSlave');
+ } else if (name == ACCELERATOR_DEMO_MODE) {
+ if (DEMO_MODE_SETUP_AVAILABLE_SCREEN_GROUP.indexOf(currentStepId) !=
+ -1) {
+ chrome.send('setupDemoMode');
+ }
}
},
@@ -547,10 +570,6 @@ cr.define('cr.ui.login', function() {
newStep.setAttribute(
'aria-label',
loadTimeData.getString('signinScreenTitle'));
- } else if (nextStepId == SCREEN_OOBE_NETWORK) {
- newStep.setAttribute(
- 'aria-label',
- loadTimeData.getString('networkScreenAccessibleTitle'));
}
// Default control to be focused (if specified).
@@ -640,6 +659,10 @@ cr.define('cr.ui.login', function() {
return;
var screenId = screen.id;
+ if (screenId == SCREEN_ACCOUNT_PICKER && this.showingViewsLogin) {
+ chrome.send('updateGaiaDialogVisibility', [false]);
+ return;
+ }
// Make sure the screen is decorated.
this.preloadScreen(screen);
@@ -735,6 +758,12 @@ cr.define('cr.ui.login', function() {
// This requires |screen| to have 'box-sizing: border-box'.
screen.style.width = width + 'px';
screen.style.height = height + 'px';
+
+ if (this.showingViewsLogin) {
+ chrome.send('updateGaiaDialogSize', [width, height]);
+ $('scroll-container').classList.toggle('disable-scroll', true);
+ $('scroll-container').scrollTop = $('inner-container').offsetTop;
+ }
},
/**
diff --git a/chromium/ui/message_center/BUILD.gn b/chromium/ui/message_center/BUILD.gn
index b684c1e02de..ed816055fb4 100644
--- a/chromium/ui/message_center/BUILD.gn
+++ b/chromium/ui/message_center/BUILD.gn
@@ -17,6 +17,7 @@ aggregate_vector_icons("message_center_vector_icons") {
"notification_close_button.icon",
"notification_expand_less.icon",
"notification_expand_more.icon",
+ "notification_inline_reply.icon",
"notification_settings_button.1x.icon",
"notification_settings_button.icon",
"product.icon",
@@ -28,11 +29,14 @@ jumbo_component("message_center") {
deps = [
"//base",
"//ui/base",
- "//ui/message_center/public/cpp",
"//ui/strings",
"//url",
]
+ public_deps = [
+ "//ui/message_center/public/cpp",
+ ]
+
defines = [ "MESSAGE_CENTER_IMPLEMENTATION" ]
if (enable_message_center) {
@@ -58,8 +62,6 @@ jumbo_component("message_center") {
"//build/config/compiler:no_size_t_to_int_warning",
]
sources = [
- "change_queue.cc",
- "change_queue.h",
"cocoa/notification_controller.h",
"cocoa/notification_controller.mm",
"cocoa/opaque_views.h",
@@ -74,21 +76,15 @@ jumbo_component("message_center") {
"message_center_impl.cc",
"message_center_impl.h",
"message_center_observer.h",
+ "message_center_stats_collector.cc",
+ "message_center_stats_collector.h",
"message_center_style.cc",
"message_center_style.h",
"message_center_types.h",
- "notification.cc",
- "notification.h",
"notification_blocker.cc",
"notification_blocker.h",
- "notification_delegate.cc",
- "notification_delegate.h",
"notification_list.cc",
"notification_list.h",
- "notification_types.cc",
- "notification_types.h",
- "notifier_id.cc",
- "notifier_id.h",
"popup_timer.cc",
"popup_timer.h",
"popup_timers_controller.cc",
@@ -120,7 +116,6 @@ jumbo_component("message_center") {
sources += [
"views/bounded_label.cc",
"views/bounded_label.h",
- "views/constants.h",
"views/desktop_popup_alignment_delegate.cc",
"views/desktop_popup_alignment_delegate.h",
"views/message_popup_collection.cc",
@@ -168,21 +163,7 @@ jumbo_component("message_center") {
# Notification service disabled.
sources = [
"dummy_message_center.cc",
- "notification_delegate.cc",
- "notification_delegate.h",
]
-
- # Android implements its own notification UI manager instead of deferring to
- # the message center (when notifications are enabled). Include a minimal
- # set of files required for notifications on Android.
- if (is_android) {
- sources += [
- "notification.cc",
- "notification.h",
- "notifier_id.cc",
- "notifier_id.h",
- ]
- }
}
}
@@ -207,18 +188,18 @@ if (enable_message_center) {
public_deps = [
":message_center",
+ "//ui/message_center/public/cpp",
]
}
test("message_center_unittests") {
sources = [
- "change_queue_unittest.cc",
"cocoa/notification_controller_unittest.mm",
"cocoa/popup_collection_unittest.mm",
"cocoa/popup_controller_unittest.mm",
"message_center_impl_unittest.cc",
- "notification_delegate_unittest.cc",
"notification_list_unittest.cc",
+ "public/cpp/notification_delegate_unittest.cc",
"test/run_all_unittests.cc",
"ui_controller_unittest.cc",
]
@@ -228,6 +209,7 @@ if (enable_message_center) {
":test_support",
"//base",
"//base/test:test_support",
+ "//mojo/edk/system",
"//skia",
"//testing/gmock",
"//testing/gtest",
@@ -252,10 +234,10 @@ if (enable_message_center) {
]
if (is_chromeos) {
- sources += [ "mojo/struct_traits_unittest.cc" ]
+ sources += [ "public/mojo/struct_traits_unittest.cc" ]
deps += [
"//mojo/edk/system",
- "//ui/message_center/mojo:test_interfaces",
+ "//ui/message_center/public/mojo:test_interfaces",
]
}
diff --git a/chromium/ui/message_center/change_queue.cc b/chromium/ui/message_center/change_queue.cc
deleted file mode 100644
index a61dcd2989e..00000000000
--- a/chromium/ui/message_center/change_queue.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/message_center/change_queue.h"
-
-#include "ui/message_center/message_center_impl.h"
-#include "ui/message_center/notification.h"
-
-namespace message_center {
-
-// Change represents an operation made on a notification. Since it contains
-// the final state of the notification, except complex cases, we generally
-// optimize the list and keep only the last change for a particular notification
-// that is in the notification list around. There are two ids; |id_| is the
-// post-update notification id that has been assigned by an update, and
-// |previous_id| is the previous id of the notification before the Change.
-// The two ids are same unless the Change changes the id of the notification.
-// See the comments of id() and previous_id() for reference.
-class ChangeQueue::Change {
- public:
- Change(ChangeType type,
- const std::string& id,
- std::unique_ptr<Notification> notification);
- ~Change();
-
- // Used to transfer ownership of the contained notification.
- std::unique_ptr<Notification> PassNotification();
-
- Notification* notification() const { return notification_.get(); }
- // Returns the post-update ID. It means:
- // - ADD event: ID of the notification to be added. In this case, this must be
- // same as |previous_id()|.
- // - UPDATE event: ID of the notification after the change. If the change
- // doesn't update its ID, this value is same as |previous_id()|.
- // - DELETE event: ID of the notification to be deleted. This must be same as
- // |previous_id()|.
- const std::string& id() const { return id_; }
- ChangeType type() const { return type_; }
- bool by_user() const { return by_user_; }
- void set_by_user(bool by_user) { by_user_ = by_user; }
- // Returns the ID which is used in the notification list. In other word, it
- // means the ID before the change.
- const std::string& previous_id() const { return previous_id_; }
- void set_type(const ChangeType new_type) { type_ = new_type; }
- void ReplaceNotification(std::unique_ptr<Notification> new_notification);
-
- private:
- ChangeType type_;
- std::string id_;
- std::string previous_id_;
- bool by_user_;
- std::unique_ptr<Notification> notification_;
-
- DISALLOW_COPY_AND_ASSIGN(Change);
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// ChangeFinder
-
-struct ChangeFinder {
- explicit ChangeFinder(const std::string& id) : id(id) {}
- bool operator()(const std::unique_ptr<ChangeQueue::Change>& change) {
- return change->id() == id;
- }
-
- std::string id;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-// ChangeQueue::Change
-
-ChangeQueue::Change::Change(ChangeType type,
- const std::string& id,
- std::unique_ptr<Notification> notification)
- : type_(type),
- previous_id_(id),
- by_user_(false),
- notification_(std::move(notification)) {
- DCHECK(!id.empty());
- DCHECK(type != CHANGE_TYPE_DELETE || !notification_);
-
- id_ = notification_ ? notification_->id() : previous_id_;
-}
-
-ChangeQueue::Change::~Change() {}
-
-std::unique_ptr<Notification> ChangeQueue::Change::PassNotification() {
- return std::move(notification_);
-}
-
-void ChangeQueue::Change::ReplaceNotification(
- std::unique_ptr<Notification> new_notification) {
- id_ = new_notification ? new_notification->id() : previous_id_;
- notification_.swap(new_notification);
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// ChangeQueue
-
-ChangeQueue::ChangeQueue() = default;
-
-ChangeQueue::~ChangeQueue() = default;
-
-void ChangeQueue::ApplyChanges(MessageCenterImpl* message_center) {
- while (!changes_.empty()) {
- auto iter = changes_.begin();
- std::unique_ptr<Change> change(std::move(*iter));
- changes_.erase(iter);
- ApplyChangeInternal(message_center, std::move(change));
- }
-}
-
-void ChangeQueue::AddNotification(std::unique_ptr<Notification> notification) {
- std::string id = notification->id();
- changes_.push_back(
- std::make_unique<Change>(CHANGE_TYPE_ADD, id, std::move(notification)));
-}
-
-void ChangeQueue::UpdateNotification(
- const std::string& old_id,
- std::unique_ptr<Notification> notification) {
- changes_.push_back(std::make_unique<Change>(CHANGE_TYPE_UPDATE, old_id,
- std::move(notification)));
-}
-
-void ChangeQueue::RemoveNotification(const std::string& id, bool by_user) {
- auto change = std::make_unique<Change>(CHANGE_TYPE_DELETE, id, nullptr);
- change->set_by_user(by_user);
- changes_.push_back(std::move(change));
-}
-
-Notification* ChangeQueue::GetLatestNotification(const std::string& id) const {
- auto iter =
- std::find_if(changes_.rbegin(), changes_.rend(), ChangeFinder(id));
- if (iter == changes_.rend())
- return nullptr;
-
- if ((*iter)->type() == CHANGE_TYPE_DELETE)
- return nullptr;
-
- return (*iter)->notification();
-}
-
-void ChangeQueue::ApplyChangeInternal(MessageCenterImpl* message_center,
- std::unique_ptr<Change> change) {
- switch (change->type()) {
- case CHANGE_TYPE_ADD:
- message_center->AddNotificationImmediately(change->PassNotification());
- break;
- case CHANGE_TYPE_UPDATE:
- message_center->UpdateNotificationImmediately(change->previous_id(),
- change->PassNotification());
- break;
- case CHANGE_TYPE_DELETE:
- message_center->RemoveNotificationImmediately(change->previous_id(),
- change->by_user());
- break;
- default:
- NOTREACHED();
- }
-}
-
-} // namespace message_center
diff --git a/chromium/ui/message_center/change_queue.h b/chromium/ui/message_center/change_queue.h
deleted file mode 100644
index b2c9d287c6b..00000000000
--- a/chromium/ui/message_center/change_queue.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_MESSAGE_CENTER_CHANGE_QUEUE_H_
-#define UI_MESSAGE_CENTER_CHANGE_QUEUE_H_
-
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "ui/message_center/message_center_export.h"
-
-namespace message_center {
-
-class MessageCenterImpl;
-class Notification;
-
-// ChangeQueue keeps track of all the changes. This class can be used for
-// queuing changes during the message center can't be updated.
-class MESSAGE_CENTER_EXPORT ChangeQueue {
- public:
- enum ChangeType {
- CHANGE_TYPE_ADD = 0,
- CHANGE_TYPE_UPDATE,
- CHANGE_TYPE_DELETE
- };
-
- // Change represents an operation made on a notification. Since it contains
- // the final state of the notification, we only keep the last change for a
- // particular notification that is in the notification list around. There are
- // two ids; |id_| is the newest notification id that has been assigned by an
- // update, and |notification_list_id_| is the id of the notification it should
- // be updating as it exists in the notification list.
- class Change;
-
- ChangeQueue();
- ~ChangeQueue();
-
- // Called when the message center has appropriate visibility. Modifies
- // |message_center| but does not retain it. This also causes the queue to
- // empty itself.
- void ApplyChanges(MessageCenterImpl* message_center);
-
- // Causes a TYPE_ADD change to be added to the queue.
- void AddNotification(std::unique_ptr<Notification> notification);
-
- // Causes a TYPE_UPDATE change to be added to the queue.
- void UpdateNotification(const std::string& old_id,
- std::unique_ptr<Notification> notification);
-
- // Causes a TYPE_DELETE change to be added to the queue.
- void RemoveNotification(const std::string& id, bool by_user);
-
- // Returns the pointer to the Notification in the latest Change which has the
- // given ID. If the Change is UPDATE, the ID after the change is searched.
- // If the Change id REMOVE, this returns nullptr.
- // ChangeQueue keeps retaining ownership of the Notification. The returned
- // notification can be modified or be copied by caller.
- Notification* GetLatestNotification(const std::string& id) const;
-
- private:
- void ApplyChangeInternal(MessageCenterImpl* message_center,
- std::unique_ptr<Change> change);
-
- std::vector<std::unique_ptr<Change>> changes_;
-
- DISALLOW_COPY_AND_ASSIGN(ChangeQueue);
-};
-
-} // namespace message_center
-
-#endif // UI_MESSAGE_CENTER_CHANGE_QUEUE_H_
diff --git a/chromium/ui/message_center/change_queue_unittest.cc b/chromium/ui/message_center/change_queue_unittest.cc
deleted file mode 100644
index bf475f2d052..00000000000
--- a/chromium/ui/message_center/change_queue_unittest.cc
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/message_center/change_queue.h"
-
-#include <utility>
-
-#include "base/strings/utf_string_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/message_center/message_center_impl.h"
-
-using base::UTF8ToUTF16;
-
-namespace message_center {
-
-namespace {
-
-Notification* CreateSimpleNotification(const std::string& id) {
- RichNotificationData optional_fields;
- optional_fields.buttons.push_back(ButtonInfo(UTF8ToUTF16("foo")));
- optional_fields.buttons.push_back(ButtonInfo(UTF8ToUTF16("foo")));
- return new Notification(
- NOTIFICATION_TYPE_SIMPLE, id, UTF8ToUTF16("title"), UTF8ToUTF16(id),
- gfx::Image() /* icon */, base::string16() /* display_source */, GURL(),
- NotifierId(NotifierId::APPLICATION, "change_queue_test"), optional_fields,
- NULL);
-}
-
-} // namespace
-
-class ChangeQueueTest : public testing::Test {
- public:
- ChangeQueueTest() = default;
- ~ChangeQueueTest() override = default;
-
- MessageCenterImpl* message_center() { return &message_center_; }
-
- private:
- MessageCenterImpl message_center_;
-};
-
-TEST_F(ChangeQueueTest, Queueing) {
- ChangeQueue queue;
- std::string id("id1");
- std::string id2("id2");
- NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
-
- // First, add and update a notification to ensure updates happen
- // normally.
- std::unique_ptr<Notification> notification(CreateSimpleNotification(id));
- message_center()->AddNotification(std::move(notification));
- notification.reset(CreateSimpleNotification(id2));
- message_center()->UpdateNotification(id, std::move(notification));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(id2));
- EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
-
- // Then update a notification; nothing should have happened.
- notification.reset(CreateSimpleNotification(id));
- queue.UpdateNotification(id2, std::move(notification));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(id2));
- EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
-
- // Apply the changes from the queue.
- queue.ApplyChanges(message_center());
-
- // Close the message center; then the update should have propagated.
- EXPECT_FALSE(message_center()->FindVisibleNotificationById(id2));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
-}
-
-TEST_F(ChangeQueueTest, SimpleQueueing) {
- ChangeQueue queue;
- std::string ids[6] = {"0", "1", "2", "3", "4", "5"};
- NotifierId notifier_id1(NotifierId::APPLICATION, "app1");
-
- std::unique_ptr<Notification> notification;
- // Prepare initial notifications on NotificationList.
- // NL: ["0", "1", "2", "4"]
- int i = 0;
- for (; i < 3; i++) {
- notification.reset(CreateSimpleNotification(ids[i]));
- message_center()->AddNotification(std::move(notification));
- }
- for (i = 0; i < 3; i++) {
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[i]));
- }
- for (; i < 6; i++) {
- EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[i]));
- }
-
- // This should update notification "1" to have id "4".
- notification.reset(CreateSimpleNotification(ids[4]));
- queue.AddNotification(std::move(notification));
-
- // Change the ID: "2" -> "5", "5" -> "3".
- notification.reset(CreateSimpleNotification(ids[5]));
- queue.UpdateNotification(ids[2], std::move(notification));
- notification.reset(CreateSimpleNotification(ids[3]));
- queue.UpdateNotification(ids[5], std::move(notification));
-
- // This should update notification "4" to "5".
- notification.reset(CreateSimpleNotification(ids[5]));
- queue.UpdateNotification(ids[4], std::move(notification));
-
- // This should create a new "4", that doesn't overwrite the update from 4
- // before.
- notification.reset(CreateSimpleNotification(ids[4]));
- queue.AddNotification(std::move(notification));
-
- // The NL should still be the same: ["0", "1", "2", "4"]
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[1]));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[2]));
- EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[3]));
- EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[4]));
- EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[5]));
- EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 3u);
-
- // Apply the changes from the queue.
- queue.ApplyChanges(message_center());
-
- // Changes should be applied.
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[0]));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[1]));
- EXPECT_FALSE(message_center()->FindVisibleNotificationById(ids[2]));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[3]));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[4]));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(ids[5]));
- EXPECT_EQ(message_center()->GetVisibleNotifications().size(), 5u);
-}
-
-} // namespace message_center
diff --git a/chromium/ui/message_center/cocoa/notification_controller.mm b/chromium/ui/message_center/cocoa/notification_controller.mm
index 61e9c0e63ee..38cb370b42b 100644
--- a/chromium/ui/message_center/cocoa/notification_controller.mm
+++ b/chromium/ui/message_center/cocoa/notification_controller.mm
@@ -22,8 +22,8 @@
#include "ui/gfx/text_utils.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_style.h"
-#include "ui/message_center/notification.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/strings/grit/ui_strings.h"
#include "url/gurl.h"
diff --git a/chromium/ui/message_center/cocoa/notification_controller_unittest.mm b/chromium/ui/message_center/cocoa/notification_controller_unittest.mm
index 99bb8049325..72c3441def9 100644
--- a/chromium/ui/message_center/cocoa/notification_controller_unittest.mm
+++ b/chromium/ui/message_center/cocoa/notification_controller_unittest.mm
@@ -15,9 +15,9 @@
#import "ui/base/cocoa/hover_image_button.h"
#import "ui/base/test/cocoa_helper.h"
#include "ui/message_center/fake_message_center.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_types.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_types.h"
using base::ASCIIToUTF16;
using base::UTF8ToUTF16;
@@ -148,7 +148,7 @@ TEST_F(NotificationControllerTest, BasicLayout) {
TEST_F(NotificationControllerTest, NotificationSetttingsButtonLayout) {
message_center::RichNotificationData data;
- data.settings_button_handler = SettingsButtonHandler::TRAY;
+ data.settings_button_handler = SettingsButtonHandler::INLINE;
std::unique_ptr<message_center::Notification> notification(
new message_center::Notification(
message_center::NOTIFICATION_TYPE_SIMPLE, "",
@@ -302,16 +302,16 @@ TEST_F(NotificationControllerTest, Image) {
TEST_F(NotificationControllerTest, List) {
message_center::RichNotificationData optional;
- message_center::NotificationItem item1(
- UTF8ToUTF16("First title"), UTF8ToUTF16("first message"));
+ message_center::NotificationItem item1{UTF8ToUTF16("First title"),
+ UTF8ToUTF16("first message")};
optional.items.push_back(item1);
- message_center::NotificationItem item2(
+ message_center::NotificationItem item2{
UTF8ToUTF16("Second title"),
- UTF8ToUTF16("second slightly longer message"));
+ UTF8ToUTF16("second slightly longer message")};
optional.items.push_back(item2);
- message_center::NotificationItem item3(
+ message_center::NotificationItem item3{
UTF8ToUTF16(""), // Test for empty string.
- UTF8ToUTF16(" ")); // Test for string containing only spaces.
+ UTF8ToUTF16(" ")}; // Test for string containing only spaces.
optional.items.push_back(item3);
optional.context_message = UTF8ToUTF16("Context Message");
diff --git a/chromium/ui/message_center/cocoa/popup_collection_unittest.mm b/chromium/ui/message_center/cocoa/popup_collection_unittest.mm
index 0bdc39689fb..e8a5d3fe9b3 100644
--- a/chromium/ui/message_center/cocoa/popup_collection_unittest.mm
+++ b/chromium/ui/message_center/cocoa/popup_collection_unittest.mm
@@ -16,8 +16,8 @@
#import "ui/message_center/cocoa/notification_controller.h"
#import "ui/message_center/cocoa/popup_controller.h"
#include "ui/message_center/message_center.h"
-#include "ui/message_center/notification.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
using base::ASCIIToUTF16;
diff --git a/chromium/ui/message_center/cocoa/popup_controller_unittest.mm b/chromium/ui/message_center/cocoa/popup_controller_unittest.mm
index cbe289e56e1..191b2d68463 100644
--- a/chromium/ui/message_center/cocoa/popup_controller_unittest.mm
+++ b/chromium/ui/message_center/cocoa/popup_controller_unittest.mm
@@ -10,7 +10,7 @@
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#import "ui/base/test/cocoa_helper.h"
-#include "ui/message_center/notification.h"
+#include "ui/message_center/public/cpp/notification.h"
using base::ASCIIToUTF16;
diff --git a/chromium/ui/message_center/fake_message_center.cc b/chromium/ui/message_center/fake_message_center.cc
index 6bb96cc932a..7bc04916264 100644
--- a/chromium/ui/message_center/fake_message_center.cc
+++ b/chromium/ui/message_center/fake_message_center.cc
@@ -39,7 +39,7 @@ bool FakeMessageCenter::IsQuietMode() const {
return false;
}
-message_center::Notification* FakeMessageCenter::FindVisibleNotificationById(
+Notification* FakeMessageCenter::FindVisibleNotificationById(
const std::string& id) {
for (auto* notification : GetVisibleNotifications()) {
if (id == notification->id())
diff --git a/chromium/ui/message_center/fake_message_center.h b/chromium/ui/message_center/fake_message_center.h
index b10be1b57ef..0c4ad7243eb 100644
--- a/chromium/ui/message_center/fake_message_center.h
+++ b/chromium/ui/message_center/fake_message_center.h
@@ -27,8 +27,7 @@ class FakeMessageCenter : public MessageCenter {
size_t NotificationCount() const override;
bool HasPopupNotifications() const override;
bool IsQuietMode() const override;
- message_center::Notification* FindVisibleNotificationById(
- const std::string& id) override;
+ Notification* FindVisibleNotificationById(const std::string& id) override;
const NotificationList::Notifications& GetVisibleNotifications() override;
NotificationList::PopupNotifications GetPopupNotifications() override;
void AddNotification(std::unique_ptr<Notification> notification) override;
diff --git a/chromium/ui/message_center/message_center.h b/chromium/ui/message_center/message_center.h
index c0666c34dc8..493c1454813 100644
--- a/chromium/ui/message_center/message_center.h
+++ b/chromium/ui/message_center/message_center.h
@@ -24,7 +24,7 @@ class DownloadNotificationTestBase;
// is shown, closed, or clicked on.
//
// MessageCenter is agnostic of profiles; it uses the string returned by
-// message_center::Notification::id() to uniquely identify a notification. It is
+// Notification::id() to uniquely identify a notification. It is
// the caller's responsibility to formulate the id so that 2 different
// notification should have different ids. For example, if the caller supports
// multiple profiles, then caller should encode both profile characteristics and
@@ -73,8 +73,7 @@ class MESSAGE_CENTER_EXPORT MessageCenter {
// Find the notification with the corresponding id. Returns null if not
// found. The returned instance is owned by the message center.
- virtual message_center::Notification* FindVisibleNotificationById(
- const std::string& id) = 0;
+ virtual Notification* FindVisibleNotificationById(const std::string& id) = 0;
// Gets all notifications to be shown to the user in the message center. Note
// that queued changes due to the message center being open are not reflected
diff --git a/chromium/ui/message_center/message_center_impl.cc b/chromium/ui/message_center/message_center_impl.cc
index 98421d1b534..53485f966a1 100644
--- a/chromium/ui/message_center/message_center_impl.cc
+++ b/chromium/ui/message_center/message_center_impl.cc
@@ -18,58 +18,23 @@
#include "base/strings/string_util.h"
#include "build/build_config.h"
#include "ui/message_center/message_center_types.h"
-#include "ui/message_center/notification.h"
#include "ui/message_center/notification_blocker.h"
#include "ui/message_center/notification_list.h"
-#include "ui/message_center/notification_types.h"
#include "ui/message_center/popup_timers_controller.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
-#include "ui/message_center/public/cpp/message_center_switches.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_types.h"
namespace message_center {
-namespace internal {
-
-////////////////////////////////////////////////////////////////////////////////
-// ScopedNotificationsIterationLock
-
-class ScopedNotificationsIterationLock {
- public:
- // Lock may be used recursively.
- explicit ScopedNotificationsIterationLock(MessageCenterImpl* message_center)
- : message_center_(message_center),
- original_value_(message_center->iterating_) {
- message_center_->iterating_ = true;
- }
-
- ~ScopedNotificationsIterationLock() {
- DCHECK(message_center_->iterating_);
-
- // |original_value_| must be false. But handle the other case just in case.
- message_center_->iterating_ = original_value_;
- if (!original_value_) {
- message_center_->notification_change_queue_->ApplyChanges(
- message_center_);
- }
- }
-
- private:
- MessageCenterImpl* message_center_;
- const bool original_value_;
-
- DISALLOW_COPY_AND_ASSIGN(ScopedNotificationsIterationLock);
-};
-
-} // namespace internal
-
////////////////////////////////////////////////////////////////////////////////
// MessageCenterImpl
MessageCenterImpl::MessageCenterImpl()
: MessageCenter(),
- popup_timers_controller_(new PopupTimersController(this)) {
+ popup_timers_controller_(std::make_unique<PopupTimersController>(this)),
+ stats_collector_(this) {
notification_list_.reset(new NotificationList(this));
- notification_change_queue_.reset(new ChangeQueue());
}
MessageCenterImpl::~MessageCenterImpl() {
@@ -107,29 +72,25 @@ void MessageCenterImpl::RemoveNotificationBlocker(
void MessageCenterImpl::OnBlockingStateChanged(NotificationBlocker* blocker) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
- std::list<const Notification*> blocked;
+ std::list<std::string> blocked;
NotificationList::PopupNotifications popups =
notification_list_->GetPopupNotifications(blockers_, &blocked);
// Close already displayed pop-ups that are blocked now.
- for (const auto* notification : blocked) {
+ for (const std::string& notification_id : blocked) {
// Do not call MessageCenterImpl::MarkSinglePopupAsShown() directly here
// just for performance reason. MessageCenterImpl::MarkSinglePopupAsShown()
// calls NotificationList::MarkSinglePopupAsShown(), but the whole cache
// will be recreated below.
- if (notification->IsRead())
- notification_list_->MarkSinglePopupAsShown(notification->id(), true);
+ if (FindVisibleNotificationById(notification_id)->IsRead())
+ notification_list_->MarkSinglePopupAsShown(notification_id, true);
}
visible_notifications_ =
notification_list_->GetVisibleNotifications(blockers_);
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (const auto* notification : blocked) {
- for (auto& observer : observer_list_)
- observer.OnNotificationUpdated(notification->id());
- }
+ for (const std::string& notification_id : blocked) {
+ for (auto& observer : observer_list_)
+ observer.OnNotificationUpdated(notification_id);
}
for (auto& observer : observer_list_)
observer.OnBlockingStateChanged(blocker);
@@ -137,19 +98,15 @@ void MessageCenterImpl::OnBlockingStateChanged(NotificationBlocker* blocker) {
void MessageCenterImpl::SetVisibility(Visibility visibility) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
visible_ = (visibility == VISIBILITY_MESSAGE_CENTER);
if (visible_) {
std::set<std::string> updated_ids;
notification_list_->SetNotificationsShown(blockers_, &updated_ids);
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (const auto& id : updated_ids) {
- for (auto& observer : observer_list_)
- observer.OnNotificationUpdated(id);
- }
+ for (const auto& id : updated_ids) {
+ for (auto& observer : observer_list_)
+ observer.OnNotificationUpdated(id);
}
}
@@ -178,7 +135,7 @@ bool MessageCenterImpl::IsQuietMode() const {
return notification_list_->quiet_mode();
}
-message_center::Notification* MessageCenterImpl::FindVisibleNotificationById(
+Notification* MessageCenterImpl::FindVisibleNotificationById(
const std::string& id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
return notification_list_->GetNotificationById(id);
@@ -193,7 +150,7 @@ MessageCenterImpl::GetVisibleNotifications() {
NotificationList::PopupNotifications
MessageCenterImpl::GetPopupNotifications() {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- return notification_list_->GetPopupNotifications(blockers_, NULL);
+ return notification_list_->GetPopupNotifications(blockers_, nullptr);
}
//------------------------------------------------------------------------------
@@ -206,20 +163,6 @@ void MessageCenterImpl::AddNotification(
for (size_t i = 0; i < blockers_.size(); ++i)
blockers_[i]->CheckState();
- if (iterating_) {
- notification_change_queue_->AddNotification(std::move(notification));
- return;
- }
-
- AddNotificationImmediately(std::move(notification));
-}
-
-void MessageCenterImpl::AddNotificationImmediately(
- std::unique_ptr<Notification> notification) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
- const std::string id = notification->id();
-
// Sometimes the notification can be added with the same id and the
// |notification_list| will replace the notification instead of adding new.
// This is essentially an update rather than addition.
@@ -228,13 +171,10 @@ void MessageCenterImpl::AddNotificationImmediately(
visible_notifications_ =
notification_list_->GetVisibleNotifications(blockers_);
- if (already_exists) {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
+ for (auto& observer : observer_list_) {
+ if (already_exists)
observer.OnNotificationUpdated(id);
- } else {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
+ else
observer.OnNotificationAdded(id);
}
}
@@ -246,35 +186,18 @@ void MessageCenterImpl::UpdateNotification(
for (size_t i = 0; i < blockers_.size(); ++i)
blockers_[i]->CheckState();
- if (iterating_) {
- notification_change_queue_->UpdateNotification(old_id,
- std::move(new_notification));
- return;
- }
-
- UpdateNotificationImmediately(old_id, std::move(new_notification));
-}
-
-void MessageCenterImpl::UpdateNotificationImmediately(
- const std::string& old_id,
- std::unique_ptr<Notification> new_notification) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
std::string new_id = new_notification->id();
notification_list_->UpdateNotificationMessage(old_id,
std::move(new_notification));
visible_notifications_ =
notification_list_->GetVisibleNotifications(blockers_);
- if (old_id == new_id) {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
+ for (auto& observer : observer_list_) {
+ if (old_id == new_id) {
observer.OnNotificationUpdated(new_id);
- } else {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
+ } else {
observer.OnNotificationRemoved(old_id, false);
- for (auto& observer : observer_list_)
observer.OnNotificationAdded(new_id);
+ }
}
}
@@ -282,21 +205,8 @@ void MessageCenterImpl::RemoveNotification(const std::string& id,
bool by_user) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (iterating_) {
- notification_change_queue_->RemoveNotification(id, by_user);
- return;
- }
-
- RemoveNotificationImmediately(id, by_user);
-}
-
-void MessageCenterImpl::RemoveNotificationImmediately(
- const std::string& id, bool by_user) {
- DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
-
Notification* notification = FindVisibleNotificationById(id);
- if (notification == NULL)
+ if (!notification)
return;
if (by_user && notification->pinned()) {
@@ -319,27 +229,8 @@ void MessageCenterImpl::RemoveNotificationImmediately(
notification_list_->RemoveNotification(copied_id);
visible_notifications_ =
notification_list_->GetVisibleNotifications(blockers_);
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
- observer.OnNotificationRemoved(copied_id, by_user);
- }
-}
-
-Notification* MessageCenterImpl::GetLatestNotificationIncludingQueued(
- const std::string& id) const {
- Notification* queued_notification =
- notification_change_queue_->GetLatestNotification(id);
- if (queued_notification) {
- DCHECK(iterating_);
- return queued_notification;
- }
-
- Notification* notification = notification_list_->GetNotificationById(id);
- if (notification)
- return notification;
-
- return nullptr;
+ for (auto& observer : observer_list_)
+ observer.OnNotificationRemoved(copied_id, by_user);
}
void MessageCenterImpl::RemoveNotificationsForNotifierId(
@@ -357,7 +248,6 @@ void MessageCenterImpl::RemoveNotificationsForNotifierId(
void MessageCenterImpl::RemoveAllNotifications(bool by_user, RemoveType type) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
bool remove_pinned = (type == RemoveType::ALL);
const NotificationBlockers& blockers =
@@ -382,12 +272,9 @@ void MessageCenterImpl::RemoveAllNotifications(bool by_user, RemoveType type) {
visible_notifications_ =
notification_list_->GetVisibleNotifications(blockers_);
}
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (const auto& id : ids) {
- for (auto& observer : observer_list_)
- observer.OnNotificationRemoved(id, by_user);
- }
+ for (const auto& id : ids) {
+ for (auto& observer : observer_list_)
+ observer.OnNotificationRemoved(id, by_user);
}
}
@@ -395,21 +282,7 @@ void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id,
const gfx::Image& image) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- if (iterating_) {
- Notification* notification =
- GetLatestNotificationIncludingQueued(notification_id);
- if (notification) {
- std::unique_ptr<Notification> copied_notification =
- std::make_unique<Notification>(*notification);
- copied_notification->set_icon(image);
- notification_change_queue_->UpdateNotification(
- notification_id, std::move(copied_notification));
- }
- return;
- }
-
if (notification_list_->SetNotificationIcon(notification_id, image)) {
- internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationUpdated(notification_id);
}
@@ -417,22 +290,8 @@ void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id,
void MessageCenterImpl::SetNotificationImage(const std::string& notification_id,
const gfx::Image& image) {
- if (iterating_) {
- Notification* notification =
- GetLatestNotificationIncludingQueued(notification_id);
- if (notification) {
- std::unique_ptr<Notification> copied_notification =
- std::make_unique<Notification>(*notification);
- copied_notification->set_image(image);
- notification_change_queue_->UpdateNotification(
- notification_id, std::move(copied_notification));
- }
- return;
- }
-
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (notification_list_->SetNotificationImage(notification_id, image)) {
- internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationUpdated(notification_id);
}
@@ -441,23 +300,9 @@ void MessageCenterImpl::SetNotificationImage(const std::string& notification_id,
void MessageCenterImpl::SetNotificationButtonIcon(
const std::string& notification_id, int button_index,
const gfx::Image& image) {
- if (iterating_) {
- Notification* notification =
- GetLatestNotificationIncludingQueued(notification_id);
- if (notification) {
- std::unique_ptr<Notification> copied_notification =
- std::make_unique<Notification>(*notification);
- copied_notification->SetButtonIcon(button_index, image);
- notification_change_queue_->UpdateNotification(
- notification_id, std::move(copied_notification));
- }
- return;
- }
-
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (notification_list_->SetNotificationButtonIcon(notification_id,
button_index, image)) {
- internal::ScopedNotificationsIterationLock lock(this);
for (auto& observer : observer_list_)
observer.OnNotificationUpdated(notification_id);
}
@@ -465,7 +310,6 @@ void MessageCenterImpl::SetNotificationButtonIcon(
void MessageCenterImpl::ClickOnNotification(const std::string& id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
if (FindVisibleNotificationById(id) == NULL)
return;
#if defined(OS_CHROMEOS)
@@ -474,19 +318,15 @@ void MessageCenterImpl::ClickOnNotification(const std::string& id) {
#endif
scoped_refptr<NotificationDelegate> delegate =
notification_list_->GetNotificationDelegate(id);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationClicked(id);
if (delegate.get())
delegate->Click();
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
- observer.OnNotificationClicked(id);
- }
}
void MessageCenterImpl::ClickOnNotificationButton(const std::string& id,
int button_index) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
if (!FindVisibleNotificationById(id))
return;
#if defined(OS_CHROMEOS)
@@ -495,13 +335,10 @@ void MessageCenterImpl::ClickOnNotificationButton(const std::string& id,
#endif
scoped_refptr<NotificationDelegate> delegate =
notification_list_->GetNotificationDelegate(id);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationButtonClicked(id, button_index);
if (delegate.get())
delegate->ButtonClick(button_index);
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
- observer.OnNotificationButtonClicked(id, button_index);
- }
}
void MessageCenterImpl::ClickOnNotificationButtonWithReply(
@@ -517,18 +354,14 @@ void MessageCenterImpl::ClickOnNotificationButtonWithReply(
#endif
scoped_refptr<NotificationDelegate> delegate =
notification_list_->GetNotificationDelegate(id);
+ for (auto& observer : observer_list_)
+ observer.OnNotificationButtonClickedWithReply(id, button_index, reply);
if (delegate.get())
delegate->ButtonClickWithReply(button_index, reply);
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
- observer.OnNotificationButtonClickedWithReply(id, button_index, reply);
- }
}
void MessageCenterImpl::ClickOnSettingsButton(const std::string& id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
Notification* notification = notification_list_->GetNotificationById(id);
bool handled_by_delegate =
@@ -538,16 +371,12 @@ void MessageCenterImpl::ClickOnSettingsButton(const std::string& id) {
if (handled_by_delegate)
notification->delegate()->SettingsClick();
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
- observer.OnNotificationSettingsClicked(handled_by_delegate);
- }
+ for (auto& observer : observer_list_)
+ observer.OnNotificationSettingsClicked(handled_by_delegate);
}
void MessageCenterImpl::DisableNotification(const std::string& id) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
- DCHECK(!iterating_);
Notification* notification = notification_list_->GetNotificationById(id);
if (notification && notification->delegate()) {
@@ -562,20 +391,12 @@ void MessageCenterImpl::MarkSinglePopupAsShown(const std::string& id,
if (FindVisibleNotificationById(id) == NULL)
return;
-// This method doesn't check the |iterating_| flag, since this is called
-// during iteration.
-// TODO(yoshiki): Investigate and not to call this method during iteration if
-// necessary.
-
#if !defined(OS_CHROMEOS)
RemoveNotification(id, false);
#else
notification_list_->MarkSinglePopupAsShown(id, mark_notification_as_read);
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
- observer.OnNotificationUpdated(id);
- }
+ for (auto& observer : observer_list_)
+ observer.OnNotificationUpdated(id);
#endif // defined(OS_CHROMEOS)
}
@@ -594,11 +415,8 @@ void MessageCenterImpl::DisplayedNotification(
notification_list_->MarkSinglePopupAsDisplayed(id);
scoped_refptr<NotificationDelegate> delegate =
notification_list_->GetNotificationDelegate(id);
- {
- internal::ScopedNotificationsIterationLock lock(this);
- for (auto& observer : observer_list_)
- observer.OnNotificationDisplayed(id, source);
- }
+ for (auto& observer : observer_list_)
+ observer.OnNotificationDisplayed(id, source);
}
void MessageCenterImpl::SetQuietMode(bool in_quiet_mode) {
diff --git a/chromium/ui/message_center/message_center_impl.h b/chromium/ui/message_center/message_center_impl.h
index 0c9e263c060..36270ff1a66 100644
--- a/chromium/ui/message_center/message_center_impl.h
+++ b/chromium/ui/message_center/message_center_impl.h
@@ -16,20 +16,16 @@
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
-#include "ui/message_center/change_queue.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_observer.h"
+#include "ui/message_center/message_center_stats_collector.h"
#include "ui/message_center/message_center_types.h"
#include "ui/message_center/notification_blocker.h"
-#include "ui/message_center/notifier_id.h"
#include "ui/message_center/popup_timers_controller.h"
+#include "ui/message_center/public/cpp/notifier_id.h"
namespace message_center {
-namespace internal {
-class ScopedNotificationsIterationLock;
-};
-
// The default implementation of MessageCenter.
class MESSAGE_CENTER_EXPORT MessageCenterImpl
: public MessageCenter,
@@ -48,8 +44,7 @@ class MESSAGE_CENTER_EXPORT MessageCenterImpl
size_t NotificationCount() const override;
bool HasPopupNotifications() const override;
bool IsQuietMode() const override;
- message_center::Notification* FindVisibleNotificationById(
- const std::string& id) override;
+ Notification* FindVisibleNotificationById(const std::string& id) override;
const NotificationList::Notifications& GetVisibleNotifications() override;
NotificationList::PopupNotifications GetPopupNotifications() override;
void AddNotification(std::unique_ptr<Notification> notification) override;
@@ -88,23 +83,10 @@ class MESSAGE_CENTER_EXPORT MessageCenterImpl
// NotificationBlocker::Observer overrides:
void OnBlockingStateChanged(NotificationBlocker* blocker) override;
- // Unexposed methods:
- void AddNotificationImmediately(std::unique_ptr<Notification> notification);
- void UpdateNotificationImmediately(
- const std::string& old_id,
- std::unique_ptr<Notification> new_notification);
- void RemoveNotificationImmediately(const std::string& id, bool by_user);
-
protected:
void DisableTimersForTest() override;
private:
- friend internal::ScopedNotificationsIterationLock;
- class ScopedNotificationsLock;
-
- Notification* GetLatestNotificationIncludingQueued(
- const std::string& id) const;
-
THREAD_CHECKER(thread_checker_);
std::unique_ptr<NotificationList> notification_list_;
@@ -113,15 +95,13 @@ class MESSAGE_CENTER_EXPORT MessageCenterImpl
std::unique_ptr<PopupTimersController> popup_timers_controller_;
std::unique_ptr<base::OneShotTimer> quiet_mode_timer_;
std::vector<NotificationBlocker*> blockers_;
- std::unique_ptr<ChangeQueue> notification_change_queue_;
bool visible_ = false;
- // modified by ScopedNotificationsIterationLock.
- bool iterating_ = false;
-
base::string16 system_notification_app_name_;
+ MessageCenterStatsCollector stats_collector_;
+
DISALLOW_COPY_AND_ASSIGN(MessageCenterImpl);
};
diff --git a/chromium/ui/message_center/message_center_impl_unittest.cc b/chromium/ui/message_center/message_center_impl_unittest.cc
index 9921fa5f0f7..3ca85df31f2 100644
--- a/chromium/ui/message_center/message_center_impl_unittest.cc
+++ b/chromium/ui/message_center/message_center_impl_unittest.cc
@@ -23,9 +23,9 @@
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_types.h"
#include "ui/message_center/notification_blocker.h"
-#include "ui/message_center/notification_types.h"
-#include "ui/message_center/notifier_id.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification_types.h"
+#include "ui/message_center/public/cpp/notifier_id.h"
using base::UTF8ToUTF16;
@@ -73,8 +73,7 @@ class RemoveObserver : public MessageCenterObserver {
} // anonymous namespace
-class MessageCenterImplTest : public testing::Test,
- public MessageCenterObserver {
+class MessageCenterImplTest : public testing::Test {
public:
MessageCenterImplTest() {}
@@ -118,14 +117,13 @@ class MessageCenterImplTest : public testing::Test,
}
Notification* CreateNotification(const std::string& id,
- message_center::NotificationType type) {
+ NotificationType type) {
return CreateNotificationWithNotifierId(id, "app1", type);
}
- Notification* CreateNotificationWithNotifierId(
- const std::string& id,
- const std::string& notifier_id,
- message_center::NotificationType type) {
+ Notification* CreateNotificationWithNotifierId(const std::string& id,
+ const std::string& notifier_id,
+ NotificationType type) {
RichNotificationData optional_fields;
optional_fields.buttons.push_back(ButtonInfo(UTF8ToUTF16("foo")));
optional_fields.buttons.push_back(ButtonInfo(UTF8ToUTF16("foo")));
@@ -163,7 +161,7 @@ class ToggledNotificationBlocker : public NotificationBlocker {
// NotificationBlocker overrides:
bool ShouldShowNotificationAsPopup(
- const message_center::Notification& notification) const override {
+ const Notification& notification) const override {
return notifications_enabled_;
}
@@ -403,8 +401,7 @@ TEST_F(MessageCenterImplTest, NotificationBlocker) {
EXPECT_EQ(2u, message_center()->GetVisibleNotifications().size());
// "id1" is displayed as a pop-up so that it will be closed when blocked.
- message_center()->DisplayedNotification("id1",
- message_center::DISPLAY_SOURCE_POPUP);
+ message_center()->DisplayedNotification("id1", DISPLAY_SOURCE_POPUP);
// Block all notifications. All popups are gone and message center should be
// hidden.
@@ -452,8 +449,7 @@ TEST_F(MessageCenterImplTest, NotificationsDuringBlocked) {
EXPECT_EQ(1u, message_center()->GetVisibleNotifications().size());
// "id1" is displayed as a pop-up so that it will be closed when blocked.
- message_center()->DisplayedNotification("id1",
- message_center::DISPLAY_SOURCE_POPUP);
+ message_center()->DisplayedNotification("id1", DISPLAY_SOURCE_POPUP);
// Create a notification during blocked. Still no popups.
blocker.SetNotificationsEnabled(false);
@@ -493,8 +489,7 @@ TEST_F(MessageCenterImplTest, NotificationBlockerAllowsPopups) {
notifier_id2, RichNotificationData(), NULL)));
// "id1" is displayed as a pop-up so that it will be closed when blocked.
- message_center()->DisplayedNotification("id1",
- message_center::DISPLAY_SOURCE_POPUP);
+ message_center()->DisplayedNotification("id1", DISPLAY_SOURCE_POPUP);
// "id1" is closed but "id2" is still visible as a popup.
blocker.SetNotificationsEnabled(false);
@@ -787,36 +782,5 @@ TEST_F(MessageCenterImplTest, RemoveWhileMessageCenterVisible) {
EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
}
-TEST_F(MessageCenterImplTest, RemoveWhileIteratingObserver) {
- std::string id("id1");
- CheckObserver check1(message_center(), id);
- CheckObserver check2(message_center(), id);
- RemoveObserver remove(message_center(), id);
-
- // Prepare a notification
- std::unique_ptr<Notification> notification(CreateSimpleNotification(id));
- message_center()->AddNotification(std::move(notification));
- EXPECT_TRUE(message_center()->FindVisibleNotificationById(id));
-
- // Install the test handlers
- message_center()->AddObserver(&check1);
- message_center()->AddObserver(&remove);
- message_center()->AddObserver(&check2);
-
- // Update the notification. The notification will be removed in the observer,
- // but the actual removal will be done at the end of the iteration.
- // Notification keeps alive during iteration. This is checked by
- // CheckObserver.
- notification.reset(CreateSimpleNotification(id));
- message_center()->UpdateNotification(id, std::move(notification));
-
- // Notification is removed correctly.
- EXPECT_FALSE(message_center()->FindVisibleNotificationById(id));
-
- message_center()->RemoveObserver(&check1);
- message_center()->RemoveObserver(&remove);
- message_center()->RemoveObserver(&check2);
-}
-
} // namespace internal
} // namespace message_center
diff --git a/chromium/ui/message_center/message_center_observer.h b/chromium/ui/message_center/message_center_observer.h
index feb358bd0a9..9ef0ec65c84 100644
--- a/chromium/ui/message_center/message_center_observer.h
+++ b/chromium/ui/message_center/message_center_observer.h
@@ -14,6 +14,8 @@ namespace message_center {
class NotificationBlocker;
// An observer class for the change of notifications in the MessageCenter.
+// WARNING: It is not safe to modify the message center from within these
+// callbacks.
class MESSAGE_CENTER_EXPORT MessageCenterObserver {
public:
virtual ~MessageCenterObserver() {}
diff --git a/chromium/ui/message_center/message_center_stats_collector.cc b/chromium/ui/message_center/message_center_stats_collector.cc
new file mode 100644
index 00000000000..210e0bf85f5
--- /dev/null
+++ b/chromium/ui/message_center/message_center_stats_collector.cc
@@ -0,0 +1,153 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/message_center/message_center_stats_collector.h"
+
+#include <stddef.h>
+
+#include <string>
+
+#include "base/metrics/histogram_macros.h"
+#include "base/metrics/user_metrics.h"
+#include "ui/message_center/message_center.h"
+
+namespace message_center {
+
+MessageCenterStatsCollector::NotificationStats::NotificationStats() {}
+
+MessageCenterStatsCollector::NotificationStats::NotificationStats(
+ const std::string& id)
+ : id_(id) {
+ for (size_t i = 0; i < NOTIFICATION_ACTION_COUNT; i++) {
+ actions_[i] = false;
+ }
+}
+
+MessageCenterStatsCollector::NotificationStats::~NotificationStats() {}
+
+void MessageCenterStatsCollector::NotificationStats::CollectAction(
+ NotificationActionType type) {
+ DCHECK(!id_.empty());
+
+ UMA_HISTOGRAM_ENUMERATION("Notifications.Actions", type,
+ NOTIFICATION_ACTION_COUNT);
+ actions_[type] = true;
+}
+
+void MessageCenterStatsCollector::NotificationStats::RecordAggregateStats() {
+ DCHECK(!id_.empty());
+
+ for (size_t i = 0; i < NOTIFICATION_ACTION_COUNT; i++) {
+ if (!actions_[i])
+ continue;
+ UMA_HISTOGRAM_ENUMERATION("Notifications.PerNotificationActions",
+ static_cast<NotificationActionType>(i),
+ NOTIFICATION_ACTION_COUNT);
+ }
+}
+
+MessageCenterStatsCollector::MessageCenterStatsCollector(
+ MessageCenter* message_center)
+ : message_center_(message_center) {
+ message_center_->AddObserver(this);
+}
+
+MessageCenterStatsCollector::~MessageCenterStatsCollector() {
+ message_center_->RemoveObserver(this);
+}
+
+void MessageCenterStatsCollector::OnNotificationAdded(
+ const std::string& notification_id) {
+ stats_[notification_id] = NotificationStats(notification_id);
+
+ StatsCollection::iterator iter = stats_.find(notification_id);
+ DCHECK(iter != stats_.end());
+
+ stats_[notification_id].CollectAction(NOTIFICATION_ACTION_ADD);
+}
+
+void MessageCenterStatsCollector::OnNotificationRemoved(
+ const std::string& notification_id,
+ bool by_user) {
+ StatsCollection::iterator iter = stats_.find(notification_id);
+ if (iter == stats_.end())
+ return;
+ NotificationStats& notification_stat = iter->second;
+ notification_stat.CollectAction(by_user
+ ? NOTIFICATION_ACTION_CLOSE_BY_USER
+ : NOTIFICATION_ACTION_CLOSE_BY_SYSTEM);
+ notification_stat.RecordAggregateStats();
+ stats_.erase(notification_id);
+}
+
+void MessageCenterStatsCollector::OnNotificationUpdated(
+ const std::string& notification_id) {
+ StatsCollection::iterator iter = stats_.find(notification_id);
+ if (iter == stats_.end())
+ return;
+ NotificationStats& notification_stat = iter->second;
+
+ notification_stat.CollectAction(NOTIFICATION_ACTION_UPDATE);
+}
+
+void MessageCenterStatsCollector::OnNotificationClicked(
+ const std::string& notification_id) {
+ StatsCollection::iterator iter = stats_.find(notification_id);
+ if (iter == stats_.end())
+ return;
+ NotificationStats& notification_stat = iter->second;
+
+ notification_stat.CollectAction(NOTIFICATION_ACTION_CLICK);
+}
+
+void MessageCenterStatsCollector::OnNotificationButtonClicked(
+ const std::string& notification_id,
+ int button_index) {
+ StatsCollection::iterator iter = stats_.find(notification_id);
+ if (iter == stats_.end())
+ return;
+ NotificationStats& notification_stat = iter->second;
+
+ notification_stat.CollectAction(NOTIFICATION_ACTION_BUTTON_CLICK);
+}
+
+void MessageCenterStatsCollector::OnNotificationSettingsClicked(bool handled) {
+ base::RecordAction(base::UserMetricsAction("Notifications.ShowSiteSettings"));
+}
+
+void MessageCenterStatsCollector::OnNotificationDisplayed(
+ const std::string& notification_id,
+ const DisplaySource source) {
+ StatsCollection::iterator iter = stats_.find(notification_id);
+ if (iter == stats_.end())
+ return;
+ NotificationStats& notification_stat = iter->second;
+
+ notification_stat.CollectAction(NOTIFICATION_ACTION_DISPLAY);
+}
+
+void MessageCenterStatsCollector::OnCenterVisibilityChanged(
+ Visibility visibility) {
+ switch (visibility) {
+ case VISIBILITY_TRANSIENT:
+ break;
+ case VISIBILITY_MESSAGE_CENTER:
+ base::RecordAction(
+ base::UserMetricsAction("Notifications.ShowMessageCenter"));
+ break;
+ case VISIBILITY_SETTINGS:
+ base::RecordAction(base::UserMetricsAction("Notifications.ShowSettings"));
+ break;
+ }
+}
+
+void MessageCenterStatsCollector::OnQuietModeChanged(bool in_quiet_mode) {
+ if (in_quiet_mode) {
+ base::RecordAction(base::UserMetricsAction("Notifications.Mute"));
+ } else {
+ base::RecordAction(base::UserMetricsAction("Notifications.Unmute"));
+ }
+}
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/message_center_stats_collector.h b/chromium/ui/message_center/message_center_stats_collector.h
new file mode 100644
index 00000000000..6906f65d42f
--- /dev/null
+++ b/chromium/ui/message_center/message_center_stats_collector.h
@@ -0,0 +1,89 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_MESSAGE_CENTER_MESSAGE_CENTER_STATS_COLLECTOR_H_
+#define UI_MESSAGE_CENTER_MESSAGE_CENTER_STATS_COLLECTOR_H_
+
+#include <set>
+#include <string>
+
+#include "base/macros.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/message_center_observer.h"
+#include "ui/message_center/message_center_types.h"
+
+namespace message_center {
+
+class MessageCenter;
+
+// MessageCenterStatsCollector sends both raw and per-notification statistics
+// to the UMA servers, if the user has opted in. It observes the message center
+// to gather its data.
+class MessageCenterStatsCollector : public MessageCenterObserver {
+ public:
+ enum NotificationActionType {
+ NOTIFICATION_ACTION_UNKNOWN,
+ NOTIFICATION_ACTION_ADD,
+ NOTIFICATION_ACTION_UPDATE,
+ NOTIFICATION_ACTION_CLICK,
+ NOTIFICATION_ACTION_BUTTON_CLICK,
+ NOTIFICATION_ACTION_DISPLAY,
+ NOTIFICATION_ACTION_CLOSE_BY_USER,
+ NOTIFICATION_ACTION_CLOSE_BY_SYSTEM,
+ // NOTE: Add new action types only immediately above this line. Also,
+ // make sure the enum list in tools/histogram/histograms.xml is
+ // updated with any change in here.
+ NOTIFICATION_ACTION_COUNT
+ };
+
+ explicit MessageCenterStatsCollector(MessageCenter* message_center);
+ ~MessageCenterStatsCollector() override;
+
+ private:
+ // Represents the aggregate stats for each notification.
+ class NotificationStats {
+ public:
+ // Default constructor for map.
+ NotificationStats();
+
+ explicit NotificationStats(const std::string& id);
+ virtual ~NotificationStats();
+
+ // Called when we get an action from the message center.
+ void CollectAction(NotificationActionType type);
+
+ // Sends aggregate data to UMA.
+ void RecordAggregateStats();
+
+ private:
+ std::string id_;
+ bool actions_[NOTIFICATION_ACTION_COUNT];
+ };
+
+ // MessageCenterObserver
+ void OnNotificationAdded(const std::string& notification_id) override;
+ void OnNotificationRemoved(const std::string& notification_id,
+ bool by_user) override;
+ void OnNotificationUpdated(const std::string& notification_id) override;
+ void OnNotificationClicked(const std::string& notification_id) override;
+ void OnNotificationButtonClicked(const std::string& notification_id,
+ int button_index) override;
+ void OnNotificationSettingsClicked(bool handled) override;
+ void OnNotificationDisplayed(const std::string& notification_id,
+ const DisplaySource source) override;
+ void OnCenterVisibilityChanged(Visibility visibility) override;
+ void OnQuietModeChanged(bool in_quiet_mode) override;
+
+ // Weak, global.
+ MessageCenter* message_center_;
+
+ typedef std::map<std::string, NotificationStats> StatsCollection;
+ StatsCollection stats_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageCenterStatsCollector);
+};
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_MESSAGE_CENTER_STATS_COLLECTOR_H_
diff --git a/chromium/ui/message_center/message_center_switches.h b/chromium/ui/message_center/message_center_switches.h
deleted file mode 100644
index a589933161b..00000000000
--- a/chromium/ui/message_center/message_center_switches.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_MESSAGE_CENTER_MESSAGE_CENTER_SWITCHES_H_
-#define UI_MESSAGE_CENTER_MESSAGE_CENTER_SWITCHES_H_
-
-#include "base/compiler_specific.h"
-#include "ui/message_center/message_center_export.h"
-
-namespace switches {
-
-MESSAGE_CENTER_EXPORT extern const char
- kEnableMessageCenterNewStyleNotification[];
-MESSAGE_CENTER_EXPORT extern const char
- kDisableMessageCenterNewStyleNotification[];
-
-} // namespace switches
-
-#endif // UI_MESSAGE_CENTER_MESSAGE_CENTER_SWITCHES_H_
diff --git a/chromium/ui/message_center/mojo/notification.mojom b/chromium/ui/message_center/mojo/notification.mojom
deleted file mode 100644
index 73985b2d1c3..00000000000
--- a/chromium/ui/message_center/mojo/notification.mojom
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-module message_center.mojom;
-
-import "mojo/common/string16.mojom";
-import "ui/gfx/image/mojo/image.mojom";
-import "url/mojo/url.mojom";
-
-// Matches message_center::NotificationType.
-enum NotificationType {
- SIMPLE = 0,
- BASE_FORMAT = 1,
- IMAGE = 2,
- MULTIPLE = 3,
- PROGRESS = 4,
- CUSTOM = 5,
-};
-
-// These fields and their meanings are identical to those in
-// message_center::RichNotificationData.
-// TODO(estade): Add the rest of the fields for RichNotificationData.
-struct RichNotificationData {
- int32 progress;
- mojo.common.mojom.String16 progress_status;
- bool should_make_spoken_feedback_for_popup_updates;
- bool clickable;
- bool pinned;
- mojo.common.mojom.String16 accessible_name;
- uint32 accent_color;
-};
-
-// TODO(mhashmi): Add the rest of the fields for a Notification
-struct Notification {
- NotificationType type;
-
- // TODO(mhashmi): Server-side code (in Ash) needs to make sure this id won't
- // collide with ids from different clients
- string id;
-
- mojo.common.mojom.String16 title;
- mojo.common.mojom.String16 message;
- gfx.mojom.ImageSkia? icon;
- mojo.common.mojom.String16 display_source;
- url.mojom.Url origin_url;
-
- RichNotificationData optional_fields;
-};
diff --git a/chromium/ui/message_center/mojo/notification_struct_traits.cc b/chromium/ui/message_center/mojo/notification_struct_traits.cc
deleted file mode 100644
index 2a6ae93193e..00000000000
--- a/chromium/ui/message_center/mojo/notification_struct_traits.cc
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/message_center/mojo/notification_struct_traits.h"
-
-#include "mojo/common/string16_struct_traits.h"
-#include "ui/gfx/image/mojo/image_skia_struct_traits.h"
-#include "url/mojo/url_gurl_struct_traits.h"
-
-namespace mojo {
-
-using message_center::mojom::NotificationDataView;
-using message_center::mojom::RichNotificationDataDataView;
-using message_center::Notification;
-using message_center::RichNotificationData;
-using NotificationStructTraits =
- StructTraits<NotificationDataView, Notification>;
-using RichNotificationDataStructTraits =
- StructTraits<RichNotificationDataDataView, RichNotificationData>;
-
-// static
-int RichNotificationDataStructTraits::progress(
- const message_center::RichNotificationData& r) {
- return r.progress;
-}
-
-// static
-const base::string16& RichNotificationDataStructTraits::progress_status(
- const message_center::RichNotificationData& r) {
- return r.progress_status;
-}
-
-// static
-bool RichNotificationDataStructTraits::
- should_make_spoken_feedback_for_popup_updates(
- const message_center::RichNotificationData& r) {
- return r.should_make_spoken_feedback_for_popup_updates;
-}
-
-// static
-bool RichNotificationDataStructTraits::clickable(
- const message_center::RichNotificationData& r) {
- return r.clickable;
-}
-
-// static
-bool RichNotificationDataStructTraits::pinned(
- const message_center::RichNotificationData& r) {
- return r.pinned;
-}
-
-// static
-const base::string16& RichNotificationDataStructTraits::accessible_name(
- const message_center::RichNotificationData& r) {
- return r.accessible_name;
-}
-
-// static
-SkColor RichNotificationDataStructTraits::accent_color(
- const message_center::RichNotificationData& r) {
- return r.accent_color;
-}
-
-// static
-bool RichNotificationDataStructTraits::Read(RichNotificationDataDataView data,
- RichNotificationData* out) {
- out->progress = data.progress();
- out->should_make_spoken_feedback_for_popup_updates =
- data.should_make_spoken_feedback_for_popup_updates();
- out->clickable = data.clickable();
- out->pinned = data.pinned();
- out->accent_color = data.accent_color();
- return data.ReadProgressStatus(&out->progress_status) &&
- data.ReadAccessibleName(&out->accessible_name);
-}
-
-// static
-message_center::NotificationType NotificationStructTraits::type(
- const Notification& n) {
- return n.type();
-}
-
-// static
-const std::string& NotificationStructTraits::id(const Notification& n) {
- return n.id();
-}
-
-// static
-const base::string16& NotificationStructTraits::title(const Notification& n) {
- return n.title();
-}
-
-// static
-const base::string16& NotificationStructTraits::message(const Notification& n) {
- return n.message();
-}
-
-// static
-gfx::ImageSkia NotificationStructTraits::icon(const Notification& n) {
- return n.icon().AsImageSkia();
-}
-
-// static
-const base::string16& NotificationStructTraits::display_source(
- const Notification& n) {
- return n.display_source();
-}
-
-// static
-const GURL& NotificationStructTraits::origin_url(const Notification& n) {
- return n.origin_url();
-}
-
-// static
-const RichNotificationData& NotificationStructTraits::optional_fields(
- const Notification& n) {
- return n.rich_notification_data();
-}
-
-// static
-bool NotificationStructTraits::Read(NotificationDataView data,
- Notification* out) {
- gfx::ImageSkia icon;
- if (!data.ReadIcon(&icon))
- return false;
- out->set_icon(gfx::Image(icon));
- return EnumTraits<message_center::mojom::NotificationType,
- message_center::NotificationType>::FromMojom(data.type(),
- &out->type_) &&
- data.ReadId(&out->id_) && data.ReadTitle(&out->title_) &&
- data.ReadMessage(&out->message_) &&
- data.ReadDisplaySource(&out->display_source_) &&
- data.ReadOriginUrl(&out->origin_url_) &&
- data.ReadOptionalFields(&out->optional_fields_);
-}
-
-} // namespace mojo
diff --git a/chromium/ui/message_center/mojo/notification_struct_traits.h b/chromium/ui/message_center/mojo/notification_struct_traits.h
deleted file mode 100644
index 8042ad49149..00000000000
--- a/chromium/ui/message_center/mojo/notification_struct_traits.h
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_MESSAGE_CENTER_NOTIFICATION_STRUCT_TRAITS_H_
-#define UI_MESSAGE_CENTER_NOTIFICATION_STRUCT_TRAITS_H_
-
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/message_center/mojo/notification.mojom-shared.h"
-#include "ui/message_center/notification.h"
-
-namespace mojo {
-
-template <>
-struct EnumTraits<message_center::mojom::NotificationType,
- message_center::NotificationType> {
- static message_center::mojom::NotificationType ToMojom(
- message_center::NotificationType type) {
- switch (type) {
- case message_center::NOTIFICATION_TYPE_SIMPLE:
- return message_center::mojom::NotificationType::SIMPLE;
- case message_center::NOTIFICATION_TYPE_BASE_FORMAT:
- return message_center::mojom::NotificationType::BASE_FORMAT;
- case message_center::NOTIFICATION_TYPE_IMAGE:
- return message_center::mojom::NotificationType::IMAGE;
- case message_center::NOTIFICATION_TYPE_MULTIPLE:
- return message_center::mojom::NotificationType::MULTIPLE;
- case message_center::NOTIFICATION_TYPE_PROGRESS:
- return message_center::mojom::NotificationType::PROGRESS;
- case message_center::NOTIFICATION_TYPE_CUSTOM:
- return message_center::mojom::NotificationType::CUSTOM;
- }
- NOTREACHED();
- return message_center::mojom::NotificationType::SIMPLE;
- }
-
- static bool FromMojom(message_center::mojom::NotificationType input,
- message_center::NotificationType* out) {
- switch (input) {
- case message_center::mojom::NotificationType::SIMPLE:
- *out = message_center::NOTIFICATION_TYPE_SIMPLE;
- return true;
- case message_center::mojom::NotificationType::BASE_FORMAT:
- *out = message_center::NOTIFICATION_TYPE_BASE_FORMAT;
- return true;
- case message_center::mojom::NotificationType::IMAGE:
- *out = message_center::NOTIFICATION_TYPE_IMAGE;
- return true;
- case message_center::mojom::NotificationType::MULTIPLE:
- *out = message_center::NOTIFICATION_TYPE_MULTIPLE;
- return true;
- case message_center::mojom::NotificationType::PROGRESS:
- *out = message_center::NOTIFICATION_TYPE_PROGRESS;
- return true;
- case message_center::mojom::NotificationType::CUSTOM:
- *out = message_center::NOTIFICATION_TYPE_CUSTOM;
- return true;
- }
- NOTREACHED();
- return false;
- }
-};
-
-template <>
-struct StructTraits<message_center::mojom::RichNotificationDataDataView,
- message_center::RichNotificationData> {
- static int progress(const message_center::RichNotificationData& r);
- static const base::string16& progress_status(
- const message_center::RichNotificationData& r);
- static bool should_make_spoken_feedback_for_popup_updates(
- const message_center::RichNotificationData& r);
- static bool clickable(const message_center::RichNotificationData& r);
- static bool pinned(const message_center::RichNotificationData& r);
- static const base::string16& accessible_name(
- const message_center::RichNotificationData& r);
- static SkColor accent_color(const message_center::RichNotificationData& r);
- static bool Read(message_center::mojom::RichNotificationDataDataView data,
- message_center::RichNotificationData* out);
-};
-
-template <>
-struct StructTraits<message_center::mojom::NotificationDataView,
- message_center::Notification> {
- static message_center::NotificationType type(
- const message_center::Notification& n);
- static const std::string& id(const message_center::Notification& n);
- static const base::string16& title(const message_center::Notification& n);
- static const base::string16& message(const message_center::Notification& n);
- static gfx::ImageSkia icon(const message_center::Notification& n);
- static const base::string16& display_source(
- const message_center::Notification& n);
- static const GURL& origin_url(const message_center::Notification& n);
- static const message_center::RichNotificationData& optional_fields(
- const message_center::Notification& n);
- static bool Read(message_center::mojom::NotificationDataView data,
- message_center::Notification* out);
-};
-
-} // namespace mojo
-
-#endif // UI_MESSAGE_CENTER_NOTIFICATION_STRUCT_TRAITS_H_
diff --git a/chromium/ui/message_center/notification_blocker.h b/chromium/ui/message_center/notification_blocker.h
index f9408f0f0a5..1082c349cf0 100644
--- a/chromium/ui/message_center/notification_blocker.h
+++ b/chromium/ui/message_center/notification_blocker.h
@@ -7,7 +7,7 @@
#include "base/observer_list.h"
#include "ui/message_center/message_center_export.h"
-#include "ui/message_center/notification.h"
+#include "ui/message_center/public/cpp/notification.h"
namespace message_center {
class MessageCenter;
diff --git a/chromium/ui/message_center/notification_delegate.h b/chromium/ui/message_center/notification_delegate.h
deleted file mode 100644
index 96288541d2f..00000000000
--- a/chromium/ui/message_center/notification_delegate.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_MESSAGE_CENTER_NOTIFICATION_DELEGATE_H_
-#define UI_MESSAGE_CENTER_NOTIFICATION_DELEGATE_H_
-
-#include <memory>
-#include <string>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/optional.h"
-#include "base/strings/string16.h"
-#include "ui/message_center/message_center_export.h"
-
-namespace message_center {
-
-// Delegate for a notification. This class has two roles: to implement callback
-// methods for notification, and to provide an identity of the associated
-// notification.
-class MESSAGE_CENTER_EXPORT NotificationDelegate
- : public base::RefCountedThreadSafe<NotificationDelegate> {
- public:
- // To be called when the desktop notification is closed. If closed by a
- // user explicitly (as opposed to timeout/script), |by_user| should be true.
- virtual void Close(bool by_user);
-
- // To be called when a desktop notification is clicked.
- virtual void Click();
-
- // To be called when the user clicks a button in a notification.
- virtual void ButtonClick(int button_index);
-
- // To be called when the user types a reply to a notification.
- // TODO(crbug.com/599859) Support this feature in the message center -
- // currently it is only supported on Android.
- virtual void ButtonClickWithReply(int button_index,
- const base::string16& reply);
-
- // To be called when the user clicks the settings button in a notification
- // which has a CUSTOM settings button action.
- virtual void SettingsClick();
-
- // Called when the user attempts to disable the notification.
- virtual void DisableNotification();
-
- protected:
- virtual ~NotificationDelegate() {}
-
- private:
- friend class base::RefCountedThreadSafe<NotificationDelegate>;
-};
-
-// A simple notification delegate which invokes the passed closure when the body
-// or a button is clicked.
-class MESSAGE_CENTER_EXPORT HandleNotificationClickDelegate
- : public NotificationDelegate {
- public:
- // The parameter is the index of the button that was clicked, or nullopt if
- // the body was clicked.
- using ButtonClickCallback =
- base::RepeatingCallback<void(base::Optional<int>)>;
-
- // Creates a delegate that handles clicks on a button or on the body.
- explicit HandleNotificationClickDelegate(const ButtonClickCallback& callback);
-
- // Creates a delegate that only handles clicks on the body of the
- // notification.
- explicit HandleNotificationClickDelegate(
- const base::RepeatingClosure& closure);
-
- // message_center::NotificationDelegate overrides:
- void Click() override;
- void ButtonClick(int button_index) override;
-
- protected:
- ~HandleNotificationClickDelegate() override;
-
- private:
- ButtonClickCallback callback_;
-
- DISALLOW_COPY_AND_ASSIGN(HandleNotificationClickDelegate);
-};
-
-} // namespace message_center
-
-#endif // UI_MESSAGE_CENTER_NOTIFICATION_DELEGATE_H_
diff --git a/chromium/ui/message_center/notification_list.cc b/chromium/ui/message_center/notification_list.cc
index 505ff1a80b6..03882443b45 100644
--- a/chromium/ui/message_center/notification_list.cc
+++ b/chromium/ui/message_center/notification_list.cc
@@ -12,10 +12,10 @@
#include "base/values.h"
#include "ui/gfx/image/image.h"
#include "ui/message_center/message_center.h"
-#include "ui/message_center/notification.h"
#include "ui/message_center/notification_blocker.h"
-#include "ui/message_center/notification_types.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_types.h"
namespace message_center {
@@ -177,9 +177,9 @@ bool NotificationList::HasPopupNotifications(
return false;
}
-NotificationList::PopupNotifications NotificationList::GetPopupNotifications(
- const NotificationBlockers& blockers,
- std::list<const Notification*>* blocked) {
+NotificationList::PopupNotifications
+NotificationList::GetPopupNotifications(const NotificationBlockers& blockers,
+ std::list<std::string>* blocked) {
PopupNotifications result;
size_t default_priority_popup_count = 0;
@@ -196,7 +196,7 @@ NotificationList::PopupNotifications NotificationList::GetPopupNotifications(
if (!ShouldShowNotificationAsPopup(*notification, blockers)) {
if (blocked)
- blocked->push_back(notification);
+ blocked->push_back(notification->id());
continue;
}
diff --git a/chromium/ui/message_center/notification_list.h b/chromium/ui/message_center/notification_list.h
index 9acf7fabcfe..c5a7935e93f 100644
--- a/chromium/ui/message_center/notification_list.h
+++ b/chromium/ui/message_center/notification_list.h
@@ -15,7 +15,7 @@
#include "base/macros.h"
#include "ui/message_center/message_center_export.h"
#include "ui/message_center/notification_blocker.h"
-#include "ui/message_center/notification_types.h"
+#include "ui/message_center/public/cpp/notification_types.h"
namespace base {
class TimeDelta;
@@ -113,9 +113,8 @@ class MESSAGE_CENTER_EXPORT NotificationList {
// It also stores the list of notifications which are blocked by |blockers|
// to |blocked|. |blocked| can be NULL if the caller doesn't care which
// notifications are blocked.
- PopupNotifications GetPopupNotifications(
- const NotificationBlockers& blockers,
- std::list<const Notification*>* blocked);
+ PopupNotifications GetPopupNotifications(const NotificationBlockers& blockers,
+ std::list<std::string>* blocked);
// Marks a specific popup item as shown. Set |mark_notification_as_read| to
// true in case marking the notification as read too.
diff --git a/chromium/ui/message_center/notification_list_unittest.cc b/chromium/ui/message_center/notification_list_unittest.cc
index 71b181508b3..995358660d6 100644
--- a/chromium/ui/message_center/notification_list_unittest.cc
+++ b/chromium/ui/message_center/notification_list_unittest.cc
@@ -16,9 +16,9 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/message_center/fake_message_center.h"
#include "ui/message_center/notification_blocker.h"
-#include "ui/message_center/notification_types.h"
-#include "ui/message_center/notifier_id.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification_types.h"
+#include "ui/message_center/public/cpp/notifier_id.h"
using base::UTF8ToUTF16;
@@ -39,8 +39,7 @@ class NotificationListTest : public testing::Test {
// Currently NotificationListTest doesn't care about some fields like title or
// message, so put a simple template on it. Returns the id of the new
// notification.
- std::string AddNotification(
- const message_center::RichNotificationData& optional_fields) {
+ std::string AddNotification(const RichNotificationData& optional_fields) {
std::string new_id;
std::unique_ptr<Notification> notification(
MakeNotification(optional_fields, &new_id));
@@ -50,16 +49,16 @@ class NotificationListTest : public testing::Test {
}
std::string AddNotification() {
- return AddNotification(message_center::RichNotificationData());
+ return AddNotification(RichNotificationData());
}
// Construct a new notification for testing, but don't add it to the list yet.
std::unique_ptr<Notification> MakeNotification(
- const message_center::RichNotificationData& optional_fields,
+ const RichNotificationData& optional_fields,
std::string* id_out) {
*id_out = base::StringPrintf(kIdFormat, counter_);
std::unique_ptr<Notification> notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, *id_out,
+ NOTIFICATION_TYPE_SIMPLE, *id_out,
UTF8ToUTF16(base::StringPrintf(kTitleFormat, counter_)),
UTF8ToUTF16(base::StringPrintf(kMessageFormat, counter_)), gfx::Image(),
UTF8ToUTF16(kDisplaySource), GURL(),
@@ -69,12 +68,12 @@ class NotificationListTest : public testing::Test {
}
std::unique_ptr<Notification> MakeNotification(std::string* id_out) {
- return MakeNotification(message_center::RichNotificationData(), id_out);
+ return MakeNotification(RichNotificationData(), id_out);
}
// Utility methods of AddNotification.
std::string AddPriorityNotification(NotificationPriority priority) {
- message_center::RichNotificationData optional;
+ RichNotificationData optional;
optional.priority = priority;
return AddNotification(optional);
}
@@ -169,12 +168,11 @@ TEST_F(NotificationListTest, UpdateNotification) {
std::string id0 = AddNotification();
std::string replaced = id0 + "_replaced";
EXPECT_EQ(1u, notification_list()->NotificationCount(blockers()));
- std::unique_ptr<Notification> notification(
- new Notification(message_center::NOTIFICATION_TYPE_SIMPLE, replaced,
- UTF8ToUTF16("newtitle"), UTF8ToUTF16("newbody"),
- gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
- NotifierId(NotifierId::APPLICATION, kExtensionId),
- message_center::RichNotificationData(), NULL));
+ std::unique_ptr<Notification> notification(new Notification(
+ NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
+ UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
+ NotifierId(NotifierId::APPLICATION, kExtensionId), RichNotificationData(),
+ NULL));
notification_list()->UpdateNotificationMessage(id0, std::move(notification));
EXPECT_EQ(1u, notification_list()->NotificationCount(blockers()));
const NotificationList::Notifications notifications =
@@ -223,34 +221,34 @@ TEST_F(NotificationListTest, GetNotificationsByNotifierId) {
NotifierId id2(GURL("http://example.com"));
NotifierId id3(NotifierId::SYSTEM_COMPONENT, "system-notifier");
std::unique_ptr<Notification> notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, "id0", UTF8ToUTF16("title0"),
+ NOTIFICATION_TYPE_SIMPLE, "id0", UTF8ToUTF16("title0"),
UTF8ToUTF16("message0"), gfx::Image(), UTF8ToUTF16("source0"), GURL(),
- id0, message_center::RichNotificationData(), NULL));
+ id0, RichNotificationData(), NULL));
notification_list()->AddNotification(std::move(notification));
notification.reset(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, "id1", UTF8ToUTF16("title1"),
+ NOTIFICATION_TYPE_SIMPLE, "id1", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source0"), GURL(),
- id0, message_center::RichNotificationData(), NULL));
+ id0, RichNotificationData(), NULL));
notification_list()->AddNotification(std::move(notification));
notification.reset(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, "id2", UTF8ToUTF16("title1"),
+ NOTIFICATION_TYPE_SIMPLE, "id2", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source1"), GURL(),
- id0, message_center::RichNotificationData(), NULL));
+ id0, RichNotificationData(), NULL));
notification_list()->AddNotification(std::move(notification));
notification.reset(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, "id3", UTF8ToUTF16("title1"),
+ NOTIFICATION_TYPE_SIMPLE, "id3", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source2"), GURL(),
- id1, message_center::RichNotificationData(), NULL));
+ id1, RichNotificationData(), NULL));
notification_list()->AddNotification(std::move(notification));
notification.reset(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, "id4", UTF8ToUTF16("title1"),
+ NOTIFICATION_TYPE_SIMPLE, "id4", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source2"), GURL(),
- id2, message_center::RichNotificationData(), NULL));
+ id2, RichNotificationData(), NULL));
notification_list()->AddNotification(std::move(notification));
notification.reset(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, "id5", UTF8ToUTF16("title1"),
+ NOTIFICATION_TYPE_SIMPLE, "id5", UTF8ToUTF16("title1"),
UTF8ToUTF16("message1"), gfx::Image(), UTF8ToUTF16("source2"), GURL(),
- id3, message_center::RichNotificationData(), NULL));
+ id3, RichNotificationData(), NULL));
notification_list()->AddNotification(std::move(notification));
NotificationList::Notifications by_notifier_id =
@@ -390,12 +388,11 @@ TEST_F(NotificationListTest, PriorityPromotion) {
std::string replaced = id0 + "_replaced";
EXPECT_EQ(1u, notification_list()->NotificationCount(blockers()));
EXPECT_EQ(0u, GetPopupCounts());
- message_center::RichNotificationData optional;
+ RichNotificationData optional;
optional.priority = 1;
std::unique_ptr<Notification> notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, replaced,
- UTF8ToUTF16("newtitle"), UTF8ToUTF16("newbody"), gfx::Image(),
- UTF8ToUTF16(kDisplaySource), GURL(),
+ NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
+ UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierId::APPLICATION, kExtensionId), optional, NULL));
notification_list()->UpdateNotificationMessage(id0, std::move(notification));
EXPECT_EQ(1u, notification_list()->NotificationCount(blockers()));
@@ -416,10 +413,10 @@ TEST_F(NotificationListTest, PriorityPromotionWithPopups) {
EXPECT_EQ(0u, GetPopupCounts());
// id0 promoted to LOW->DEFAULT, it'll appear as toast (popup).
- message_center::RichNotificationData priority;
+ RichNotificationData priority;
priority.priority = DEFAULT_PRIORITY;
std::unique_ptr<Notification> notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, id0, UTF8ToUTF16("newtitle"),
+ NOTIFICATION_TYPE_SIMPLE, id0, UTF8ToUTF16("newtitle"),
UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierId::APPLICATION, kExtensionId), priority, NULL));
notification_list()->UpdateNotificationMessage(id0, std::move(notification));
@@ -429,7 +426,7 @@ TEST_F(NotificationListTest, PriorityPromotionWithPopups) {
// update with no promotion change for id0, it won't appear as a toast.
notification.reset(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, id0, UTF8ToUTF16("newtitle2"),
+ NOTIFICATION_TYPE_SIMPLE, id0, UTF8ToUTF16("newtitle2"),
UTF8ToUTF16("newbody2"), gfx::Image(), UTF8ToUTF16(kDisplaySource),
GURL(), NotifierId(NotifierId::APPLICATION, kExtensionId), priority,
NULL));
@@ -439,7 +436,7 @@ TEST_F(NotificationListTest, PriorityPromotionWithPopups) {
// id1 promoted to DEFAULT->HIGH, it'll appear as toast (popup).
priority.priority = HIGH_PRIORITY;
notification.reset(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle"),
+ NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle"),
UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
NotifierId(NotifierId::APPLICATION, kExtensionId), priority, NULL));
notification_list()->UpdateNotificationMessage(id1, std::move(notification));
@@ -450,7 +447,7 @@ TEST_F(NotificationListTest, PriorityPromotionWithPopups) {
// id1 promoted to HIGH->MAX, it'll appear as toast again.
priority.priority = MAX_PRIORITY;
notification.reset(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle2"),
+ NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle2"),
UTF8ToUTF16("newbody2"), gfx::Image(), UTF8ToUTF16(kDisplaySource),
GURL(), NotifierId(NotifierId::APPLICATION, kExtensionId), priority,
NULL));
@@ -462,7 +459,7 @@ TEST_F(NotificationListTest, PriorityPromotionWithPopups) {
// id1 demoted to MAX->DEFAULT, no appearing as toast.
priority.priority = DEFAULT_PRIORITY;
notification.reset(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle3"),
+ NOTIFICATION_TYPE_SIMPLE, id1, UTF8ToUTF16("newtitle3"),
UTF8ToUTF16("newbody3"), gfx::Image(), UTF8ToUTF16(kDisplaySource),
GURL(), NotifierId(NotifierId::APPLICATION, kExtensionId), priority,
NULL));
@@ -473,11 +470,10 @@ TEST_F(NotificationListTest, PriorityPromotionWithPopups) {
TEST_F(NotificationListTest, WebNotificationUpdatePromotion) {
std::string notification_id = "replaced-web-notification";
std::unique_ptr<Notification> original_notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
+ NOTIFICATION_TYPE_SIMPLE, notification_id,
UTF8ToUTF16("Web Notification"), UTF8ToUTF16("Notification contents"),
gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
- NotifierId(GURL("https://example.com/")),
- message_center::RichNotificationData(), NULL));
+ NotifierId(GURL("https://example.com/")), RichNotificationData(), NULL));
EXPECT_EQ(0u, GetPopupCounts());
notification_list()->AddNotification(std::move(original_notification));
@@ -487,12 +483,11 @@ TEST_F(NotificationListTest, WebNotificationUpdatePromotion) {
EXPECT_EQ(0u, GetPopupCounts());
std::unique_ptr<Notification> replaced_notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
+ NOTIFICATION_TYPE_SIMPLE, notification_id,
UTF8ToUTF16("Web Notification Replacement"),
UTF8ToUTF16("New notification contents"), gfx::Image(),
UTF8ToUTF16(kDisplaySource), GURL(),
- NotifierId(GURL("https://example.com/")),
- message_center::RichNotificationData(), NULL));
+ NotifierId(GURL("https://example.com/")), RichNotificationData(), NULL));
// Web Notifications will be re-shown as popups even if their priority didn't
// change, to match the behavior of the Web Notification API.
@@ -503,7 +498,7 @@ TEST_F(NotificationListTest, WebNotificationUpdatePromotion) {
TEST_F(NotificationListTest, NotificationOrderAndPriority) {
base::Time now = base::Time::Now();
- message_center::RichNotificationData optional;
+ RichNotificationData optional;
optional.timestamp = now;
optional.priority = 2;
std::string max_id = AddNotification(optional);
@@ -592,12 +587,11 @@ TEST_F(NotificationListTest, UpdateAfterMarkedAsShown) {
EXPECT_TRUE(n1->IsRead());
const std::string replaced("test-replaced-id");
- std::unique_ptr<Notification> notification(
- new Notification(message_center::NOTIFICATION_TYPE_SIMPLE, replaced,
- UTF8ToUTF16("newtitle"), UTF8ToUTF16("newbody"),
- gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
- NotifierId(NotifierId::APPLICATION, kExtensionId),
- message_center::RichNotificationData(), NULL));
+ std::unique_ptr<Notification> notification(new Notification(
+ NOTIFICATION_TYPE_SIMPLE, replaced, UTF8ToUTF16("newtitle"),
+ UTF8ToUTF16("newbody"), gfx::Image(), UTF8ToUTF16(kDisplaySource), GURL(),
+ NotifierId(NotifierId::APPLICATION, kExtensionId), RichNotificationData(),
+ NULL));
notification_list()->UpdateNotificationMessage(id1, std::move(notification));
n1 = GetNotification(id1);
EXPECT_TRUE(n1 == NULL);
@@ -638,21 +632,21 @@ TEST_F(NotificationListTest, TestPushingShownNotification) {
TEST_F(NotificationListTest, TestHasNotificationOfType) {
std::string id = AddNotification();
- EXPECT_TRUE(notification_list()->HasNotificationOfType(
- id, message_center::NOTIFICATION_TYPE_SIMPLE));
+ EXPECT_TRUE(
+ notification_list()->HasNotificationOfType(id, NOTIFICATION_TYPE_SIMPLE));
EXPECT_FALSE(notification_list()->HasNotificationOfType(
- id, message_center::NOTIFICATION_TYPE_PROGRESS));
+ id, NOTIFICATION_TYPE_PROGRESS));
- std::unique_ptr<Notification> updated_notification(new Notification(
- message_center::NOTIFICATION_TYPE_PROGRESS, id, UTF8ToUTF16("updated"),
- UTF8ToUTF16("updated"), gfx::Image(), base::string16(), GURL(),
- NotifierId(), RichNotificationData(), NULL));
+ std::unique_ptr<Notification> updated_notification(
+ new Notification(NOTIFICATION_TYPE_PROGRESS, id, UTF8ToUTF16("updated"),
+ UTF8ToUTF16("updated"), gfx::Image(), base::string16(),
+ GURL(), NotifierId(), RichNotificationData(), NULL));
notification_list()->AddNotification(std::move(updated_notification));
- EXPECT_FALSE(notification_list()->HasNotificationOfType(
- id, message_center::NOTIFICATION_TYPE_SIMPLE));
+ EXPECT_FALSE(
+ notification_list()->HasNotificationOfType(id, NOTIFICATION_TYPE_SIMPLE));
EXPECT_TRUE(notification_list()->HasNotificationOfType(
- id, message_center::NOTIFICATION_TYPE_PROGRESS));
+ id, NOTIFICATION_TYPE_PROGRESS));
}
} // namespace message_center
diff --git a/chromium/ui/message_center/notification_types.cc b/chromium/ui/message_center/notification_types.cc
deleted file mode 100644
index a54ed7bd325..00000000000
--- a/chromium/ui/message_center/notification_types.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/message_center/notification_types.h"
-
-namespace message_center {
-
-const char kPriorityKey[] = "priority";
-const char kTimestampKey[] = "timestamp";
-const char kButtonOneTitleKey[] = "button_one_title";
-const char kButtonOneIconUrlKey[] = "button_one_icon_url";
-const char kButtonTwoTitleKey[] = "button_two_title";
-const char kButtonTwoIconUrlKey[] = "button_two_icon_url";
-const char kExpandedMessageKey[] = "expanded_message";
-const char kImageUrlKey[] = "image_url";
-const char kItemsKey[] = "items";
-const char kItemTitleKey[] = "title";
-const char kItemMessageKey[] = "message";
-const char kPrivateNeverTimeoutKey[] = "private_never_timeout";
-
-} // namespace message_center
diff --git a/chromium/ui/message_center/notification_types.h b/chromium/ui/message_center/notification_types.h
deleted file mode 100644
index 965fdd7fd9d..00000000000
--- a/chromium/ui/message_center/notification_types.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_MESSAGE_CENTER_NOTIFICATION_TYPES_H_
-#define UI_MESSAGE_CENTER_NOTIFICATION_TYPES_H_
-
-#include "ui/message_center/message_center_export.h"
-
-namespace message_center {
-
-// Keys for optional fields in Notification.
-MESSAGE_CENTER_EXPORT extern const char kPriorityKey[];
-MESSAGE_CENTER_EXPORT extern const char kTimestampKey[];
-MESSAGE_CENTER_EXPORT extern const char kButtonOneTitleKey[];
-MESSAGE_CENTER_EXPORT extern const char kButtonOneIconUrlKey[];
-MESSAGE_CENTER_EXPORT extern const char kButtonTwoTitleKey[];
-MESSAGE_CENTER_EXPORT extern const char kButtonTwoIconUrlKey[];
-MESSAGE_CENTER_EXPORT extern const char kExpandedMessageKey[];
-MESSAGE_CENTER_EXPORT extern const char kImageUrlKey[];
-MESSAGE_CENTER_EXPORT extern const char kItemsKey[];
-MESSAGE_CENTER_EXPORT extern const char kItemTitleKey[];
-MESSAGE_CENTER_EXPORT extern const char kItemMessageKey[];
-// This key should not be used by the extension API handler. It's not allowed
-// to use it there, it's used to cancel timeout for webkit notifications.
-MESSAGE_CENTER_EXPORT extern const char kPrivateNeverTimeoutKey[];
-
-// Notification types. Note that the values in this enumeration are being
-// recoded in a histogram, updates should not change the entries' values.
-enum NotificationType {
- NOTIFICATION_TYPE_SIMPLE = 0,
- NOTIFICATION_TYPE_BASE_FORMAT = 1,
- NOTIFICATION_TYPE_IMAGE = 2,
- NOTIFICATION_TYPE_MULTIPLE = 3,
- NOTIFICATION_TYPE_PROGRESS = 4, // Notification with progress bar.
- NOTIFICATION_TYPE_CUSTOM = 5,
-
- // Add new values before this line.
- NOTIFICATION_TYPE_LAST = NOTIFICATION_TYPE_CUSTOM
-};
-
-enum NotificationPriority {
- MIN_PRIORITY = -2,
- LOW_PRIORITY = -1,
- DEFAULT_PRIORITY = 0,
- HIGH_PRIORITY = 1,
- MAX_PRIORITY = 2,
-
- // Top priority for system-level notifications.. This can't be set from
- // kPriorityKey, instead you have to call SetSystemPriority() of
- // Notification object.
- SYSTEM_PRIORITY = 3,
-};
-
-} // namespace message_center
-
-#endif // UI_MESSAGE_CENTER_NOTIFICATION_TYPES_H_
diff --git a/chromium/ui/message_center/public/DEPS b/chromium/ui/message_center/public/DEPS
new file mode 100644
index 00000000000..5502cd434d1
--- /dev/null
+++ b/chromium/ui/message_center/public/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "-ui/message_center",
+ "+ui/message_center/public",
+]
diff --git a/chromium/ui/message_center/public/cpp/BUILD.gn b/chromium/ui/message_center/public/cpp/BUILD.gn
index 75ce71c849c..a647bb534f5 100644
--- a/chromium/ui/message_center/public/cpp/BUILD.gn
+++ b/chromium/ui/message_center/public/cpp/BUILD.gn
@@ -6,11 +6,20 @@ import("//build/config/jumbo.gni")
# C++ headers and sources that can be used outside message_center.
jumbo_component("cpp") {
+ output_name = "ui_message_center_cpp"
+
sources = [
+ "features.cc",
+ "features.h",
"message_center_constants.h",
"message_center_public_export.h",
- "message_center_switches.cc",
- "message_center_switches.h",
+ "notification.cc",
+ "notification.h",
+ "notification_delegate.cc",
+ "notification_delegate.h",
+ "notification_types.h",
+ "notifier_id.cc",
+ "notifier_id.h",
]
defines = [ "MESSAGE_CENTER_PUBLIC_IMPLEMENTATION" ]
@@ -19,5 +28,7 @@ jumbo_component("cpp") {
"//base",
"//skia",
"//ui/gfx",
+ "//ui/strings",
+ "//url",
]
}
diff --git a/chromium/ui/message_center/public/cpp/features.cc b/chromium/ui/message_center/public/cpp/features.cc
new file mode 100644
index 00000000000..079e49bfdf5
--- /dev/null
+++ b/chromium/ui/message_center/public/cpp/features.cc
@@ -0,0 +1,18 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/message_center/public/cpp/features.h"
+
+namespace message_center {
+
+const base::Feature kNewStyleNotifications {
+ "NewStyleNotifications",
+#if defined(OS_CHROMEOS)
+ base::FEATURE_ENABLED_BY_DEFAULT
+#else
+ base::FEATURE_DISABLED_BY_DEFAULT
+#endif
+};
+
+} // namespace message_center
diff --git a/chromium/ui/message_center/public/cpp/features.h b/chromium/ui/message_center/public/cpp/features.h
new file mode 100644
index 00000000000..dadaddbb22e
--- /dev/null
+++ b/chromium/ui/message_center/public/cpp/features.h
@@ -0,0 +1,19 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_MESSAGE_CENTER_PUBLIC_CPP_FEATURES_H_
+#define UI_MESSAGE_CENTER_PUBLIC_CPP_FEATURES_H_
+
+#include "base/feature_list.h"
+#include "ui/message_center/public/cpp/message_center_public_export.h"
+
+namespace message_center {
+
+// This feature controls whether the new (material design) style notifications
+// should be used.
+MESSAGE_CENTER_PUBLIC_EXPORT extern const base::Feature kNewStyleNotifications;
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_PUBLIC_CPP_FEATURES_H_
diff --git a/chromium/ui/message_center/public/cpp/message_center_constants.h b/chromium/ui/message_center/public/cpp/message_center_constants.h
index 39f52903846..6cdbadde8c3 100644
--- a/chromium/ui/message_center/public/cpp/message_center_constants.h
+++ b/chromium/ui/message_center/public/cpp/message_center_constants.h
@@ -35,8 +35,9 @@ const size_t kMaxVisiblePopupNotifications = 3;
const int kNotificationWidth = 360;
// Colors.
-const SkColor kMessageCenterBorderColor = SkColorSetRGB(0xC7, 0xCA, 0xCE);
-const SkColor kMessageCenterShadowColor = SkColorSetA(SK_ColorBLACK, 0.5 * 255);
+constexpr SkColor kMessageCenterBorderColor = SkColorSetRGB(0xC7, 0xCA, 0xCE);
+constexpr SkColor kMessageCenterShadowColor =
+ SkColorSetA(SK_ColorBLACK, 0.5 * 255);
// Within a notification ///////////////////////////////////////////////////////
@@ -64,30 +65,30 @@ const int kMessageLineHeight = 18; // In DIPs.
// Colors.
// Background of the card.
-const SkColor kNotificationBackgroundColor = SK_ColorWHITE;
+constexpr SkColor kNotificationBackgroundColor = SK_ColorWHITE;
// Background of the image.
-const SkColor kImageBackgroundColor = kNotificationBackgroundColor;
+constexpr SkColor kImageBackgroundColor = kNotificationBackgroundColor;
// Title, message, ...
-const SkColor kRegularTextColor = SkColorSetRGB(0x33, 0x33, 0x33);
-const SkColor kDimTextColor = SkColorSetRGB(0x7f, 0x7f, 0x7f);
+constexpr SkColor kRegularTextColor = SkColorSetRGB(0x33, 0x33, 0x33);
+constexpr SkColor kDimTextColor = SkColorSetRGB(0x7f, 0x7f, 0x7f);
// The focus border.
-const SkColor kFocusBorderColor = SkColorSetRGB(64, 128, 250);
+constexpr SkColor kFocusBorderColor = SkColorSetRGB(64, 128, 250);
// Foreground of small icon image.
-const SkColor kSmallImageMaskForegroundColor = SK_ColorWHITE;
+constexpr SkColor kSmallImageMaskForegroundColor = SK_ColorWHITE;
// Background of small icon image.
-const SkColor kSmallImageMaskBackgroundColor = SkColorSetRGB(0xa3, 0xa3, 0xa3);
+constexpr SkColor kSmallImageMaskBackgroundColor =
+ SkColorSetRGB(0xa3, 0xa3, 0xa3);
// Background of the close button and the settings button
-const SkColor kControlButtonBackgroundColor =
+constexpr SkColor kControlButtonBackgroundColor =
SkColorSetA(SK_ColorWHITE, 0.9 * 0xff);
// Accent colors of system notifications.
-const SkColor kSystemNotificationColorNormal = SkColorSetRGB(0x33, 0x67, 0xd6);
-const SkColor kSystemNotificationColorWarning = SkColorSetRGB(0xea, 0x61, 0x0);
-const SkColor kSystemNotificationColorCriticalWarning =
- SkColorSetRGB(0xc5, 0x39, 0x29);
+constexpr SkColor kSystemNotificationColorNormal = gfx::kGoogleBlue700;
+constexpr SkColor kSystemNotificationColorWarning = gfx::kGoogleYellow900;
+constexpr SkColor kSystemNotificationColorCriticalWarning = gfx::kGoogleRed700;
// Default accent color of notifications that are not generated by system.
-const SkColor kNotificationDefaultAccentColor = gfx::kChromeIconGrey;
+constexpr SkColor kNotificationDefaultAccentColor = gfx::kChromeIconGrey;
// For list notifications.
// Not used when --enabled-new-style-notification is set.
@@ -106,8 +107,8 @@ const int kButtonIconTopPadding = 11; // In DIPs.
const int kButtonIconToTitlePadding = 16; // In DIPs.
#if !defined(OS_LINUX) || defined(USE_AURA)
-const SkColor kButtonSeparatorColor = SkColorSetRGB(234, 234, 234);
-const SkColor kHoveredButtonBackgroundColor = SkColorSetRGB(243, 243, 243);
+constexpr SkColor kButtonSeparatorColor = SkColorSetRGB(234, 234, 234);
+constexpr SkColor kHoveredButtonBackgroundColor = SkColorSetRGB(243, 243, 243);
#endif
// Progress bar.
@@ -115,8 +116,8 @@ const int kProgressBarTopPadding = 16;
#if defined(OS_MACOSX)
const int kProgressBarThickness = 5;
const int kProgressBarCornerRadius = 3;
-const SkColor kProgressBarBackgroundColor = SkColorSetARGB(26, 0, 0, 0);
-const SkColor kProgressBarSliceColor = SkColorSetRGB(26, 194, 34);
+constexpr SkColor kProgressBarBackgroundColor = SkColorSetARGB(26, 0, 0, 0);
+constexpr SkColor kProgressBarSliceColor = SkColorSetRGB(26, 194, 34);
#endif
// Line limits.
@@ -137,9 +138,6 @@ constexpr int kMarginBetweenItemsInList = 8;
// Horizontal & vertical space around & between popup notifications.
constexpr int kMarginBetweenPopups = 10;
-// Shadow in the tray.
-const SkColor kShadowColor = SkColorSetARGB(0.3 * 255, 0, 0, 0);
-
// Radius of the rounded corners of a notification.
// The corners are only rounded in Chrome OS.
constexpr int kNotificationCornerRadius = 2;
diff --git a/chromium/ui/message_center/public/cpp/message_center_switches.cc b/chromium/ui/message_center/public/cpp/message_center_switches.cc
deleted file mode 100644
index 08bcec0d04d..00000000000
--- a/chromium/ui/message_center/public/cpp/message_center_switches.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/message_center/public/cpp/message_center_switches.h"
-
-#include "base/command_line.h"
-
-namespace message_center {
-
-bool IsNewStyleNotificationEnabled() {
-// For Chrome OS, the default is Enabled.
-// For other platforms, the default is Disabled.
-#if defined(OS_CHROMEOS)
- // Returns true if not explicitly disabled.
- return !base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kDisableMessageCenterNewStyleNotification);
-#else
- // Returns true if explicitly enabled.
- return base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableMessageCenterNewStyleNotification);
-#endif
-}
-
-namespace switches {
-
-// Flag to enable or disable new-style notification. This flag will be removed
-// once the feature gets stable.
-const char kEnableMessageCenterNewStyleNotification[] =
- "enabled-new-style-notification";
-const char kDisableMessageCenterNewStyleNotification[] =
- "disabled-new-style-notification";
-
-} // namespace switches
-
-} // namespace message_center
diff --git a/chromium/ui/message_center/public/cpp/message_center_switches.h b/chromium/ui/message_center/public/cpp/message_center_switches.h
deleted file mode 100644
index 461b81d6048..00000000000
--- a/chromium/ui/message_center/public/cpp/message_center_switches.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_MESSAGE_CENTER_PUBLIC_CPP_MESSAGE_CENTER_SWITCHES_H_
-#define UI_MESSAGE_CENTER_PUBLIC_CPP_MESSAGE_CENTER_SWITCHES_H_
-
-#include "ui/message_center/public/cpp/message_center_public_export.h"
-
-namespace message_center {
-
-// Returns if new style notification is enabled, i.e. NotificationViewMD is
-// used instead of NotificationView.
-bool MESSAGE_CENTER_PUBLIC_EXPORT IsNewStyleNotificationEnabled();
-
-namespace switches {
-
-MESSAGE_CENTER_PUBLIC_EXPORT extern const char
- kEnableMessageCenterNewStyleNotification[];
-MESSAGE_CENTER_PUBLIC_EXPORT extern const char
- kDisableMessageCenterNewStyleNotification[];
-
-} // namespace switches
-
-} // namespace message_center
-
-#endif // UI_MESSAGE_CENTER_PUBLIC_CPP_MESSAGE_CENTER_SWITCHES_H_
diff --git a/chromium/ui/message_center/notification.cc b/chromium/ui/message_center/public/cpp/notification.cc
index d5fda30e3ed..dd06417bce3 100644
--- a/chromium/ui/message_center/notification.cc
+++ b/chromium/ui/message_center/public/cpp/notification.cc
@@ -2,25 +2,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/message_center/notification.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include <map>
#include <memory>
+#include "base/lazy_instance.h"
#include "base/logging.h"
-#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/vector_icon_types.h"
-#include "ui/message_center/notification_delegate.h"
-#include "ui/message_center/notification_types.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
+#include "ui/message_center/public/cpp/notification_types.h"
namespace message_center {
namespace {
-unsigned g_next_serial_number_ = 0;
+unsigned g_next_serial_number = 0;
+
+base::LazyInstance<std::map<std::string, const gfx::VectorIcon&>>::Leaky
+ g_vector_icon_registry = LAZY_INSTANCE_INITIALIZER;
const gfx::ImageSkia CreateSolidColorImage(int width,
int height,
@@ -40,50 +44,20 @@ gfx::Image DeepCopyImage(const gfx::Image& image) {
} // namespace
-NotificationItem::NotificationItem(const base::string16& title,
- const base::string16& message)
- : title(title),
- message(message) {
-}
-
-ButtonInfo::ButtonInfo(const base::string16& title)
- : title(title) {
-}
+ButtonInfo::ButtonInfo(const base::string16& title) : title(title) {}
ButtonInfo::ButtonInfo(const ButtonInfo& other) = default;
+ButtonInfo::ButtonInfo() = default;
+
ButtonInfo::~ButtonInfo() = default;
ButtonInfo& ButtonInfo::operator=(const ButtonInfo& other) = default;
RichNotificationData::RichNotificationData() : timestamp(base::Time::Now()) {}
-RichNotificationData::RichNotificationData(const RichNotificationData& other)
- : priority(other.priority),
- never_timeout(other.never_timeout),
- timestamp(other.timestamp),
- context_message(other.context_message),
- image(other.image),
- small_image(other.small_image),
- vector_small_image(other.vector_small_image),
- items(other.items),
- progress(other.progress),
- progress_status(other.progress_status),
- buttons(other.buttons),
- should_make_spoken_feedback_for_popup_updates(
- other.should_make_spoken_feedback_for_popup_updates),
- clickable(other.clickable),
-#if defined(OS_CHROMEOS)
- pinned(other.pinned),
-#endif // defined(OS_CHROMEOS)
- vibration_pattern(other.vibration_pattern),
- renotify(other.renotify),
- silent(other.silent),
- accessible_name(other.accessible_name),
- accent_color(other.accent_color),
- settings_button_handler(other.settings_button_handler),
- fullscreen_visibility(other.fullscreen_visibility) {
-}
+RichNotificationData::RichNotificationData(const RichNotificationData& other) =
+ default;
RichNotificationData::~RichNotificationData() = default;
@@ -107,60 +81,21 @@ Notification::Notification(NotificationType type,
display_source_(display_source),
origin_url_(origin_url),
notifier_id_(notifier_id),
- serial_number_(g_next_serial_number_++),
optional_fields_(optional_fields),
+ serial_number_(g_next_serial_number++),
shown_as_popup_(false),
is_read_(false),
delegate_(std::move(delegate)) {}
Notification::Notification(const std::string& id, const Notification& other)
- : type_(other.type_),
- id_(id),
- title_(other.title_),
- message_(other.message_),
- icon_(other.icon_),
- display_source_(other.display_source_),
- origin_url_(other.origin_url_),
- notifier_id_(other.notifier_id_),
- serial_number_(other.serial_number_),
- optional_fields_(other.optional_fields_),
- shown_as_popup_(other.shown_as_popup_),
- is_read_(other.is_read_),
- delegate_(other.delegate_) {}
-
-Notification::Notification(const Notification& other)
- : type_(other.type_),
- id_(other.id_),
- title_(other.title_),
- message_(other.message_),
- icon_(other.icon_),
- display_source_(other.display_source_),
- origin_url_(other.origin_url_),
- notifier_id_(other.notifier_id_),
- serial_number_(other.serial_number_),
- optional_fields_(other.optional_fields_),
- shown_as_popup_(other.shown_as_popup_),
- is_read_(other.is_read_),
- delegate_(other.delegate_) {}
-
-Notification& Notification::operator=(const Notification& other) {
- type_ = other.type_;
- id_ = other.id_;
- title_ = other.title_;
- message_ = other.message_;
- icon_ = other.icon_;
- display_source_ = other.display_source_;
- origin_url_ = other.origin_url_;
- notifier_id_ = other.notifier_id_;
- serial_number_ = other.serial_number_;
- optional_fields_ = other.optional_fields_;
- shown_as_popup_ = other.shown_as_popup_;
- is_read_ = other.is_read_;
- delegate_ = other.delegate_;
-
- return *this;
+ : Notification(other) {
+ id_ = id;
}
+Notification::Notification(const Notification& other) = default;
+
+Notification& Notification::operator=(const Notification& other) = default;
+
Notification::~Notification() = default;
// static
@@ -241,7 +176,7 @@ std::unique_ptr<Notification> Notification::CreateSystemNotification(
const base::string16& message,
const gfx::Image& icon,
const std::string& system_component_id,
- const base::Closure& click_callback) {
+ const base::RepeatingClosure& click_callback) {
DCHECK(!click_callback.is_null());
std::unique_ptr<Notification> notification = CreateSystemNotification(
NOTIFICATION_TYPE_SIMPLE, notification_id, title, message, icon,
@@ -270,29 +205,38 @@ std::unique_ptr<Notification> Notification::CreateSystemNotification(
const gfx::VectorIcon& small_image,
SystemNotificationWarningLevel color_type) {
DCHECK_EQ(NotifierId::SYSTEM_COMPONENT, notifier_id.type);
- SkColor color = message_center::kSystemNotificationColorNormal;
+ SkColor color = kSystemNotificationColorNormal;
switch (color_type) {
case SystemNotificationWarningLevel::NORMAL:
- color = message_center::kSystemNotificationColorNormal;
+ color = kSystemNotificationColorNormal;
break;
case SystemNotificationWarningLevel::WARNING:
- color = message_center::kSystemNotificationColorWarning;
+ color = kSystemNotificationColorWarning;
break;
case SystemNotificationWarningLevel::CRITICAL_WARNING:
- color = message_center::kSystemNotificationColorCriticalWarning;
+ color = kSystemNotificationColorCriticalWarning;
break;
}
std::unique_ptr<Notification> notification = std::make_unique<Notification>(
type, id, title, message, icon, display_source, origin_url, notifier_id,
optional_fields, delegate);
notification->set_accent_color(color);
- notification->set_small_image(
- small_image.is_empty() ? gfx::Image()
- : gfx::Image(gfx::CreateVectorIcon(
- small_image, kSmallImageSizeMD, color)));
if (!small_image.is_empty())
notification->set_vector_small_image(small_image);
return notification;
}
+// static
+void RegisterVectorIcon(const gfx::VectorIcon& vector_icon) {
+ g_vector_icon_registry.Get().insert(
+ std::pair<std::string, const gfx::VectorIcon&>(vector_icon.name,
+ vector_icon));
+}
+
+// static
+const gfx::VectorIcon* GetRegisteredVectorIcon(const std::string& id) {
+ auto iter = g_vector_icon_registry.Get().find(id);
+ return iter != g_vector_icon_registry.Get().end() ? &iter->second : nullptr;
+}
+
} // namespace message_center
diff --git a/chromium/ui/message_center/notification.h b/chromium/ui/message_center/public/cpp/notification.h
index 8fc687babce..c91d0dac645 100644
--- a/chromium/ui/message_center/notification.h
+++ b/chromium/ui/message_center/public/cpp/notification.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_MESSAGE_CENTER_NOTIFICATION_H_
-#define UI_MESSAGE_CENTER_NOTIFICATION_H_
+#ifndef UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFICATION_H_
+#define UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFICATION_H_
#include <stddef.h>
@@ -11,6 +11,7 @@
#include <vector>
#include "base/memory/ref_counted.h"
+#include "base/optional.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "base/values.h"
@@ -21,10 +22,10 @@
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/vector_icon_types.h"
-#include "ui/message_center/message_center_export.h"
-#include "ui/message_center/notification_delegate.h"
-#include "ui/message_center/notification_types.h"
-#include "ui/message_center/notifier_id.h"
+#include "ui/message_center/public/cpp/message_center_public_export.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
+#include "ui/message_center/public/cpp/notification_types.h"
+#include "ui/message_center/public/cpp/notifier_id.h"
#include "url/gurl.h"
namespace gfx {
@@ -38,34 +39,24 @@ class NotificationDataView;
}
// Represents an individual item in NOTIFICATION_TYPE_MULTIPLE notifications.
-struct MESSAGE_CENTER_EXPORT NotificationItem {
- NotificationItem(const base::string16& title, const base::string16& message);
-
+struct MESSAGE_CENTER_PUBLIC_EXPORT NotificationItem {
base::string16 title;
base::string16 message;
};
-enum class ButtonType {
- // A simple button having an icon and a title that the user can click on.
- BUTTON,
-
- // A button having an icon and a title that should also enable the user to
- // input text, enabling them to quickly respond from the notification.
- TEXT
-};
-
enum class SettingsButtonHandler {
- NONE, // No button. This is the default.
- TRAY, // Button shown, the tray handles clicks. Only used on Chrome OS.
- DELEGATE // Button shown, notification's delegate handles action.
+ NONE = 0, // No button. This is the default.
+ INLINE = 1, // Button shown, settings inline.
+ DELEGATE = 2 // Button shown, notification's delegate handles action.
};
enum class SystemNotificationWarningLevel { NORMAL, WARNING, CRITICAL_WARNING };
// Represents a button to be shown as part of a notification.
-struct MESSAGE_CENTER_EXPORT ButtonInfo {
+struct MESSAGE_CENTER_PUBLIC_EXPORT ButtonInfo {
explicit ButtonInfo(const base::string16& title);
ButtonInfo(const ButtonInfo& other);
+ ButtonInfo();
~ButtonInfo();
ButtonInfo& operator=(const ButtonInfo& other);
@@ -77,25 +68,20 @@ struct MESSAGE_CENTER_EXPORT ButtonInfo {
// requirements of the notification.
gfx::Image icon;
- // Type of this button.
- ButtonType type = ButtonType::BUTTON;
-
- // The placeholder string that should be displayed in the input field for TEXT
- // type buttons until the user has entered a response themselves.
- base::string16 placeholder;
+ // The placeholder string that should be displayed in the input field for
+ // text input type buttons until the user has entered a response themselves.
+ // If the value is null, there is no input field associated with the button.
+ base::Optional<base::string16> placeholder;
};
-// TODO(estade): add an ALWAYS value to mark notifications as additionally
-// visible over system fullscreen windows such as Chrome OS login so we don't
-// need to centrally track Ash system notification IDs.
enum class FullscreenVisibility {
- NONE, // Don't show the notification over fullscreen (default).
- OVER_USER, // Show over the current fullscreened client window.
- // windows (like Chrome OS login).
+ NONE = 0, // Don't show the notification over fullscreen (default).
+ OVER_USER = 1, // Show over the current fullscreened client window.
+ // windows (like Chrome OS login).
};
// Represents rich features available for notifications.
-class MESSAGE_CENTER_EXPORT RichNotificationData {
+class MESSAGE_CENTER_PUBLIC_EXPORT RichNotificationData {
public:
RichNotificationData();
RichNotificationData(const RichNotificationData& other);
@@ -198,7 +184,7 @@ class MESSAGE_CENTER_EXPORT RichNotificationData {
FullscreenVisibility fullscreen_visibility = FullscreenVisibility::NONE;
};
-class MESSAGE_CENTER_EXPORT Notification {
+class MESSAGE_CENTER_PUBLIC_EXPORT Notification {
public:
// Default constructor needed for generated mojom files.
Notification();
@@ -406,9 +392,7 @@ class MESSAGE_CENTER_EXPORT Notification {
}
bool clickable() const { return optional_fields_.clickable; }
- void set_clickable(bool clickable) {
- optional_fields_.clickable = clickable;
- }
+ void set_clickable(bool clickable) { optional_fields_.clickable = clickable; }
bool pinned() const {
#if defined(OS_CHROMEOS)
@@ -478,7 +462,7 @@ class MESSAGE_CENTER_EXPORT Notification {
const base::string16& message,
const gfx::Image& icon,
const std::string& system_component_id,
- const base::Closure& click_callback);
+ const base::RepeatingClosure& click_callback);
// Factory method to create all kinds of notifications generated by system,
// from normal priority ones to critical priority ones.
@@ -523,16 +507,29 @@ class MESSAGE_CENTER_EXPORT Notification {
// it's a system notification.
GURL origin_url_;
NotifierId notifier_id_;
- unsigned serial_number_;
RichNotificationData optional_fields_;
+
+ // TODO(estade): these book-keeping fields should be moved into
+ // NotificationList.
+ unsigned serial_number_;
bool shown_as_popup_; // True if this has been shown as a popup.
- bool is_read_; // True if this has been seen in the message center.
+ bool is_read_; // True if this has been seen in the message center.
// A proxy object that allows access back to the JavaScript object that
// represents the notification, for firing events.
scoped_refptr<NotificationDelegate> delegate_;
};
+// Registering a vector icon allows it to later be looked up by name. This is
+// useful for vector icons sent over mojo: assuming the receiver has a known set
+// of icons it expects to see, this allows for icon lookup without
+// serialization/deserialization.
+MESSAGE_CENTER_PUBLIC_EXPORT
+void RegisterVectorIcon(const gfx::VectorIcon& vector_icon);
+
+MESSAGE_CENTER_PUBLIC_EXPORT
+const gfx::VectorIcon* GetRegisteredVectorIcon(const std::string& id);
+
} // namespace message_center
-#endif // UI_MESSAGE_CENTER_NOTIFICATION_H_
+#endif // UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFICATION_H_
diff --git a/chromium/ui/message_center/notification_delegate.cc b/chromium/ui/message_center/public/cpp/notification_delegate.cc
index 27cc82096c6..42b536b97ac 100644
--- a/chromium/ui/message_center/notification_delegate.cc
+++ b/chromium/ui/message_center/public/cpp/notification_delegate.cc
@@ -2,29 +2,52 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/message_center/notification_delegate.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
#include "base/bind.h"
#include "base/logging.h"
namespace message_center {
-// NotificationDelegate:
+// ThunkNotificationDelegate:
-void NotificationDelegate::Close(bool by_user) {}
+ThunkNotificationDelegate::ThunkNotificationDelegate(
+ base::WeakPtr<NotificationObserver> impl)
+ : impl_(impl) {}
-void NotificationDelegate::Click() {}
+void ThunkNotificationDelegate::Close(bool by_user) {
+ if (impl_)
+ impl_->Close(by_user);
+}
+
+void ThunkNotificationDelegate::Click() {
+ if (impl_)
+ impl_->Click();
+}
-void NotificationDelegate::ButtonClick(int button_index) {}
+void ThunkNotificationDelegate::ButtonClick(int button_index) {
+ if (impl_)
+ impl_->ButtonClick(button_index);
+}
-void NotificationDelegate::ButtonClickWithReply(int button_index,
- const base::string16& reply) {
- NOTIMPLEMENTED();
+void ThunkNotificationDelegate::ButtonClickWithReply(
+ int button_index,
+ const base::string16& reply) {
+ if (impl_)
+ impl_->ButtonClickWithReply(button_index, reply);
}
-void NotificationDelegate::SettingsClick() {}
+void ThunkNotificationDelegate::SettingsClick() {
+ if (impl_)
+ impl_->SettingsClick();
+}
+
+void ThunkNotificationDelegate::DisableNotification() {
+ if (impl_)
+ impl_->DisableNotification();
+}
-void NotificationDelegate::DisableNotification() {}
+ThunkNotificationDelegate::~ThunkNotificationDelegate() = default;
// HandleNotificationClickDelegate:
@@ -33,7 +56,7 @@ HandleNotificationClickDelegate::HandleNotificationClickDelegate(
if (!callback.is_null()) {
// Create a callback that consumes and ignores the button index parameter,
// and just runs the provided closure.
- callback_ = base::Bind(
+ callback_ = base::BindRepeating(
[](const base::RepeatingClosure& closure,
base::Optional<int> button_index) {
DCHECK(!button_index);
diff --git a/chromium/ui/message_center/public/cpp/notification_delegate.h b/chromium/ui/message_center/public/cpp/notification_delegate.h
new file mode 100644
index 00000000000..8f5a5321969
--- /dev/null
+++ b/chromium/ui/message_center/public/cpp/notification_delegate.h
@@ -0,0 +1,119 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFICATION_DELEGATE_H_
+#define UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFICATION_DELEGATE_H_
+
+#include <memory>
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/optional.h"
+#include "base/strings/string16.h"
+#include "ui/message_center/public/cpp/message_center_public_export.h"
+
+namespace message_center {
+
+// Handles actions performed on a notification.
+class MESSAGE_CENTER_PUBLIC_EXPORT NotificationObserver {
+ public:
+ // To be called when the desktop notification is closed. If closed by a
+ // user explicitly (as opposed to timeout/script), |by_user| should be true.
+ virtual void Close(bool by_user) {}
+
+ // To be called when a desktop notification is clicked.
+ virtual void Click() {}
+
+ // To be called when the user clicks a button in a notification.
+ virtual void ButtonClick(int button_index) {}
+
+ // To be called when the user types a reply to a notification.
+ virtual void ButtonClickWithReply(int button_index,
+ const base::string16& reply) {}
+
+ // To be called when the user clicks the settings button in a notification
+ // which has a DELEGATE settings button action.
+ virtual void SettingsClick() {}
+
+ // Called when the user attempts to disable the notification.
+ virtual void DisableNotification() {}
+};
+
+// Ref counted version of NotificationObserver, required to satisfy
+// message_center::Notification::delegate_.
+class MESSAGE_CENTER_PUBLIC_EXPORT NotificationDelegate
+ : public NotificationObserver,
+ public base::RefCountedThreadSafe<NotificationDelegate> {
+ protected:
+ virtual ~NotificationDelegate() = default;
+
+ private:
+ friend class base::RefCountedThreadSafe<NotificationDelegate>;
+};
+
+// A pass-through which converts the RefCounted requirement to a WeakPtr
+// requirement. This class replaces the need for individual delegates that pass
+// through to an actual controller class, and which only exist because the
+// actual controller has a strong ownership model. TODO(estade): replace many
+// existing NotificationDelegate overrides with an instance of this class.
+class MESSAGE_CENTER_PUBLIC_EXPORT ThunkNotificationDelegate
+ : public NotificationDelegate {
+ public:
+ explicit ThunkNotificationDelegate(base::WeakPtr<NotificationObserver> impl);
+
+ // NotificationDelegate:
+ void Close(bool by_user) override;
+ void Click() override;
+ void ButtonClick(int button_index) override;
+ void ButtonClickWithReply(int button_index,
+ const base::string16& reply) override;
+ void SettingsClick() override;
+ void DisableNotification() override;
+
+ protected:
+ ~ThunkNotificationDelegate() override;
+
+ private:
+ base::WeakPtr<NotificationObserver> impl_;
+
+ DISALLOW_COPY_AND_ASSIGN(ThunkNotificationDelegate);
+};
+
+// A simple notification delegate which invokes the passed closure when the body
+// or a button is clicked.
+class MESSAGE_CENTER_PUBLIC_EXPORT HandleNotificationClickDelegate
+ : public NotificationDelegate {
+ public:
+ // The parameter is the index of the button that was clicked, or nullopt if
+ // the body was clicked.
+ using ButtonClickCallback =
+ base::RepeatingCallback<void(base::Optional<int>)>;
+
+ // Creates a delegate that handles clicks on a button or on the body.
+ explicit HandleNotificationClickDelegate(const ButtonClickCallback& callback);
+
+ // Creates a delegate that only handles clicks on the body of the
+ // notification.
+ explicit HandleNotificationClickDelegate(
+ const base::RepeatingClosure& closure);
+
+ // NotificationDelegate overrides:
+ void Click() override;
+ void ButtonClick(int button_index) override;
+
+ protected:
+ ~HandleNotificationClickDelegate() override;
+
+ private:
+ ButtonClickCallback callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(HandleNotificationClickDelegate);
+};
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFICATION_DELEGATE_H_
diff --git a/chromium/ui/message_center/notification_delegate_unittest.cc b/chromium/ui/message_center/public/cpp/notification_delegate_unittest.cc
index c45ee0ba9ff..09874d1ceeb 100644
--- a/chromium/ui/message_center/notification_delegate_unittest.cc
+++ b/chromium/ui/message_center/public/cpp/notification_delegate_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/message_center/notification_delegate.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
#include "base/bind.h"
#include "base/callback.h"
diff --git a/chromium/ui/message_center/public/cpp/notification_types.h b/chromium/ui/message_center/public/cpp/notification_types.h
new file mode 100644
index 00000000000..1ab3876b7e6
--- /dev/null
+++ b/chromium/ui/message_center/public/cpp/notification_types.h
@@ -0,0 +1,39 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFICATION_TYPES_H_
+#define UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFICATION_TYPES_H_
+
+namespace message_center {
+
+// Notification types. Note that the values in this enumeration are being
+// recoded in a histogram, updates should not change the entries' values.
+enum NotificationType {
+ NOTIFICATION_TYPE_SIMPLE = 0,
+ NOTIFICATION_TYPE_BASE_FORMAT = 1,
+ NOTIFICATION_TYPE_IMAGE = 2,
+ NOTIFICATION_TYPE_MULTIPLE = 3,
+ NOTIFICATION_TYPE_PROGRESS = 4, // Notification with progress bar.
+ NOTIFICATION_TYPE_CUSTOM = 5,
+
+ // Add new values before this line.
+ NOTIFICATION_TYPE_LAST = NOTIFICATION_TYPE_CUSTOM
+};
+
+enum NotificationPriority {
+ MIN_PRIORITY = -2,
+ LOW_PRIORITY = -1,
+ DEFAULT_PRIORITY = 0,
+ HIGH_PRIORITY = 1,
+ MAX_PRIORITY = 2,
+
+ // Top priority for system-level notifications.. This can't be set from
+ // kPriorityKey, instead you have to call SetSystemPriority() of
+ // Notification object.
+ SYSTEM_PRIORITY = 3,
+};
+
+} // namespace message_center
+
+#endif // UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFICATION_TYPES_H_
diff --git a/chromium/ui/message_center/notifier_id.cc b/chromium/ui/message_center/public/cpp/notifier_id.cc
index 6bf32a3352f..c25aaeb47b1 100644
--- a/chromium/ui/message_center/notifier_id.cc
+++ b/chromium/ui/message_center/public/cpp/notifier_id.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/message_center/notifier_id.h"
+#include "ui/message_center/public/cpp/notifier_id.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
diff --git a/chromium/ui/message_center/notifier_id.h b/chromium/ui/message_center/public/cpp/notifier_id.h
index ac11acd0f48..720d3a74655 100644
--- a/chromium/ui/message_center/notifier_id.h
+++ b/chromium/ui/message_center/public/cpp/notifier_id.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_MESSAGE_CENTER_NOTIFIER_ID_H_
-#define UI_MESSAGE_CENTER_NOTIFIER_ID_H_
+#ifndef UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFIER_ID_H_
+#define UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFIER_ID_H_
#include <stddef.h>
@@ -13,15 +13,14 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "ui/gfx/image/image.h"
-#include "ui/message_center/message_center_export.h"
+#include "ui/message_center/public/cpp/message_center_public_export.h"
#include "url/gurl.h"
namespace message_center {
// A struct that identifies the source of notifications. For example, a web page
// might send multiple notifications but they'd all have the same NotifierId.
-// TODO(estade): move to public directory.
-struct MESSAGE_CENTER_EXPORT NotifierId {
+struct MESSAGE_CENTER_PUBLIC_EXPORT NotifierId {
// This enum is being used for histogram reporting and the elements should not
// be re-ordered.
enum NotifierType : int {
@@ -62,4 +61,4 @@ struct MESSAGE_CENTER_EXPORT NotifierId {
} // namespace message_center
-#endif // UI_MESSAGE_CENTER_NOTIFIER_ID_H_
+#endif // UI_MESSAGE_CENTER_PUBLIC_CPP_NOTIFIER_ID_H_
diff --git a/chromium/ui/message_center/mojo/BUILD.gn b/chromium/ui/message_center/public/mojo/BUILD.gn
index b28d9663823..d6aaf8314fe 100644
--- a/chromium/ui/message_center/mojo/BUILD.gn
+++ b/chromium/ui/message_center/public/mojo/BUILD.gn
@@ -13,7 +13,7 @@ mojom("mojo") {
public_deps = [
"//mojo/common:common_custom_types",
"//ui/gfx/image/mojo:interfaces",
- "//url/mojo:url_mojom_gurl",
+ "//url/mojom:url_mojom_gurl",
]
}
@@ -43,7 +43,7 @@ source_set("struct_traits") {
"//mojo/public/cpp/bindings",
"//ui/gfx",
"//ui/gfx/image/mojo:struct_traits",
- "//ui/message_center",
- "//url/mojo:url_mojom_gurl",
+ "//ui/message_center/public/cpp",
+ "//url/mojom:url_mojom_gurl",
]
}
diff --git a/chromium/ui/message_center/mojo/DEPS b/chromium/ui/message_center/public/mojo/DEPS
index 6cfa565faca..6cfa565faca 100644
--- a/chromium/ui/message_center/mojo/DEPS
+++ b/chromium/ui/message_center/public/mojo/DEPS
diff --git a/chromium/ui/message_center/mojo/OWNERS b/chromium/ui/message_center/public/mojo/OWNERS
index fae57c3c2c5..fae57c3c2c5 100644
--- a/chromium/ui/message_center/mojo/OWNERS
+++ b/chromium/ui/message_center/public/mojo/OWNERS
diff --git a/chromium/ui/message_center/public/mojo/notification.mojom b/chromium/ui/message_center/public/mojo/notification.mojom
new file mode 100644
index 00000000000..1b1b4ba3cd2
--- /dev/null
+++ b/chromium/ui/message_center/public/mojo/notification.mojom
@@ -0,0 +1,93 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module message_center.mojom;
+
+import "mojo/common/time.mojom";
+import "mojo/public/mojom/base/string16.mojom";
+import "ui/gfx/image/mojo/image.mojom";
+import "ui/message_center/public/mojo/notifier_id.mojom";
+import "url/mojom/url.mojom";
+
+// Matches message_center::NotificationType.
+enum NotificationType {
+ SIMPLE = 0,
+ BASE_FORMAT = 1,
+ IMAGE = 2,
+ MULTIPLE = 3,
+ PROGRESS = 4,
+ CUSTOM = 5,
+};
+
+// Matches message_center::SettingsButtonHandler.
+enum SettingsButtonHandler {
+ NONE = 0,
+ INLINE = 1,
+ DELEGATE = 2,
+};
+
+// Matches message_center::FullscreenVisibility.
+enum FullscreenVisibility {
+ NONE= 0,
+ OVER_USER = 1,
+};
+
+// The fields and their meanings match message_center::NotificationItem.
+struct NotificationItem {
+ mojo_base.mojom.String16 title;
+ mojo_base.mojom.String16 message;
+};
+
+// The fields and their meanings match message_center::ButtonInfo.
+struct ButtonInfo {
+ mojo_base.mojom.String16 title;
+ gfx.mojom.ImageSkia? icon;
+ mojo_base.mojom.String16? placeholder;
+};
+
+// These fields and their meanings are identical to those in
+// message_center::RichNotificationData.
+struct RichNotificationData {
+ int32 priority;
+ bool never_time_out;
+ mojo.common.mojom.Time timestamp;
+ // |context_message| intentionally omitted. See https://crbug.com/797084
+ gfx.mojom.ImageSkia? image;
+ gfx.mojom.ImageSkia? small_image;
+ array<NotificationItem> items;
+ int32 progress;
+ mojo_base.mojom.String16 progress_status;
+ array<ButtonInfo> buttons;
+ bool should_make_spoken_feedback_for_popup_updates;
+ bool clickable;
+ bool pinned;
+ // |vibration_pattern| intentionally omitted
+ // |renotify| intentionally omitted
+ // |silent| intentionally omitted
+ mojo_base.mojom.String16 accessible_name;
+ string vector_small_image_id;
+ uint32 accent_color;
+ SettingsButtonHandler settings_button_handler;
+ FullscreenVisibility fullscreen_visibility;
+};
+
+struct Notification {
+ NotificationType type;
+
+ // TODO(mhashmi): Server-side code (in Ash) needs to make sure this id won't
+ // collide with ids from different clients
+ string id;
+
+ mojo_base.mojom.String16 title;
+ mojo_base.mojom.String16 message;
+ gfx.mojom.ImageSkia? icon;
+ mojo_base.mojom.String16 display_source;
+ url.mojom.Url origin_url;
+ NotifierId notifier_id;
+ RichNotificationData optional_fields;
+ // |serial_number_| intentionally omitted.
+ // |shown_as_popup_| intentionally omitted.
+ // |is_read_| intentionally omitted.
+ // |delegate_| intentionally omitted.
+};
diff --git a/chromium/ui/message_center/mojo/notification.typemap b/chromium/ui/message_center/public/mojo/notification.typemap
index 1e613e5e66d..c56dfa79be4 100644
--- a/chromium/ui/message_center/mojo/notification.typemap
+++ b/chromium/ui/message_center/public/mojo/notification.typemap
@@ -2,14 +2,17 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-mojom = "//ui/message_center/mojo/notification.mojom"
-public_headers = [ "//ui/message_center/notification.h" ]
-traits_headers = [ "//ui/message_center/mojo/notification_struct_traits.h" ]
+mojom = "//ui/message_center/public/mojo/notification.mojom"
+public_headers = [ "//ui/message_center/public/cpp/notification.h" ]
+traits_headers =
+ [ "//ui/message_center/public/mojo/notification_struct_traits.h" ]
deps = [
"//ui/gfx/image/mojo:struct_traits",
- "//ui/message_center/mojo:struct_traits",
+ "//ui/message_center/public/mojo:struct_traits",
]
type_mappings = [
+ "message_center.mojom.NotificationItem=message_center::NotificationItem",
+ "message_center.mojom.ButtonInfo=message_center::ButtonInfo",
"message_center.mojom.RichNotificationData=message_center::RichNotificationData",
"message_center.mojom.NotificationType=message_center::NotificationType",
"message_center.mojom.Notification=message_center::Notification",
diff --git a/chromium/ui/message_center/public/mojo/notification_struct_traits.cc b/chromium/ui/message_center/public/mojo/notification_struct_traits.cc
new file mode 100644
index 00000000000..35b84fdf5e0
--- /dev/null
+++ b/chromium/ui/message_center/public/mojo/notification_struct_traits.cc
@@ -0,0 +1,268 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/message_center/public/mojo/notification_struct_traits.h"
+
+#include "mojo/common/time_struct_traits.h"
+#include "mojo/public/cpp/base/string16_mojom_traits.h"
+#include "ui/gfx/image/mojo/image_skia_struct_traits.h"
+#include "ui/message_center/public/mojo/notifier_id_struct_traits.h"
+#include "url/mojom/url_gurl_mojom_traits.h"
+
+namespace mojo {
+
+using message_center::mojom::NotificationDataView;
+using message_center::mojom::RichNotificationDataDataView;
+using message_center::NotificationItem;
+using message_center::ButtonInfo;
+using message_center::Notification;
+using message_center::RichNotificationData;
+using NotificationItemStructTraits =
+ StructTraits<message_center::mojom::NotificationItemDataView,
+ NotificationItem>;
+using ButtonInfoStructTraits =
+ StructTraits<message_center::mojom::ButtonInfoDataView, ButtonInfo>;
+using RichNotificationDataStructTraits =
+ StructTraits<RichNotificationDataDataView, RichNotificationData>;
+using NotificationStructTraits =
+ StructTraits<NotificationDataView, Notification>;
+
+// static
+bool NotificationItemStructTraits::Read(
+ message_center::mojom::NotificationItemDataView data,
+ message_center::NotificationItem* out) {
+ return data.ReadTitle(&out->title) && data.ReadMessage(&out->message);
+}
+
+// static
+gfx::ImageSkia ButtonInfoStructTraits::icon(
+ const message_center::ButtonInfo& b) {
+ return b.icon.AsImageSkia();
+}
+
+// static
+bool ButtonInfoStructTraits::Read(
+ message_center::mojom::ButtonInfoDataView data,
+ ButtonInfo* out) {
+ gfx::ImageSkia icon;
+ if (!data.ReadIcon(&icon))
+ return false;
+ out->icon = gfx::Image(icon);
+ return data.ReadTitle(&out->title) && data.ReadPlaceholder(&out->placeholder);
+}
+
+// static
+int RichNotificationDataStructTraits::priority(const RichNotificationData& r) {
+ return r.priority;
+}
+
+// static
+bool RichNotificationDataStructTraits::never_time_out(
+ const RichNotificationData& r) {
+ return r.never_timeout;
+}
+
+// static
+const base::Time& RichNotificationDataStructTraits::timestamp(
+ const RichNotificationData& r) {
+ return r.timestamp;
+}
+
+// static
+gfx::ImageSkia RichNotificationDataStructTraits::image(
+ const RichNotificationData& r) {
+ return r.image.AsImageSkia();
+}
+
+// static
+gfx::ImageSkia RichNotificationDataStructTraits::small_image(
+ const RichNotificationData& r) {
+ return r.small_image.AsImageSkia();
+}
+
+// static
+const std::vector<NotificationItem>& RichNotificationDataStructTraits::items(
+ const RichNotificationData& r) {
+ return r.items;
+}
+
+// static
+int RichNotificationDataStructTraits::progress(const RichNotificationData& r) {
+ return r.progress;
+}
+
+// static
+const base::string16& RichNotificationDataStructTraits::progress_status(
+ const RichNotificationData& r) {
+ return r.progress_status;
+}
+
+// static
+const std::vector<ButtonInfo>& RichNotificationDataStructTraits::buttons(
+ const RichNotificationData& r) {
+ return r.buttons;
+}
+
+// static
+bool RichNotificationDataStructTraits::
+ should_make_spoken_feedback_for_popup_updates(
+ const RichNotificationData& r) {
+ return r.should_make_spoken_feedback_for_popup_updates;
+}
+
+// static
+bool RichNotificationDataStructTraits::clickable(
+ const RichNotificationData& r) {
+ return r.clickable;
+}
+
+// static
+bool RichNotificationDataStructTraits::pinned(const RichNotificationData& r) {
+ return r.pinned;
+}
+
+// static
+const base::string16& RichNotificationDataStructTraits::accessible_name(
+ const RichNotificationData& r) {
+ return r.accessible_name;
+}
+
+// static
+std::string RichNotificationDataStructTraits::vector_small_image_id(
+ const message_center::RichNotificationData& r) {
+ if (r.vector_small_image && r.vector_small_image->name)
+ return r.vector_small_image->name;
+ return std::string();
+}
+
+// static
+SkColor RichNotificationDataStructTraits::accent_color(
+ const RichNotificationData& r) {
+ return r.accent_color;
+}
+
+// static
+message_center::SettingsButtonHandler
+RichNotificationDataStructTraits::settings_button_handler(
+ const RichNotificationData& r) {
+ return r.settings_button_handler;
+}
+
+// static
+message_center::FullscreenVisibility
+RichNotificationDataStructTraits::fullscreen_visibility(
+ const RichNotificationData& r) {
+ return r.fullscreen_visibility;
+}
+
+// static
+bool RichNotificationDataStructTraits::Read(RichNotificationDataDataView data,
+ RichNotificationData* out) {
+ out->priority = data.priority();
+ out->never_timeout = data.never_time_out();
+ gfx::ImageSkia image, small_image;
+ if (!data.ReadImage(&image))
+ return false;
+ out->image = gfx::Image(image);
+ if (!data.ReadSmallImage(&small_image))
+ return false;
+ out->small_image = gfx::Image(small_image);
+ out->progress = data.progress();
+ out->should_make_spoken_feedback_for_popup_updates =
+ data.should_make_spoken_feedback_for_popup_updates();
+ out->clickable = data.clickable();
+ out->pinned = data.pinned();
+
+ // Look up the vector icon by ID. This will only work if RegisterVectorIcon
+ // has been called with an appropriate icon.
+ std::string icon_id;
+ if (data.ReadVectorSmallImageId(&icon_id) && !icon_id.empty()) {
+ out->vector_small_image = message_center::GetRegisteredVectorIcon(icon_id);
+ if (!out->vector_small_image)
+ LOG(ERROR) << "Couldn't find icon: " + icon_id;
+ }
+
+ out->accent_color = data.accent_color();
+ return data.ReadTimestamp(&out->timestamp) && data.ReadItems(&out->items) &&
+ data.ReadButtons(&out->buttons) &&
+ data.ReadProgressStatus(&out->progress_status) &&
+ data.ReadAccessibleName(&out->accessible_name) &&
+ EnumTraits<message_center::mojom::SettingsButtonHandler,
+ message_center::SettingsButtonHandler>::
+ FromMojom(data.settings_button_handler(),
+ &out->settings_button_handler) &&
+ EnumTraits<message_center::mojom::FullscreenVisibility,
+ message_center::FullscreenVisibility>::
+ FromMojom(data.fullscreen_visibility(),
+ &out->fullscreen_visibility);
+}
+
+// static
+message_center::NotificationType NotificationStructTraits::type(
+ const Notification& n) {
+ return n.type();
+}
+
+// static
+const std::string& NotificationStructTraits::id(const Notification& n) {
+ return n.id();
+}
+
+// static
+const base::string16& NotificationStructTraits::title(const Notification& n) {
+ return n.title();
+}
+
+// static
+const base::string16& NotificationStructTraits::message(const Notification& n) {
+ return n.message();
+}
+
+// static
+gfx::ImageSkia NotificationStructTraits::icon(const Notification& n) {
+ return n.icon().AsImageSkia();
+}
+
+// static
+const base::string16& NotificationStructTraits::display_source(
+ const Notification& n) {
+ return n.display_source();
+}
+
+// static
+const GURL& NotificationStructTraits::origin_url(const Notification& n) {
+ return n.origin_url();
+}
+
+// static
+const message_center::NotifierId& NotificationStructTraits::notifier_id(
+ const Notification& n) {
+ return n.notifier_id();
+}
+
+// static
+const RichNotificationData& NotificationStructTraits::optional_fields(
+ const Notification& n) {
+ return n.rich_notification_data();
+}
+
+// static
+bool NotificationStructTraits::Read(NotificationDataView data,
+ Notification* out) {
+ gfx::ImageSkia icon;
+ if (!data.ReadIcon(&icon))
+ return false;
+ out->set_icon(gfx::Image(icon));
+ return EnumTraits<message_center::mojom::NotificationType,
+ message_center::NotificationType>::FromMojom(data.type(),
+ &out->type_) &&
+ data.ReadId(&out->id_) && data.ReadTitle(&out->title_) &&
+ data.ReadMessage(&out->message_) &&
+ data.ReadDisplaySource(&out->display_source_) &&
+ data.ReadOriginUrl(&out->origin_url_) &&
+ data.ReadNotifierId(&out->notifier_id_) &&
+ data.ReadOptionalFields(&out->optional_fields_);
+}
+
+} // namespace mojo
diff --git a/chromium/ui/message_center/public/mojo/notification_struct_traits.h b/chromium/ui/message_center/public/mojo/notification_struct_traits.h
new file mode 100644
index 00000000000..e97e4a6c504
--- /dev/null
+++ b/chromium/ui/message_center/public/mojo/notification_struct_traits.h
@@ -0,0 +1,215 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_MESSAGE_CENTER_PUBLIC_MOJO_NOTIFICATION_STRUCT_TRAITS_H_
+#define UI_MESSAGE_CENTER_PUBLIC_MOJO_NOTIFICATION_STRUCT_TRAITS_H_
+
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/mojo/notification.mojom-shared.h"
+
+namespace mojo {
+
+template <>
+struct EnumTraits<message_center::mojom::NotificationType,
+ message_center::NotificationType> {
+ static message_center::mojom::NotificationType ToMojom(
+ message_center::NotificationType type) {
+ switch (type) {
+ case message_center::NOTIFICATION_TYPE_SIMPLE:
+ return message_center::mojom::NotificationType::SIMPLE;
+ case message_center::NOTIFICATION_TYPE_BASE_FORMAT:
+ return message_center::mojom::NotificationType::BASE_FORMAT;
+ case message_center::NOTIFICATION_TYPE_IMAGE:
+ return message_center::mojom::NotificationType::IMAGE;
+ case message_center::NOTIFICATION_TYPE_MULTIPLE:
+ return message_center::mojom::NotificationType::MULTIPLE;
+ case message_center::NOTIFICATION_TYPE_PROGRESS:
+ return message_center::mojom::NotificationType::PROGRESS;
+ case message_center::NOTIFICATION_TYPE_CUSTOM:
+ return message_center::mojom::NotificationType::CUSTOM;
+ }
+ NOTREACHED();
+ return message_center::mojom::NotificationType::SIMPLE;
+ }
+
+ static bool FromMojom(message_center::mojom::NotificationType input,
+ message_center::NotificationType* out) {
+ switch (input) {
+ case message_center::mojom::NotificationType::SIMPLE:
+ *out = message_center::NOTIFICATION_TYPE_SIMPLE;
+ return true;
+ case message_center::mojom::NotificationType::BASE_FORMAT:
+ *out = message_center::NOTIFICATION_TYPE_BASE_FORMAT;
+ return true;
+ case message_center::mojom::NotificationType::IMAGE:
+ *out = message_center::NOTIFICATION_TYPE_IMAGE;
+ return true;
+ case message_center::mojom::NotificationType::MULTIPLE:
+ *out = message_center::NOTIFICATION_TYPE_MULTIPLE;
+ return true;
+ case message_center::mojom::NotificationType::PROGRESS:
+ *out = message_center::NOTIFICATION_TYPE_PROGRESS;
+ return true;
+ case message_center::mojom::NotificationType::CUSTOM:
+ *out = message_center::NOTIFICATION_TYPE_CUSTOM;
+ return true;
+ }
+ NOTREACHED();
+ return false;
+ }
+};
+
+template <>
+struct EnumTraits<message_center::mojom::SettingsButtonHandler,
+ message_center::SettingsButtonHandler> {
+ static message_center::mojom::SettingsButtonHandler ToMojom(
+ message_center::SettingsButtonHandler type) {
+ switch (type) {
+ case message_center::SettingsButtonHandler::NONE:
+ return message_center::mojom::SettingsButtonHandler::NONE;
+ case message_center::SettingsButtonHandler::INLINE:
+ return message_center::mojom::SettingsButtonHandler::INLINE;
+ case message_center::SettingsButtonHandler::DELEGATE:
+ return message_center::mojom::SettingsButtonHandler::DELEGATE;
+ }
+ NOTREACHED();
+ return message_center::mojom::SettingsButtonHandler::NONE;
+ }
+
+ static bool FromMojom(message_center::mojom::SettingsButtonHandler input,
+ message_center::SettingsButtonHandler* out) {
+ switch (input) {
+ case message_center::mojom::SettingsButtonHandler::NONE:
+ *out = message_center::SettingsButtonHandler::NONE;
+ return true;
+ case message_center::mojom::SettingsButtonHandler::INLINE:
+ *out = message_center::SettingsButtonHandler::INLINE;
+ return true;
+ case message_center::mojom::SettingsButtonHandler::DELEGATE:
+ *out = message_center::SettingsButtonHandler::DELEGATE;
+ return true;
+ }
+ NOTREACHED();
+ return false;
+ }
+};
+
+template <>
+struct EnumTraits<message_center::mojom::FullscreenVisibility,
+ message_center::FullscreenVisibility> {
+ static message_center::mojom::FullscreenVisibility ToMojom(
+ message_center::FullscreenVisibility type) {
+ switch (type) {
+ case message_center::FullscreenVisibility::NONE:
+ return message_center::mojom::FullscreenVisibility::NONE;
+ case message_center::FullscreenVisibility::OVER_USER:
+ return message_center::mojom::FullscreenVisibility::OVER_USER;
+ }
+ NOTREACHED();
+ return message_center::mojom::FullscreenVisibility::NONE;
+ }
+
+ static bool FromMojom(message_center::mojom::FullscreenVisibility input,
+ message_center::FullscreenVisibility* out) {
+ switch (input) {
+ case message_center::mojom::FullscreenVisibility::NONE:
+ *out = message_center::FullscreenVisibility::NONE;
+ return true;
+ case message_center::mojom::FullscreenVisibility::OVER_USER:
+ *out = message_center::FullscreenVisibility::OVER_USER;
+ return true;
+ }
+ NOTREACHED();
+ return false;
+ }
+};
+
+template <>
+struct StructTraits<message_center::mojom::NotificationItemDataView,
+ message_center::NotificationItem> {
+ static const base::string16& title(
+ const message_center::NotificationItem& n) {
+ return n.title;
+ }
+ static const base::string16& message(
+ const message_center::NotificationItem& n) {
+ return n.message;
+ }
+ static bool Read(message_center::mojom::NotificationItemDataView data,
+ message_center::NotificationItem* out);
+};
+
+template <>
+struct StructTraits<message_center::mojom::ButtonInfoDataView,
+ message_center::ButtonInfo> {
+ static const base::string16& title(const message_center::ButtonInfo& b) {
+ return b.title;
+ }
+ static gfx::ImageSkia icon(const message_center::ButtonInfo& b);
+ static const base::Optional<base::string16>& placeholder(
+ const message_center::ButtonInfo& b) {
+ return b.placeholder;
+ }
+ static bool Read(message_center::mojom::ButtonInfoDataView data,
+ message_center::ButtonInfo* out);
+};
+
+template <>
+struct StructTraits<message_center::mojom::RichNotificationDataDataView,
+ message_center::RichNotificationData> {
+ static int priority(const message_center::RichNotificationData& r);
+ static bool never_time_out(const message_center::RichNotificationData& r);
+ static const base::Time& timestamp(
+ const message_center::RichNotificationData& r);
+ static gfx::ImageSkia image(const message_center::RichNotificationData& r);
+ static gfx::ImageSkia small_image(
+ const message_center::RichNotificationData& r);
+ static const std::vector<message_center::NotificationItem>& items(
+ const message_center::RichNotificationData& r);
+ static int progress(const message_center::RichNotificationData& r);
+ static const base::string16& progress_status(
+ const message_center::RichNotificationData& r);
+ static const std::vector<message_center::ButtonInfo>& buttons(
+ const message_center::RichNotificationData& r);
+ static bool should_make_spoken_feedback_for_popup_updates(
+ const message_center::RichNotificationData& r);
+ static bool clickable(const message_center::RichNotificationData& r);
+ static bool pinned(const message_center::RichNotificationData& r);
+ static const base::string16& accessible_name(
+ const message_center::RichNotificationData& r);
+ static std::string vector_small_image_id(
+ const message_center::RichNotificationData& r);
+ static SkColor accent_color(const message_center::RichNotificationData& r);
+ static message_center::SettingsButtonHandler settings_button_handler(
+ const message_center::RichNotificationData& r);
+ static message_center::FullscreenVisibility fullscreen_visibility(
+ const message_center::RichNotificationData& r);
+ static bool Read(message_center::mojom::RichNotificationDataDataView data,
+ message_center::RichNotificationData* out);
+};
+
+template <>
+struct StructTraits<message_center::mojom::NotificationDataView,
+ message_center::Notification> {
+ static message_center::NotificationType type(
+ const message_center::Notification& n);
+ static const std::string& id(const message_center::Notification& n);
+ static const base::string16& title(const message_center::Notification& n);
+ static const base::string16& message(const message_center::Notification& n);
+ static gfx::ImageSkia icon(const message_center::Notification& n);
+ static const base::string16& display_source(
+ const message_center::Notification& n);
+ static const GURL& origin_url(const message_center::Notification& n);
+ static const message_center::NotifierId& notifier_id(
+ const message_center::Notification& n);
+ static const message_center::RichNotificationData& optional_fields(
+ const message_center::Notification& n);
+ static bool Read(message_center::mojom::NotificationDataView data,
+ message_center::Notification* out);
+};
+
+} // namespace mojo
+
+#endif // UI_MESSAGE_CENTER_PUBLIC_MOJO_NOTIFICATION_STRUCT_TRAITS_H_
diff --git a/chromium/ui/message_center/mojo/notifier_id.mojom b/chromium/ui/message_center/public/mojo/notifier_id.mojom
index cf7a9a6167f..0227ad3f250 100644
--- a/chromium/ui/message_center/mojo/notifier_id.mojom
+++ b/chromium/ui/message_center/public/mojo/notifier_id.mojom
@@ -4,16 +4,16 @@
module message_center.mojom;
-import "mojo/common/string16.mojom";
-import "url/mojo/url.mojom";
+import "mojo/public/mojom/base/string16.mojom";
+import "url/mojom/url.mojom";
// Equivalent to message_center::NotifierId::NotifierType. Used in UMA, so it
// should not be reordered.
enum NotifierType {
- APPLICATION,
- ARC_APPLICATION,
- WEB_PAGE,
- SYSTEM_COMPONENT,
+ APPLICATION = 0,
+ ARC_APPLICATION = 1,
+ WEB_PAGE = 2,
+ SYSTEM_COMPONENT = 3,
SIZE,
};
diff --git a/chromium/ui/message_center/mojo/notifier_id.typemap b/chromium/ui/message_center/public/mojo/notifier_id.typemap
index 00a923cd955..743319ce232 100644
--- a/chromium/ui/message_center/mojo/notifier_id.typemap
+++ b/chromium/ui/message_center/public/mojo/notifier_id.typemap
@@ -2,11 +2,12 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-mojom = "//ui/message_center/mojo/notifier_id.mojom"
-public_headers = [ "//ui/message_center/notifier_id.h" ]
-traits_headers = [ "//ui/message_center/mojo/notifier_id_struct_traits.h" ]
+mojom = "//ui/message_center/public/mojo/notifier_id.mojom"
+public_headers = [ "//ui/message_center/public/cpp/notifier_id.h" ]
+traits_headers =
+ [ "//ui/message_center/public/mojo/notifier_id_struct_traits.h" ]
deps = [
- "//ui/message_center/mojo:struct_traits",
+ "//ui/message_center/public/mojo:struct_traits",
]
type_mappings = [
"message_center.mojom.NotifierId=message_center::NotifierId",
diff --git a/chromium/ui/message_center/mojo/notifier_id_struct_traits.cc b/chromium/ui/message_center/public/mojo/notifier_id_struct_traits.cc
index 424df76756c..d2b9f6b3e64 100644
--- a/chromium/ui/message_center/mojo/notifier_id_struct_traits.cc
+++ b/chromium/ui/message_center/public/mojo/notifier_id_struct_traits.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/message_center/mojo/notifier_id_struct_traits.h"
+#include "ui/message_center/public/mojo/notifier_id_struct_traits.h"
#include "mojo/common/common_custom_types_struct_traits.h"
-#include "url/mojo/url_gurl_struct_traits.h"
+#include "url/mojom/url_gurl_mojom_traits.h"
namespace mojo {
diff --git a/chromium/ui/message_center/mojo/notifier_id_struct_traits.h b/chromium/ui/message_center/public/mojo/notifier_id_struct_traits.h
index bf55f0c266c..fefc0d91f17 100644
--- a/chromium/ui/message_center/mojo/notifier_id_struct_traits.h
+++ b/chromium/ui/message_center/public/mojo/notifier_id_struct_traits.h
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_MESSAGE_CENTER_NOTIFIER_ID_STRUCT_TRAITS_H_
-#define UI_MESSAGE_CENTER_NOTIFIER_ID_STRUCT_TRAITS_H_
+#ifndef UI_MESSAGE_CENTER_PUBLIC_MOJO_NOTIFIER_ID_STRUCT_TRAITS_H_
+#define UI_MESSAGE_CENTER_PUBLIC_MOJO_NOTIFIER_ID_STRUCT_TRAITS_H_
-#include "ui/message_center/mojo/notifier_id.mojom-shared.h"
-#include "ui/message_center/notifier_id.h"
+#include "ui/message_center/public/cpp/notifier_id.h"
+#include "ui/message_center/public/mojo/notifier_id.mojom-shared.h"
namespace mojo {
@@ -68,4 +68,4 @@ struct StructTraits<message_center::mojom::NotifierIdDataView,
} // namespace mojo
-#endif // UI_MESSAGE_CENTER_NOTIFIER_ID_STRUCT_TRAITS_H_
+#endif // UI_MESSAGE_CENTER_PUBLIC_MOJO_NOTIFIER_ID_STRUCT_TRAITS_H_
diff --git a/chromium/ui/message_center/mojo/struct_traits_unittest.cc b/chromium/ui/message_center/public/mojo/struct_traits_unittest.cc
index 5ddbea3e1e3..59f0263524b 100644
--- a/chromium/ui/message_center/mojo/struct_traits_unittest.cc
+++ b/chromium/ui/message_center/public/mojo/struct_traits_unittest.cc
@@ -7,11 +7,12 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "mojo/public/cpp/bindings/binding_set.h"
+#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/image/image_unittest_util.h"
-#include "ui/message_center/mojo/traits_test_service.mojom.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notifier_id.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notifier_id.h"
+#include "ui/message_center/public/mojo/traits_test_service.mojom.h"
namespace message_center {
namespace {
@@ -36,6 +37,12 @@ class StructTraitsTest : public testing::Test, public mojom::TraitsTestService {
EXPECT_EQ(input.icon().Height(), output.icon().Height());
EXPECT_EQ(input.display_source(), output.display_source());
EXPECT_EQ(input.origin_url(), output.origin_url());
+ EXPECT_EQ(input.notifier_id(), output.notifier_id());
+ EXPECT_EQ(input.priority(), output.priority());
+ EXPECT_TRUE(gfx::test::AreImagesEqual(input.image(), output.image()));
+ EXPECT_TRUE(
+ gfx::test::AreImagesEqual(input.small_image(), output.small_image()));
+ EXPECT_EQ(input.timestamp(), output.timestamp());
EXPECT_EQ(input.progress(), output.progress());
EXPECT_EQ(input.progress_status(), output.progress_status());
EXPECT_EQ(input.rich_notification_data()
@@ -45,6 +52,9 @@ class StructTraitsTest : public testing::Test, public mojom::TraitsTestService {
EXPECT_EQ(input.clickable(), output.clickable());
EXPECT_EQ(input.accessible_name(), output.accessible_name());
EXPECT_EQ(input.accent_color(), output.accent_color());
+ EXPECT_EQ(input.should_show_settings_button(),
+ output.should_show_settings_button());
+ EXPECT_EQ(input.fullscreen_visibility(), output.fullscreen_visibility());
}
private:
@@ -71,8 +81,11 @@ TEST_F(StructTraitsTest, Notification) {
base::string16 display_source(base::ASCIIToUTF16("display_source"));
GURL origin_url("www.example.com");
NotifierId notifier_id(NotifierId::NotifierType::APPLICATION, id);
+ notifier_id.profile_id = "profile_id";
+ RichNotificationData optional_fields;
+ optional_fields.settings_button_handler = SettingsButtonHandler::INLINE;
Notification input(type, id, title, message, icon, display_source, origin_url,
- notifier_id, RichNotificationData(), nullptr);
+ notifier_id, optional_fields, nullptr);
mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy();
Notification output;
@@ -80,11 +93,15 @@ TEST_F(StructTraitsTest, Notification) {
Compare(input, output);
// Set some optional fields to non-default values and test again.
+ input.set_never_timeout(true);
input.set_type(NotificationType::NOTIFICATION_TYPE_PROGRESS);
input.set_progress(50);
input.set_progress_status(base::ASCIIToUTF16("progress text"));
input.set_clickable(!input.clickable());
+ input.set_image(gfx::test::CreateImage(48, 48));
+ input.set_small_image(gfx::test::CreateImage(16, 16));
input.set_accent_color(SK_ColorMAGENTA);
+ input.set_fullscreen_visibility(FullscreenVisibility::OVER_USER);
proxy->EchoNotification(input, &output);
Compare(input, output);
}
diff --git a/chromium/ui/message_center/mojo/traits_test_service.mojom b/chromium/ui/message_center/public/mojo/traits_test_service.mojom
index e5c96fe3eeb..bb1ed449928 100644
--- a/chromium/ui/message_center/mojo/traits_test_service.mojom
+++ b/chromium/ui/message_center/public/mojo/traits_test_service.mojom
@@ -4,7 +4,7 @@
module message_center.mojom;
-import "ui/message_center/mojo/notification.mojom";
+import "ui/message_center/public/mojo/notification.mojom";
// All functions on this interface echo their arguments to test StructTraits
// serialization and deserialization.
diff --git a/chromium/ui/message_center/mojo/typemaps.gni b/chromium/ui/message_center/public/mojo/typemaps.gni
index a7f5b3d481c..a215ae335f0 100644
--- a/chromium/ui/message_center/mojo/typemaps.gni
+++ b/chromium/ui/message_center/public/mojo/typemaps.gni
@@ -3,6 +3,6 @@
# found in the LICENSE file.
typemaps = [
- "//ui/message_center/mojo/notification.typemap",
- "//ui/message_center/mojo/notifier_id.typemap",
+ "//ui/message_center/public/mojo/notification.typemap",
+ "//ui/message_center/public/mojo/notifier_id.typemap",
]
diff --git a/chromium/ui/message_center/ui_controller.cc b/chromium/ui/message_center/ui_controller.cc
index 3fd67d1474d..997b24750f9 100644
--- a/chromium/ui/message_center/ui_controller.cc
+++ b/chromium/ui/message_center/ui_controller.cc
@@ -9,7 +9,6 @@
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/simple_menu_model.h"
@@ -42,20 +41,16 @@ bool UiController::ShowMessageCenterBubble(bool show_by_click) {
message_center_visible_ = delegate_->ShowMessageCenter(show_by_click);
if (message_center_visible_) {
- message_center_->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
+ message_center_->SetVisibility(VISIBILITY_MESSAGE_CENTER);
NotifyUiControllerChanged();
}
return message_center_visible_;
}
bool UiController::HideMessageCenterBubble() {
-#if defined(OS_CHROMEOS)
- // TODO(yoshiki): Move the message center bubble related logic to ash/.
- hide_empty_message_center_callback_.reset();
-#endif
-
if (!message_center_visible_)
return false;
+
delegate_->HideMessageCenter();
MarkMessageCenterHidden();
@@ -66,7 +61,7 @@ void UiController::MarkMessageCenterHidden() {
if (!message_center_visible_)
return;
message_center_visible_ = false;
- message_center_->SetVisibility(message_center::VISIBILITY_TRANSIENT);
+ message_center_->SetVisibility(VISIBILITY_TRANSIENT);
// Some notifications (like system ones) should appear as popups again
// after the message center is closed.
@@ -117,7 +112,7 @@ void UiController::ShowNotifierSettingsBubble() {
HidePopupBubbleInternal();
message_center_visible_ = delegate_->ShowNotifierSettings();
- message_center_->SetVisibility(message_center::VISIBILITY_SETTINGS);
+ message_center_->SetVisibility(VISIBILITY_SETTINGS);
NotifyUiControllerChanged();
}
@@ -166,26 +161,11 @@ void UiController::OnBlockingStateChanged(NotificationBlocker* blocker) {
}
void UiController::OnMessageCenterChanged() {
-#if defined(OS_CHROMEOS)
- // TODO(yoshiki): Move the message center bubble related logic to ash/.
if (message_center_visible_ && message_center_->NotificationCount() == 0) {
- if (hide_empty_message_center_callback_)
- return;
-
- hide_empty_message_center_callback_ =
- std::make_unique<base::CancelableClosure>(base::Bind(
- base::IgnoreResult(&UiController::HideMessageCenterBubble),
- base::Unretained(this)));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, hide_empty_message_center_callback_->callback());
+ HideMessageCenterBubble();
return;
}
- // Cancel the callback if necessary.
- if (hide_empty_message_center_callback_)
- hide_empty_message_center_callback_.reset();
-#endif
-
if (popups_visible_ && !message_center_->HasPopupNotifications())
HidePopupBubbleInternal();
else if (!popups_visible_ && message_center_->HasPopupNotifications())
diff --git a/chromium/ui/message_center/ui_controller.h b/chromium/ui/message_center/ui_controller.h
index bbe26caa972..582ad520d4e 100644
--- a/chromium/ui/message_center/ui_controller.h
+++ b/chromium/ui/message_center/ui_controller.h
@@ -5,13 +5,12 @@
#ifndef UI_MESSAGE_CENTER_UI_CONTROLLER_H_
#define UI_MESSAGE_CENTER_UI_CONTROLLER_H_
-#include "base/cancelable_callback.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "ui/message_center/message_center_export.h"
#include "ui/message_center/message_center_observer.h"
-#include "ui/message_center/notifier_id.h"
+#include "ui/message_center/public/cpp/notifier_id.h"
#include "ui/message_center/ui_delegate.h"
namespace message_center {
@@ -53,10 +52,8 @@ class MESSAGE_CENTER_EXPORT UiController : public MessageCenterObserver {
bool message_center_visible() { return message_center_visible_; }
bool popups_visible() { return popups_visible_; }
UiDelegate* delegate() { return delegate_; }
- const message_center::MessageCenter* message_center() const {
- return message_center_;
- }
- message_center::MessageCenter* message_center() { return message_center_; }
+ const MessageCenter* message_center() const { return message_center_; }
+ MessageCenter* message_center() { return message_center_; }
// Overridden from MessageCenterObserver:
void OnNotificationAdded(const std::string& notification_id) override;
@@ -77,15 +74,11 @@ class MESSAGE_CENTER_EXPORT UiController : public MessageCenterObserver {
void NotifyUiControllerChanged();
void HidePopupBubbleInternal();
- message_center::MessageCenter* message_center_;
+ MessageCenter* message_center_;
bool message_center_visible_ = false;
bool popups_visible_ = false;
UiDelegate* delegate_;
-#if defined(OS_CHROMEOS)
- std::unique_ptr<base::CancelableClosure> hide_empty_message_center_callback_;
-#endif
-
DISALLOW_COPY_AND_ASSIGN(UiController);
};
diff --git a/chromium/ui/message_center/ui_controller_unittest.cc b/chromium/ui/message_center/ui_controller_unittest.cc
index 75795f7277e..a7163fe6d46 100644
--- a/chromium/ui/message_center/ui_controller_unittest.cc
+++ b/chromium/ui/message_center/ui_controller_unittest.cc
@@ -11,15 +11,15 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/models/menu_model.h"
#include "ui/message_center/message_center.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_types.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_types.h"
using base::ASCIIToUTF16;
namespace message_center {
namespace {
-class TestNotificationDelegate : public message_center::NotificationDelegate {
+class TestNotificationDelegate : public NotificationDelegate {
public:
TestNotificationDelegate() = default;
@@ -78,13 +78,11 @@ class UiControllerTest : public testing::Test {
}
Notification* AddNotification(const std::string& id, NotifierId notifier_id) {
- std::unique_ptr<Notification> notification(
- new Notification(message_center::NOTIFICATION_TYPE_SIMPLE, id,
- ASCIIToUTF16("Test Web Notification"),
- ASCIIToUTF16("Notification message body."),
- gfx::Image(), ASCIIToUTF16("www.test.org"), GURL(),
- notifier_id, message_center::RichNotificationData(),
- new TestNotificationDelegate()));
+ std::unique_ptr<Notification> notification(new Notification(
+ NOTIFICATION_TYPE_SIMPLE, id, ASCIIToUTF16("Test Web Notification"),
+ ASCIIToUTF16("Notification message body."), gfx::Image(),
+ ASCIIToUTF16("www.test.org"), GURL(), notifier_id,
+ RichNotificationData(), new TestNotificationDelegate()));
Notification* notification_ptr = notification.get();
message_center_->AddNotification(std::move(notification));
return notification_ptr;
@@ -185,12 +183,11 @@ TEST_F(UiControllerTest, MessageCenterReopenPopupsForSystemPriority) {
ASSERT_FALSE(ui_controller_->message_center_visible());
std::unique_ptr<Notification> notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE,
- "MessageCenterReopnPopupsForSystemPriority",
+ NOTIFICATION_TYPE_SIMPLE, "MessageCenterReopnPopupsForSystemPriority",
ASCIIToUTF16("Test Web Notification"),
ASCIIToUTF16("Notification message body."), gfx::Image(),
ASCIIToUTF16("www.test.org"), GURL(), DummyNotifierId(),
- message_center::RichNotificationData(), NULL /* delegate */));
+ RichNotificationData(), NULL /* delegate */));
notification->SetSystemPriority();
message_center_->AddNotification(std::move(notification));
diff --git a/chromium/ui/message_center/vector_icons/OWNERS b/chromium/ui/message_center/vector_icons/OWNERS
new file mode 100644
index 00000000000..d7ec991d34a
--- /dev/null
+++ b/chromium/ui/message_center/vector_icons/OWNERS
@@ -0,0 +1 @@
+file://components/vector_icons/OWNERS
diff --git a/chromium/ui/message_center/vector_icons/notification_inline_reply.icon b/chromium/ui/message_center/vector_icons/notification_inline_reply.icon
new file mode 100644
index 00000000000..e12869934bf
--- /dev/null
+++ b/chromium/ui/message_center/vector_icons/notification_inline_reply.icon
@@ -0,0 +1,13 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+CANVAS_DIMENSIONS, 96,
+MOVE_TO, 10.04f, 82,
+LINE_TO, 86, 48,
+LINE_TO, 10.04f, 14,
+LINE_TO, 10, 40.44f,
+LINE_TO, 64.29f, 48,
+LINE_TO, 10, 55.56f,
+CLOSE,
+END \ No newline at end of file
diff --git a/chromium/ui/message_center/vector_icons/vector_icons.cc.template b/chromium/ui/message_center/vector_icons/vector_icons.cc.template
index 7a94527074b..7473cb40556 100644
--- a/chromium/ui/message_center/vector_icons/vector_icons.cc.template
+++ b/chromium/ui/message_center/vector_icons/vector_icons.cc.template
@@ -10,11 +10,7 @@
#include "base/logging.h"
#include "ui/gfx/vector_icon_types.h"
-#define PATH_ELEMENT_TEMPLATE(path_name, ...) \
-static constexpr gfx::PathElement path_name[] = {__VA_ARGS__};
-
-#define VECTOR_ICON_TEMPLATE(icon_name, path_name, path_name_1x) \
-const gfx::VectorIcon icon_name = { path_name , path_name_1x };
+#include "components/vector_icons/cc_macros.h"
namespace message_center {
diff --git a/chromium/ui/message_center/views/bounded_label.cc b/chromium/ui/message_center/views/bounded_label.cc
index 334cc34f830..01ad8a33463 100644
--- a/chromium/ui/message_center/views/bounded_label.cc
+++ b/chromium/ui/message_center/views/bounded_label.cc
@@ -278,9 +278,9 @@ BoundedLabel::BoundedLabel(const base::string16& text)
BoundedLabel::~BoundedLabel() {
}
-void BoundedLabel::SetColors(SkColor textColor, SkColor backgroundColor) {
- label_->SetEnabledColor(textColor);
- label_->SetBackgroundColor(backgroundColor);
+void BoundedLabel::SetColor(SkColor text_color) {
+ label_->SetEnabledColor(text_color);
+ label_->SetAutoColorReadabilityEnabled(false);
}
void BoundedLabel::SetLineHeight(int height) {
diff --git a/chromium/ui/message_center/views/bounded_label.h b/chromium/ui/message_center/views/bounded_label.h
index 1ae1a16f581..ff7aa7a4228 100644
--- a/chromium/ui/message_center/views/bounded_label.h
+++ b/chromium/ui/message_center/views/bounded_label.h
@@ -38,7 +38,7 @@ class MESSAGE_CENTER_EXPORT BoundedLabel : public views::View {
BoundedLabel(const base::string16& text);
~BoundedLabel() override;
- void SetColors(SkColor textColor, SkColor backgroundColor);
+ void SetColor(SkColor text_color);
void SetLineHeight(int height); // Pass in 0 for default height.
void SetLineLimit(int lines); // Pass in -1 for no limit.
void SetText(const base::string16& text); // Additionally clears caches.
diff --git a/chromium/ui/message_center/views/constants.h b/chromium/ui/message_center/views/constants.h
deleted file mode 100644
index 5ef550d405a..00000000000
--- a/chromium/ui/message_center/views/constants.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_MESSAGE_CENTER_VIEWS_CONSTANTS_H_
-#define UI_MESSAGE_CENTER_VIEWS_CONSTANTS_H_
-
-#include <stddef.h>
-
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/message_center/public/cpp/message_center_constants.h"
-
-namespace message_center {
-
-// The text background colors below are used only to keep
-// view::Label from modifying the text color and will not actually be drawn.
-// See view::Label's RecalculateColors() for details.
-const SkColor kRegularTextBackgroundColor = SK_ColorWHITE;
-const SkColor kDimTextBackgroundColor = SK_ColorWHITE;
-const SkColor kContextTextBackgroundColor = SK_ColorWHITE;
-
-const int kTextBottomPadding = 12;
-const int kItemTitleToMessagePadding = 3;
-const int kButtonVerticalPadding = 0;
-const int kButtonTitleTopPadding = 0;
-const int kNotificationSettingsPadding = 5;
-
-// Character limits: Displayed text will be subject to the line limits above,
-// but we also remove trailing characters from text to reduce processing cost.
-// Character limit = pixels per line * line limit / min. pixels per character.
-const int kMinPixelsPerTitleCharacter = 4;
-const size_t kMessageCharacterLimit =
- message_center::kNotificationWidth *
- message_center::kMessageExpandedLineLimit / 3;
-const size_t kContextMessageCharacterLimit =
- message_center::kNotificationWidth *
- message_center::kContextMessageLineLimit / 3;
-
-} // namespace message_center
-
-#endif // UI_MESSAGE_CENTER_VIEWS_CONSTANTS_H_
diff --git a/chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc b/chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc
index 56aa3b95cc6..e0d9364527c 100644
--- a/chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc
+++ b/chromium/ui/message_center/views/desktop_popup_alignment_delegate.cc
@@ -39,7 +39,7 @@ int DesktopPopupAlignmentDelegate::GetToastOriginX(
return work_area_.right() - kMarginBetweenPopups - toast_bounds.width();
}
-int DesktopPopupAlignmentDelegate::GetBaseLine() const {
+int DesktopPopupAlignmentDelegate::GetBaseline() const {
return IsTopDown() ? work_area_.y() + kMarginBetweenPopups
: work_area_.bottom() - kMarginBetweenPopups;
}
diff --git a/chromium/ui/message_center/views/desktop_popup_alignment_delegate.h b/chromium/ui/message_center/views/desktop_popup_alignment_delegate.h
index 93c05fc57cc..93fb52cfd54 100644
--- a/chromium/ui/message_center/views/desktop_popup_alignment_delegate.h
+++ b/chromium/ui/message_center/views/desktop_popup_alignment_delegate.h
@@ -33,7 +33,7 @@ class MESSAGE_CENTER_EXPORT DesktopPopupAlignmentDelegate
// Overridden from PopupAlignmentDelegate:
int GetToastOriginX(const gfx::Rect& toast_bounds) const override;
- int GetBaseLine() const override;
+ int GetBaseline() const override;
gfx::Rect GetWorkArea() const override;
bool IsTopDown() const override;
bool IsFromLeft() const override;
diff --git a/chromium/ui/message_center/views/message_popup_collection.cc b/chromium/ui/message_center/views/message_popup_collection.cc
index 45871e6e7e4..edd1bbdf3ad 100644
--- a/chromium/ui/message_center/views/message_popup_collection.cc
+++ b/chromium/ui/message_center/views/message_popup_collection.cc
@@ -7,19 +7,21 @@
#include <set>
#include "base/bind.h"
+#include "base/feature_list.h"
#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "base/memory/weak_ptr.h"
-#include "base/run_loop.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
-#include "ui/accessibility/ax_enums.h"
+#include "build/build_config.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/message_center/message_center.h"
-#include "ui/message_center/notification.h"
#include "ui/message_center/notification_list.h"
+#include "ui/message_center/public/cpp/features.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/ui_controller.h"
#include "ui/message_center/views/message_view.h"
#include "ui/message_center/views/message_view_context_menu_controller.h"
@@ -36,11 +38,6 @@
namespace message_center {
namespace {
-// Timeout between the last user-initiated close of the toast and the moment
-// when normal layout/update of the toast stack continues. If the last toast was
-// just closed, the timeout is shorter.
-const int kMouseExitedDeferTimeoutMs = 200;
-
// The margin between messages (and between the anchor unless
// first_item_has_no_margin was specified).
const int kToastMarginY = kMarginBetweenPopups;
@@ -55,11 +52,11 @@ MessagePopupCollection::MessagePopupCollection(
tray_(tray),
alignment_delegate_(alignment_delegate) {
DCHECK(message_center_);
- defer_timer_.reset(new base::OneShotTimer);
message_center_->AddObserver(this);
alignment_delegate_->set_collection(this);
#if !defined(OS_CHROMEOS)
- context_menu_controller_.reset(new MessageViewContextMenuController());
+ if (!base::FeatureList::IsEnabled(message_center::kNewStyleNotifications))
+ context_menu_controller_.reset(new MessageViewContextMenuController());
#endif
}
@@ -123,12 +120,37 @@ void MessagePopupCollection::UpdateWidgets() {
}
bool top_down = alignment_delegate_->IsTopDown();
- int base = GetBaseLine(toasts_.empty() ? NULL : toasts_.back());
+ int base = GetBaseline();
#if defined(OS_CHROMEOS)
bool is_primary_display =
alignment_delegate_->IsPrimaryDisplayForNotification();
#endif
+ // Check if the popups contain a new notification.
+ bool has_new_toasts = false;
+ for (auto* popup : popups) {
+ if (!FindToast(popup->id())) {
+ has_new_toasts = true;
+ break;
+ }
+ }
+
+ // If a new notification is found, collapse all existing notifications
+ // beforehand.
+ if (has_new_toasts) {
+ for (Toasts::const_iterator iter = toasts_.begin();
+ iter != toasts_.end();) {
+ // SetExpanded() may fire PreferredSizeChanged(), which may end up
+ // removing the toast in OnNotificationUpdated(). So we have to increment
+ // the iterator in a way that is safe even if the current iterator is
+ // invalidated during the loop.
+ MessageView* view = (*iter++)->message_view();
+ if (view->IsMouseHovered() || view->IsManuallyExpandedOrCollapsed())
+ continue;
+ view->SetExpanded(false);
+ }
+ }
+
// Iterate in the reverse order to keep the oldest toasts on screen. Newer
// items may be ignored if there are no room to place them.
for (NotificationList::PopupNotifications::const_reverse_iterator iter =
@@ -150,10 +172,6 @@ void MessagePopupCollection::UpdateWidgets() {
// Create top-level notification.
MessageView* view = MessageViewFactory::Create(notification, true);
observed_views_.Add(view);
-#if defined(OS_CHROMEOS)
- // Disable pinned feature since this is a popup.
- view->set_force_disable_pinned();
-#endif // defined(OS_CHROMEOS)
view->SetExpanded(true);
#if !defined(OS_CHROMEOS)
@@ -198,11 +216,11 @@ void MessagePopupCollection::UpdateWidgets() {
if (views::ViewsDelegate::GetInstance()) {
views::ViewsDelegate::GetInstance()->NotifyAccessibilityEvent(
- toast, ui::AX_EVENT_ALERT);
+ toast, ax::mojom::Event::kAlert);
}
- message_center_->DisplayedNotification(
- notification.id(), message_center::DISPLAY_SOURCE_POPUP);
+ message_center_->DisplayedNotification(notification.id(),
+ DISPLAY_SOURCE_POPUP);
}
}
@@ -212,9 +230,6 @@ void MessagePopupCollection::OnMouseEntered(ToastContentsView* toast_entered) {
latest_toast_entered_ = toast_entered;
PausePopupTimers();
-
- if (user_is_closing_toasts_by_clicking_)
- defer_timer_->Stop();
}
void MessagePopupCollection::OnMouseExited(ToastContentsView* toast_exited) {
@@ -224,15 +239,7 @@ void MessagePopupCollection::OnMouseExited(ToastContentsView* toast_exited) {
return;
latest_toast_entered_ = NULL;
- if (user_is_closing_toasts_by_clicking_) {
- defer_timer_->Start(
- FROM_HERE,
- base::TimeDelta::FromMilliseconds(kMouseExitedDeferTimeoutMs),
- this,
- &MessagePopupCollection::OnDeferTimerExpired);
- } else {
- RestartPopupTimers();
- }
+ RestartPopupTimers();
}
std::set<std::string> MessagePopupCollection::CloseAllWidgets() {
@@ -270,8 +277,8 @@ void MessagePopupCollection::RemoveToast(ToastContentsView* toast,
void MessagePopupCollection::RepositionWidgets() {
bool top_down = alignment_delegate_->IsTopDown();
- int base = GetBaseLine(NULL); // We don't want to position relative to last
- // toast - we want re-position.
+ // We don't want to position relative to last toast - we want re-position.
+ int base = alignment_delegate_->GetBaseline();
for (Toasts::const_iterator iter = toasts_.begin(); iter != toasts_.end();) {
Toasts::const_iterator curr = iter++;
@@ -299,60 +306,27 @@ void MessagePopupCollection::RepositionWidgets() {
}
}
-void MessagePopupCollection::RepositionWidgetsWithTarget() {
+int MessagePopupCollection::GetBaseline() const {
if (toasts_.empty())
- return;
+ return alignment_delegate_->GetBaseline();
- bool top_down = alignment_delegate_->IsTopDown();
-
- // Nothing to do if there are no widgets above target if bottom-aligned or no
- // widgets below target if top-aligned.
- if (top_down ? toasts_.back()->origin().y() < target_top_edge_
- : toasts_.back()->origin().y() > target_top_edge_)
- return;
-
- Toasts::reverse_iterator iter = toasts_.rbegin();
- for (; iter != toasts_.rend(); ++iter) {
- // We only reposition widgets above target if bottom-aligned or widgets
- // below target if top-aligned.
- if (top_down ? (*iter)->origin().y() < target_top_edge_
- : (*iter)->origin().y() > target_top_edge_)
- break;
- }
- --iter;
-
- // Slide length is the number of pixels the widgets should move so that their
- // bottom edge (top-edge if top-aligned) touches the target.
- int slide_length = std::abs(target_top_edge_ - (*iter)->origin().y());
- for (;; --iter) {
- gfx::Rect bounds((*iter)->bounds());
-
- // If top-aligned, shift widgets upwards by slide_length. If bottom-aligned,
- // shift them downwards by slide_length.
- if (top_down)
- bounds.set_y(bounds.y() - slide_length);
- else
- bounds.set_y(bounds.y() + slide_length);
- (*iter)->SetBoundsWithAnimation(bounds);
+ if (alignment_delegate_->IsTopDown())
+ return toasts_.back()->bounds().bottom() + kToastMarginY;
- if (iter == toasts_.rbegin())
- break;
- }
+ return toasts_.back()->origin().y() - kToastMarginY;
}
-int MessagePopupCollection::GetBaseLine(ToastContentsView* last_toast) const {
- if (!last_toast) {
- return alignment_delegate_->GetBaseLine();
- } else if (alignment_delegate_->IsTopDown()) {
- return toasts_.back()->bounds().bottom() + kToastMarginY;
- } else {
- return toasts_.back()->origin().y() - kToastMarginY;
- }
+int MessagePopupCollection::GetBaselineForToast(
+ ToastContentsView* toast) const {
+ if (alignment_delegate_->IsTopDown())
+ return toast->bounds().y();
+ else
+ return toast->bounds().bottom();
}
void MessagePopupCollection::OnNotificationAdded(
const std::string& notification_id) {
- DoUpdateIfPossible();
+ DoUpdate();
}
void MessagePopupCollection::OnNotificationRemoved(
@@ -367,34 +341,10 @@ void MessagePopupCollection::OnNotificationRemoved(
if (iter == toasts_.end())
return;
- target_top_edge_ = (*iter)->bounds().y();
- if (by_user && !user_is_closing_toasts_by_clicking_) {
- // [Re] start a timeout after which the toasts re-position to their
- // normal locations after tracking the mouse pointer for easy deletion.
- // This provides a period of time when toasts are easy to remove because
- // they re-position themselves to have Close button right under the mouse
- // pointer. If the user continue to remove the toasts, the delay is reset.
- // Once user stopped removing the toasts, the toasts re-populate/rearrange
- // after the specified delay.
- user_is_closing_toasts_by_clicking_ = true;
- IncrementDeferCounter();
- }
-
- // CloseWithAnimation ultimately causes a call to RemoveToast, which calls
- // OnMouseExited. This means that |user_is_closing_toasts_by_clicking_| must
- // have been set before this call, otherwise it will remain true even after
- // the toast is closed, since the defer timer won't be started.
RemoveToast(*iter, /*mark_as_shown=*/true);
if (by_user)
- RepositionWidgetsWithTarget();
-}
-
-void MessagePopupCollection::OnDeferTimerExpired() {
- user_is_closing_toasts_by_clicking_ = false;
- DecrementDeferCounter();
-
- RestartPopupTimers();
+ RepositionWidgets();
}
void MessagePopupCollection::OnNotificationUpdated(
@@ -439,10 +389,7 @@ void MessagePopupCollection::OnNotificationUpdated(
if (!updated)
RemoveToast(*toast_iter, /*mark_as_shown=*/true);
- if (user_is_closing_toasts_by_clicking_)
- RepositionWidgetsWithTarget();
- else
- DoUpdateIfPossible();
+ DoUpdate();
}
ToastContentsView* MessagePopupCollection::FindToast(
@@ -455,42 +402,16 @@ ToastContentsView* MessagePopupCollection::FindToast(
return NULL;
}
-void MessagePopupCollection::IncrementDeferCounter() {
- defer_counter_++;
-}
-
-void MessagePopupCollection::DecrementDeferCounter() {
- defer_counter_--;
- DCHECK(defer_counter_ >= 0);
- DoUpdateIfPossible();
-}
-
// This is the main sequencer of tasks. It does a step, then waits for
// all started transitions to play out before doing the next step.
// First, remove all expired toasts.
-// Then, reposition widgets (the reposition on close happens before all
-// deferred tasks are even able to run)
+// Then, reposition widgets.
// Then, see if there is vacant space for new toasts.
-void MessagePopupCollection::DoUpdateIfPossible() {
- if (defer_counter_ > 0)
- return;
-
+void MessagePopupCollection::DoUpdate() {
RepositionWidgets();
- if (defer_counter_ > 0)
- return;
-
// Reposition could create extra space which allows additional widgets.
UpdateWidgets();
-
- if (defer_counter_ > 0)
- return;
-
- // Test support. Quit the test run loop when no more updates are deferred,
- // meaining th echeck for updates did not cause anything to change so no new
- // transition animations were started.
- if (run_loop_for_test_.get())
- run_loop_for_test_->Quit();
}
void MessagePopupCollection::OnDisplayMetricsChanged(
@@ -508,17 +429,7 @@ views::Widget* MessagePopupCollection::GetWidgetForTest(const std::string& id)
return NULL;
}
-void MessagePopupCollection::CreateRunLoopForTest() {
- run_loop_for_test_.reset(new base::RunLoop());
-}
-
-void MessagePopupCollection::WaitForTest() {
- run_loop_for_test_->Run();
- run_loop_for_test_.reset();
-}
-
gfx::Rect MessagePopupCollection::GetToastRectAt(size_t index) const {
- DCHECK(defer_counter_ == 0) << "Fetching the bounds with animations active.";
size_t i = 0;
for (Toasts::const_iterator iter = toasts_.begin(); iter != toasts_.end();
++iter) {
diff --git a/chromium/ui/message_center/views/message_popup_collection.h b/chromium/ui/message_center/views/message_popup_collection.h
index 51af94202cf..178e41f9b77 100644
--- a/chromium/ui/message_center/views/message_popup_collection.h
+++ b/chromium/ui/message_center/views/message_popup_collection.h
@@ -22,10 +22,6 @@
#include "ui/views/view_observer.h"
#include "ui/views/widget/widget_observer.h"
-namespace base {
-class RunLoop;
-}
-
namespace display {
class Display;
}
@@ -74,17 +70,8 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
void OnMouseEntered(ToastContentsView* toast_entered);
void OnMouseExited(ToastContentsView* toast_exited);
- // Invoked by toasts when they start/finish their animations.
- // While "defer counter" is greater than zero, the popup collection does
- // not perform updates. It is used to wait for various animations and user
- // actions like serial closing of the toasts, when the remaining toasts "flow
- // under the mouse".
- void IncrementDeferCounter();
- void DecrementDeferCounter();
-
- // Runs the next step in update/animate sequence, if the defer counter is not
- // zero. Otherwise, simply waits when it becomes zero.
- void DoUpdateIfPossible();
+ // Runs the next step in update/animate sequence.
+ void DoUpdate();
// Removes the toast from our internal list of toasts; this is called when the
// toast is irrevocably closed (such as within RemoveToast).
@@ -110,14 +97,13 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
// Repositions all of the widgets based on the current work area.
void RepositionWidgets();
- // Repositions widgets to the top edge of the notification toast that was
- // just removed, so that the user can click close button without mouse moves.
- // See crbug.com/224089
- void RepositionWidgetsWithTarget();
-
- // The base line is an (imaginary) line that would touch the bottom of the
+ // The baseline is an (imaginary) line that would touch the bottom of the
// next created notification if bottom-aligned or its top if top-aligned.
- int GetBaseLine(ToastContentsView* last_toast) const;
+ int GetBaseline() const;
+
+ // Returns the top of the toast when IsTopDown() is true, otherwise returns
+ // the bottom of the toast.
+ int GetBaselineForToast(ToastContentsView* toast) const;
// Overridden from MessageCenterObserver:
void OnNotificationAdded(const std::string& notification_id) override;
@@ -135,8 +121,6 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
// "ForTest" methods.
views::Widget* GetWidgetForTest(const std::string& id) const;
- void CreateRunLoopForTest();
- void WaitForTest();
gfx::Rect GetToastRectAt(size_t index) const;
MessageCenter* message_center_;
@@ -145,30 +129,14 @@ class MESSAGE_CENTER_EXPORT MessagePopupCollection
PopupAlignmentDelegate* alignment_delegate_;
- int defer_counter_ = 0;
-
// This is only used to compare with incoming events, do not assume that
// the toast will be valid if this pointer is non-NULL.
ToastContentsView* latest_toast_entered_ = nullptr;
- // Denotes a mode when user is clicking the Close button of toasts in a
- // sequence, w/o moving the mouse. We reposition the toasts so the next one
- // happens to be right under the mouse, and the user can just dispose of
- // multipel toasts by clicking. The mode ends when defer_timer_ expires.
- bool user_is_closing_toasts_by_clicking_ = false;
- std::unique_ptr<base::OneShotTimer> defer_timer_;
- // The top edge to align the position of the next toast during 'close by
- // clicking" mode.
- // Only to be used when user_is_closing_toasts_by_clicking_ is true.
- int target_top_edge_ = 0;
-
// This is the number of pause request for timer. If it's more than zero, the
// timer is paused. If zero, the timer is not paused.
int timer_pause_counter_ = 0;
- // Weak, only exists temporarily in tests.
- std::unique_ptr<base::RunLoop> run_loop_for_test_;
-
std::unique_ptr<MessageViewContextMenuController> context_menu_controller_;
ScopedObserver<views::View, views::ViewObserver> observed_views_{this};
diff --git a/chromium/ui/message_center/views/message_popup_collection_unittest.cc b/chromium/ui/message_center/views/message_popup_collection_unittest.cc
index f1c48b1fd8f..c643fa73c94 100644
--- a/chromium/ui/message_center/views/message_popup_collection_unittest.cc
+++ b/chromium/ui/message_center/views/message_popup_collection_unittest.cc
@@ -12,8 +12,8 @@
#include <numeric>
#include <utility>
-#include "base/message_loop/message_loop.h"
#include "base/optional.h"
+#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
@@ -25,6 +25,7 @@
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/image/image_unittest_util.h"
#include "ui/message_center/fake_message_center.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
#include "ui/message_center/views/desktop_popup_alignment_delegate.h"
@@ -33,23 +34,22 @@
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
+namespace message_center {
+
namespace {
-std::unique_ptr<message_center::Notification> CreateTestNotification(
- std::string id,
- std::string text) {
- return std::make_unique<message_center::Notification>(
- message_center::NOTIFICATION_TYPE_BASE_FORMAT, id,
- base::UTF8ToUTF16("test title"), base::ASCIIToUTF16(text), gfx::Image(),
+std::unique_ptr<Notification> CreateTestNotification(std::string id,
+ std::string text) {
+ return std::make_unique<Notification>(
+ NOTIFICATION_TYPE_BASE_FORMAT, id, base::UTF8ToUTF16("test title"),
+ base::ASCIIToUTF16(text), gfx::Image(),
base::string16() /* display_source */, GURL(),
- message_center::NotifierId(message_center::NotifierId::APPLICATION, id),
- message_center::RichNotificationData(),
- new message_center::NotificationDelegate());
+ NotifierId(NotifierId::APPLICATION, id), RichNotificationData(),
+ new NotificationDelegate());
}
// Provides an aura window context for widget creation.
-class TestPopupAlignmentDelegate
- : public message_center::DesktopPopupAlignmentDelegate {
+class TestPopupAlignmentDelegate : public DesktopPopupAlignmentDelegate {
public:
explicit TestPopupAlignmentDelegate(gfx::NativeWindow context)
: context_(context) {}
@@ -70,10 +70,10 @@ class TestPopupAlignmentDelegate
} // namespace
-namespace message_center {
namespace test {
-class MessagePopupCollectionTest : public views::ViewsTestBase {
+class MessagePopupCollectionTest : public views::ViewsTestBase,
+ public views::WidgetObserver {
public:
void SetUp() override {
views::ViewsTestBase::SetUp();
@@ -85,10 +85,9 @@ class MessagePopupCollectionTest : public views::ViewsTestBase {
// This size fits test machines resolution and also can keep a few toasts
// w/o ill effects of hitting the screen overflow. This allows us to assume
// and verify normal layout of the toast stack.
- SetDisplayInfo(gfx::Rect(0, 0, 600, 390), // taskbar at the bottom.
- gfx::Rect(0, 0, 600, 400));
+ SetDisplayInfo(gfx::Rect(0, 0, 1920, 1070), // taskbar at the bottom.
+ gfx::Rect(0, 0, 1920, 1080));
id_ = 0;
- PrepareForWait();
}
void TearDown() override {
@@ -123,7 +122,6 @@ class MessagePopupCollectionTest : public views::ViewsTestBase {
dummy_display.set_bounds(display_bounds);
dummy_display.set_work_area(work_area);
alignment_delegate_->RecomputeAlignment(dummy_display);
- PrepareForWait();
}
gfx::Rect GetWorkArea() {
@@ -142,34 +140,52 @@ class MessagePopupCollectionTest : public views::ViewsTestBase {
std::string AddNotification() {
std::string id = base::IntToString(id_++);
- std::unique_ptr<Notification> notification(new Notification(
+ std::unique_ptr<Notification> notification = std::make_unique<Notification>(
NOTIFICATION_TYPE_BASE_FORMAT, id, base::UTF8ToUTF16("test title"),
base::UTF8ToUTF16("test message"), gfx::Image(),
base::string16() /* display_source */, GURL(), NotifierId(),
- message_center::RichNotificationData(), new NotificationDelegate()));
+ RichNotificationData(), new NotificationDelegate());
MessageCenter::Get()->AddNotification(std::move(notification));
return id;
}
- void PrepareForWait() { collection_->CreateRunLoopForTest(); }
-
- // Assumes there is non-zero pending work.
- void WaitForTransitionsDone() {
- collection_->WaitForTest();
- collection_->CreateRunLoopForTest();
+ std::string AddImageNotification() {
+ std::string id = base::IntToString(id_++);
+ std::unique_ptr<Notification> notification = std::make_unique<Notification>(
+ NOTIFICATION_TYPE_IMAGE, id, base::UTF8ToUTF16("test title"),
+ base::UTF8ToUTF16("test message"), gfx::Image(),
+ base::string16() /* display_source */, GURL(), NotifierId(),
+ RichNotificationData(), new NotificationDelegate());
+ notification->set_image(gfx::test::CreateImage(100, 100));
+ MessageCenter::Get()->AddNotification(std::move(notification));
+ return id;
}
void CloseAllToasts() {
// Assumes there is at least one toast to close.
EXPECT_TRUE(GetToastCounts() > 0);
- MessageCenter::Get()->RemoveAllNotifications(
- false /* by_user */, MessageCenter::RemoveType::ALL);
+
+ auto toasts = collection_->toasts_;
+ for (ToastContentsView* toast : toasts) {
+ toast->GetWidget()->CloseNow();
+ }
}
gfx::Rect GetToastRectAt(size_t index) {
return collection_->GetToastRectAt(index);
}
+ void RemoveToastAndWaitForClose(const std::string& id) {
+ GetWidget(id)->AddObserver(this);
+ MessageCenter::Get()->RemoveNotification(id, true /* by_user */);
+ widget_close_run_loop_.Run();
+ }
+
+ // views::WidgetObserver
+ void OnWidgetDestroyed(views::Widget* widget) override {
+ widget_close_run_loop_.Quit();
+ }
+
// Checks:
// 1) sizes of toast and corresponding widget are equal;
// 2) widgets do not owerlap;
@@ -177,6 +193,7 @@ class MessagePopupCollectionTest : public views::ViewsTestBase {
class CheckedAnimationDelegate : public gfx::AnimationDelegate {
public:
explicit CheckedAnimationDelegate(MessagePopupCollectionTest* test);
+ ~CheckedAnimationDelegate() override;
// returns first encountered error
const base::Optional<std::string>& error_msg() const { return error_msg_; }
@@ -214,6 +231,7 @@ class MessagePopupCollectionTest : public views::ViewsTestBase {
const MessagePopupCollection::Toasts& toasts);
private:
+ base::RunLoop widget_close_run_loop_;
std::unique_ptr<MessagePopupCollection> collection_;
std::unique_ptr<DesktopPopupAlignmentDelegate> alignment_delegate_;
int id_;
@@ -226,6 +244,11 @@ MessagePopupCollectionTest::CheckedAnimationDelegate::CheckedAnimationDelegate(
animation_delegate().bounds_animation_->set_delegate(this);
}
+MessagePopupCollectionTest::CheckedAnimationDelegate::
+ ~CheckedAnimationDelegate() {
+ animation_delegate().bounds_animation_->set_delegate(&animation_delegate());
+}
+
void MessagePopupCollectionTest::CheckedAnimationDelegate::AnimationEnded(
const gfx::Animation* animation) {
animation_delegate().AnimationEnded(animation);
@@ -334,21 +357,18 @@ TEST_F(MessagePopupCollectionTest, DismissOnClick) {
std::string id1 = AddNotification();
std::string id2 = AddNotification();
- WaitForTransitionsDone();
EXPECT_EQ(2u, GetToastCounts());
EXPECT_TRUE(IsToastShown(id1));
EXPECT_TRUE(IsToastShown(id2));
MessageCenter::Get()->ClickOnNotification(id2);
- WaitForTransitionsDone();
EXPECT_EQ(1u, GetToastCounts());
EXPECT_TRUE(IsToastShown(id1));
EXPECT_FALSE(IsToastShown(id2));
MessageCenter::Get()->ClickOnNotificationButton(id1, 0);
- WaitForTransitionsDone();
EXPECT_EQ(0u, GetToastCounts());
EXPECT_FALSE(IsToastShown(id1));
EXPECT_FALSE(IsToastShown(id2));
@@ -359,21 +379,20 @@ TEST_F(MessagePopupCollectionTest, DismissOnClick) {
TEST_F(MessagePopupCollectionTest, NotDismissedOnClick) {
std::string id1 = AddNotification();
std::string id2 = AddNotification();
- WaitForTransitionsDone();
EXPECT_EQ(2u, GetToastCounts());
EXPECT_TRUE(IsToastShown(id1));
EXPECT_TRUE(IsToastShown(id2));
MessageCenter::Get()->ClickOnNotification(id2);
- collection()->DoUpdateIfPossible();
+ collection()->DoUpdate();
EXPECT_EQ(2u, GetToastCounts());
EXPECT_TRUE(IsToastShown(id1));
EXPECT_TRUE(IsToastShown(id2));
MessageCenter::Get()->ClickOnNotificationButton(id1, 0);
- collection()->DoUpdateIfPossible();
+ collection()->DoUpdate();
EXPECT_EQ(2u, GetToastCounts());
EXPECT_TRUE(IsToastShown(id1));
EXPECT_TRUE(IsToastShown(id2));
@@ -387,7 +406,6 @@ TEST_F(MessagePopupCollectionTest, NotDismissedOnClick) {
TEST_F(MessagePopupCollectionTest, ShutdownDuringShowing) {
std::string id1 = AddNotification();
std::string id2 = AddNotification();
- WaitForTransitionsDone();
EXPECT_EQ(2u, GetToastCounts());
EXPECT_TRUE(IsToastShown(id1));
EXPECT_TRUE(IsToastShown(id2));
@@ -405,7 +423,6 @@ TEST_F(MessagePopupCollectionTest, DefaultPositioning) {
std::string id1 = AddNotification();
std::string id2 = AddNotification();
std::string id3 = AddNotification();
- WaitForTransitionsDone();
gfx::Rect r0 = GetToastRectAt(0);
gfx::Rect r1 = GetToastRectAt(1);
@@ -436,7 +453,6 @@ TEST_F(MessagePopupCollectionTest, DefaultPositioning) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
- WaitForTransitionsDone();
}
TEST_F(MessagePopupCollectionTest, DefaultPositioningWithRightTaskbar) {
@@ -447,7 +463,6 @@ TEST_F(MessagePopupCollectionTest, DefaultPositioningWithRightTaskbar) {
gfx::Rect(0, 0, 600, 400)); // Display-bounds.
std::string id0 = AddNotification();
std::string id1 = AddNotification();
- WaitForTransitionsDone();
gfx::Rect r0 = GetToastRectAt(0);
gfx::Rect r1 = GetToastRectAt(1);
@@ -463,7 +478,6 @@ TEST_F(MessagePopupCollectionTest, DefaultPositioningWithRightTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
- WaitForTransitionsDone();
}
TEST_F(MessagePopupCollectionTest, TopDownPositioningWithTopTaskbar) {
@@ -472,7 +486,6 @@ TEST_F(MessagePopupCollectionTest, TopDownPositioningWithTopTaskbar) {
gfx::Rect(0, 0, 600, 400)); // Display-bounds.
std::string id0 = AddNotification();
std::string id1 = AddNotification();
- WaitForTransitionsDone();
gfx::Rect r0 = GetToastRectAt(0);
gfx::Rect r1 = GetToastRectAt(1);
@@ -488,7 +501,6 @@ TEST_F(MessagePopupCollectionTest, TopDownPositioningWithTopTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
- WaitForTransitionsDone();
}
TEST_F(MessagePopupCollectionTest, TopDownPositioningWithLeftAndTopTaskbar) {
@@ -500,7 +512,6 @@ TEST_F(MessagePopupCollectionTest, TopDownPositioningWithLeftAndTopTaskbar) {
gfx::Rect(0, 0, 600, 400)); // Display-bounds.
std::string id0 = AddNotification();
std::string id1 = AddNotification();
- WaitForTransitionsDone();
gfx::Rect r0 = GetToastRectAt(0);
gfx::Rect r1 = GetToastRectAt(1);
@@ -516,7 +527,6 @@ TEST_F(MessagePopupCollectionTest, TopDownPositioningWithLeftAndTopTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
- WaitForTransitionsDone();
}
TEST_F(MessagePopupCollectionTest, TopDownPositioningWithBottomAndTopTaskbar) {
@@ -528,7 +538,6 @@ TEST_F(MessagePopupCollectionTest, TopDownPositioningWithBottomAndTopTaskbar) {
gfx::Rect(0, 0, 600, 400)); // Display-bounds.
std::string id0 = AddNotification();
std::string id1 = AddNotification();
- WaitForTransitionsDone();
gfx::Rect r0 = GetToastRectAt(0);
gfx::Rect r1 = GetToastRectAt(1);
@@ -544,7 +553,6 @@ TEST_F(MessagePopupCollectionTest, TopDownPositioningWithBottomAndTopTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
- WaitForTransitionsDone();
}
TEST_F(MessagePopupCollectionTest, LeftPositioningWithLeftTaskbar) {
@@ -553,7 +561,6 @@ TEST_F(MessagePopupCollectionTest, LeftPositioningWithLeftTaskbar) {
gfx::Rect(0, 0, 600, 400)); // Display-bounds.
std::string id0 = AddNotification();
std::string id1 = AddNotification();
- WaitForTransitionsDone();
gfx::Rect r0 = GetToastRectAt(0);
gfx::Rect r1 = GetToastRectAt(1);
@@ -572,13 +579,34 @@ TEST_F(MessagePopupCollectionTest, LeftPositioningWithLeftTaskbar) {
CloseAllToasts();
EXPECT_EQ(0u, GetToastCounts());
- WaitForTransitionsDone();
+}
+
+// Regression test for https://crbug.com/679397
+TEST_F(MessagePopupCollectionTest, MultipleNotificationHeight) {
+ std::string id0 = AddNotification();
+ std::string id1 = AddImageNotification();
+ EXPECT_EQ(2u, GetToastCounts());
+
+ gfx::Rect r0 = GetToast(id0)->bounds();
+
+ RemoveToastAndWaitForClose(id0);
+ EXPECT_EQ(1u, GetToastCounts());
+
+ gfx::Rect r1 = GetToast(id1)->bounds();
+
+ // The heights should be different as one is an image notification while
+ // another is a basic notification, but the bottom positions after the
+ // animation should be same even though the heights are different.
+ EXPECT_NE(r0.height(), r1.height());
+ EXPECT_EQ(r0.bottom(), r1.bottom());
+
+ CloseAllToasts();
+ EXPECT_EQ(0u, GetToastCounts());
}
TEST_F(MessagePopupCollectionTest, DetectMouseHover) {
std::string id0 = AddNotification();
std::string id1 = AddNotification();
- WaitForTransitionsDone();
views::WidgetDelegateView* toast0 = GetToast(id0);
EXPECT_TRUE(toast0 != NULL);
@@ -614,7 +642,6 @@ TEST_F(MessagePopupCollectionTest, DetectMouseHover) {
TEST_F(MessagePopupCollectionTest, DetectMouseHoverWithUserClose) {
std::string id0 = AddNotification();
std::string id1 = AddNotification();
- WaitForTransitionsDone();
views::WidgetDelegateView* toast0 = GetToast(id0);
EXPECT_TRUE(toast0 != NULL);
@@ -624,18 +651,15 @@ TEST_F(MessagePopupCollectionTest, DetectMouseHoverWithUserClose) {
ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(), gfx::Point(),
ui::EventTimeForNow(), 0, 0);
toast1->OnMouseEntered(event);
- static_cast<MessageCenterObserver*>(collection())->OnNotificationRemoved(
- id1, true);
+ RemoveToastAndWaitForClose(id1);
EXPECT_FALSE(MouseInCollection());
std::string id2 = AddNotification();
- WaitForTransitionsDone();
views::WidgetDelegateView* toast2 = GetToast(id2);
EXPECT_TRUE(toast2 != NULL);
CloseAllToasts();
- WaitForTransitionsDone();
}
TEST_F(MessagePopupCollectionTest, ManyPopupNotifications) {
@@ -646,7 +670,6 @@ TEST_F(MessagePopupCollectionTest, ManyPopupNotifications) {
ids[i] = AddNotification();
}
- WaitForTransitionsDone();
for (size_t i = 0; i < notifications_to_add - 1; ++i) {
EXPECT_TRUE(IsToastShown(ids[i])) << "Should show the " << i << "th ID";
@@ -654,7 +677,6 @@ TEST_F(MessagePopupCollectionTest, ManyPopupNotifications) {
EXPECT_FALSE(IsToastShown(ids[notifications_to_add - 1]));
CloseAllToasts();
- WaitForTransitionsDone();
}
#if defined(OS_CHROMEOS)
@@ -667,12 +689,11 @@ TEST_F(MessagePopupCollectionTest, CloseNonClosableNotifications) {
base::UTF8ToUTF16("test title"), base::UTF8ToUTF16("test message"),
gfx::Image(), base::string16() /* display_source */, GURL(),
NotifierId(NotifierId::APPLICATION, kNotificationId),
- message_center::RichNotificationData(), new NotificationDelegate()));
+ RichNotificationData(), new NotificationDelegate()));
notification->set_pinned(true);
// Add a pinned notification.
MessageCenter::Get()->AddNotification(std::move(notification));
- WaitForTransitionsDone();
// Confirms that there is a toast.
EXPECT_EQ(1u, GetToastCounts());
@@ -686,7 +707,6 @@ TEST_F(MessagePopupCollectionTest, CloseNonClosableNotifications) {
toast1->OnMouseEntered(event);
static_cast<MessageCenterObserver*>(collection())
->OnNotificationRemoved(kNotificationId, true);
- WaitForTransitionsDone();
// Confirms that there is no toast.
EXPECT_EQ(0u, GetToastCounts());
@@ -727,7 +747,6 @@ TEST_F(MessagePopupCollectionTest, ChangingNotificationSize) {
}
}
- WaitForTransitionsDone();
// Confirms that there are 2 toasts of 3 notifications.
EXPECT_EQ(3u, GetToastCounts());
@@ -741,8 +760,6 @@ TEST_F(MessagePopupCollectionTest, ChangingNotificationSize) {
CheckedAnimationDelegate checked_animation(this);
- WaitForTransitionsDone();
-
EXPECT_FALSE(checked_animation.error_msg())
<< "Animation error, test case: " << id << ' ' << update.name << ":\n"
<< *checked_animation.error_msg();
@@ -750,7 +767,6 @@ TEST_F(MessagePopupCollectionTest, ChangingNotificationSize) {
}
CloseAllToasts();
- WaitForTransitionsDone();
}
} // namespace test
diff --git a/chromium/ui/message_center/views/message_view.cc b/chromium/ui/message_center/views/message_view.cc
index 25904ad06cf..41912b341f7 100644
--- a/chromium/ui/message_center/views/message_view.cc
+++ b/chromium/ui/message_center/views/message_view.cc
@@ -4,6 +4,7 @@
#include "ui/message_center/views/message_view.h"
+#include "base/feature_list.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h"
@@ -14,8 +15,8 @@
#include "ui/gfx/shadow_util.h"
#include "ui/gfx/shadow_value.h"
#include "ui/message_center/message_center.h"
+#include "ui/message_center/public/cpp/features.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
-#include "ui/message_center/public/cpp/message_center_switches.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
@@ -26,6 +27,8 @@
#include "ui/views/painter.h"
#include "ui/views/widget/widget.h"
+namespace message_center {
+
namespace {
const SkColor kBorderColor = SkColorSetARGB(0x1F, 0x0, 0x0, 0x0);
@@ -37,8 +40,7 @@ bool sidebar_enabled = false;
// Creates a text for spoken feedback from the data contained in the
// notification.
-base::string16 CreateAccessibleName(
- const message_center::Notification& notification) {
+base::string16 CreateAccessibleName(const Notification& notification) {
if (!notification.accessible_name().empty())
return notification.accessible_name();
@@ -46,10 +48,8 @@ base::string16 CreateAccessibleName(
std::vector<base::string16> accessible_lines = {
notification.title(), notification.message(),
notification.context_message()};
- std::vector<message_center::NotificationItem> items = notification.items();
- for (size_t i = 0;
- i < items.size() && i < message_center::kNotificationMaximumItems;
- ++i) {
+ std::vector<NotificationItem> items = notification.items();
+ for (size_t i = 0; i < items.size() && i < kNotificationMaximumItems; ++i) {
accessible_lines.push_back(items[i].title + base::ASCIIToUTF16(" ") +
items[i].message);
}
@@ -57,17 +57,11 @@ base::string16 CreateAccessibleName(
}
bool ShouldRoundMessageViewCorners() {
-#if defined(OS_CHROMEOS)
- return true;
-#else
- return message_center::IsNewStyleNotificationEnabled();
-#endif
+ return base::FeatureList::IsEnabled(message_center::kNewStyleNotifications);
}
} // namespace
-namespace message_center {
-
// static
const char MessageView::kViewClassName[] = "MessageView";
@@ -96,8 +90,7 @@ MessageView::MessageView(const Notification& notification)
UpdateWithNotification(notification);
}
-MessageView::~MessageView() {
-}
+MessageView::~MessageView() {}
void MessageView::UpdateWithNotification(const Notification& notification) {
pinned_ = notification.pinned();
@@ -140,6 +133,15 @@ bool MessageView::IsExpanded() const {
return false;
}
+bool MessageView::IsManuallyExpandedOrCollapsed() const {
+ // Not implemented by default.
+ return false;
+}
+
+void MessageView::SetManuallyExpandedOrCollapsed(bool value) {
+ // Not implemented by default.
+}
+
void MessageView::OnContainerAnimationStarted() {
// Not implemented by default.
}
@@ -149,9 +151,9 @@ void MessageView::OnContainerAnimationEnded() {
}
void MessageView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_BUTTON;
+ node_data->role = ax::mojom::Role::kButton;
node_data->AddStringAttribute(
- ui::AX_ATTR_ROLE_DESCRIPTION,
+ ax::mojom::StringAttribute::kRoleDescription,
l10n_util::GetStringUTF8(
IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME));
node_data->SetName(accessible_name_);
@@ -274,7 +276,9 @@ void MessageView::OnSlideOut() {
}
bool MessageView::GetPinned() const {
- return pinned_ && !force_disable_pinned_;
+ // Only nested notifications can be pinned. Standalones (i.e. popups) can't
+ // be.
+ return pinned_ && is_nested_;
}
void MessageView::OnCloseButtonPressed() {
@@ -282,7 +286,7 @@ void MessageView::OnCloseButtonPressed() {
true /* by_user */);
}
-void MessageView::OnSettingsButtonPressed() {
+void MessageView::OnSettingsButtonPressed(const ui::Event& event) {
MessageCenter::Get()->ClickOnSettingsButton(notification_id_);
}
diff --git a/chromium/ui/message_center/views/message_view.h b/chromium/ui/message_center/views/message_view.h
index 48d4d5a3995..0cbbaf18602 100644
--- a/chromium/ui/message_center/views/message_view.h
+++ b/chromium/ui/message_center/views/message_view.h
@@ -15,9 +15,10 @@
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/message_center/message_center_export.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_delegate.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_delegate.h"
#include "ui/message_center/views/slide_out_controller.h"
+#include "ui/views/animation/ink_drop_host_view.h"
#include "ui/views/view.h"
namespace views {
@@ -33,7 +34,7 @@ class NotificationControlButtonsView;
// An base class for a notification entry. Contains background and other
// elements shared by derived notification views.
class MESSAGE_CENTER_EXPORT MessageView
- : public views::View,
+ : public views::InkDropHostView,
public views::SlideOutController::Delegate {
public:
static const char kViewClassName[];
@@ -61,6 +62,8 @@ class MESSAGE_CENTER_EXPORT MessageView
virtual void SetExpanded(bool expanded);
virtual bool IsExpanded() const;
+ virtual bool IsManuallyExpandedOrCollapsed() const;
+ virtual void SetManuallyExpandedOrCollapsed(bool value);
// Invoked when the container view of MessageView (e.g. MessageCenterView in
// ash) is starting the animation that possibly hides some part of
@@ -70,7 +73,7 @@ class MESSAGE_CENTER_EXPORT MessageView
virtual void OnContainerAnimationEnded();
void OnCloseButtonPressed();
- virtual void OnSettingsButtonPressed();
+ virtual void OnSettingsButtonPressed(const ui::Event& event);
// views::View
void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
@@ -94,11 +97,6 @@ class MESSAGE_CENTER_EXPORT MessageView
void set_scroller(views::ScrollView* scroller) { scroller_ = scroller; }
std::string notification_id() const { return notification_id_; }
-#if defined(OS_CHROMEOS)
- // By calling this, all notifications are treated as non-pinned forcibly.
- void set_force_disable_pinned() { force_disable_pinned_ = true; }
-#endif
-
protected:
// Creates and add close button to view hierarchy when necessary. Derived
// classes should call this after its view hierarchy is populated to ensure
@@ -112,6 +110,8 @@ class MESSAGE_CENTER_EXPORT MessageView
views::View* background_view() { return background_view_; }
views::ScrollView* scroller() { return scroller_; }
+ bool is_nested() const { return is_nested_; }
+
private:
std::string notification_id_;
views::View* background_view_ = nullptr; // Owned by views hierarchy.
@@ -121,9 +121,6 @@ class MESSAGE_CENTER_EXPORT MessageView
// Flag if the notification is set to pinned or not.
bool pinned_ = false;
- // Flag if pin is forcibly disabled on this view. If true, the view is never
- // pinned regardless of the value of |pinned_|.
- bool force_disable_pinned_ = false;
std::unique_ptr<views::Painter> focus_painter_;
diff --git a/chromium/ui/message_center/views/message_view_context_menu_controller.cc b/chromium/ui/message_center/views/message_view_context_menu_controller.cc
index 811f8bc2fef..bcd9817db11 100644
--- a/chromium/ui/message_center/views/message_view_context_menu_controller.cc
+++ b/chromium/ui/message_center/views/message_view_context_menu_controller.cc
@@ -27,6 +27,12 @@ void MessageViewContextMenuController::ShowContextMenuForView(
Notification* notification =
MessageCenter::Get()->FindVisibleNotificationById(
message_view->notification_id());
+
+ // Notification is null if the notification view is being removed or some
+ // invalid status. In this case, just returns.
+ if (!notification)
+ return;
+
menu_model_ = std::make_unique<NotificationMenuModel>(*notification);
if (!menu_model_ || menu_model_->GetItemCount() == 0)
diff --git a/chromium/ui/message_center/views/message_view_factory.cc b/chromium/ui/message_center/views/message_view_factory.cc
index a4d78220bf9..07ed14273ea 100644
--- a/chromium/ui/message_center/views/message_view_factory.cc
+++ b/chromium/ui/message_center/views/message_view_factory.cc
@@ -5,9 +5,10 @@
#include "ui/message_center/views/message_view_factory.h"
#include "base/command_line.h"
+#include "base/feature_list.h"
#include "base/lazy_instance.h"
-#include "ui/message_center/notification_types.h"
-#include "ui/message_center/public/cpp/message_center_switches.h"
+#include "ui/message_center/public/cpp/features.h"
+#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/message_center/views/notification_view.h"
#include "ui/message_center/views/notification_view_md.h"
@@ -35,7 +36,7 @@ MessageView* MessageViewFactory::Create(const Notification& notification,
case NOTIFICATION_TYPE_SIMPLE:
case NOTIFICATION_TYPE_PROGRESS:
// All above roads lead to the generic NotificationView.
- if (IsNewStyleNotificationEnabled())
+ if (base::FeatureList::IsEnabled(message_center::kNewStyleNotifications))
notification_view = new NotificationViewMD(notification);
else
notification_view = new NotificationView(notification);
diff --git a/chromium/ui/message_center/views/message_view_factory.h b/chromium/ui/message_center/views/message_view_factory.h
index acb39f02c14..883257ebff7 100644
--- a/chromium/ui/message_center/views/message_view_factory.h
+++ b/chromium/ui/message_center/views/message_view_factory.h
@@ -24,8 +24,7 @@ class MESSAGE_CENTER_EXPORT MessageViewFactory {
public:
// A function that creates MessageView for a NOTIFICATION_TYPE_CUSTOM
// notification.
- typedef base::Callback<std::unique_ptr<message_center::MessageView>(
- const message_center::Notification&)>
+ typedef base::Callback<std::unique_ptr<MessageView>(const Notification&)>
CustomMessageViewFactoryFunction;
static MessageView* Create(const Notification& notification, bool top_level);
diff --git a/chromium/ui/message_center/views/notification_button.cc b/chromium/ui/message_center/views/notification_button.cc
index f4110cce723..5f92deff742 100644
--- a/chromium/ui/message_center/views/notification_button.cc
+++ b/chromium/ui/message_center/views/notification_button.cc
@@ -7,7 +7,6 @@
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
-#include "ui/message_center/views/constants.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
#include "ui/views/controls/image_view.h"
@@ -25,12 +24,10 @@ NotificationButton::NotificationButton(views::ButtonListener* listener)
SetBackground(views::CreateSolidBackground(kNotificationBackgroundColor));
set_notify_enter_exit_on_child(true);
SetLayoutManager(std::make_unique<views::BoxLayout>(
- views::BoxLayout::kHorizontal,
- gfx::Insets(kButtonVerticalPadding,
- message_center::kButtonHorizontalPadding),
- message_center::kButtonIconToTitlePadding));
+ views::BoxLayout::kHorizontal, gfx::Insets(0, kButtonHorizontalPadding),
+ kButtonIconToTitlePadding));
SetFocusPainter(views::Painter::CreateSolidFocusPainter(
- message_center::kFocusBorderColor, gfx::Insets(1, 2, 2, 2)));
+ kFocusBorderColor, gfx::Insets(1, 2, 2, 2)));
}
NotificationButton::~NotificationButton() {
@@ -43,41 +40,36 @@ void NotificationButton::SetIcon(const gfx::ImageSkia& image) {
icon_ = NULL;
} else {
icon_ = new views::ImageView();
- icon_->SetImageSize(gfx::Size(message_center::kNotificationButtonIconSize,
- message_center::kNotificationButtonIconSize));
+ icon_->SetImageSize(
+ gfx::Size(kNotificationButtonIconSize, kNotificationButtonIconSize));
icon_->SetImage(image);
icon_->SetHorizontalAlignment(views::ImageView::LEADING);
icon_->SetVerticalAlignment(views::ImageView::LEADING);
- icon_->SetBorder(views::CreateEmptyBorder(
- message_center::kButtonIconTopPadding, 0, 0, 0));
+ icon_->SetBorder(views::CreateEmptyBorder(kButtonIconTopPadding, 0, 0, 0));
AddChildViewAt(icon_, 0);
}
}
void NotificationButton::SetTitle(const base::string16& title) {
- if (title_ != NULL)
+ if (title_)
delete title_; // This removes the title from this view's children.
- if (title.empty()) {
- title_ = NULL;
- } else {
+ title_ = nullptr;
+ if (!title.empty()) {
title_ = new views::Label(title);
title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- title_->SetEnabledColor(message_center::kRegularTextColor);
- title_->SetBackgroundColor(kRegularTextBackgroundColor);
- title_->SetBorder(
- views::CreateEmptyBorder(kButtonTitleTopPadding, 0, 0, 0));
+ title_->SetEnabledColor(kRegularTextColor);
+ title_->SetAutoColorReadabilityEnabled(false);
AddChildView(title_);
}
SetAccessibleName(title);
}
gfx::Size NotificationButton::CalculatePreferredSize() const {
- return gfx::Size(message_center::kNotificationWidth,
- message_center::kButtonHeight);
+ return gfx::Size(kNotificationWidth, kButtonHeight);
}
int NotificationButton::GetHeightForWidth(int width) const {
- return message_center::kButtonHeight;
+ return kButtonHeight;
}
void NotificationButton::OnFocus() {
@@ -95,8 +87,7 @@ void NotificationButton::ViewHierarchyChanged(
void NotificationButton::StateChanged(ButtonState old_state) {
if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
- SetBackground(views::CreateSolidBackground(
- message_center::kHoveredButtonBackgroundColor));
+ SetBackground(views::CreateSolidBackground(kHoveredButtonBackgroundColor));
} else {
SetBackground(views::CreateSolidBackground(kNotificationBackgroundColor));
}
diff --git a/chromium/ui/message_center/views/notification_control_buttons_view.cc b/chromium/ui/message_center/views/notification_control_buttons_view.cc
index b4fb713601a..bf1dae50e71 100644
--- a/chromium/ui/message_center/views/notification_control_buttons_view.cc
+++ b/chromium/ui/message_center/views/notification_control_buttons_view.cc
@@ -20,6 +20,8 @@
#include "ui/views/background.h"
#include "ui/views/layout/box_layout.h"
+namespace message_center {
+
namespace {
// This value should be the same as the duration of reveal animation of
@@ -28,13 +30,10 @@ constexpr auto kBackgroundColorChangeDuration =
base::TimeDelta::FromMilliseconds(360);
// The initial background color of the view.
-constexpr SkColor kInitialBackgroundColor =
- message_center::kControlButtonBackgroundColor;
+constexpr SkColor kInitialBackgroundColor = kControlButtonBackgroundColor;
} // anonymous namespace
-namespace message_center {
-
const char NotificationControlButtonsView::kViewClassName[] =
"NotificationControlButtonsView";
@@ -58,7 +57,7 @@ NotificationControlButtonsView::~NotificationControlButtonsView() = default;
void NotificationControlButtonsView::ShowCloseButton(bool show) {
if (show && !close_button_) {
- close_button_ = std::make_unique<message_center::PaddedButton>(this);
+ close_button_ = std::make_unique<PaddedButton>(this);
close_button_->set_owned_by_client();
close_button_->SetImage(views::Button::STATE_NORMAL,
gfx::CreateVectorIcon(kNotificationCloseButtonIcon,
@@ -81,7 +80,7 @@ void NotificationControlButtonsView::ShowCloseButton(bool show) {
void NotificationControlButtonsView::ShowSettingsButton(bool show) {
if (show && !settings_button_) {
- settings_button_ = std::make_unique<message_center::PaddedButton>(this);
+ settings_button_ = std::make_unique<PaddedButton>(this);
settings_button_->set_owned_by_client();
settings_button_->SetImage(
views::Button::STATE_NORMAL,
@@ -156,7 +155,7 @@ void NotificationControlButtonsView::ButtonPressed(views::Button* sender,
if (close_button_ && sender == close_button_.get()) {
message_view_->OnCloseButtonPressed();
} else if (settings_button_ && sender == settings_button_.get()) {
- message_view_->OnSettingsButtonPressed();
+ message_view_->OnSettingsButtonPressed(event);
}
}
diff --git a/chromium/ui/message_center/views/notification_control_buttons_view.h b/chromium/ui/message_center/views/notification_control_buttons_view.h
index 31441a979dc..176221ee972 100644
--- a/chromium/ui/message_center/views/notification_control_buttons_view.h
+++ b/chromium/ui/message_center/views/notification_control_buttons_view.h
@@ -77,8 +77,8 @@ class MESSAGE_CENTER_EXPORT NotificationControlButtonsView
private:
MessageView* message_view_;
- std::unique_ptr<message_center::PaddedButton> close_button_;
- std::unique_ptr<message_center::PaddedButton> settings_button_;
+ std::unique_ptr<PaddedButton> close_button_;
+ std::unique_ptr<PaddedButton> settings_button_;
std::unique_ptr<gfx::LinearAnimation> bgcolor_animation_;
SkColor bgcolor_origin_;
diff --git a/chromium/ui/message_center/views/notification_header_view.cc b/chromium/ui/message_center/views/notification_header_view.cc
index d6f7a7e5f20..731494c65f6 100644
--- a/chromium/ui/message_center/views/notification_header_view.cc
+++ b/chromium/ui/message_center/views/notification_header_view.cc
@@ -9,6 +9,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
+#include "build/build_config.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/color_palette.h"
@@ -36,27 +37,27 @@ constexpr int kHeaderHorizontalSpacing = 2;
// The padding outer the header and the control buttons.
constexpr gfx::Insets kHeaderOuterPadding(2, 2, 0, 2);
-// Paddings of the views of texts.
-// Top: 9px = 11px (from the mock) - 2px (outer padding)
-// Buttom: 6px from the mock
-constexpr gfx::Insets kTextViewPadding(9, 0, 6, 0);
+// Default paddings of the views of texts. Adjusted on Windows.
+// Top: 9px = 11px (from the mock) - 2px (outer padding).
+// Buttom: 6px from the mock.
+constexpr gfx::Insets kTextViewPaddingDefault(9, 0, 6, 0);
// Paddings of the entire header.
-// Left: 14px = 16px (from the mock) - 2px (outer padding)
-// Right: 2px = minimum padding between the control buttons and the header
+// Left: 14px = 16px (from the mock) - 2px (outer padding).
+// Right: 2px = minimum padding between the control buttons and the header.
constexpr gfx::Insets kHeaderPadding(0, 14, 0, 2);
// Paddings of the app icon (small image).
-// Top: 8px = 10px (from the mock) - 2px (outer padding)
-// Bottom: 4px from the mock
-// Right: 4px = 6px (from the mock) - kHeaderHorizontalSpacing
+// Top: 8px = 10px (from the mock) - 2px (outer padding).
+// Bottom: 4px from the mock.
+// Right: 4px = 6px (from the mock) - kHeaderHorizontalSpacing.
constexpr gfx::Insets kAppIconPadding(8, 0, 4, 4);
// Size of the expand icon. 8px = 32px - 15px - 9px (values from the mock).
constexpr int kExpandIconSize = 8;
// Paddings of the expand buttons.
-// Top: 13px = 15px (from the mock) - 2px (outer padding)
-// Bottom: 9px from the mock
+// Top: 13px = 15px (from the mock) - 2px (outer padding).
+// Bottom: 9px from the mock.
constexpr gfx::Insets kExpandIconViewPadding(13, 2, 9, 0);
// Bullet character. The divider symbol between different parts of the header.
@@ -115,7 +116,7 @@ void ExpandButton::OnBlur() {
}
void ExpandButton::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_BUTTON;
+ node_data->role = ax::mojom::Role::kButton;
node_data->SetName(views::ImageView::GetTooltipText());
}
@@ -157,6 +158,27 @@ gfx::FontList GetHeaderTextFontList() {
return gfx::FontList(font);
}
+gfx::Insets CalculateTopPadding(int font_list_height) {
+#if defined(OS_WIN)
+ // On Windows, the fonts can have slightly different metrics reported,
+ // depending on where the code runs. In Chrome, DirectWrite is on, which means
+ // font metrics are reported from Skia, which rounds from float using ceil.
+ // In unit tests, however, GDI is used to report metrics, and the height
+ // reported there is consistent with other platforms. This means there is a
+ // difference of 1px in height between Chrome on Windows and everything else
+ // (where everything else includes unit tests on Windows). This 1px causes the
+ // text and everything else to stop aligning correctly, so we account for it
+ // by shrinking the top padding by 1.
+ if (font_list_height != 15) {
+ DCHECK_EQ(16, font_list_height);
+ return kTextViewPaddingDefault - gfx::Insets(1 /* top */, 0, 0, 0);
+ }
+#endif
+
+ DCHECK_EQ(15, font_list_height);
+ return kTextViewPaddingDefault;
+}
+
} // namespace
NotificationHeaderView::NotificationHeaderView(
@@ -188,11 +210,10 @@ NotificationHeaderView::NotificationHeaderView(
DCHECK_EQ(kInnerHeaderHeight, app_icon_view_->GetPreferredSize().height());
app_info_container->AddChildView(app_icon_view_);
- // Font list for text views. The height must be 15px to match with the mock.
+ // Font list for text views.
gfx::FontList font_list = GetHeaderTextFontList();
- DCHECK_EQ(15, font_list.GetHeight());
-
const int font_list_height = font_list.GetHeight();
+ gfx::Insets text_view_padding(CalculateTopPadding(font_list_height));
// App name view
app_name_view_ = new views::Label(base::string16());
@@ -200,7 +221,7 @@ NotificationHeaderView::NotificationHeaderView(
app_name_view_->SetLineHeight(font_list_height);
app_name_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
app_name_view_->SetEnabledColor(accent_color_);
- app_name_view_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
+ app_name_view_->SetBorder(views::CreateEmptyBorder(text_view_padding));
DCHECK_EQ(kInnerHeaderHeight, app_name_view_->GetPreferredSize().height());
app_info_container->AddChildView(app_name_view_);
@@ -210,7 +231,7 @@ NotificationHeaderView::NotificationHeaderView(
summary_text_divider_->SetFontList(font_list);
summary_text_divider_->SetLineHeight(font_list_height);
summary_text_divider_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- summary_text_divider_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
+ summary_text_divider_->SetBorder(views::CreateEmptyBorder(text_view_padding));
summary_text_divider_->SetVisible(false);
DCHECK_EQ(kInnerHeaderHeight,
summary_text_divider_->GetPreferredSize().height());
@@ -221,7 +242,7 @@ NotificationHeaderView::NotificationHeaderView(
summary_text_view_->SetFontList(font_list);
summary_text_view_->SetLineHeight(font_list_height);
summary_text_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- summary_text_view_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
+ summary_text_view_->SetBorder(views::CreateEmptyBorder(text_view_padding));
summary_text_view_->SetVisible(false);
DCHECK_EQ(kInnerHeaderHeight,
summary_text_view_->GetPreferredSize().height());
@@ -233,7 +254,7 @@ NotificationHeaderView::NotificationHeaderView(
timestamp_divider_->SetFontList(font_list);
timestamp_divider_->SetLineHeight(font_list_height);
timestamp_divider_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- timestamp_divider_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
+ timestamp_divider_->SetBorder(views::CreateEmptyBorder(text_view_padding));
timestamp_divider_->SetVisible(false);
DCHECK_EQ(kInnerHeaderHeight,
timestamp_divider_->GetPreferredSize().height());
@@ -244,7 +265,7 @@ NotificationHeaderView::NotificationHeaderView(
timestamp_view_->SetFontList(font_list);
timestamp_view_->SetLineHeight(font_list_height);
timestamp_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- timestamp_view_->SetBorder(views::CreateEmptyBorder(kTextViewPadding));
+ timestamp_view_->SetBorder(views::CreateEmptyBorder(text_view_padding));
timestamp_view_->SetVisible(false);
DCHECK_EQ(kInnerHeaderHeight, timestamp_view_->GetPreferredSize().height());
app_info_container->AddChildView(timestamp_view_);
@@ -352,6 +373,14 @@ bool NotificationHeaderView::IsExpandButtonEnabled() {
return expand_button_->visible();
}
+void NotificationHeaderView::SetSubpixelRenderingEnabled(bool enabled) {
+ app_name_view_->SetSubpixelRenderingEnabled(enabled);
+ summary_text_divider_->SetSubpixelRenderingEnabled(enabled);
+ summary_text_view_->SetSubpixelRenderingEnabled(enabled);
+ timestamp_divider_->SetSubpixelRenderingEnabled(enabled);
+ timestamp_view_->SetSubpixelRenderingEnabled(enabled);
+}
+
std::unique_ptr<views::InkDrop> NotificationHeaderView::CreateInkDrop() {
return std::make_unique<views::InkDropStub>();
}
diff --git a/chromium/ui/message_center/views/notification_header_view.h b/chromium/ui/message_center/views/notification_header_view.h
index 7a316d38f1c..dd40f3f5ebf 100644
--- a/chromium/ui/message_center/views/notification_header_view.h
+++ b/chromium/ui/message_center/views/notification_header_view.h
@@ -40,6 +40,7 @@ class NotificationHeaderView : public views::Button {
void ClearOverflowIndicator();
void ClearTimestamp();
bool IsExpandButtonEnabled();
+ void SetSubpixelRenderingEnabled(bool enabled);
// Button override:
std::unique_ptr<views::InkDrop> CreateInkDrop() override;
@@ -52,7 +53,7 @@ class NotificationHeaderView : public views::Button {
// Update visibility for both |summary_text_view_| and |timestamp_view_|.
void UpdateSummaryTextVisibility();
- SkColor accent_color_ = message_center::kNotificationDefaultAccentColor;
+ SkColor accent_color_ = kNotificationDefaultAccentColor;
views::Label* app_name_view_ = nullptr;
views::Label* summary_text_divider_ = nullptr;
diff --git a/chromium/ui/message_center/views/notification_menu_model.h b/chromium/ui/message_center/views/notification_menu_model.h
index 867f1f1752f..22658b74b00 100644
--- a/chromium/ui/message_center/views/notification_menu_model.h
+++ b/chromium/ui/message_center/views/notification_menu_model.h
@@ -8,7 +8,7 @@
#include "base/macros.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/message_center/message_center_export.h"
-#include "ui/message_center/notification.h"
+#include "ui/message_center/public/cpp/notification.h"
namespace message_center {
diff --git a/chromium/ui/message_center/views/notification_menu_model_unittest.cc b/chromium/ui/message_center/views/notification_menu_model_unittest.cc
index e5b9f010fad..ab0ca492524 100644
--- a/chromium/ui/message_center/views/notification_menu_model_unittest.cc
+++ b/chromium/ui/message_center/views/notification_menu_model_unittest.cc
@@ -11,14 +11,14 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/models/menu_model.h"
#include "ui/message_center/message_center.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_types.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/message_center/ui_controller.h"
namespace message_center {
namespace {
-class TestNotificationDelegate : public message_center::NotificationDelegate {
+class TestNotificationDelegate : public NotificationDelegate {
public:
TestNotificationDelegate() = default;
@@ -54,12 +54,11 @@ class NotificationMenuModelTest : public testing::Test {
Notification* AddNotification(const std::string& id, NotifierId notifier_id) {
std::unique_ptr<Notification> notification(new Notification(
- message_center::NOTIFICATION_TYPE_SIMPLE, id,
+ NOTIFICATION_TYPE_SIMPLE, id,
base::ASCIIToUTF16("Test Web Notification"),
base::ASCIIToUTF16("Notification message body."), gfx::Image(),
base::ASCIIToUTF16("www.test.org"), GURL(), notifier_id,
- message_center::RichNotificationData(),
- new TestNotificationDelegate()));
+ RichNotificationData(), new TestNotificationDelegate()));
Notification* notification_ptr = notification.get();
message_center_->AddNotification(std::move(notification));
return notification_ptr;
@@ -81,11 +80,11 @@ TEST_F(NotificationMenuModelTest, ContextMenuTestWithMessageCenter) {
NotifierId notifier_id2(NotifierId::APPLICATION, "sample-app");
std::unique_ptr<Notification> notification = std::make_unique<Notification>(
- message_center::NOTIFICATION_TYPE_SIMPLE, id2,
+ NOTIFICATION_TYPE_SIMPLE, id2,
base::ASCIIToUTF16("Test Web Notification"),
base::ASCIIToUTF16("Notification message body."), gfx::Image(),
- display_source, GURL(), notifier_id2,
- message_center::RichNotificationData(), new TestNotificationDelegate());
+ display_source, GURL(), notifier_id2, RichNotificationData(),
+ new TestNotificationDelegate());
std::unique_ptr<ui::MenuModel> model(
std::make_unique<NotificationMenuModel>(*notification));
diff --git a/chromium/ui/message_center/views/notification_view.cc b/chromium/ui/message_center/views/notification_view.cc
index 8b34638444c..7dc5d5d0346 100644
--- a/chromium/ui/message_center/views/notification_view.cc
+++ b/chromium/ui/message_center/views/notification_view.cc
@@ -23,11 +23,10 @@
#include "ui/gfx/text_elider.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_style.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_types.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/message_center/views/bounded_label.h"
-#include "ui/message_center/views/constants.h"
#include "ui/message_center/views/notification_button.h"
#include "ui/message_center/views/notification_control_buttons_view.h"
#include "ui/message_center/views/padded_button.h"
@@ -52,6 +51,18 @@ namespace message_center {
namespace {
+const int kTextBottomPadding = 12;
+const int kItemTitleToMessagePadding = 3;
+
+// Character limit = pixels per line * line limit / min. pixels per character.
+const int kMinPixelsPerTitleCharacter = 4;
+
+constexpr size_t kMessageCharacterLimit =
+ kNotificationWidth * kMessageExpandedLineLimit / 3;
+
+constexpr size_t kContextMessageCharacterLimit =
+ kNotificationWidth * kContextMessageLineLimit / 3;
+
// Dimensions.
const int kProgressBarBottomPadding = 0;
@@ -109,14 +120,14 @@ NotificationItemView::NotificationItemView(const NotificationItem& item) {
title->set_collapse_when_hidden(true);
title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
title->SetEnabledColor(kRegularTextColor);
- title->SetBackgroundColor(kRegularTextBackgroundColor);
+ title->SetAutoColorReadabilityEnabled(false);
AddChildView(title);
views::Label* message = new views::Label(item.message);
message->set_collapse_when_hidden(true);
message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
message->SetEnabledColor(kDimTextColor);
- message->SetBackgroundColor(kDimTextBackgroundColor);
+ message->SetAutoColorReadabilityEnabled(false);
AddChildView(message);
PreferredSizeChanged();
@@ -391,19 +402,18 @@ void NotificationView::CreateOrUpdateTitleView(
const gfx::FontList& font_list =
views::Label().font_list().DeriveWithSizeDelta(2);
- int title_character_limit =
+ constexpr int kTitleCharacterLimit =
kNotificationWidth * kMaxTitleLines / kMinPixelsPerTitleCharacter;
- base::string16 title = gfx::TruncateString(notification.title(),
- title_character_limit,
- gfx::WORD_BREAK);
+ base::string16 title = gfx::TruncateString(
+ notification.title(), kTitleCharacterLimit, gfx::WORD_BREAK);
if (!title_view_) {
int padding = kTitleLineHeight - font_list.GetHeight();
title_view_ = new BoundedLabel(title, font_list);
title_view_->SetLineHeight(kTitleLineHeight);
title_view_->SetLineLimit(kMaxTitleLines);
- title_view_->SetColors(kRegularTextColor, kRegularTextBackgroundColor);
+ title_view_->SetColor(kRegularTextColor);
title_view_->SetBorder(MakeTextBorder(padding, 3, 0));
top_view_->AddChildView(title_view_);
} else {
@@ -429,7 +439,7 @@ void NotificationView::CreateOrUpdateMessageView(
int padding = kMessageLineHeight - views::Label().font_list().GetHeight();
message_view_ = new BoundedLabel(text);
message_view_->SetLineHeight(kMessageLineHeight);
- message_view_->SetColors(kRegularTextColor, kDimTextBackgroundColor);
+ message_view_->SetColor(kRegularTextColor);
message_view_->SetBorder(MakeTextBorder(padding, 4, 0));
top_view_->AddChildView(message_view_);
} else {
@@ -473,8 +483,7 @@ void NotificationView::CreateOrUpdateContextMessageView(
context_message_view_ = new BoundedLabel(message);
context_message_view_->SetLineLimit(kContextMessageLineLimit);
context_message_view_->SetLineHeight(kMessageLineHeight);
- context_message_view_->SetColors(kDimTextColor,
- kContextTextBackgroundColor);
+ context_message_view_->SetColor(kDimTextColor);
context_message_view_->SetBorder(MakeTextBorder(padding, 4, 0));
top_view_->AddChildView(context_message_view_);
} else {
diff --git a/chromium/ui/message_center/views/notification_view.h b/chromium/ui/message_center/views/notification_view.h
index c1da69280ed..f1f0e2fbdef 100644
--- a/chromium/ui/message_center/views/notification_view.h
+++ b/chromium/ui/message_center/views/notification_view.h
@@ -85,7 +85,7 @@ class MESSAGE_CENTER_EXPORT NotificationView
void CreateOrUpdateSmallIconView(const Notification& notification);
void CreateOrUpdateImageView(const Notification& notification);
void CreateOrUpdateActionButtonViews(const Notification& notification);
- // TODO(yoshiki): Move this to message_center::MessageView
+ // TODO(yoshiki): Move this to MessageView
void UpdateControlButtonsVisibilityWithNotification(
const Notification& notification);
diff --git a/chromium/ui/message_center/views/notification_view_md.cc b/chromium/ui/message_center/views/notification_view_md.cc
index fa12e58aa31..eaf1c4852b6 100644
--- a/chromium/ui/message_center/views/notification_view_md.cc
+++ b/chromium/ui/message_center/views/notification_view_md.cc
@@ -13,23 +13,24 @@
#include "ui/base/cursor/cursor.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/canvas.h"
+#include "ui/gfx/color_palette.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/text_elider.h"
#include "ui/message_center/message_center.h"
-#include "ui/message_center/notification.h"
-#include "ui/message_center/notification_types.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/message_center/vector_icons.h"
#include "ui/message_center/views/bounded_label.h"
-#include "ui/message_center/views/constants.h"
#include "ui/message_center/views/notification_control_buttons_view.h"
#include "ui/message_center/views/notification_header_view.h"
#include "ui/message_center/views/padded_button.h"
#include "ui/message_center/views/proportional_image_view.h"
#include "ui/strings/grit/ui_strings.h"
+#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
#include "ui/views/animation/ink_drop_highlight.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
@@ -64,31 +65,37 @@ constexpr gfx::Size kLargeImageMinSize(328, 0);
constexpr gfx::Size kLargeImageMaxSize(328, 218);
constexpr gfx::Insets kLeftContentPadding(2, 4, 0, 4);
constexpr gfx::Insets kLeftContentPaddingWithIcon(2, 4, 0, 12);
-constexpr gfx::Insets kNotificationInputPadding(0, 16, 0, 16);
+constexpr gfx::Insets kInputTextfieldPadding(16, 16, 16, 0);
+constexpr gfx::Insets kInputReplyButtonPadding(0, 14, 0, 14);
constexpr gfx::Insets kSettingsRowPadding(8, 0, 0, 0);
constexpr gfx::Insets kSettingsRadioButtonPadding(14, 18, 14, 18);
constexpr gfx::Insets kSettingsButtonRowPadding(8);
// Background of inline actions area.
-const SkColor kActionsRowBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee);
-// Base ink drop color of action buttons.
-const SkColor kActionButtonInkDropBaseColor = SkColorSetRGB(0x0, 0x0, 0x0);
+constexpr SkColor kActionsRowBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee);
// Ripple ink drop opacity of action buttons.
const float kActionButtonInkDropRippleVisibleOpacity = 0.08f;
// Highlight (hover) ink drop opacity of action buttons.
const float kActionButtonInkDropHighlightVisibleOpacity = 0.08f;
// Text color of action button.
-const SkColor kActionButtonTextColor = SkColorSetRGB(0x33, 0x67, 0xD6);
+constexpr SkColor kActionButtonTextColor = gfx::kGoogleBlue700;
// Background color of the large image.
-const SkColor kLargeImageBackgroundColor = SkColorSetRGB(0xf5, 0xf5, 0xf5);
+constexpr SkColor kLargeImageBackgroundColor = SkColorSetRGB(0xf5, 0xf5, 0xf5);
-const SkColor kRegularTextColorMD = SkColorSetRGB(0x21, 0x21, 0x21);
-const SkColor kDimTextColorMD = SkColorSetRGB(0x75, 0x75, 0x75);
+constexpr SkColor kRegularTextColorMD = SkColorSetRGB(0x21, 0x21, 0x21);
+constexpr SkColor kDimTextColorMD = SkColorSetRGB(0x75, 0x75, 0x75);
-// The text color and the background color of inline reply input field.
-const SkColor kInputTextColor = SkColorSetRGB(0xFF, 0xFF, 0xFF);
-const SkColor kInputPlaceholderColor = SkColorSetARGB(0x8A, 0xFF, 0xFF, 0xFF);
-const SkColor kInputBackgroundColor = SkColorSetRGB(0x33, 0x67, 0xD6);
+// Background of inline settings area.
+const SkColor kSettingsRowBackgroundColor = SkColorSetRGB(0xee, 0xee, 0xee);
+
+// Text color and icon color of inline reply area when the textfield is empty.
+constexpr SkColor kTextfieldPlaceholderTextColorMD =
+ SkColorSetA(SK_ColorWHITE, 0x8A);
+constexpr SkColor kTextfieldPlaceholderIconColorMD =
+ SkColorSetA(SK_ColorWHITE, 0x60);
+
+// The icon size of inline reply input field.
+constexpr int kInputReplyButtonSize = 20;
// Max number of lines for message_view_.
constexpr int kMaxLinesForMessageView = 1;
@@ -99,17 +106,23 @@ constexpr int kCompactTitleMessageViewSpacing = 12;
constexpr int kProgressBarHeight = 4;
constexpr int kMessageViewWidthWithIcon =
- message_center::kNotificationWidth - kIconViewSize.width() -
+ kNotificationWidth - kIconViewSize.width() -
kLeftContentPaddingWithIcon.left() - kLeftContentPaddingWithIcon.right() -
kContentRowPadding.left() - kContentRowPadding.right();
constexpr int kMessageViewWidth =
- message_center::kNotificationWidth - kLeftContentPadding.left() -
+ kNotificationWidth - kLeftContentPadding.left() -
kLeftContentPadding.right() - kContentRowPadding.left() -
kContentRowPadding.right();
-// "Roboto-Regular, 13sp" is specified in the mock.
-constexpr int kTextFontSize = 13;
+const int kMinPixelsPerTitleCharacterMD = 4;
+
+// Character limit = pixels per line * line limit / min. pixels per character.
+constexpr size_t kMessageCharacterLimitMD =
+ kNotificationWidth * kMessageExpandedLineLimit / 3;
+
+// The default is 12, so this normally come out to 13.
+constexpr int kTextFontSizeDelta = 1;
// In progress notification, if both the title and the message are long, the
// message would be prioritized and the title would be elided.
@@ -117,13 +130,21 @@ constexpr int kTextFontSize = 13;
// the ratio of the message width is limited to this value.
constexpr double kProgressNotificationMessageRatio = 0.7;
+// Users on ChromeOS are used to the Settings and Close buttons not being
+// visible at all times, but users on other platforms expect them to be visible.
+constexpr bool AlwaysShowControlButtons() {
+#if defined(OS_CHROMEOS)
+ return false;
+#else
+ return true;
+#endif
+}
+
// FontList for the texts except for the header.
gfx::FontList GetTextFontList() {
gfx::Font default_font;
- int font_size_delta = kTextFontSize - default_font.GetFontSize();
- gfx::Font font = default_font.Derive(font_size_delta, gfx::Font::NORMAL,
+ gfx::Font font = default_font.Derive(kTextFontSizeDelta, gfx::Font::NORMAL,
gfx::Font::Weight::NORMAL);
- DCHECK_EQ(kTextFontSize, font.GetFontSize());
return gfx::FontList(font);
}
@@ -150,7 +171,7 @@ class ClickActivator : public ui::EventHandler {
// ItemView ////////////////////////////////////////////////////////////////////
-ItemView::ItemView(const message_center::NotificationItem& item) {
+ItemView::ItemView(const NotificationItem& item) {
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::kHorizontal, gfx::Insets(), 0));
@@ -160,8 +181,8 @@ ItemView::ItemView(const message_center::NotificationItem& item) {
title->SetFontList(font_list);
title->set_collapse_when_hidden(true);
title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- title->SetEnabledColor(message_center::kRegularTextColorMD);
- title->SetBackgroundColor(message_center::kDimTextBackgroundColor);
+ title->SetEnabledColor(kRegularTextColorMD);
+ title->SetAutoColorReadabilityEnabled(false);
AddChildView(title);
views::Label* message = new views::Label(l10n_util::GetStringFUTF16(
@@ -170,7 +191,7 @@ ItemView::ItemView(const message_center::NotificationItem& item) {
message->set_collapse_when_hidden(true);
message->SetHorizontalAlignment(gfx::ALIGN_LEFT);
message->SetEnabledColor(kDimTextColorMD);
- message->SetBackgroundColor(message_center::kDimTextBackgroundColor);
+ message->SetAutoColorReadabilityEnabled(false);
AddChildView(message);
}
@@ -189,29 +210,30 @@ const char* CompactTitleMessageView::GetClassName() const {
}
CompactTitleMessageView::CompactTitleMessageView() {
- SetLayoutManager(std::make_unique<views::FillLayout>());
-
const gfx::FontList& font_list = GetTextFontList();
- title_view_ = new views::Label();
- title_view_->SetFontList(font_list);
- title_view_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- title_view_->SetEnabledColor(kRegularTextColorMD);
- AddChildView(title_view_);
-
- message_view_ = new views::Label();
- message_view_->SetFontList(font_list);
- message_view_->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
- message_view_->SetEnabledColor(kDimTextColorMD);
- AddChildView(message_view_);
+ title_ = new views::Label();
+ title_->SetFontList(font_list);
+ title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ title_->SetEnabledColor(kRegularTextColorMD);
+ AddChildView(title_);
+
+ message_ = new views::Label();
+ message_->SetFontList(font_list);
+ message_->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
+ message_->SetEnabledColor(kDimTextColorMD);
+ AddChildView(message_);
}
-void CompactTitleMessageView::OnPaint(gfx::Canvas* canvas) {
- base::string16 title = title_;
- base::string16 message = message_;
-
- const gfx::FontList& font_list = GetTextFontList();
+gfx::Size CompactTitleMessageView::CalculatePreferredSize() const {
+ gfx::Size title_size = title_->GetPreferredSize();
+ gfx::Size message_size = message_->GetPreferredSize();
+ return gfx::Size(title_size.width() + message_size.width() +
+ kCompactTitleMessageViewSpacing,
+ std::max(title_size.height(), message_size.height()));
+}
+void CompactTitleMessageView::Layout() {
// Elides title and message.
// * If the message is too long, the message occupies at most
// kProgressNotificationMessageRatio of the width.
@@ -220,21 +242,24 @@ void CompactTitleMessageView::OnPaint(gfx::Canvas* canvas) {
// title is shown.
// * If they are short enough, the title is left-aligned and the message is
// right-aligned.
- message = gfx::ElideText(
- message, font_list,
- title.empty()
- ? width()
- : static_cast<int>(kProgressNotificationMessageRatio * width()),
- gfx::ELIDE_TAIL);
- const int message_width = gfx::Canvas::GetStringWidthF(message, font_list);
+ const int message_width = std::min(
+ message_->GetPreferredSize().width(),
+ title_->GetPreferredSize().width() > 0
+ ? static_cast<int>(kProgressNotificationMessageRatio * width())
+ : width());
const int title_width =
std::max(0, width() - message_width - kCompactTitleMessageViewSpacing);
- title = gfx::ElideText(title, font_list, title_width, gfx::ELIDE_TAIL);
- title_view_->SetText(title);
- message_view_->SetText(message);
+ title_->SetBounds(0, 0, title_width, height());
+ message_->SetBounds(width() - message_width, 0, message_width, height());
+}
- views::View::OnPaint(canvas);
+void CompactTitleMessageView::set_title(const base::string16& title) {
+ title_->SetText(title);
+}
+
+void CompactTitleMessageView::set_message(const base::string16& message) {
+ message_->SetText(message);
}
// LargeImageView //////////////////////////////////////////////////////////////
@@ -301,8 +326,7 @@ LargeImageContainerView::LargeImageContainerView()
: image_view_(new LargeImageView()) {
SetLayoutManager(std::make_unique<views::FillLayout>());
SetBorder(views::CreateEmptyBorder(kLargeImageContainerPadding));
- SetBackground(
- views::CreateSolidBackground(message_center::kImageBackgroundColor));
+ SetBackground(views::CreateSolidBackground(kImageBackgroundColor));
AddChildView(image_view_);
}
@@ -318,19 +342,18 @@ const char* LargeImageContainerView::GetClassName() const {
// NotificationButtonMD ////////////////////////////////////////////////////////
-NotificationButtonMD::NotificationButtonMD(views::ButtonListener* listener,
- bool is_inline_reply,
- const base::string16& label,
- const base::string16& placeholder)
+NotificationButtonMD::NotificationButtonMD(
+ views::ButtonListener* listener,
+ const base::string16& label,
+ const base::Optional<base::string16>& placeholder)
: views::LabelButton(listener,
base::i18n::ToUpper(label),
views::style::CONTEXT_BUTTON_MD),
- is_inline_reply_(is_inline_reply),
placeholder_(placeholder) {
SetHorizontalAlignment(gfx::ALIGN_CENTER);
SetInkDropMode(views::LabelButton::InkDropMode::ON);
set_has_ink_drop_action_on_click(true);
- set_ink_drop_base_color(kActionButtonInkDropBaseColor);
+ set_ink_drop_base_color(SK_ColorBLACK);
set_ink_drop_visible_opacity(kActionButtonInkDropRippleVisibleOpacity);
SetEnabledTextColors(kActionButtonTextColor);
SetBorder(views::CreateEmptyBorder(kActionButtonPadding));
@@ -356,35 +379,141 @@ NotificationButtonMD::CreateInkDropHighlight() const {
return highlight;
}
-// NotificationInputMD /////////////////////////////////////////////////////////
+// NotificationInputTextfieldMD ////////////////////////////////////////////////
-NotificationInputMD::NotificationInputMD(NotificationInputDelegate* delegate)
- : delegate_(delegate), index_(0) {
- set_controller(this);
- SetTextColor(kInputTextColor);
- SetBackgroundColor(kInputBackgroundColor);
- set_placeholder_text_color(kInputPlaceholderColor);
- SetBorder(views::CreateEmptyBorder(kNotificationInputPadding));
+NotificationInputTextfieldMD::NotificationInputTextfieldMD(
+ views::TextfieldController* controller)
+ : index_(0) {
+ set_controller(controller);
+ SetTextColor(SK_ColorWHITE);
+ SetBackgroundColor(SK_ColorTRANSPARENT);
+ set_placeholder_text_color(kTextfieldPlaceholderTextColorMD);
+ SetBorder(views::CreateEmptyBorder(kInputTextfieldPadding));
}
-NotificationInputMD::~NotificationInputMD() = default;
+NotificationInputTextfieldMD::~NotificationInputTextfieldMD() = default;
+
+void NotificationInputTextfieldMD::set_placeholder(
+ const base::string16& placeholder) {
+ if (placeholder.empty()) {
+ set_placeholder_text(l10n_util::GetStringUTF16(
+ IDS_MESSAGE_CENTER_NOTIFICATION_INLINE_REPLY_PLACEHOLDER));
+ } else {
+ set_placeholder_text(placeholder);
+ }
+}
+
+// NotificationInputReplyButtonMD //////////////////////////////////////////////
+
+NotificationInputReplyButtonMD::NotificationInputReplyButtonMD(
+ views::ButtonListener* listener)
+ : views::ImageButton(listener) {
+ SetPlaceholderImage();
+ SetBorder(views::CreateEmptyBorder(kInputReplyButtonPadding));
+ SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
+}
+
+NotificationInputReplyButtonMD::~NotificationInputReplyButtonMD() = default;
+
+void NotificationInputReplyButtonMD::SetNormalImage() {
+ SetImage(STATE_NORMAL,
+ gfx::CreateVectorIcon(kNotificationInlineReplyIcon,
+ kInputReplyButtonSize, SK_ColorWHITE));
+}
-bool NotificationInputMD::HandleKeyEvent(views::Textfield* sender,
- const ui::KeyEvent& event) {
+void NotificationInputReplyButtonMD::SetPlaceholderImage() {
+ SetImage(
+ STATE_NORMAL,
+ gfx::CreateVectorIcon(kNotificationInlineReplyIcon, kInputReplyButtonSize,
+ kTextfieldPlaceholderIconColorMD));
+}
+
+// NotificationInputContainerMD ////////////////////////////////////////////////
+
+NotificationInputContainerMD::NotificationInputContainerMD(
+ NotificationInputDelegate* delegate)
+ : delegate_(delegate),
+ ink_drop_container_(new views::InkDropContainerView()),
+ textfield_(new NotificationInputTextfieldMD(this)),
+ button_(new NotificationInputReplyButtonMD(this)) {
+ auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
+ views::BoxLayout::kHorizontal, gfx::Insets(), 0));
+ SetBackground(views::CreateSolidBackground(kActionsRowBackgroundColor));
+
+ SetInkDropMode(InkDropMode::ON);
+ set_ink_drop_visible_opacity(1);
+
+ ink_drop_container_->SetPaintToLayer();
+ ink_drop_container_->layer()->SetFillsBoundsOpaquely(false);
+ AddChildView(ink_drop_container_);
+
+ AddChildView(textfield_);
+ layout->SetFlexForView(textfield_, 1);
+
+ AddChildView(button_);
+}
+
+NotificationInputContainerMD::~NotificationInputContainerMD() = default;
+
+void NotificationInputContainerMD::AnimateBackground(
+ const ui::LocatedEvent& event) {
+ if (View::HitTestPoint(event.location()))
+ AnimateInkDrop(views::InkDropState::ACTION_PENDING,
+ ui::LocatedEvent::FromIfValid(&event));
+}
+
+void NotificationInputContainerMD::AddInkDropLayer(ui::Layer* ink_drop_layer) {
+ textfield_->SetPaintToLayer();
+ textfield_->layer()->SetFillsBoundsOpaquely(false);
+ button_->SetPaintToLayer();
+ button_->layer()->SetFillsBoundsOpaquely(false);
+ ink_drop_container_->AddInkDropLayer(ink_drop_layer);
+ InstallInkDropMask(ink_drop_layer);
+}
+
+void NotificationInputContainerMD::RemoveInkDropLayer(
+ ui::Layer* ink_drop_layer) {
+ textfield_->DestroyLayer();
+ button_->DestroyLayer();
+ ResetInkDropMask();
+ ink_drop_container_->RemoveInkDropLayer(ink_drop_layer);
+}
+
+std::unique_ptr<views::InkDropRipple>
+NotificationInputContainerMD::CreateInkDropRipple() const {
+ return std::make_unique<views::FloodFillInkDropRipple>(
+ size(), GetInkDropCenterBasedOnLastEvent(), GetInkDropBaseColor(),
+ ink_drop_visible_opacity());
+}
+
+SkColor NotificationInputContainerMD::GetInkDropBaseColor() const {
+ return gfx::kGoogleBlue700;
+}
+
+bool NotificationInputContainerMD::HandleKeyEvent(views::Textfield* sender,
+ const ui::KeyEvent& event) {
if (event.type() == ui::ET_KEY_PRESSED &&
event.key_code() == ui::VKEY_RETURN) {
- delegate_->OnNotificationInputSubmit(index_, text());
+ delegate_->OnNotificationInputSubmit(textfield_->index(),
+ textfield_->text());
return true;
}
return event.type() == ui::ET_KEY_RELEASED;
}
-void NotificationInputMD::set_placeholder(const base::string16& placeholder) {
- if (placeholder.empty()) {
- set_placeholder_text(l10n_util::GetStringUTF16(
- IDS_MESSAGE_CENTER_NOTIFICATION_INLINE_REPLY_PLACEHOLDER));
+void NotificationInputContainerMD::OnAfterUserAction(views::Textfield* sender) {
+ if (textfield_->text().empty()) {
+ button_->SetPlaceholderImage();
} else {
- set_placeholder_text(placeholder);
+ button_->SetNormalImage();
+ }
+}
+
+void NotificationInputContainerMD::ButtonPressed(views::Button* sender,
+ const ui::Event& event) {
+ if (sender == button_) {
+ delegate_->OnNotificationInputSubmit(textfield_->index(),
+ textfield_->text());
}
}
@@ -396,6 +525,7 @@ class InlineSettingsRadioButton : public views::RadioButton {
: views::RadioButton(label_text, 1 /* group */, true /* force_md */) {
label()->SetFontList(GetTextFontList());
label()->SetEnabledColor(kRegularTextColorMD);
+ label()->SetSubpixelRenderingEnabled(false);
}
};
@@ -460,10 +590,18 @@ void NotificationViewMD::CreateOrUpdateViews(const Notification& notification) {
}
NotificationViewMD::NotificationViewMD(const Notification& notification)
- : MessageView(notification), clickable_(notification.clickable()) {
+ : MessageView(notification),
+ ink_drop_container_(new views::InkDropContainerView()),
+ clickable_(notification.clickable()) {
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::kVertical, gfx::Insets(), 0));
+ set_ink_drop_visible_opacity(1);
+
+ ink_drop_container_->SetPaintToLayer();
+ ink_drop_container_->layer()->SetFillsBoundsOpaquely(false);
+ AddChildView(ink_drop_container_);
+
control_buttons_view_ =
std::make_unique<NotificationControlButtonsView>(this);
control_buttons_view_->set_owned_by_client();
@@ -511,10 +649,9 @@ NotificationViewMD::NotificationViewMD(const Notification& notification)
action_buttons_row_->SetVisible(false);
actions_row_->AddChildView(action_buttons_row_);
- // |inline_reply_| is a textfield for inline reply.
- inline_reply_ = new NotificationInputMD(this);
+ // |inline_reply_| is a container for an inline textfield.
+ inline_reply_ = new NotificationInputContainerMD(this);
inline_reply_->SetVisible(false);
-
actions_row_->AddChildView(inline_reply_);
CreateOrUpdateViews(notification);
@@ -561,6 +698,16 @@ void NotificationViewMD::Layout() {
action_buttons_row_->set_clip_path(path);
inline_reply_->set_clip_path(path);
}
+
+ // The animation is needed to run inside of the border, which is shown only
+ // when the notification is nested.
+ if (is_nested()) {
+ gfx::Rect ink_drop_bounds = GetLocalBounds();
+ ink_drop_bounds.Inset(gfx::Insets(kNotificationBorderThickness));
+ ink_drop_container_->SetBoundsRect(ink_drop_bounds);
+ } else {
+ ink_drop_container_->SetBoundsRect(GetLocalBounds());
+ }
}
void NotificationViewMD::OnFocus() {
@@ -595,16 +742,6 @@ gfx::NativeCursor NotificationViewMD::GetCursor(const ui::MouseEvent& event) {
return views::GetNativeHandCursor();
}
-void NotificationViewMD::OnMouseEntered(const ui::MouseEvent& event) {
- MessageView::OnMouseEntered(event);
- UpdateControlButtonsVisibility();
-}
-
-void NotificationViewMD::OnMouseExited(const ui::MouseEvent& event) {
- MessageView::OnMouseExited(event);
- UpdateControlButtonsVisibility();
-}
-
bool NotificationViewMD::OnMousePressed(const ui::MouseEvent& event) {
if (!event.IsOnlyLeftMouseButton())
return false;
@@ -625,6 +762,20 @@ bool NotificationViewMD::OnMousePressed(const ui::MouseEvent& event) {
return MessageView::OnMousePressed(event);
}
+void NotificationViewMD::OnMouseEvent(ui::MouseEvent* event) {
+ switch (event->type()) {
+ case ui::ET_MOUSE_ENTERED:
+ UpdateControlButtonsVisibility();
+ break;
+ case ui::ET_MOUSE_EXITED:
+ UpdateControlButtonsVisibility();
+ break;
+ default:
+ break;
+ }
+ View::OnMouseEvent(event);
+}
+
void NotificationViewMD::UpdateWithNotification(
const Notification& notification) {
MessageView::UpdateWithNotification(notification);
@@ -654,7 +805,8 @@ void NotificationViewMD::ButtonPressed(views::Button* sender,
// Tapping anywhere on |header_row_| can expand the notification, though only
// |expand_button| can be focused by TAB.
if (sender == header_row_) {
- if (IsExpandable()) {
+ if (IsExpandable() && content_row_->visible()) {
+ SetManuallyExpandedOrCollapsed(true);
ToggleExpanded();
Layout();
SchedulePaint();
@@ -666,9 +818,12 @@ void NotificationViewMD::ButtonPressed(views::Button* sender,
for (size_t i = 0; i < action_buttons_.size(); ++i) {
if (sender != action_buttons_[i])
continue;
- if (action_buttons_[i]->is_inline_reply()) {
- inline_reply_->set_index(i);
- inline_reply_->set_placeholder(action_buttons_[i]->placeholder());
+ if (action_buttons_[i]->placeholder()) {
+ inline_reply_->textfield()->set_index(i);
+ inline_reply_->textfield()->set_placeholder(
+ *action_buttons_[i]->placeholder());
+ inline_reply_->textfield()->RequestFocus();
+ inline_reply_->AnimateBackground(*event.AsLocatedEvent());
inline_reply_->SetVisible(true);
action_buttons_row_->SetVisible(false);
Layout();
@@ -682,7 +837,7 @@ void NotificationViewMD::ButtonPressed(views::Button* sender,
if (sender == settings_done_button_) {
if (block_all_button_->checked())
MessageCenter::Get()->DisableNotification(id);
- ToggleInlineSettings();
+ ToggleInlineSettings(event);
return;
}
}
@@ -703,10 +858,9 @@ void NotificationViewMD::RequestFocusOnCloseButton() {
void NotificationViewMD::CreateOrUpdateContextTitleView(
const Notification& notification) {
- header_row_->SetAccentColor(
- notification.accent_color() == SK_ColorTRANSPARENT
- ? message_center::kNotificationDefaultAccentColor
- : notification.accent_color());
+ header_row_->SetAccentColor(notification.accent_color() == SK_ColorTRANSPARENT
+ ? kNotificationDefaultAccentColor
+ : notification.accent_color());
header_row_->SetTimestamp(notification.timestamp());
base::string16 app_name = notification.display_source();
@@ -733,7 +887,7 @@ void NotificationViewMD::CreateOrUpdateTitleView(
}
int title_character_limit =
- kNotificationWidth * kMaxTitleLines / kMinPixelsPerTitleCharacter;
+ kNotificationWidth * kMaxTitleLines / kMinPixelsPerTitleCharacterMD;
base::string16 title = gfx::TruncateString(
notification.title(), title_character_limit, gfx::WORD_BREAK);
@@ -761,14 +915,14 @@ void NotificationViewMD::CreateOrUpdateMessageView(
}
base::string16 text = gfx::TruncateString(
- notification.message(), kMessageCharacterLimit, gfx::WORD_BREAK);
+ notification.message(), kMessageCharacterLimitMD, gfx::WORD_BREAK);
const gfx::FontList& font_list = GetTextFontList();
if (!message_view_) {
message_view_ = new BoundedLabel(text, font_list);
message_view_->SetLineLimit(kMaxLinesForMessageView);
- message_view_->SetColors(kDimTextColorMD, kContextTextBackgroundColor);
+ message_view_->SetColor(kDimTextColorMD);
left_content_->AddChildView(message_view_);
} else {
@@ -812,8 +966,8 @@ void NotificationViewMD::CreateOrUpdateProgressBarView(
if (!progress_bar_view_) {
progress_bar_view_ = new views::ProgressBar(kProgressBarHeight,
/* allow_round_corner */ false);
- progress_bar_view_->SetBorder(views::CreateEmptyBorder(
- message_center::kProgressBarTopPadding, 0, 0, 0));
+ progress_bar_view_->SetBorder(
+ views::CreateEmptyBorder(kProgressBarTopPadding, 0, 0, 0));
left_content_->AddChildView(progress_bar_view_);
}
@@ -875,8 +1029,13 @@ void NotificationViewMD::CreateOrUpdateListItemViews(
void NotificationViewMD::CreateOrUpdateIconView(
const Notification& notification) {
+ const bool use_image_for_icon = notification.icon().IsEmpty();
+
+ gfx::ImageSkia icon = use_image_for_icon ? notification.image().AsImageSkia()
+ : notification.icon().AsImageSkia();
+
if (notification.type() == NOTIFICATION_TYPE_PROGRESS ||
- notification.type() == NOTIFICATION_TYPE_MULTIPLE) {
+ notification.type() == NOTIFICATION_TYPE_MULTIPLE || icon.isNull()) {
DCHECK(!icon_view_ || right_content_->Contains(icon_view_));
delete icon_view_;
icon_view_ = nullptr;
@@ -888,12 +1047,6 @@ void NotificationViewMD::CreateOrUpdateIconView(
right_content_->AddChildView(icon_view_);
}
- const bool use_image_for_icon = notification.icon().IsEmpty();
- gfx::ImageSkia icon;
- if (use_image_for_icon)
- icon = notification.image().AsImageSkia();
- else
- icon = notification.icon().AsImageSkia();
icon_view_->SetImage(icon, icon.size());
// Hide the icon on the right side when the notification is expanded.
@@ -902,10 +1055,15 @@ void NotificationViewMD::CreateOrUpdateIconView(
void NotificationViewMD::CreateOrUpdateSmallIconView(
const Notification& notification) {
- if (notification.small_image().IsEmpty())
- header_row_->ClearAppIcon();
- else
+ if (!notification.vector_small_image().is_empty()) {
+ header_row_->SetAppIcon(
+ gfx::CreateVectorIcon(notification.vector_small_image(),
+ kSmallImageSizeMD, notification.accent_color()));
+ } else if (!notification.small_image().IsEmpty()) {
header_row_->SetAppIcon(notification.small_image().AsImageSkia());
+ } else {
+ header_row_->ClearAppIcon();
+ }
}
void NotificationViewMD::CreateOrUpdateImageView(
@@ -930,7 +1088,7 @@ void NotificationViewMD::CreateOrUpdateImageView(
void NotificationViewMD::CreateOrUpdateActionButtonViews(
const Notification& notification) {
- std::vector<ButtonInfo> buttons = notification.buttons();
+ const std::vector<ButtonInfo>& buttons = notification.buttons();
bool new_buttons = action_buttons_.size() != buttons.size();
if (new_buttons || buttons.size() == 0) {
@@ -944,10 +1102,8 @@ void NotificationViewMD::CreateOrUpdateActionButtonViews(
for (size_t i = 0; i < buttons.size(); ++i) {
ButtonInfo button_info = buttons[i];
if (new_buttons) {
- bool is_inline_reply =
- button_info.type == message_center::ButtonType::TEXT;
NotificationButtonMD* button = new NotificationButtonMD(
- this, is_inline_reply, button_info.title, button_info.placeholder);
+ this, button_info.title, button_info.placeholder);
action_buttons_.push_back(button);
action_buttons_row_->AddChildView(button);
} else {
@@ -980,13 +1136,13 @@ void NotificationViewMD::CreateOrUpdateActionButtonViews(
void NotificationViewMD::CreateOrUpdateInlineSettingsViews(
const Notification& notification) {
if (settings_row_) {
- DCHECK_EQ(SettingsButtonHandler::TRAY,
+ DCHECK_EQ(SettingsButtonHandler::INLINE,
notification.rich_notification_data().settings_button_handler);
return;
}
if (notification.rich_notification_data().settings_button_handler !=
- SettingsButtonHandler::TRAY) {
+ SettingsButtonHandler::INLINE) {
return;
}
@@ -994,11 +1150,28 @@ void NotificationViewMD::CreateOrUpdateInlineSettingsViews(
settings_row_ = new views::View();
settings_row_->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::kVertical, kSettingsRowPadding, 0));
- settings_row_->SetBackground(
- views::CreateSolidBackground(kActionsRowBackgroundColor));
+
+ int block_notifications_message_id = 0;
+ switch (notification.notifier_id().type) {
+ case NotifierId::APPLICATION:
+ case NotifierId::ARC_APPLICATION:
+ block_notifications_message_id =
+ IDS_MESSAGE_CENTER_BLOCK_ALL_NOTIFICATIONS_APP;
+ break;
+ case NotifierId::WEB_PAGE:
+ block_notifications_message_id =
+ IDS_MESSAGE_CENTER_BLOCK_ALL_NOTIFICATIONS_SITE;
+ break;
+ case NotifierId::SYSTEM_COMPONENT:
+ case NotifierId::SIZE:
+ block_notifications_message_id =
+ IDS_MESSAGE_CENTER_BLOCK_ALL_NOTIFICATIONS;
+ break;
+ }
+ DCHECK_NE(block_notifications_message_id, 0);
block_all_button_ = new InlineSettingsRadioButton(
- l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_BLOCK_ALL_NOTIFICATIONS));
+ l10n_util::GetStringUTF16(block_notifications_message_id));
block_all_button_->set_listener(this);
block_all_button_->SetBorder(
views::CreateEmptyBorder(kSettingsRadioButtonPadding));
@@ -1013,8 +1186,10 @@ void NotificationViewMD::CreateOrUpdateInlineSettingsViews(
settings_row_->SetVisible(false);
settings_done_button_ = new NotificationButtonMD(
- this, false, l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_DONE),
- base::EmptyString16());
+ this, l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS_DONE),
+ base::nullopt);
+ settings_done_button_->SetTextSubpixelRenderingEnabled(false);
+
auto* settings_button_row = new views::View;
auto settings_button_layout = std::make_unique<views::BoxLayout>(
views::BoxLayout::kHorizontal, kSettingsButtonRowPadding, 0);
@@ -1078,10 +1253,9 @@ void NotificationViewMD::UpdateViewForExpandedState(bool expanded) {
list_items_count_ -
(expanded ? item_views_.size() : kMaxLinesForMessageView));
- if (icon_view_)
- icon_view_->SetVisible(!hide_icon_on_expanded_ || !expanded);
-
- if (icon_view_ && icon_view_->visible()) {
+ right_content_->SetVisible(icon_view_ &&
+ (!hide_icon_on_expanded_ || !expanded));
+ if (right_content_->visible()) {
left_content_->SetBorder(
views::CreateEmptyBorder(kLeftContentPaddingWithIcon));
@@ -1099,34 +1273,38 @@ void NotificationViewMD::UpdateViewForExpandedState(bool expanded) {
}
}
-void NotificationViewMD::ToggleInlineSettings() {
+void NotificationViewMD::ToggleInlineSettings(const ui::Event& event) {
DCHECK(settings_row_);
bool inline_settings_visible = !settings_row_->visible();
settings_row_->SetVisible(inline_settings_visible);
content_row_->SetVisible(!inline_settings_visible);
- actions_row_->SetVisible(expanded_ && !inline_settings_visible);
-
- // When inline settings is shown, the background color of the entire
- // notification should be |kActionsRowBackgroundColor|.
- header_row_->SetBackground(views::CreateSolidBackground(
- inline_settings_visible ? kActionsRowBackgroundColor
- : kNotificationBackgroundColor));
// Always check "Don't block" when inline settings is shown.
// If it's already blocked, users should not see inline settings.
// Toggling should reset the state.
dont_block_button_->SetChecked(true);
+ SetExpanded(!inline_settings_visible);
+
PreferredSizeChanged();
+
+ if (inline_settings_visible)
+ AddBackgroundAnimation(event);
+ else
+ RemoveBackgroundAnimation();
+
+ Layout();
+ SchedulePaint();
}
// TODO(yoshiki): Move this to the parent class (MessageView) and share the code
// among NotificationView and ArcNotificationView.
void NotificationViewMD::UpdateControlButtonsVisibility() {
const bool target_visibility =
- IsMouseHovered() || control_buttons_view_->IsCloseButtonFocused() ||
+ AlwaysShowControlButtons() || IsMouseHovered() ||
+ control_buttons_view_->IsCloseButtonFocused() ||
control_buttons_view_->IsSettingsButtonFocused();
control_buttons_view_->SetVisible(target_visibility);
@@ -1151,11 +1329,19 @@ void NotificationViewMD::SetExpanded(bool expanded) {
PreferredSizeChanged();
}
-void NotificationViewMD::OnSettingsButtonPressed() {
+bool NotificationViewMD::IsManuallyExpandedOrCollapsed() const {
+ return manually_expanded_or_collapsed_;
+}
+
+void NotificationViewMD::SetManuallyExpandedOrCollapsed(bool value) {
+ manually_expanded_or_collapsed_ = value;
+}
+
+void NotificationViewMD::OnSettingsButtonPressed(const ui::Event& event) {
if (settings_row_)
- ToggleInlineSettings();
+ ToggleInlineSettings(event);
else
- MessageView::OnSettingsButtonPressed();
+ MessageView::OnSettingsButtonPressed(event);
}
void NotificationViewMD::Activate() {
@@ -1163,4 +1349,78 @@ void NotificationViewMD::Activate() {
GetWidget()->Activate();
}
+void NotificationViewMD::AddBackgroundAnimation(const ui::Event& event) {
+ SetInkDropMode(InkDropMode::ON);
+ // In case the animation is triggered from keyboard operation.
+ if (!event.IsLocatedEvent()) {
+ AnimateInkDrop(views::InkDropState::ACTION_PENDING, nullptr);
+ return;
+ }
+
+ // Convert the point of |event| from the coordinate system of
+ // |control_buttons_view_| to that of NotificationViewMD, create a new
+ // LocatedEvent which has the new point.
+ views::View* target = static_cast<views::View*>(event.target());
+ const gfx::Point& location = event.AsLocatedEvent()->location();
+ gfx::Point converted_location(location);
+ View::ConvertPointToTarget(target, this, &converted_location);
+ std::unique_ptr<ui::Event> cloned_event = ui::Event::Clone(event);
+ ui::LocatedEvent* cloned_located_event = cloned_event->AsLocatedEvent();
+ cloned_located_event->set_location(converted_location);
+
+ if (View::HitTestPoint(event.AsLocatedEvent()->location())) {
+ AnimateInkDrop(views::InkDropState::ACTION_PENDING,
+ ui::LocatedEvent::FromIfValid(cloned_located_event));
+ }
+}
+
+void NotificationViewMD::RemoveBackgroundAnimation() {
+ AnimateInkDrop(views::InkDropState::HIDDEN, nullptr);
+}
+
+void NotificationViewMD::AddInkDropLayer(ui::Layer* ink_drop_layer) {
+ GetInkDrop()->AddObserver(this);
+ header_row_->SetPaintToLayer();
+ header_row_->layer()->SetFillsBoundsOpaquely(false);
+ block_all_button_->SetPaintToLayer();
+ block_all_button_->layer()->SetFillsBoundsOpaquely(false);
+ dont_block_button_->SetPaintToLayer();
+ dont_block_button_->layer()->SetFillsBoundsOpaquely(false);
+ settings_done_button_->SetPaintToLayer();
+ settings_done_button_->layer()->SetFillsBoundsOpaquely(false);
+ ink_drop_container_->AddInkDropLayer(ink_drop_layer);
+ InstallInkDropMask(ink_drop_layer);
+}
+
+void NotificationViewMD::RemoveInkDropLayer(ui::Layer* ink_drop_layer) {
+ header_row_->DestroyLayer();
+ block_all_button_->DestroyLayer();
+ dont_block_button_->DestroyLayer();
+ settings_done_button_->DestroyLayer();
+ ResetInkDropMask();
+ ink_drop_container_->RemoveInkDropLayer(ink_drop_layer);
+ GetInkDrop()->RemoveObserver(this);
+}
+
+std::unique_ptr<views::InkDropRipple> NotificationViewMD::CreateInkDropRipple()
+ const {
+ return std::make_unique<views::FloodFillInkDropRipple>(
+ ink_drop_container_->size(), GetInkDropCenterBasedOnLastEvent(),
+ GetInkDropBaseColor(), ink_drop_visible_opacity());
+}
+
+SkColor NotificationViewMD::GetInkDropBaseColor() const {
+ return kSettingsRowBackgroundColor;
+}
+
+void NotificationViewMD::InkDropAnimationStarted() {
+ header_row_->SetSubpixelRenderingEnabled(false);
+}
+
+void NotificationViewMD::InkDropRippleAnimationEnded(
+ views::InkDropState ink_drop_state) {
+ if (ink_drop_state == views::InkDropState::HIDDEN)
+ header_row_->SetSubpixelRenderingEnabled(true);
+}
+
} // namespace message_center
diff --git a/chromium/ui/message_center/views/notification_view_md.h b/chromium/ui/message_center/views/notification_view_md.h
index fff369554b1..d9ed79d902b 100644
--- a/chromium/ui/message_center/views/notification_view_md.h
+++ b/chromium/ui/message_center/views/notification_view_md.h
@@ -9,15 +9,19 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "base/optional.h"
#include "ui/message_center/message_center_export.h"
#include "ui/message_center/views/message_view.h"
+#include "ui/views/animation/ink_drop_observer.h"
#include "ui/views/controls/button/button.h"
+#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/view_targeter_delegate.h"
namespace views {
+class ImageButton;
class Label;
class LabelButton;
class ProgressBar;
@@ -34,7 +38,7 @@ class ProportionalImageView;
// message next to each other within a single column.
class ItemView : public views::View {
public:
- explicit ItemView(const message_center::NotificationItem& item);
+ explicit ItemView(const NotificationItem& item);
~ItemView() override;
const char* GetClassName() const override;
@@ -52,19 +56,17 @@ class CompactTitleMessageView : public views::View {
const char* GetClassName() const override;
- void OnPaint(gfx::Canvas* canvas) override;
+ gfx::Size CalculatePreferredSize() const override;
+ void Layout() override;
- void set_title(const base::string16& title) { title_ = title; }
- void set_message(const base::string16& message) { message_ = message; }
+ void set_title(const base::string16& title);
+ void set_message(const base::string16& message);
private:
DISALLOW_COPY_AND_ASSIGN(CompactTitleMessageView);
- base::string16 title_;
- base::string16 message_;
-
- views::Label* title_view_ = nullptr;
- views::Label* message_view_ = nullptr;
+ views::Label* title_ = nullptr;
+ views::Label* message_ = nullptr;
};
class LargeImageView : public views::View {
@@ -112,9 +114,8 @@ class NotificationButtonMD : public views::LabelButton {
// |placeholder| is placeholder text shown on the input field. Only used when
// |is_inline_reply| is true.
NotificationButtonMD(views::ButtonListener* listener,
- bool is_inline_reply,
const base::string16& label,
- const base::string16& placeholder);
+ const base::Optional<base::string16>& placeholder);
~NotificationButtonMD() override;
void SetText(const base::string16& text) override;
@@ -125,12 +126,12 @@ class NotificationButtonMD : public views::LabelButton {
SkColor enabled_color_for_testing() { return label()->enabled_color(); }
- bool is_inline_reply() const { return is_inline_reply_; }
- const base::string16& placeholder() const { return placeholder_; }
+ const base::Optional<base::string16>& placeholder() const {
+ return placeholder_;
+ }
private:
- const bool is_inline_reply_;
- const base::string16 placeholder_;
+ const base::Optional<base::string16> placeholder_;
DISALLOW_COPY_AND_ASSIGN(NotificationButtonMD);
};
@@ -142,26 +143,71 @@ class NotificationInputDelegate {
virtual ~NotificationInputDelegate() = default;
};
-class NotificationInputMD : public views::Textfield,
- public views::TextfieldController {
+class NotificationInputTextfieldMD : public views::Textfield {
public:
- NotificationInputMD(NotificationInputDelegate* delegate);
- ~NotificationInputMD() override;
-
- bool HandleKeyEvent(views::Textfield* sender,
- const ui::KeyEvent& key_event) override;
+ NotificationInputTextfieldMD(views::TextfieldController* controller);
+ ~NotificationInputTextfieldMD() override;
void set_index(size_t index) { index_ = index; }
void set_placeholder(const base::string16& placeholder);
- private:
- NotificationInputDelegate* const delegate_;
+ size_t index() const { return index_; };
+ private:
// |index_| is the notification action index that should be passed as the
// argument of ClickOnNotificationButtonWithReply.
size_t index_ = 0;
- DISALLOW_COPY_AND_ASSIGN(NotificationInputMD);
+ DISALLOW_COPY_AND_ASSIGN(NotificationInputTextfieldMD);
+};
+
+class NotificationInputReplyButtonMD : public views::ImageButton {
+ public:
+ NotificationInputReplyButtonMD(views::ButtonListener* listener);
+ ~NotificationInputReplyButtonMD() override;
+
+ void SetNormalImage();
+ void SetPlaceholderImage();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(NotificationInputReplyButtonMD);
+};
+
+class NotificationInputContainerMD : public views::InkDropHostView,
+ public views::ButtonListener,
+ public views::TextfieldController {
+ public:
+ NotificationInputContainerMD(NotificationInputDelegate* delegate);
+ ~NotificationInputContainerMD() override;
+
+ void AnimateBackground(const ui::LocatedEvent& event);
+
+ // Overridden from views::InkDropHostView:
+ void AddInkDropLayer(ui::Layer* ink_drop_layer) override;
+ void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override;
+ std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override;
+ SkColor GetInkDropBaseColor() const override;
+
+ // Overridden from views::TextfieldController:
+ bool HandleKeyEvent(views::Textfield* sender,
+ const ui::KeyEvent& key_event) override;
+ void OnAfterUserAction(views::Textfield* sender) override;
+
+ // Overridden from views::ButtonListener:
+ void ButtonPressed(views::Button* sender, const ui::Event& event) override;
+
+ NotificationInputTextfieldMD* textfield() const { return textfield_; };
+ NotificationInputReplyButtonMD* button() const { return button_; };
+
+ private:
+ NotificationInputDelegate* const delegate_;
+
+ views::InkDropContainerView* const ink_drop_container_;
+
+ NotificationInputTextfieldMD* const textfield_;
+ NotificationInputReplyButtonMD* const button_;
+
+ DISALLOW_COPY_AND_ASSIGN(NotificationInputContainerMD);
};
// View that displays all current types of notification (web, basic, image, and
@@ -170,6 +216,7 @@ class NotificationInputMD : public views::Textfield,
// returned by the Create() factory method below.
class MESSAGE_CENTER_EXPORT NotificationViewMD
: public MessageView,
+ public views::InkDropObserver,
public NotificationInputDelegate,
public views::ButtonListener,
public views::ViewTargeterDelegate {
@@ -179,14 +226,22 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
void Activate();
+ void AddBackgroundAnimation(const ui::Event& event);
+ void RemoveBackgroundAnimation();
+
// Overridden from views::View:
void Layout() override;
void OnFocus() override;
void ScrollRectToVisible(const gfx::Rect& rect) override;
gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override;
- void OnMouseEntered(const ui::MouseEvent& event) override;
- void OnMouseExited(const ui::MouseEvent& event) override;
bool OnMousePressed(const ui::MouseEvent& event) override;
+ void OnMouseEvent(ui::MouseEvent* event) override;
+
+ // Overridden from views::InkDropHostView:
+ void AddInkDropLayer(ui::Layer* ink_drop_layer) override;
+ void RemoveInkDropLayer(ui::Layer* ink_drop_layer) override;
+ std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override;
+ SkColor GetInkDropBaseColor() const override;
// Overridden from MessageView:
void UpdateWithNotification(const Notification& notification) override;
@@ -197,7 +252,14 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
NotificationControlButtonsView* GetControlButtonsView() const override;
bool IsExpanded() const override;
void SetExpanded(bool expanded) override;
- void OnSettingsButtonPressed() override;
+ bool IsManuallyExpandedOrCollapsed() const override;
+ void SetManuallyExpandedOrCollapsed(bool value) override;
+
+ void OnSettingsButtonPressed(const ui::Event& event) override;
+
+ // views::InkDropObserver:
+ void InkDropAnimationStarted() override;
+ void InkDropRippleAnimationEnded(views::InkDropState ink_drop_state) override;
// Overridden from NotificationInputDelegate:
void OnNotificationInputSubmit(size_t index,
@@ -216,6 +278,7 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, ExpandLongMessage);
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, TestAccentColor);
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, UseImageAsIcon);
+ FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, NotificationWithoutIcon);
FRIEND_TEST_ALL_PREFIXES(NotificationViewMDTest, InlineSettings);
friend class NotificationViewMDTest;
@@ -241,7 +304,9 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
bool IsExpandable();
void ToggleExpanded();
void UpdateViewForExpandedState(bool expanded);
- void ToggleInlineSettings();
+ void ToggleInlineSettings(const ui::Event& event);
+
+ views::InkDropContainerView* const ink_drop_container_;
// View containing close and settings buttons
std::unique_ptr<NotificationControlButtonsView> control_buttons_view_;
@@ -249,6 +314,10 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
// Whether this notification is expanded or not.
bool expanded_ = false;
+ // True if the notification is expanded/collapsed by user interaction.
+ // If true, MessagePopupCollection will not auto-collapse the notification.
+ bool manually_expanded_or_collapsed_ = false;
+
// Whether hiding icon on the right side when expanded.
bool hide_icon_on_expanded_ = false;
@@ -279,7 +348,7 @@ class MESSAGE_CENTER_EXPORT NotificationViewMD
views::ProgressBar* progress_bar_view_ = nullptr;
CompactTitleMessageView* compact_title_message_view_ = nullptr;
views::View* action_buttons_row_ = nullptr;
- NotificationInputMD* inline_reply_ = nullptr;
+ NotificationInputContainerMD* inline_reply_ = nullptr;
// Views for inline settings.
views::RadioButton* block_all_button_ = nullptr;
diff --git a/chromium/ui/message_center/views/notification_view_md_unittest.cc b/chromium/ui/message_center/views/notification_view_md_unittest.cc
index f4d8a89d983..f8574e2975f 100644
--- a/chromium/ui/message_center/views/notification_view_md_unittest.cc
+++ b/chromium/ui/message_center/views/notification_view_md_unittest.cc
@@ -54,6 +54,11 @@ class NotificationTestDelegate : public NotificationDelegate {
submitted_reply_string_ = reply;
}
+ void Reset() {
+ clicked_button_index_ = -1;
+ submitted_reply_string_ = base::EmptyString16();
+ }
+
void DisableNotification() override { disable_notification_called_ = true; }
int clicked_button_index() const { return clicked_button_index_; }
@@ -142,7 +147,7 @@ void NotificationViewMDTest::SetUp() {
// Create a dummy notification.
delegate_ = new NotificationTestDelegate();
data_.reset(new RichNotificationData());
- data_->settings_button_handler = SettingsButtonHandler::TRAY;
+ data_->settings_button_handler = SettingsButtonHandler::INLINE;
notification_.reset(new Notification(
NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"),
base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"),
@@ -173,6 +178,7 @@ void NotificationViewMDTest::SetUp() {
}
void NotificationViewMDTest::TearDown() {
+ notification_view_->SetInkDropMode(MessageView::InkDropMode::OFF);
notification_view_->RemoveObserver(this);
widget()->Close();
notification_view_.reset();
@@ -308,8 +314,7 @@ TEST_F(NotificationViewMDTest, CreateOrUpdateTest) {
EXPECT_EQ(nullptr, notification_view()->title_view_);
EXPECT_EQ(nullptr, notification_view()->message_view_);
EXPECT_EQ(nullptr, notification_view()->image_container_view_);
- // We still expect an icon view for all layouts.
- EXPECT_NE(nullptr, notification_view()->icon_view_);
+ EXPECT_EQ(nullptr, notification_view()->icon_view_);
}
TEST_F(NotificationViewMDTest, TestIconSizing) {
@@ -468,7 +473,7 @@ TEST_F(NotificationViewMDTest, TestInlineReply) {
delegate_->set_expecting_reply_submission(true);
std::vector<ButtonInfo> buttons = CreateButtons(2);
- buttons[1].type = ButtonType::TEXT;
+ buttons[1].placeholder = base::string16();
notification()->set_buttons(buttons);
UpdateNotificationViews();
widget()->Show();
@@ -501,17 +506,53 @@ TEST_F(NotificationViewMDTest, TestInlineReply) {
generator.ClickLeftButton();
generator.ClickLeftButton();
EXPECT_TRUE(notification_view()->inline_reply_->visible());
- EXPECT_TRUE(notification_view()->inline_reply_->HasFocus());
+ EXPECT_TRUE(notification_view()->inline_reply_->textfield()->visible());
+ EXPECT_TRUE(notification_view()->inline_reply_->textfield()->HasFocus());
- // Type the text and submit.
- ui::KeyboardCode keycodes[] = {ui::VKEY_T, ui::VKEY_E, ui::VKEY_S, ui::VKEY_T,
- ui::VKEY_RETURN};
+ // Type the text.
+ ui::KeyboardCode keycodes[] = {ui::VKEY_T, ui::VKEY_E, ui::VKEY_S,
+ ui::VKEY_T};
+ for (ui::KeyboardCode keycode : keycodes) {
+ generator.PressKey(keycode, ui::EF_NONE);
+ generator.ReleaseKey(keycode, ui::EF_NONE);
+ }
+ // Submit by typing RETURN key.
+ generator.PressKey(ui::VKEY_RETURN, ui::EF_NONE);
+ generator.ReleaseKey(ui::VKEY_RETURN, ui::EF_NONE);
+ EXPECT_EQ(1, delegate_->clicked_button_index());
+ EXPECT_EQ(base::ASCIIToUTF16("test"), delegate_->submitted_reply_string());
+
+ // Reset values.
+ delegate_->Reset();
+
+ // Now construct a mouse click event 1 pixel inside the boundary of the action
+ // button.
+ cursor_location = gfx::Point(1, 1);
+ views::View::ConvertPointToScreen(notification_view()->action_buttons_[1],
+ &cursor_location);
+ generator.MoveMouseTo(cursor_location);
+ generator.ClickLeftButton();
+
+ // Nothing should be submitted at this point.
+ EXPECT_EQ(-1, delegate_->clicked_button_index());
+ EXPECT_EQ(base::EmptyString16(), delegate_->submitted_reply_string());
+
+ // Click the button again and focus on the inline textfield.
+ generator.ClickLeftButton();
+
+ // Type the text.
for (ui::KeyboardCode keycode : keycodes) {
generator.PressKey(keycode, ui::EF_NONE);
generator.ReleaseKey(keycode, ui::EF_NONE);
}
+ // Submit by clicking the reply button.
+ cursor_location = gfx::Point(1, 1);
+ views::View::ConvertPointToScreen(
+ notification_view()->inline_reply_->button(), &cursor_location);
+ generator.MoveMouseTo(cursor_location);
+ generator.ClickLeftButton();
EXPECT_EQ(1, delegate_->clicked_button_index());
EXPECT_EQ(base::ASCIIToUTF16("test"), delegate_->submitted_reply_string());
}
@@ -637,11 +678,25 @@ TEST_F(NotificationViewMDTest, ExpandLongMessage) {
EXPECT_EQ(collapsed_height, notification_view()->message_view_->height());
EXPECT_EQ(collapsed_preferred_height,
notification_view()->GetPreferredSize().height());
+
+ // Test |manually_expanded_or_collapsed| being set when the toggle is done by
+ // user interaction.
+ EXPECT_FALSE(notification_view()->IsManuallyExpandedOrCollapsed());
+
+ // Construct a mouse click event 1 pixel inside the header.
+ gfx::Point done_cursor_location(1, 1);
+ views::View::ConvertPointToScreen(notification_view()->header_row_,
+ &done_cursor_location);
+ ui::test::EventGenerator generator(widget()->GetNativeWindow());
+ generator.MoveMouseTo(done_cursor_location);
+ generator.ClickLeftButton();
+
+ EXPECT_TRUE(notification_view()->IsManuallyExpandedOrCollapsed());
}
TEST_F(NotificationViewMDTest, TestAccentColor) {
- const SkColor kActionButtonTextColor = SkColorSetRGB(0x33, 0x67, 0xD6);
- const SkColor kCustomAccentColor = SkColorSetRGB(0xea, 0x61, 0x0);
+ constexpr SkColor kActionButtonTextColor = gfx::kGoogleBlue700;
+ constexpr SkColor kCustomAccentColor = gfx::kGoogleYellow900;
notification()->set_buttons(CreateButtons(2));
UpdateNotificationViews();
@@ -654,7 +709,7 @@ TEST_F(NotificationViewMDTest, TestAccentColor) {
// By default, header does not have accent color (default grey), and
// buttons have default accent color.
- EXPECT_EQ(message_center::kNotificationDefaultAccentColor,
+ EXPECT_EQ(kNotificationDefaultAccentColor,
notification_view()->header_row_->accent_color_for_testing());
EXPECT_EQ(
kActionButtonTextColor,
@@ -689,24 +744,43 @@ TEST_F(NotificationViewMDTest, UseImageAsIcon) {
UpdateNotificationViews();
EXPECT_FALSE(notification_view()->expanded_);
EXPECT_TRUE(notification_view()->icon_view_->visible());
+ EXPECT_TRUE(notification_view()->right_content_->visible());
// Icon on the right side is still visible when expanded.
notification_view()->ToggleExpanded();
EXPECT_TRUE(notification_view()->expanded_);
EXPECT_TRUE(notification_view()->icon_view_->visible());
+ EXPECT_TRUE(notification_view()->right_content_->visible());
notification_view()->ToggleExpanded();
EXPECT_FALSE(notification_view()->expanded_);
- // Test notification with use_image_as_icon e.g. screenshot preview.
+ // Test notification with |use_image_for_icon| e.g. screenshot preview.
notification()->set_icon(gfx::Image());
UpdateNotificationViews();
EXPECT_TRUE(notification_view()->icon_view_->visible());
+ EXPECT_TRUE(notification_view()->right_content_->visible());
// Icon on the right side is not visible when expanded.
notification_view()->ToggleExpanded();
EXPECT_TRUE(notification_view()->expanded_);
- EXPECT_FALSE(notification_view()->icon_view_->visible());
+ EXPECT_TRUE(notification_view()->icon_view_->visible());
+ EXPECT_FALSE(notification_view()->right_content_->visible());
+}
+
+TEST_F(NotificationViewMDTest, NotificationWithoutIcon) {
+ notification()->set_icon(gfx::Image());
+ notification()->set_image(gfx::Image());
+ UpdateNotificationViews();
+
+ // If the notification has no icon, |icon_view_| shouldn't be created.
+ EXPECT_FALSE(notification_view()->icon_view_);
+ EXPECT_FALSE(notification_view()->right_content_->visible());
+
+ // Toggling should not affect the icon.
+ notification_view()->ToggleExpanded();
+ EXPECT_FALSE(notification_view()->icon_view_);
+ EXPECT_FALSE(notification_view()->right_content_->visible());
}
TEST_F(NotificationViewMDTest, InlineSettings) {
@@ -715,22 +789,27 @@ TEST_F(NotificationViewMDTest, InlineSettings) {
// Inline settings will be shown by clicking settings button.
EXPECT_FALSE(notification_view()->settings_row_->visible());
- notification_view()->OnSettingsButtonPressed();
+ gfx::Point settings_cursor_location(1, 1);
+ views::View::ConvertPointToScreen(
+ notification_view()->control_buttons_view_.get()->settings_button(),
+ &settings_cursor_location);
+ ui::test::EventGenerator generator(widget()->GetNativeWindow());
+ generator.MoveMouseTo(settings_cursor_location);
+ generator.ClickLeftButton();
EXPECT_TRUE(notification_view()->settings_row_->visible());
// By clicking settings button again, it will toggle.
- notification_view()->OnSettingsButtonPressed();
+ generator.ClickLeftButton();
EXPECT_FALSE(notification_view()->settings_row_->visible());
// Show inline settings again.
- notification_view()->OnSettingsButtonPressed();
+ generator.ClickLeftButton();
EXPECT_TRUE(notification_view()->settings_row_->visible());
// Construct a mouse click event 1 pixel inside the done button.
gfx::Point done_cursor_location(1, 1);
views::View::ConvertPointToScreen(notification_view()->settings_done_button_,
&done_cursor_location);
- ui::test::EventGenerator generator(widget()->GetNativeWindow());
generator.MoveMouseTo(done_cursor_location);
generator.ClickLeftButton();
@@ -738,7 +817,8 @@ TEST_F(NotificationViewMDTest, InlineSettings) {
EXPECT_FALSE(notification_view()->settings_row_->visible());
EXPECT_FALSE(delegate_->disable_notification_called());
- notification_view()->OnSettingsButtonPressed();
+ generator.MoveMouseTo(settings_cursor_location);
+ generator.ClickLeftButton();
EXPECT_TRUE(notification_view()->settings_row_->visible());
// Construct a mouse click event 1 pixel inside the block all button.
diff --git a/chromium/ui/message_center/views/notification_view_unittest.cc b/chromium/ui/message_center/views/notification_view_unittest.cc
index dcd68529217..583b2a7e1c1 100644
--- a/chromium/ui/message_center/views/notification_view_unittest.cc
+++ b/chromium/ui/message_center/views/notification_view_unittest.cc
@@ -24,10 +24,10 @@
#include "ui/gfx/image/image.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/message_center_style.h"
-#include "ui/message_center/notification.h"
#include "ui/message_center/notification_list.h"
-#include "ui/message_center/notification_types.h"
-#include "ui/message_center/views/constants.h"
+#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
+#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/message_center/views/message_view_factory.h"
#include "ui/message_center/views/notification_button.h"
#include "ui/message_center/views/notification_control_buttons_view.h"
@@ -284,7 +284,7 @@ TEST_F(NotificationViewTest, CreateOrUpdateTest) {
}
TEST_F(NotificationViewTest, CreateOrUpdateTestSettingsButton) {
- data()->settings_button_handler = SettingsButtonHandler::TRAY;
+ data()->settings_button_handler = SettingsButtonHandler::INLINE;
Notification notification(
NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"),
base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"),
@@ -492,7 +492,7 @@ TEST_F(NotificationViewTest, UpdateButtonCountTest) {
}
TEST_F(NotificationViewTest, SettingsButtonTest) {
- data()->settings_button_handler = SettingsButtonHandler::TRAY;
+ data()->settings_button_handler = SettingsButtonHandler::INLINE;
Notification notf(
NOTIFICATION_TYPE_BASE_FORMAT, std::string("notification id"),
base::UTF8ToUTF16("title"), base::UTF8ToUTF16("message"),
@@ -562,10 +562,10 @@ TEST_F(NotificationViewTest, FormatContextMessageTest) {
"veryveryveryveryveyryveryveryveryveryveyryveryvery.veryveryveyrylong."
"chromium.org/hello";
- Notification notification1(
- NOTIFICATION_TYPE_BASE_FORMAT, std::string(""), base::UTF8ToUTF16(""),
- base::UTF8ToUTF16(""), CreateTestImage(80, 80), base::UTF8ToUTF16(""),
- GURL(), message_center::NotifierId(GURL()), *data(), NULL);
+ Notification notification1(NOTIFICATION_TYPE_BASE_FORMAT, std::string(""),
+ base::UTF8ToUTF16(""), base::UTF8ToUTF16(""),
+ CreateTestImage(80, 80), base::UTF8ToUTF16(""),
+ GURL(), NotifierId(GURL()), *data(), NULL);
notification1.set_context_message(base::ASCIIToUTF16(kRegularContextText));
base::string16 result =
@@ -579,7 +579,7 @@ TEST_F(NotificationViewTest, FormatContextMessageTest) {
Notification notification2(
NOTIFICATION_TYPE_BASE_FORMAT, std::string(""), base::UTF8ToUTF16(""),
base::UTF8ToUTF16(""), CreateTestImage(80, 80), base::UTF8ToUTF16(""),
- GURL(kUrlContext), message_center::NotifierId(GURL()), *data(), NULL);
+ GURL(kUrlContext), NotifierId(GURL()), *data(), NULL);
notification2.set_context_message(base::ASCIIToUTF16(""));
result = notification_view()->FormatContextMessage(notification2);
@@ -590,7 +590,7 @@ TEST_F(NotificationViewTest, FormatContextMessageTest) {
Notification notification3(
NOTIFICATION_TYPE_BASE_FORMAT, std::string(""), base::UTF8ToUTF16(""),
base::UTF8ToUTF16(""), CreateTestImage(80, 80), base::UTF8ToUTF16(""),
- GURL(kChromeUrl), message_center::NotifierId(GURL()), *data(), NULL);
+ GURL(kChromeUrl), NotifierId(GURL()), *data(), NULL);
notification3.set_context_message(base::ASCIIToUTF16(""));
result = notification_view()->FormatContextMessage(notification3);
EXPECT_TRUE(result.empty());
@@ -599,7 +599,7 @@ TEST_F(NotificationViewTest, FormatContextMessageTest) {
Notification notification4(
NOTIFICATION_TYPE_BASE_FORMAT, std::string(""), base::UTF8ToUTF16(""),
base::UTF8ToUTF16(""), CreateTestImage(80, 80), base::UTF8ToUTF16(""),
- GURL(kLongUrlContext), message_center::NotifierId(GURL()), *data(), NULL);
+ GURL(kLongUrlContext), NotifierId(GURL()), *data(), NULL);
notification4.set_context_message(base::ASCIIToUTF16(""));
result = notification_view()->FormatContextMessage(notification4);
@@ -671,6 +671,7 @@ TEST_F(NotificationViewTest, SlideOutPinned) {
ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
notification()->set_pinned(true);
+ notification_view()->SetIsNested();
UpdateNotificationViews();
std::string notification_id = notification()->id();
@@ -682,12 +683,11 @@ TEST_F(NotificationViewTest, SlideOutPinned) {
EXPECT_FALSE(IsRemoved(notification_id));
}
-TEST_F(NotificationViewTest, SlideOutForceDisablePinned) {
+TEST_F(NotificationViewTest, PopupsCantPin) {
ui::ScopedAnimationDurationScaleMode zero_duration_scope(
ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
notification()->set_pinned(true);
- notification_view()->set_force_disable_pinned();
UpdateNotificationViews();
std::string notification_id = notification()->id();
@@ -711,13 +711,14 @@ TEST_F(NotificationViewTest, SlideOutForceDisablePinned) {
}
TEST_F(NotificationViewTest, Pinned) {
+ // Notifications are popups by default (can't be pinned).
notification()->set_pinned(true);
UpdateNotificationViews();
- EXPECT_EQ(NULL, GetCloseButton());
+ EXPECT_TRUE(GetCloseButton());
- notification_view()->set_force_disable_pinned();
+ notification_view()->SetIsNested();
UpdateNotificationViews();
- EXPECT_TRUE(GetCloseButton());
+ EXPECT_FALSE(GetCloseButton());
}
#endif // defined(OS_CHROMEOS)
diff --git a/chromium/ui/message_center/views/popup_alignment_delegate.cc b/chromium/ui/message_center/views/popup_alignment_delegate.cc
index 95636377057..219e721760c 100644
--- a/chromium/ui/message_center/views/popup_alignment_delegate.cc
+++ b/chromium/ui/message_center/views/popup_alignment_delegate.cc
@@ -14,7 +14,7 @@ PopupAlignmentDelegate::~PopupAlignmentDelegate() {}
void PopupAlignmentDelegate::DoUpdateIfPossible() {
if (collection_)
- collection_->DoUpdateIfPossible();
+ collection_->DoUpdate();
}
} // namespace message_center
diff --git a/chromium/ui/message_center/views/popup_alignment_delegate.h b/chromium/ui/message_center/views/popup_alignment_delegate.h
index 48787456927..43e6a62ae3c 100644
--- a/chromium/ui/message_center/views/popup_alignment_delegate.h
+++ b/chromium/ui/message_center/views/popup_alignment_delegate.h
@@ -33,7 +33,7 @@ class MESSAGE_CENTER_EXPORT PopupAlignmentDelegate {
// Returns the baseline height of the current work area. That is the starting
// point if there are no other toasts.
- virtual int GetBaseLine() const = 0;
+ virtual int GetBaseline() const = 0;
// Returns the rect of the current work area.
virtual gfx::Rect GetWorkArea() const = 0;
diff --git a/chromium/ui/message_center/views/proportional_image_view.cc b/chromium/ui/message_center/views/proportional_image_view.cc
index 8a260960f38..b0d0d3ce84a 100644
--- a/chromium/ui/message_center/views/proportional_image_view.cc
+++ b/chromium/ui/message_center/views/proportional_image_view.cc
@@ -53,7 +53,7 @@ gfx::Size ProportionalImageView::GetImageDrawingSize() {
gfx::Size max_size = max_image_size_;
max_size.SetToMin(GetContentsBounds().size());
- return message_center::GetImageSizeForContainerSize(max_size, image_.size());
+ return GetImageSizeForContainerSize(max_size, image_.size());
}
} // namespace message_center
diff --git a/chromium/ui/message_center/views/toast_contents_view.cc b/chromium/ui/message_center/views/toast_contents_view.cc
index 151715785a7..285ca0b30a2 100644
--- a/chromium/ui/message_center/views/toast_contents_view.cc
+++ b/chromium/ui/message_center/views/toast_contents_view.cc
@@ -18,8 +18,8 @@
#include "ui/display/screen.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
-#include "ui/message_center/notification.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
+#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/views/message_popup_collection.h"
#include "ui/message_center/views/message_view.h"
#include "ui/message_center/views/popup_alignment_delegate.h"
@@ -83,6 +83,7 @@ ToastContentsView::~ToastContentsView() {
void ToastContentsView::SetContents(MessageView* view,
bool a11y_feedback_for_updates) {
+ message_view_ = view;
bool already_has_contents = child_count() > 0;
RemoveAllChildViews(true);
AddChildView(view);
@@ -93,7 +94,7 @@ void ToastContentsView::SetContents(MessageView* view,
// The notification type should be ALERT, otherwise the accessibility message
// won't be read for this view which returns ROLE_WINDOW.
if (already_has_contents && a11y_feedback_for_updates)
- NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, false);
+ NotifyAccessibilityEvent(ax::mojom::Event::kAlert, false);
}
void ToastContentsView::UpdateContents(const Notification& notification,
@@ -103,7 +104,7 @@ void ToastContentsView::UpdateContents(const Notification& notification,
message_view->UpdateWithNotification(notification);
UpdatePreferredSize();
if (a11y_feedback_for_updates)
- NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, false);
+ NotifyAccessibilityEvent(ax::mojom::Event::kAlert, false);
}
void ToastContentsView::RevealWithAnimation(gfx::Point origin) {
@@ -163,9 +164,6 @@ void ToastContentsView::SetBoundsWithAnimation(gfx::Rect new_bounds) {
animated_bounds_start_ = GetWidget()->GetWindowBoundsInScreen();
animated_bounds_end_ = new_bounds;
- if (collection_)
- collection_->IncrementDeferCounter();
-
if (bounds_animation_.get())
bounds_animation_->Stop();
@@ -174,9 +172,6 @@ void ToastContentsView::SetBoundsWithAnimation(gfx::Rect new_bounds) {
}
void ToastContentsView::StartFadeIn() {
- // The decrement is done in OnBoundsAnimationEndedOrCancelled callback.
- if (collection_)
- collection_->IncrementDeferCounter();
fade_animation_->Stop();
GetWidget()->SetOpacity(0);
@@ -186,9 +181,6 @@ void ToastContentsView::StartFadeIn() {
}
void ToastContentsView::StartFadeOut() {
- // The decrement is done in OnBoundsAnimationEndedOrCancelled callback.
- if (collection_)
- collection_->IncrementDeferCounter();
fade_animation_->Stop();
closing_animation_ = (is_closing_ ? fade_animation_.get() : nullptr);
@@ -218,13 +210,6 @@ void ToastContentsView::OnBoundsAnimationEndedOrCancelled(
widget->Close();
}
-
- // This cannot be called before GetWidget()->Close(). Decrementing defer count
- // will invoke update, which may invoke another close animation with
- // incrementing defer counter. Close() after such process will cause a
- // mismatch between increment/decrement. See crbug.com/238477
- if (collection_)
- collection_->DecrementDeferCounter();
}
// gfx::AnimationDelegate
@@ -250,7 +235,7 @@ void ToastContentsView::AnimationCanceled(
// views::WidgetDelegate
void ToastContentsView::WindowClosing() {
- if (!is_closing_ && collection_.get())
+ if (!is_closing_ && collection_)
collection_->ForgetToast(this);
}
@@ -331,7 +316,7 @@ void ToastContentsView::UpdatePreferredSize() {
void ToastContentsView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
if (child_count() > 0)
child_at(0)->GetAccessibleNodeData(node_data);
- node_data->role = ui::AX_ROLE_WINDOW;
+ node_data->role = ax::mojom::Role::kWindow;
}
const char* ToastContentsView::GetClassName() const {
diff --git a/chromium/ui/message_center/views/toast_contents_view.h b/chromium/ui/message_center/views/toast_contents_view.h
index 83227548bb5..87c0aa9bd64 100644
--- a/chromium/ui/message_center/views/toast_contents_view.h
+++ b/chromium/ui/message_center/views/toast_contents_view.h
@@ -80,6 +80,8 @@ class MESSAGE_CENTER_EXPORT ToastContentsView
const std::string& id() const { return id_; }
+ MessageView* message_view() { return message_view_; }
+
// Overridden from views::View:
void OnMouseEntered(const ui::MouseEvent& event) override;
void OnMouseExited(const ui::MouseEvent& event) override;
@@ -141,6 +143,9 @@ class MESSAGE_CENTER_EXPORT ToastContentsView
gfx::Point origin_;
gfx::Size preferred_size_;
+ // Weak reference to the MessageView.
+ MessageView* message_view_ = nullptr;
+
DISALLOW_COPY_AND_ASSIGN(ToastContentsView);
};
diff --git a/chromium/ui/native_theme/native_theme_aura.cc b/chromium/ui/native_theme/native_theme_aura.cc
index 31d5186f5a7..fb7a9c93450 100644
--- a/chromium/ui/native_theme/native_theme_aura.cc
+++ b/chromium/ui/native_theme/native_theme_aura.cc
@@ -148,7 +148,7 @@ void NativeThemeAura::PaintArrowButton(cc::PaintCanvas* canvas,
break;
case kHovered:
bg_color = SkColorSetRGB(0xD2, 0xD2, 0xD2);
- // Fall through.
+ FALLTHROUGH;
case kNormal:
arrow_color = SkColorSetRGB(0x50, 0x50, 0x50);
break;
diff --git a/chromium/ui/ozone/demo/BUILD.gn b/chromium/ui/ozone/demo/BUILD.gn
index ad191666a65..8a01fb9b10e 100644
--- a/chromium/ui/ozone/demo/BUILD.gn
+++ b/chromium/ui/ozone/demo/BUILD.gn
@@ -10,16 +10,16 @@ group("demo") {
executable("ozone_demo") {
sources = [
- "gl_renderer.cc",
- "gl_renderer.h",
"ozone_demo.cc",
"renderer.h",
"renderer_base.cc",
"renderer_base.h",
+ "skia_renderer.cc",
+ "skia_renderer.h",
"software_renderer.cc",
"software_renderer.h",
- "surfaceless_gl_renderer.cc",
- "surfaceless_gl_renderer.h",
+ "surfaceless_skia_renderer.cc",
+ "surfaceless_skia_renderer.h",
]
deps = [
diff --git a/chromium/ui/ozone/demo/gl_renderer.cc b/chromium/ui/ozone/demo/gl_renderer.cc
deleted file mode 100644
index bc9d2a5bfd3..00000000000
--- a/chromium/ui/ozone/demo/gl_renderer.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/demo/gl_renderer.h"
-
-#include "base/location.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/trace_event/trace_event.h"
-#include "ui/gl/gl_bindings.h"
-#include "ui/gl/gl_context.h"
-#include "ui/gl/gl_surface.h"
-#include "ui/gl/init/gl_factory.h"
-
-namespace ui {
-
-GlRenderer::GlRenderer(gfx::AcceleratedWidget widget,
- const scoped_refptr<gl::GLSurface>& surface,
- const gfx::Size& size)
- : RendererBase(widget, size), surface_(surface), weak_ptr_factory_(this) {}
-
-GlRenderer::~GlRenderer() {
-}
-
-bool GlRenderer::Initialize() {
- context_ = gl::init::CreateGLContext(nullptr, surface_.get(),
- gl::GLContextAttribs());
- if (!context_.get()) {
- LOG(ERROR) << "Failed to create GL context";
- return false;
- }
-
- surface_->Resize(size_, 1.f, gl::GLSurface::ColorSpace::UNSPECIFIED, true);
-
- if (!context_->MakeCurrent(surface_.get())) {
- LOG(ERROR) << "Failed to make GL context current";
- return false;
- }
-
- PostRenderFrameTask(gfx::SwapResult::SWAP_ACK);
- return true;
-}
-
-void GlRenderer::RenderFrame() {
- TRACE_EVENT0("ozone", "GlRenderer::RenderFrame");
-
- float fraction = NextFraction();
-
- context_->MakeCurrent(surface_.get());
-
- glViewport(0, 0, size_.width(), size_.height());
- glClearColor(1 - fraction, fraction, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- if (surface_->SupportsAsyncSwap()) {
- surface_->SwapBuffersAsync(base::Bind(&GlRenderer::PostRenderFrameTask,
- weak_ptr_factory_.GetWeakPtr()),
- base::Bind(&GlRenderer::OnPresentation,
- weak_ptr_factory_.GetWeakPtr()));
- } else {
- PostRenderFrameTask(surface_->SwapBuffers(base::Bind(
- &GlRenderer::OnPresentation, weak_ptr_factory_.GetWeakPtr())));
- }
-}
-
-void GlRenderer::PostRenderFrameTask(gfx::SwapResult result) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(&GlRenderer::RenderFrame, weak_ptr_factory_.GetWeakPtr()));
-}
-
-void GlRenderer::OnPresentation(const gfx::PresentationFeedback& feedback) {
- DCHECK(surface_->SupportsPresentationCallback());
- LOG_IF(ERROR, feedback.timestamp.is_null()) << "Last frame is discarded!";
-}
-
-} // namespace ui
diff --git a/chromium/ui/ozone/demo/gl_renderer.h b/chromium/ui/ozone/demo/gl_renderer.h
deleted file mode 100644
index f6c8b2bf2d0..00000000000
--- a/chromium/ui/ozone/demo/gl_renderer.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_DEMO_GL_RENDERER_H_
-#define UI_OZONE_DEMO_GL_RENDERER_H_
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "ui/gfx/swap_result.h"
-#include "ui/ozone/demo/renderer_base.h"
-
-namespace gfx {
-struct PresentationFeedback;
-} // namespace gfx
-
-namespace gl {
-class GLContext;
-class GLSurface;
-} // namespace gl
-
-namespace ui {
-
-class GlRenderer : public RendererBase {
- public:
- GlRenderer(gfx::AcceleratedWidget widget,
- const scoped_refptr<gl::GLSurface>& surface,
- const gfx::Size& size);
- ~GlRenderer() override;
-
- // Renderer:
- bool Initialize() override;
-
- protected:
- virtual void RenderFrame();
- virtual void PostRenderFrameTask(gfx::SwapResult result);
-
- scoped_refptr<gl::GLSurface> surface_;
- scoped_refptr<gl::GLContext> context_;
-
- private:
- void OnPresentation(const gfx::PresentationFeedback& feedback);
-
- base::WeakPtrFactory<GlRenderer> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(GlRenderer);
-};
-
-} // namespace ui
-
-#endif // UI_OZONE_DEMO_GL_RENDERER_H_
diff --git a/chromium/ui/ozone/demo/ozone_demo.cc b/chromium/ui/ozone/demo/ozone_demo.cc
index 38d3c919691..fc989906f2e 100644
--- a/chromium/ui/ozone/demo/ozone_demo.cc
+++ b/chromium/ui/ozone/demo/ozone_demo.cc
@@ -6,6 +6,7 @@
#include "base/at_exit.h"
#include "base/command_line.h"
+#include "base/debug/stack_trace.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
@@ -26,9 +27,9 @@
#include "ui/gfx/geometry/size.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/init/gl_factory.h"
-#include "ui/ozone/demo/gl_renderer.h"
+#include "ui/ozone/demo/skia_renderer.h"
#include "ui/ozone/demo/software_renderer.h"
-#include "ui/ozone/demo/surfaceless_gl_renderer.h"
+#include "ui/ozone/demo/surfaceless_skia_renderer.h"
#include "ui/ozone/public/ozone_gpu_test_helper.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/ozone_switches.h"
@@ -39,7 +40,6 @@ const int kTestWindowWidth = 800;
const int kTestWindowHeight = 600;
const char kDisableGpu[] = "disable-gpu";
-
const char kDisableSurfaceless[] = "disable-surfaceless";
const char kWindowSize[] = "window-size";
@@ -58,7 +58,7 @@ scoped_refptr<gl::GLSurface> CreateGLSurface(gfx::AcceleratedWidget widget) {
class RendererFactory {
public:
enum RendererType {
- GL,
+ SKIA,
SOFTWARE,
};
@@ -176,7 +176,8 @@ class DemoWindow : public ui::PlatformWindowDelegate {
void StartOnGpu() {
renderer_ =
renderer_factory_->CreateRenderer(GetAcceleratedWidget(), GetSize());
- renderer_->Initialize();
+ if (!renderer_->Initialize())
+ LOG(ERROR) << "Failed to initialize renderer.";
}
WindowManager* window_manager_; // Not owned.
@@ -206,11 +207,12 @@ bool RendererFactory::Initialize() {
ui::OzonePlatform::InitParams params;
params.single_process = true;
ui::OzonePlatform::InitializeForGPU(params);
+ ui::OzonePlatform::GetInstance()->AfterSandboxEntry();
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (!command_line->HasSwitch(kDisableGpu) && gl::init::InitializeGLOneOff() &&
gpu_helper_.Initialize(base::ThreadTaskRunnerHandle::Get())) {
- type_ = GL;
+ type_ = SKIA;
} else {
type_ = SOFTWARE;
}
@@ -222,16 +224,15 @@ std::unique_ptr<ui::Renderer> RendererFactory::CreateRenderer(
gfx::AcceleratedWidget widget,
const gfx::Size& size) {
switch (type_) {
- case GL: {
+ case SKIA: {
scoped_refptr<gl::GLSurface> surface = CreateGLSurface(widget);
if (!surface)
LOG(FATAL) << "Failed to create GL surface";
if (surface->IsSurfaceless()) {
- return std::make_unique<ui::SurfacelessGlRenderer>(widget, surface,
- size);
- } else {
- return std::make_unique<ui::GlRenderer>(widget, surface, size);
+ return std::make_unique<ui::SurfacelessSkiaRenderer>(widget, surface,
+ size);
}
+ return std::make_unique<ui::SkiaRenderer>(widget, surface, size);
}
case SOFTWARE:
return std::make_unique<ui::SoftwareRenderer>(widget, size);
@@ -334,6 +335,8 @@ int main(int argc, char** argv) {
base::CommandLine::Init(argc, argv);
base::AtExitManager exit_manager;
+ base::debug::EnableInProcessStackDumping();
+
// Initialize logging so we can enable VLOG messages.
logging::LoggingSettings settings;
logging::InitLogging(settings);
diff --git a/chromium/ui/ozone/demo/renderer_base.cc b/chromium/ui/ozone/demo/renderer_base.cc
index 577176bcd98..ccbcae74993 100644
--- a/chromium/ui/ozone/demo/renderer_base.cc
+++ b/chromium/ui/ozone/demo/renderer_base.cc
@@ -19,13 +19,16 @@ RendererBase::RendererBase(gfx::AcceleratedWidget widget, const gfx::Size& size)
RendererBase::~RendererBase() {
}
-float RendererBase::NextFraction() {
+float RendererBase::CurrentFraction() const {
float fraction =
(sinf(iteration_ * 2 * base::kPiFloat / kAnimationSteps) + 1) / 2;
+ return fraction;
+}
+float RendererBase::NextFraction() {
+ float fraction = CurrentFraction();
iteration_++;
iteration_ %= kAnimationSteps;
-
return fraction;
}
diff --git a/chromium/ui/ozone/demo/renderer_base.h b/chromium/ui/ozone/demo/renderer_base.h
index 8d7acd50fac..7199798bdcd 100644
--- a/chromium/ui/ozone/demo/renderer_base.h
+++ b/chromium/ui/ozone/demo/renderer_base.h
@@ -17,6 +17,7 @@ class RendererBase : public Renderer {
~RendererBase() override;
protected:
+ float CurrentFraction() const;
float NextFraction();
gfx::AcceleratedWidget widget_;
diff --git a/chromium/ui/ozone/demo/skia_renderer.cc b/chromium/ui/ozone/demo/skia_renderer.cc
new file mode 100644
index 00000000000..a8d7947ed8f
--- /dev/null
+++ b/chromium/ui/ozone/demo/skia_renderer.cc
@@ -0,0 +1,243 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/demo/skia_renderer.h"
+
+#include "base/command_line.h"
+#include "base/location.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "base/trace_event/trace_event.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/effects/SkGradientShader.h"
+#include "third_party/skia/include/gpu/GrBackendSurface.h"
+#include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
+#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
+#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/gl_implementation.h"
+#include "ui/gl/gl_surface.h"
+#include "ui/gl/init/gl_factory.h"
+
+namespace ui {
+
+namespace {
+
+const GrGLInterface* GrGLCreateNativeInterface() {
+ return GrGLAssembleInterface(nullptr, [](void* ctx, const char name[]) {
+ return gl::GetGLProcAddress(name);
+ });
+}
+
+const char kUseDDL[] = "use-ddl";
+
+} // namespace
+
+SkiaRenderer::SkiaRenderer(gfx::AcceleratedWidget widget,
+ const scoped_refptr<gl::GLSurface>& surface,
+ const gfx::Size& size)
+ : RendererBase(widget, size),
+ gl_surface_(surface),
+ use_ddl_(base::CommandLine::ForCurrentProcess()->HasSwitch(kUseDDL)),
+ condition_variable_(&lock_),
+ weak_ptr_factory_(this) {}
+
+SkiaRenderer::~SkiaRenderer() {
+ if (use_ddl_)
+ StopDDLRenderThread();
+}
+
+bool SkiaRenderer::Initialize() {
+ gl_context_ = gl::init::CreateGLContext(nullptr, gl_surface_.get(),
+ gl::GLContextAttribs());
+ if (!gl_context_.get()) {
+ LOG(FATAL) << "Failed to create GL context";
+ return false;
+ }
+
+ gl_surface_->Resize(size_, 1.f, gl::GLSurface::ColorSpace::UNSPECIFIED, true);
+
+ if (!gl_context_->MakeCurrent(gl_surface_.get())) {
+ LOG(FATAL) << "Failed to make GL context current";
+ return false;
+ }
+
+ auto native_interface =
+ sk_sp<const GrGLInterface>(GrGLCreateNativeInterface());
+ DCHECK(native_interface);
+ GrContextOptions options;
+ if (use_ddl_)
+ options.fExplicitlyAllocateGPUResources = GrContextOptions::Enable::kYes;
+ gr_context_ = GrContext::MakeGL(std::move(native_interface), options);
+ DCHECK(gr_context_);
+
+ PostRenderFrameTask(gfx::SwapResult::SWAP_ACK);
+ return true;
+}
+
+void SkiaRenderer::RenderFrame() {
+ TRACE_EVENT0("ozone", "SkiaRenderer::RenderFrame");
+
+ // LegacyFontHost will get LCD text and skia figures out what type to use.
+ SkSurfaceProps surface_props =
+ SkSurfaceProps(0, SkSurfaceProps::kLegacyFontHost_InitType);
+
+ if (!sk_surface_) {
+ GrGLFramebufferInfo framebuffer_info;
+ framebuffer_info.fFBOID = 0;
+ GrBackendRenderTarget render_target(size_.width(), size_.height(), 0, 8,
+ kRGBA_8888_GrPixelConfig,
+ framebuffer_info);
+
+ sk_surface_ = SkSurface::MakeFromBackendRenderTarget(
+ gr_context_.get(), render_target, kBottomLeft_GrSurfaceOrigin, nullptr,
+ &surface_props);
+ }
+
+ if (use_ddl_) {
+ StartDDLRenderThreadIfNecessary(sk_surface_.get());
+ auto ddl = GetDDL();
+ sk_surface_->draw(ddl.get());
+ } else {
+ Draw(sk_surface_->getCanvas(), NextFraction());
+ }
+ gr_context_->flush();
+ glFinish();
+
+ if (gl_surface_->SupportsAsyncSwap()) {
+ gl_surface_->SwapBuffersAsync(
+ base::BindRepeating(&SkiaRenderer::PostRenderFrameTask,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::BindRepeating(&SkiaRenderer::OnPresentation,
+ weak_ptr_factory_.GetWeakPtr()));
+ } else {
+ PostRenderFrameTask(gl_surface_->SwapBuffers(base::BindRepeating(
+ &SkiaRenderer::OnPresentation, weak_ptr_factory_.GetWeakPtr())));
+ }
+}
+
+void SkiaRenderer::PostRenderFrameTask(gfx::SwapResult result) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::BindRepeating(&SkiaRenderer::RenderFrame,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void SkiaRenderer::Draw(SkCanvas* canvas, float fraction) {
+ TRACE_EVENT0("ozone", "SkiaRenderer::Draw");
+ // Clear background
+ canvas->clear(SkColorSetARGB(255, 255 * fraction, 255 * (1 - fraction), 0));
+
+ SkPaint paint;
+ paint.setColor(SK_ColorRED);
+
+ // Draw a rectangle with red paint
+ SkRect rect = SkRect::MakeXYWH(10, 10, 128, 128);
+ canvas->drawRect(rect, paint);
+
+ // Set up a linear gradient and draw a circle
+ {
+ SkPoint linearPoints[] = {{0, 0}, {300, 300}};
+ SkColor linearColors[] = {SK_ColorGREEN, SK_ColorBLACK};
+ paint.setShader(SkGradientShader::MakeLinear(
+ linearPoints, linearColors, nullptr, 2, SkShader::kMirror_TileMode));
+ paint.setAntiAlias(true);
+
+ canvas->drawCircle(200, 200, 64, paint);
+
+ // Detach shader
+ paint.setShader(nullptr);
+ }
+
+ // Draw a message with a nice black paint
+ paint.setSubpixelText(true);
+ paint.setColor(SK_ColorBLACK);
+ paint.setTextSize(32);
+
+ canvas->save();
+ static const char message[] = "Hello Ozone";
+ static const char message_ddl[] = "Hello Ozone + DDL";
+
+ // Translate and rotate
+ canvas->translate(300, 300);
+ rotation_angle_ += 0.2f;
+ if (rotation_angle_ > 360) {
+ rotation_angle_ -= 360;
+ }
+ canvas->rotate(rotation_angle_);
+
+ const char* text = use_ddl_ ? message_ddl : message;
+ // Draw the text
+ canvas->drawText(text, strlen(text), 0, 0, paint);
+
+ canvas->restore();
+}
+
+void SkiaRenderer::StartDDLRenderThreadIfNecessary(SkSurface* sk_surface) {
+ DCHECK(use_ddl_);
+ if (ddl_render_thread_)
+ return;
+ DCHECK(!surface_charaterization_.isValid());
+ DCHECK(sk_surface);
+
+ if (!sk_surface->characterize(&surface_charaterization_))
+ LOG(FATAL) << "Failed to cheracterize the skia surface!";
+ ddl_render_thread_ =
+ std::make_unique<base::DelegateSimpleThread>(this, "DDLRenderThread");
+ ddl_render_thread_->Start();
+}
+
+void SkiaRenderer::StopDDLRenderThread() {
+ if (!ddl_render_thread_)
+ return;
+ {
+ base::AutoLock auto_lock_(lock_);
+ surface_charaterization_ = SkSurfaceCharacterization();
+ condition_variable_.Signal();
+ }
+ ddl_render_thread_->Join();
+ ddl_render_thread_ = nullptr;
+ while (!ddls_.empty())
+ ddls_.pop();
+}
+
+std::unique_ptr<SkDeferredDisplayList> SkiaRenderer::GetDDL() {
+ base::AutoLock auto_lock_(lock_);
+ DCHECK(surface_charaterization_.isValid());
+ // Wait until DDL is generated by DDL render thread.
+ while (ddls_.empty())
+ condition_variable_.Wait();
+ auto ddl = std::move(ddls_.front());
+ ddls_.pop();
+ condition_variable_.Signal();
+ return ddl;
+}
+
+void SkiaRenderer::Run() {
+ base::AutoLock auto_lock(lock_);
+ while (true) {
+ // Wait until ddls_ is consumed or surface_charaterization_ is reset.
+ constexpr size_t kMaxPendingDDLS = 4;
+ while (surface_charaterization_.isValid() &&
+ ddls_.size() == kMaxPendingDDLS)
+ condition_variable_.Wait();
+ if (!surface_charaterization_.isValid())
+ break;
+ DCHECK_LT(ddls_.size(), kMaxPendingDDLS);
+ SkDeferredDisplayListRecorder recorder(surface_charaterization_);
+ std::unique_ptr<SkDeferredDisplayList> ddl;
+ {
+ base::AutoUnlock auto_unlock(lock_);
+ Draw(recorder.getCanvas(), NextFraction());
+ ddl = recorder.detach();
+ }
+ ddls_.push(std::move(ddl));
+ condition_variable_.Signal();
+ }
+}
+
+void SkiaRenderer::OnPresentation(const gfx::PresentationFeedback& feedback) {
+ DCHECK(gl_surface_->SupportsPresentationCallback());
+ LOG_IF(ERROR, feedback.timestamp.is_null()) << "Last frame is discarded!";
+}
+
+} // namespace ui
diff --git a/chromium/ui/ozone/demo/skia_renderer.h b/chromium/ui/ozone/demo/skia_renderer.h
new file mode 100644
index 00000000000..e13f5bfd6c5
--- /dev/null
+++ b/chromium/ui/ozone/demo/skia_renderer.h
@@ -0,0 +1,86 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_DEMO_SKIA_RENDERER_H_
+#define UI_OZONE_DEMO_SKIA_RENDERER_H_
+
+#include "base/containers/queue.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "base/synchronization/condition_variable.h"
+#include "base/synchronization/lock.h"
+#include "base/threading/simple_thread.h"
+#include "third_party/skia/include/core/SkDeferredDisplayListRecorder.h"
+#include "third_party/skia/include/core/SkSurface.h"
+#include "third_party/skia/include/gpu/GrContext.h"
+#include "ui/gfx/swap_result.h"
+#include "ui/ozone/demo/renderer_base.h"
+
+namespace gfx {
+struct PresentationFeedback;
+} // namespace gfx
+
+namespace gl {
+class GLContext;
+class GLSurface;
+} // namespace gl
+
+namespace ui {
+
+class SkiaRenderer : public RendererBase,
+ public base::DelegateSimpleThread::Delegate {
+ public:
+ SkiaRenderer(gfx::AcceleratedWidget widget,
+ const scoped_refptr<gl::GLSurface>& surface,
+ const gfx::Size& size);
+ ~SkiaRenderer() override;
+
+ // Renderer:
+ bool Initialize() override;
+
+ protected:
+ virtual void RenderFrame();
+ virtual void PostRenderFrameTask(gfx::SwapResult result);
+
+ void Draw(SkCanvas* canvas, float fraction);
+ void StartDDLRenderThreadIfNecessary(SkSurface* sk_surface);
+ void StopDDLRenderThread();
+ std::unique_ptr<SkDeferredDisplayList> GetDDL();
+
+ scoped_refptr<gl::GLSurface> gl_surface_;
+ scoped_refptr<gl::GLContext> gl_context_;
+
+ sk_sp<GrContext> gr_context_;
+ const bool use_ddl_;
+
+ private:
+ // base::DelegateSimpleThread::Delegate:
+ void Run() override;
+
+ void OnPresentation(const gfx::PresentationFeedback& feedback);
+
+ sk_sp<SkSurface> sk_surface_;
+
+ float rotation_angle_ = 0.f;
+
+ std::unique_ptr<base::SimpleThread> ddl_render_thread_;
+
+ // The lock to protect |surface_charaterization_| and |ddls_|.
+ base::Lock lock_;
+
+ // The condition variable for signalling change of |ddls_|.
+ base::ConditionVariable condition_variable_;
+
+ SkSurfaceCharacterization surface_charaterization_;
+ base::queue<std::unique_ptr<SkDeferredDisplayList>> ddls_;
+
+ base::WeakPtrFactory<SkiaRenderer> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SkiaRenderer);
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_DEMO_SKIA_RENDERER_H_
diff --git a/chromium/ui/ozone/demo/surfaceless_gl_renderer.h b/chromium/ui/ozone/demo/surfaceless_gl_renderer.h
deleted file mode 100644
index 4086ffc562c..00000000000
--- a/chromium/ui/ozone/demo/surfaceless_gl_renderer.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_DEMO_SURFACELESS_GL_RENDERER_H_
-#define UI_OZONE_DEMO_SURFACELESS_GL_RENDERER_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/ozone/demo/gl_renderer.h"
-
-namespace gl {
-class GLImage;
-}
-
-namespace ui {
-class OverlayCandidatesOzone;
-
-class SurfacelessGlRenderer : public GlRenderer {
- public:
- SurfacelessGlRenderer(gfx::AcceleratedWidget widget,
- const scoped_refptr<gl::GLSurface>& surface,
- const gfx::Size& size);
- ~SurfacelessGlRenderer() override;
-
- // Renderer:
- bool Initialize() override;
-
- private:
- // GlRenderer:
- void RenderFrame() override;
- void PostRenderFrameTask(gfx::SwapResult result) override;
-
- class BufferWrapper {
- public:
- BufferWrapper();
- ~BufferWrapper();
-
- gl::GLImage* image() const { return image_.get(); }
-
- bool Initialize(gfx::AcceleratedWidget widget, const gfx::Size& size);
- void BindFramebuffer();
-
- const gfx::Size size() const { return size_; }
-
- private:
- gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
- gfx::Size size_;
-
- scoped_refptr<gl::GLImage> image_;
- unsigned int gl_fb_ = 0;
- unsigned int gl_tex_ = 0;
- };
-
- std::unique_ptr<BufferWrapper> buffers_[2];
-
- std::unique_ptr<BufferWrapper> overlay_buffer_[2];
- bool disable_primary_plane_ = false;
- gfx::Rect primary_plane_rect_;
-
- std::unique_ptr<OverlayCandidatesOzone> overlay_checker_;
-
- int back_buffer_ = 0;
-
- base::WeakPtrFactory<SurfacelessGlRenderer> weak_ptr_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(SurfacelessGlRenderer);
-};
-
-} // namespace ui
-
-#endif // UI_OZONE_DEMO_SURFACELESS_GL_RENDERER_H_
diff --git a/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc b/chromium/ui/ozone/demo/surfaceless_skia_renderer.cc
index 77f617e92ff..fef66dff8af 100644
--- a/chromium/ui/ozone/demo/surfaceless_gl_renderer.cc
+++ b/chromium/ui/ozone/demo/surfaceless_skia_renderer.cc
@@ -1,15 +1,22 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
+// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/ozone/demo/surfaceless_gl_renderer.h"
+#include "ui/ozone/demo/surfaceless_skia_renderer.h"
#include <stddef.h>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "base/trace_event/trace_event.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkDeferredDisplayListRecorder.h"
+#include "third_party/skia/include/core/SkTypeface.h"
+#include "third_party/skia/include/gpu/GrBackendSurface.h"
+#include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
+#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/gfx/geometry/rect_conversions.h"
#include "ui/gl/gl_bindings.h"
@@ -26,6 +33,10 @@ namespace ui {
namespace {
+const char kPartialPrimaryPlane[] = "partial-primary-plane";
+const char kEnableOverlay[] = "enable-overlay";
+const char kDisablePrimaryPlane[] = "disable-primary-plane";
+
OverlaySurfaceCandidate MakeOverlayCandidate(int z_order,
gfx::Rect bounds_rect,
gfx::RectF crop_rect) {
@@ -37,6 +48,10 @@ OverlaySurfaceCandidate MakeOverlayCandidate(int z_order,
OverlaySurfaceCandidate overlay_candidate;
+ // Use default display format since this should be compatible with most
+ // devices.
+ overlay_candidate.format = display::DisplaySnapshot::PrimaryFormat();
+
// The bounds rectangle of the candidate overlay buffer.
overlay_candidate.buffer_size = bounds_rect.size();
// The same rectangle in floating point coordinates.
@@ -54,23 +69,43 @@ OverlaySurfaceCandidate MakeOverlayCandidate(int z_order,
} // namespace
-SurfacelessGlRenderer::BufferWrapper::BufferWrapper() {
-}
+class SurfacelessSkiaRenderer::BufferWrapper {
+ public:
+ BufferWrapper();
+ ~BufferWrapper();
+
+ gl::GLImage* image() const { return image_.get(); }
+ SkSurface* sk_surface() const { return sk_surface_.get(); }
+
+ bool Initialize(GrContext* gr_context,
+ gfx::AcceleratedWidget widget,
+ const gfx::Size& size);
+ void BindFramebuffer();
-SurfacelessGlRenderer::BufferWrapper::~BufferWrapper() {
- if (gl_fb_)
- glDeleteFramebuffersEXT(1, &gl_fb_);
+ const gfx::Size size() const { return size_; }
+ private:
+ gfx::AcceleratedWidget widget_ = gfx::kNullAcceleratedWidget;
+ gfx::Size size_;
+
+ scoped_refptr<gl::GLImage> image_;
+ unsigned int gl_tex_ = 0;
+ sk_sp<SkSurface> sk_surface_;
+};
+
+SurfacelessSkiaRenderer::BufferWrapper::BufferWrapper() = default;
+
+SurfacelessSkiaRenderer::BufferWrapper::~BufferWrapper() {
if (gl_tex_) {
image_->ReleaseTexImage(GL_TEXTURE_2D);
glDeleteTextures(1, &gl_tex_);
}
}
-bool SurfacelessGlRenderer::BufferWrapper::Initialize(
+bool SurfacelessSkiaRenderer::BufferWrapper::Initialize(
+ GrContext* gr_context,
gfx::AcceleratedWidget widget,
const gfx::Size& size) {
- glGenFramebuffersEXT(1, &gl_fb_);
glGenTextures(1, &gl_tex_);
gfx::BufferFormat format = display::DisplaySnapshot::PrimaryFormat();
@@ -86,82 +121,82 @@ bool SurfacelessGlRenderer::BufferWrapper::Initialize(
}
image_ = image;
- glBindFramebufferEXT(GL_FRAMEBUFFER, gl_fb_);
glBindTexture(GL_TEXTURE_2D, gl_tex_);
image_->BindTexImage(GL_TEXTURE_2D);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
- gl_tex_, 0);
- if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
- LOG(ERROR) << "Failed to create framebuffer "
- << glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
- return false;
- }
-
widget_ = widget;
size_ = size;
- return true;
-}
+ GrGLTextureInfo texture_info;
+ texture_info.fTarget = GL_TEXTURE_2D;
+ texture_info.fID = gl_tex_;
+ texture_info.fFormat = GL_RGBA;
+ GrBackendTexture backend_texture(size_.width(), size_.height(),
+ kRGBA_8888_GrPixelConfig, texture_info);
+ sk_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget(
+ gr_context, backend_texture, kTopLeft_GrSurfaceOrigin, 0, nullptr,
+ nullptr);
+ if (!sk_surface_) {
+ LOG(ERROR) << "Failed to create skia surface";
+ return false;
+ }
-void SurfacelessGlRenderer::BufferWrapper::BindFramebuffer() {
- glBindFramebufferEXT(GL_FRAMEBUFFER, gl_fb_);
+ return true;
}
-SurfacelessGlRenderer::SurfacelessGlRenderer(
+SurfacelessSkiaRenderer::SurfacelessSkiaRenderer(
gfx::AcceleratedWidget widget,
const scoped_refptr<gl::GLSurface>& surface,
const gfx::Size& size)
- : GlRenderer(widget, surface, size),
+ : SkiaRenderer(widget, surface, size),
overlay_checker_(ui::OzonePlatform::GetInstance()
->GetOverlayManager()
->CreateOverlayCandidates(widget)),
weak_ptr_factory_(this) {}
-SurfacelessGlRenderer::~SurfacelessGlRenderer() {
+SurfacelessSkiaRenderer::~SurfacelessSkiaRenderer() {
// Need to make current when deleting the framebuffer resources allocated in
// the buffers.
- context_->MakeCurrent(surface_.get());
+ gl_context_->MakeCurrent(gl_surface_.get());
}
-bool SurfacelessGlRenderer::Initialize() {
- if (!GlRenderer::Initialize())
+bool SurfacelessSkiaRenderer::Initialize() {
+ if (!SkiaRenderer::Initialize())
return false;
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch("partial-primary-plane"))
+ if (command_line->HasSwitch(kPartialPrimaryPlane))
primary_plane_rect_ = gfx::Rect(200, 200, 800, 800);
else
primary_plane_rect_ = gfx::Rect(size_);
for (size_t i = 0; i < arraysize(buffers_); ++i) {
buffers_[i].reset(new BufferWrapper());
- if (!buffers_[i]->Initialize(widget_, primary_plane_rect_.size()))
+ if (!buffers_[i]->Initialize(gr_context_.get(), widget_,
+ primary_plane_rect_.size()))
return false;
}
- if (command_line->HasSwitch("enable-overlay")) {
+ if (command_line->HasSwitch(kEnableOverlay)) {
gfx::Size overlay_size = gfx::Size(size_.width() / 8, size_.height() / 8);
for (size_t i = 0; i < arraysize(overlay_buffer_); ++i) {
overlay_buffer_[i].reset(new BufferWrapper());
- overlay_buffer_[i]->Initialize(gfx::kNullAcceleratedWidget, overlay_size);
-
- glViewport(0, 0, overlay_size.width(), overlay_size.height());
- glClearColor(i, 1.0, 0.0, 1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ overlay_buffer_[i]->Initialize(gr_context_.get(),
+ gfx::kNullAcceleratedWidget, overlay_size);
+ SkCanvas* sk_canvas = overlay_buffer_[i]->sk_surface()->getCanvas();
+ sk_canvas->clear(SkColorSetARGB(255, 255 * i, 255, 0));
}
}
- disable_primary_plane_ = command_line->HasSwitch("disable-primary-plane");
+ disable_primary_plane_ = command_line->HasSwitch(kDisablePrimaryPlane);
PostRenderFrameTask(gfx::SwapResult::SWAP_ACK);
return true;
}
-void SurfacelessGlRenderer::RenderFrame() {
- TRACE_EVENT0("ozone", "SurfacelessGlRenderer::RenderFrame");
-
- float fraction = NextFraction();
+void SurfacelessSkiaRenderer::RenderFrame() {
+ TRACE_EVENT0("ozone", "SurfacelessSkiaRenderer::RenderFrame");
+ float fraction = CurrentFraction();
gfx::Rect overlay_rect;
OverlayCandidatesOzone::OverlaySurfaceCandidateList overlay_list;
@@ -194,44 +229,51 @@ void SurfacelessGlRenderer::RenderFrame() {
// later time.
overlay_checker_->CheckOverlaySupport(&overlay_list);
- context_->MakeCurrent(surface_.get());
- buffers_[back_buffer_]->BindFramebuffer();
+ gl_context_->MakeCurrent(gl_surface_.get());
- glViewport(0, 0, size_.width(), size_.height());
- glClearColor(1 - fraction, 0.0, fraction, 1.0);
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ SkSurface* sk_surface = buffers_[back_buffer_]->sk_surface();
+ if (use_ddl_) {
+ StartDDLRenderThreadIfNecessary(sk_surface);
+ auto ddl = GetDDL();
+ sk_surface->draw(ddl.get());
+ } else {
+ Draw(sk_surface->getCanvas(), NextFraction());
+ }
+ gr_context_->flush();
+ glFinish();
if (!disable_primary_plane_) {
CHECK(overlay_list.front().overlay_handled);
- surface_->ScheduleOverlayPlane(0, gfx::OVERLAY_TRANSFORM_NONE,
- buffers_[back_buffer_]->image(),
- primary_plane_rect_, gfx::RectF(0, 0, 1, 1));
+ gl_surface_->ScheduleOverlayPlane(
+ 0, gfx::OVERLAY_TRANSFORM_NONE, buffers_[back_buffer_]->image(),
+ primary_plane_rect_, gfx::RectF(0, 0, 1, 1));
}
if (overlay_buffer_[0] && overlay_list.back().overlay_handled) {
- surface_->ScheduleOverlayPlane(1, gfx::OVERLAY_TRANSFORM_NONE,
- overlay_buffer_[back_buffer_]->image(),
- overlay_rect, gfx::RectF(0, 0, 1, 1));
+ gl_surface_->ScheduleOverlayPlane(1, gfx::OVERLAY_TRANSFORM_NONE,
+ overlay_buffer_[back_buffer_]->image(),
+ overlay_rect, gfx::RectF(0, 0, 1, 1));
}
back_buffer_ ^= 1;
- surface_->SwapBuffersAsync(
- base::Bind(&SurfacelessGlRenderer::PostRenderFrameTask,
- weak_ptr_factory_.GetWeakPtr()),
- base::Bind([](const gfx::PresentationFeedback&) {}));
+ gl_surface_->SwapBuffersAsync(
+ base::BindRepeating(&SurfacelessSkiaRenderer::PostRenderFrameTask,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::DoNothing());
}
-void SurfacelessGlRenderer::PostRenderFrameTask(gfx::SwapResult result) {
+void SurfacelessSkiaRenderer::PostRenderFrameTask(gfx::SwapResult result) {
switch (result) {
case gfx::SwapResult::SWAP_NAK_RECREATE_BUFFERS:
for (size_t i = 0; i < arraysize(buffers_); ++i) {
buffers_[i].reset(new BufferWrapper());
- if (!buffers_[i]->Initialize(widget_, primary_plane_rect_.size()))
+ if (!buffers_[i]->Initialize(gr_context_.get(), widget_,
+ primary_plane_rect_.size()))
LOG(FATAL) << "Failed to recreate buffer";
}
- // Fall through since we want to render a new frame anyways.
+ FALLTHROUGH; // We want to render a new frame anyways.
case gfx::SwapResult::SWAP_ACK:
- GlRenderer::PostRenderFrameTask(result);
+ SkiaRenderer::PostRenderFrameTask(result);
break;
case gfx::SwapResult::SWAP_FAILED:
LOG(FATAL) << "Failed to swap buffers";
diff --git a/chromium/ui/ozone/demo/surfaceless_skia_renderer.h b/chromium/ui/ozone/demo/surfaceless_skia_renderer.h
new file mode 100644
index 00000000000..b61a19dbb12
--- /dev/null
+++ b/chromium/ui/ozone/demo/surfaceless_skia_renderer.h
@@ -0,0 +1,51 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_DEMO_SURFACELESS_SKIA_RENDERER_H_
+#define UI_OZONE_DEMO_SURFACELESS_SKIA_RENDERER_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/ozone/demo/skia_renderer.h"
+
+namespace ui {
+class OverlayCandidatesOzone;
+
+class SurfacelessSkiaRenderer : public SkiaRenderer {
+ public:
+ SurfacelessSkiaRenderer(gfx::AcceleratedWidget widget,
+ const scoped_refptr<gl::GLSurface>& surface,
+ const gfx::Size& size);
+ ~SurfacelessSkiaRenderer() override;
+
+ // Renderer:
+ bool Initialize() override;
+
+ private:
+ // SkiaRenderer:
+ void RenderFrame() override;
+ void PostRenderFrameTask(gfx::SwapResult result) override;
+
+ class BufferWrapper;
+
+ std::unique_ptr<BufferWrapper> buffers_[2];
+
+ std::unique_ptr<BufferWrapper> overlay_buffer_[2];
+ bool disable_primary_plane_ = false;
+ gfx::Rect primary_plane_rect_;
+
+ std::unique_ptr<OverlayCandidatesOzone> overlay_checker_;
+
+ int back_buffer_ = 0;
+
+ base::WeakPtrFactory<SurfacelessSkiaRenderer> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SurfacelessSkiaRenderer);
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_DEMO_SURFACELESS_SKIA_RENDERER_H_
diff --git a/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc b/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
index 66e1fefbe4c..52a42f83617 100644
--- a/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
+++ b/chromium/ui/ozone/gl/gl_image_ozone_native_pixmap_unittest.cc
@@ -9,6 +9,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/buffer_types.h"
#include "ui/gfx/client_native_pixmap.h"
+#include "ui/gfx/client_native_pixmap_factory.h"
#include "ui/gl/gl_image_native_pixmap.h"
#include "ui/gl/test/gl_image_test_template.h"
#include "ui/ozone/public/client_native_pixmap_factory_ozone.h"
@@ -25,8 +26,11 @@ template <gfx::BufferUsage usage, gfx::BufferFormat format>
class GLImageNativePixmapTestDelegate : public GLImageTestDelegateBase {
public:
GLImageNativePixmapTestDelegate() {
- client_pixmap_factory_ = ui::CreateClientNativePixmapFactoryOzone();
+ ui::CreateClientNativePixmapFactoryOzone();
}
+
+ ~GLImageNativePixmapTestDelegate() override = default;
+
scoped_refptr<GLImage> CreateSolidColorImage(const gfx::Size& size,
const uint8_t color[4]) const {
ui::SurfaceFactoryOzone* surface_factory =
@@ -37,8 +41,9 @@ class GLImageNativePixmapTestDelegate : public GLImageTestDelegateBase {
DCHECK(pixmap);
if (usage == gfx::BufferUsage::GPU_READ_CPU_READ_WRITE ||
usage == gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE) {
- auto client_pixmap = client_pixmap_factory_->ImportFromHandle(
- pixmap->ExportHandle(), size, usage);
+ auto client_pixmap =
+ gfx::ClientNativePixmapFactory::GetInstance()->ImportFromHandle(
+ pixmap->ExportHandle(), size, usage);
bool mapped = client_pixmap->Map();
EXPECT_TRUE(mapped);
@@ -72,7 +77,7 @@ class GLImageNativePixmapTestDelegate : public GLImageTestDelegateBase {
}
private:
- std::unique_ptr<gfx::ClientNativePixmapFactory> client_pixmap_factory_;
+ DISALLOW_COPY_AND_ASSIGN(GLImageNativePixmapTestDelegate);
};
using GLImageScanoutType = testing::Types<
diff --git a/chromium/ui/ozone/platform/cast/BUILD.gn b/chromium/ui/ozone/platform/cast/BUILD.gn
index fd92abf268b..eac0aae8c8b 100644
--- a/chromium/ui/ozone/platform/cast/BUILD.gn
+++ b/chromium/ui/ozone/platform/cast/BUILD.gn
@@ -40,7 +40,7 @@ source_set("cast") {
deps = [
"//base",
- "//chromecast:chromecast_features",
+ "//chromecast:chromecast_buildflags",
"//chromecast/base:base",
"//chromecast/graphics:libcast_graphics_1.0",
"//ui/events/ozone:events_ozone",
diff --git a/chromium/ui/ozone/platform/cast/DEPS b/chromium/ui/ozone/platform/cast/DEPS
index ffc9eafa338..06cf3c34e0b 100644
--- a/chromium/ui/ozone/platform/cast/DEPS
+++ b/chromium/ui/ozone/platform/cast/DEPS
@@ -1,6 +1,6 @@
include_rules = [
"+chromecast/base/cast_features.h",
"+chromecast/base/chromecast_switches.h",
- "+chromecast/chromecast_features.h",
+ "+chromecast/chromecast_buildflags.h",
"+chromecast/public"
]
diff --git a/chromium/ui/ozone/platform/cast/ozone_platform_cast.cc b/chromium/ui/ozone/platform/cast/ozone_platform_cast.cc
index b2eed765638..bf14fa286ed 100644
--- a/chromium/ui/ozone/platform/cast/ozone_platform_cast.cc
+++ b/chromium/ui/ozone/platform/cast/ozone_platform_cast.cc
@@ -10,7 +10,7 @@
#include "base/lazy_instance.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
-#include "chromecast/chromecast_features.h"
+#include "chromecast/chromecast_buildflags.h"
#include "chromecast/public/cast_egl_platform.h"
#include "chromecast/public/cast_egl_platform_shlib.h"
#include "ui/display/types/native_display_delegate.h"
diff --git a/chromium/ui/ozone/platform/drm/BUILD.gn b/chromium/ui/ozone/platform/drm/BUILD.gn
index 3eee6279e62..99fc0d66bf2 100644
--- a/chromium/ui/ozone/platform/drm/BUILD.gn
+++ b/chromium/ui/ozone/platform/drm/BUILD.gn
@@ -81,6 +81,8 @@ source_set("gbm") {
"gpu/screen_manager.h",
"host/drm_cursor.cc",
"host/drm_cursor.h",
+ "host/drm_device_connector.cc",
+ "host/drm_device_connector.h",
"host/drm_device_handle.cc",
"host/drm_device_handle.h",
"host/drm_display_host.cc",
diff --git a/chromium/ui/ozone/platform/drm/DEPS b/chromium/ui/ozone/platform/drm/DEPS
index 7d49ef1703b..69f499a9025 100644
--- a/chromium/ui/ozone/platform/drm/DEPS
+++ b/chromium/ui/ozone/platform/drm/DEPS
@@ -2,6 +2,7 @@ include_rules = [
"+mojo/public",
"+services/service_manager",
"+services/ui",
+ "+ui/base/ui_base_features.h",
"+ui/base/ui_base_switches.h",
"+ui/base/ui_features.h", # UI features doesn't bring in all of ui/base.
"+ui/display/util",
diff --git a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc
index ef596c0689b..88456854b97 100644
--- a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.cc
@@ -120,12 +120,6 @@ bool CrtcController::SchedulePageFlip(
return true;
}
-bool CrtcController::IsFormatSupported(uint32_t fourcc_format,
- uint32_t z_order) const {
- return drm_->plane_manager()->IsFormatSupported(fourcc_format, z_order,
- crtc_);
-}
-
std::vector<uint64_t> CrtcController::GetFormatModifiers(uint32_t format) {
return drm_->plane_manager()->GetFormatModifiers(crtc_, format);
}
diff --git a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h
index dcbd0ae0e0f..98b276711bd 100644
--- a/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h
+++ b/chromium/ui/ozone/platform/drm/gpu/crtc_controller.h
@@ -59,10 +59,6 @@ class CrtcController : public base::SupportsWeakPtr<CrtcController> {
bool test_only,
scoped_refptr<PageFlipRequest> page_flip_request);
- // Returns true if hardware plane with z_order equal to |z_order| can support
- // |fourcc_format| format.
- bool IsFormatSupported(uint32_t fourcc_format, uint32_t z_order) const;
-
// Returns a vector of format modifiers for the given fourcc format
// on this CRTCs primary plane. A format modifier describes the
// actual layout of the buffer, such as whether it's linear, tiled
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
index 1abc94f9e20..15d5bae1977 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_overlay_validator.cc
@@ -75,18 +75,9 @@ std::vector<OverlayCheckReturn_Params> DrmOverlayValidator::TestPageFlip(
continue;
}
- uint32_t original_format =
- params[i].plane_z_order
- ? GetFourCCFormatFromBufferFormat(params[i].format)
- : GetFourCCFormatForOpaqueFramebuffer(params[i].format);
- if (!controller->IsFormatSupported(original_format,
- params[i].plane_z_order)) {
- returns[i].status = OVERLAY_STATUS_NOT;
- continue;
- }
-
scoped_refptr<ScanoutBuffer> buffer =
- GetBufferForPageFlipTest(drm, params[i].buffer_size, original_format,
+ GetBufferForPageFlipTest(drm, params[i].buffer_size,
+ GetFourCCFormatFromBufferFormat(params[i].format),
buffer_generator_, &reusable_buffers);
OverlayPlane plane(buffer, params[i].plane_z_order, params[i].transform,
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc
index a00011f7bb2..566de8b0b67 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -77,17 +77,18 @@ class GbmDeviceGenerator : public DrmDeviceGenerator {
} // namespace
-DrmThread::DrmThread()
- : base::Thread("DrmThread"), binding_(this), weak_ptr_factory_(this) {}
+DrmThread::DrmThread() : base::Thread("DrmThread"), weak_ptr_factory_(this) {}
DrmThread::~DrmThread() {
Stop();
}
-void DrmThread::Start() {
+void DrmThread::Start(base::OnceClosure binding_completer) {
+ complete_early_binding_requests_ = std::move(binding_completer);
base::Thread::Options thread_options;
thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
thread_options.priority = base::ThreadPriority::DISPLAY;
+
if (!StartWithOptions(thread_options))
LOG(FATAL) << "Failed to create DRM thread";
}
@@ -104,6 +105,13 @@ void DrmThread::Init() {
display_manager_.reset(
new DrmGpuDisplayManager(screen_manager_.get(), device_manager_.get()));
+
+ DCHECK(task_runner())
+ << "DrmThread::Init -- thread doesn't have a task_runner";
+
+ // DRM thread is running now so can safely handle binding requests. So drain
+ // the queue of as-yet unhandled binding requests if there are any.
+ std::move(complete_early_binding_requests_).Run();
}
void DrmThread::CreateBuffer(gfx::AcceleratedWidget widget,
@@ -343,12 +351,12 @@ void DrmThread::StartDrmDevice(StartDrmDeviceCallback callback) {
// be used from multiple threads in multiple processes.
void DrmThread::AddBindingCursorDevice(
ozone::mojom::DeviceCursorRequest request) {
- bindings_.AddBinding(this, std::move(request));
+ cursor_bindings_.AddBinding(this, std::move(request));
}
void DrmThread::AddBindingDrmDevice(ozone::mojom::DrmDeviceRequest request) {
TRACE_EVENT0("drm", "DrmThread::AddBindingDrmDevice");
- binding_.Bind(std::move(request));
+ drm_bindings_.AddBinding(this, std::move(request));
}
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread.h b/chromium/ui/ozone/platform/drm/gpu/drm_thread.h
index 5c0dcad5c22..1faf99947a0 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread.h
@@ -62,7 +62,7 @@ class DrmThread : public base::Thread,
DrmThread();
~DrmThread() override;
- void Start();
+ void Start(base::OnceClosure binding_completer);
// Must be called on the DRM thread. All methods for use from the GPU thread.
// DrmThreadProxy (on GPU)thread) is the client for these methods.
@@ -150,12 +150,16 @@ class DrmThread : public base::Thread,
std::unique_ptr<ScreenManager> screen_manager_;
std::unique_ptr<DrmGpuDisplayManager> display_manager_;
+ base::OnceClosure complete_early_binding_requests_;
+
// The mojo implementation requires a BindingSet because the DrmThread serves
// requests from two different client threads.
- mojo::BindingSet<ozone::mojom::DeviceCursor> bindings_;
+ mojo::BindingSet<ozone::mojom::DeviceCursor> cursor_bindings_;
- // The mojo implementation of DrmDevice can use a simple binding.
- mojo::Binding<ozone::mojom::DrmDevice> binding_;
+ // The mojo implementation of DrmDevice requires a BindingSet because the
+ // DrmThread services requests from different client threads when operating in
+ // mus mode
+ mojo::BindingSet<ozone::mojom::DrmDevice> drm_bindings_;
base::WeakPtrFactory<DrmThread> weak_ptr_factory_;
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
index 24a88ec901a..6e1d4a749e3 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_message_proxy.cc
@@ -26,10 +26,6 @@ void DrmThreadMessageProxy::SetDrmThread(DrmThread* thread) {
void DrmThreadMessageProxy::OnFilterAdded(IPC::Channel* channel) {
sender_ = channel;
-
- // The DRM thread needs to be started late since we need to wait for the
- // sandbox to start.
- drm_thread_->Start();
}
bool DrmThreadMessageProxy::OnMessageReceived(const IPC::Message& message) {
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
index bdc798cd2f8..2bad52ddd44 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.cc
@@ -17,13 +17,15 @@ DrmThreadProxy::DrmThreadProxy() {}
DrmThreadProxy::~DrmThreadProxy() {}
+// Used only with the paramtraits implementation.
void DrmThreadProxy::BindThreadIntoMessagingProxy(
InterThreadMessagingProxy* messaging_proxy) {
messaging_proxy->SetDrmThread(&drm_thread_);
}
-void DrmThreadProxy::StartDrmThread() {
- drm_thread_.Start();
+// Used only for the mojo implementation.
+void DrmThreadProxy::StartDrmThread(base::OnceClosure binding_drainer) {
+ drm_thread_.Start(std::move(binding_drainer));
}
std::unique_ptr<DrmWindowProxy> DrmThreadProxy::CreateDrmWindowProxy(
@@ -36,7 +38,10 @@ scoped_refptr<GbmBuffer> DrmThreadProxy::CreateBuffer(
const gfx::Size& size,
gfx::BufferFormat format,
gfx::BufferUsage usage) {
+ DCHECK(drm_thread_.task_runner())
+ << "no task runner! in DrmThreadProxy::CreateBuffer";
scoped_refptr<GbmBuffer> buffer;
+
PostSyncTask(
drm_thread_.task_runner(),
base::Bind(&DrmThread::CreateBuffer, base::Unretained(&drm_thread_),
@@ -77,6 +82,9 @@ void DrmThreadProxy::AddBindingCursorDevice(
void DrmThreadProxy::AddBindingDrmDevice(
ozone::mojom::DrmDeviceRequest request) {
+ DCHECK(drm_thread_.task_runner()) << "DrmThreadProxy::AddBindingDrmDevice "
+ "drm_thread_ task runner missing";
+
drm_thread_.task_runner()->PostTask(
FROM_HERE,
base::Bind(&DrmThread::AddBindingDrmDevice,
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
index c8a0b4b9c0b..d46de5a5faf 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_thread_proxy.h
@@ -27,7 +27,7 @@ class DrmThreadProxy {
void BindThreadIntoMessagingProxy(InterThreadMessagingProxy* messaging_proxy);
- void StartDrmThread();
+ void StartDrmThread(base::OnceClosure binding_drainer);
std::unique_ptr<DrmWindowProxy> CreateDrmWindowProxy(
gfx::AcceleratedWidget widget);
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.cc b/chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.cc
index 7f47511740d..4b153e21255 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.cc
@@ -23,8 +23,12 @@ bool DrmVSyncProvider::GetVSyncParametersIfAvailable(
return false;
}
-bool DrmVSyncProvider::SupportGetVSyncParametersIfAvailable() {
+bool DrmVSyncProvider::SupportGetVSyncParametersIfAvailable() const {
return false;
}
+bool DrmVSyncProvider::IsHWClock() const {
+ return true;
+}
+
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.h b/chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.h
index 6db9948ee68..d0ec9a6e142 100644
--- a/chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.h
+++ b/chromium/ui/ozone/platform/drm/gpu/drm_vsync_provider.h
@@ -21,7 +21,8 @@ class DrmVSyncProvider : public gfx::VSyncProvider {
void GetVSyncParameters(const UpdateVSyncCallback& callback) override;
bool GetVSyncParametersIfAvailable(base::TimeTicks* timebase,
base::TimeDelta* interval) override;
- bool SupportGetVSyncParametersIfAvailable() override;
+ bool SupportGetVSyncParametersIfAvailable() const override;
+ bool IsHWClock() const override;
private:
DrmWindowProxy* window_;
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
index 2574cf69d67..de661e983a7 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.cc
@@ -145,17 +145,6 @@ bool HardwareDisplayController::ActualSchedulePageFlip(
return status;
}
-bool HardwareDisplayController::IsFormatSupported(uint32_t fourcc_format,
- uint32_t z_order) const {
- for (size_t i = 0; i < crtc_controllers_.size(); ++i) {
- // Make sure all displays have overlay to support this format.
- if (!crtc_controllers_[i]->IsFormatSupported(fourcc_format, z_order))
- return false;
- }
-
- return true;
-}
-
std::vector<uint64_t> HardwareDisplayController::GetFormatModifiers(
uint32_t format) {
std::vector<uint64_t> modifiers;
@@ -235,39 +224,51 @@ void HardwareDisplayController::AddCrtc(
std::unique_ptr<CrtcController> HardwareDisplayController::RemoveCrtc(
const scoped_refptr<DrmDevice>& drm,
uint32_t crtc) {
- for (auto it = crtc_controllers_.begin(); it != crtc_controllers_.end();
- ++it) {
- if ((*it)->drm() == drm && (*it)->crtc() == crtc) {
- std::unique_ptr<CrtcController> controller(std::move(*it));
- crtc_controllers_.erase(it);
-
- // Remove entry from |owned_hardware_planes_| iff no other crtcs share it.
- bool found = false;
- for (auto it = crtc_controllers_.begin(); it != crtc_controllers_.end();
- ++it) {
- if ((*it)->drm() == controller->drm()) {
- found = true;
- break;
- }
- }
- if (found) {
- std::vector<HardwareDisplayPlane*> all_planes;
- HardwareDisplayPlaneList* plane_list =
- owned_hardware_planes_[drm.get()].get();
- all_planes.swap(plane_list->old_plane_list);
- for (auto* plane : all_planes) {
- if (plane->owning_crtc() != crtc)
- plane_list->old_plane_list.push_back(plane);
- }
- } else {
- owned_hardware_planes_.erase(controller->drm().get());
- }
-
- return controller;
- }
+ auto controller_it = std::find_if(
+ crtc_controllers_.begin(), crtc_controllers_.end(),
+ [drm, crtc](const std::unique_ptr<CrtcController>& crtc_controller) {
+ return crtc_controller->drm() == drm && crtc_controller->crtc() == crtc;
+ });
+ if (controller_it == crtc_controllers_.end())
+ return nullptr;
+
+ std::unique_ptr<CrtcController> controller(std::move(*controller_it));
+ crtc_controllers_.erase(controller_it);
+
+ // Remove and disable only the planes owned by the CRTC we just
+ // removed.
+ std::vector<HardwareDisplayPlane*>& old_plane_list =
+ owned_hardware_planes_[drm.get()]->old_plane_list;
+
+ // Move all the planes that have been committed in the last pageflip for this
+ // CRTC at the end of the collection.
+ auto first_plane_to_disable_it =
+ std::partition(old_plane_list.begin(), old_plane_list.end(),
+ [crtc](const HardwareDisplayPlane* plane) {
+ return plane->owning_crtc() != crtc;
+ });
+
+ // Disable the planes enabled with the last commit on |crtc|, otherwise
+ // the planes will be visible if the crtc is reassigned to another connector.
+ HardwareDisplayPlaneList hardware_plane_list;
+ std::copy(first_plane_to_disable_it, old_plane_list.end(),
+ std::back_inserter(hardware_plane_list.old_plane_list));
+ drm->plane_manager()->DisableOverlayPlanes(&hardware_plane_list);
+
+ // If it was the only CRTC for this drm device, we can remove the hardware
+ // planes list in |owned_hardware_planes_|.
+ if (std::find_if(crtc_controllers_.begin(), crtc_controllers_.end(),
+ [drm](const std::unique_ptr<CrtcController>& crtc) {
+ return crtc->drm() == drm;
+ }) == crtc_controllers_.end()) {
+ owned_hardware_planes_.erase(controller->drm().get());
+ } else {
+ // Otherwise we can remove the planes assigned to |crtc| but we can't
+ // remove the entry in |owned_hardware_planes_|.
+ old_plane_list.erase(first_plane_to_disable_it, old_plane_list.end());
}
- return nullptr;
+ return controller;
}
bool HardwareDisplayController::HasCrtc(const scoped_refptr<DrmDevice>& drm,
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h
index d96d66f4c9b..1fa3665c7dd 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_controller.h
@@ -123,8 +123,6 @@ class HardwareDisplayController {
// doesn't change any state.
bool TestPageFlip(const OverlayPlaneList& plane_list);
- bool IsFormatSupported(uint32_t fourcc_format, uint32_t z_order) const;
-
// Return the supported modifiers for |fourcc_format| for this
// controller.
std::vector<uint64_t> GetFormatModifiers(uint32_t fourcc_format);
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
index c102c12a820..b74520781ae 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.cc
@@ -310,39 +310,6 @@ const std::vector<uint32_t>& HardwareDisplayPlaneManager::GetSupportedFormats()
return supported_formats_;
}
-bool HardwareDisplayPlaneManager::IsFormatSupported(uint32_t fourcc_format,
- uint32_t z_order,
- uint32_t crtc_id) const {
- bool format_supported = false;
- int crtc_index = LookupCrtcIndex(crtc_id);
- if (crtc_index < 0) {
- LOG(ERROR) << "Cannot find crtc " << crtc_id;
- return format_supported;
- }
-
- // We dont have a way to query z_order of a plane. This is a temporary
- // solution till driver exposes z_order property.
- uint32_t plane_z_order = 0;
- for (const auto& hardware_plane : planes_) {
- if (plane_z_order > z_order)
- break;
-
- if (!hardware_plane->CanUseForCrtc(crtc_index))
- continue;
-
- if (plane_z_order == z_order) {
- if (hardware_plane->IsSupportedFormat(fourcc_format))
- format_supported = true;
-
- break;
- } else {
- plane_z_order++;
- }
- }
-
- return format_supported;
-}
-
std::vector<uint64_t> HardwareDisplayPlaneManager::GetFormatModifiers(
uint32_t crtc_id,
uint32_t format) {
diff --git a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
index 175ca07a60c..f49d7cbd611 100644
--- a/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
+++ b/chromium/ui/ozone/platform/drm/gpu/hardware_display_plane_manager.h
@@ -109,13 +109,8 @@ class HardwareDisplayPlaneManager {
virtual void RequestPlanesReadyCallback(const OverlayPlaneList& planes,
base::OnceClosure callback) = 0;
- // Returns all formats which can be scanned out by this PlaneManager. Use
- // IsFormatSupported to find if a given format is supported on a particular
- // plane for a given crtc.
+ // Returns all formats which can be scanned out by this PlaneManager.
const std::vector<uint32_t>& GetSupportedFormats() const;
- bool IsFormatSupported(uint32_t fourcc_format,
- uint32_t z_order,
- uint32_t crtc_id) const;
std::vector<uint64_t> GetFormatModifiers(uint32_t crtc_id, uint32_t format);
diff --git a/chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc b/chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
index ee3d518cc7b..2fe14daad7d 100644
--- a/chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
+++ b/chromium/ui/ozone/platform/drm/gpu/screen_manager_unittest.cc
@@ -22,8 +22,6 @@
namespace {
-void EmptySwapCallback(gfx::SwapResult, const gfx::PresentationFeedback&) {}
-
// Create a basic mode for a 6x4 screen.
const drmModeModeInfo kDefaultMode =
{0, 6, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, {'\0'}};
@@ -505,7 +503,7 @@ TEST_F(ScreenManagerTest, EnableControllerWhenWindowHasBuffer) {
window->SchedulePageFlip(
std::vector<ui::OverlayPlane>(
1, ui::OverlayPlane(buffer, base::kInvalidPlatformFile)),
- base::Bind(&EmptySwapCallback));
+ base::DoNothing());
screen_manager_->AddWindow(1, std::move(window));
screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
@@ -532,7 +530,7 @@ TEST_F(ScreenManagerTest, RejectBufferWithIncompatibleModifiers) {
window->SchedulePageFlip(
std::vector<ui::OverlayPlane>(
1, ui::OverlayPlane(buffer, base::kInvalidPlatformFile)),
- base::Bind(&EmptySwapCallback));
+ base::DoNothing());
screen_manager_->AddWindow(1, std::move(window));
screen_manager_->AddDisplayController(drm_, kPrimaryCrtc, kPrimaryConnector);
diff --git a/chromium/ui/ozone/platform/drm/host/drm_device_connector.cc b/chromium/ui/ozone/platform/drm/host/drm_device_connector.cc
new file mode 100644
index 00000000000..6bfc3cb1001
--- /dev/null
+++ b/chromium/ui/ozone/platform/drm/host/drm_device_connector.cc
@@ -0,0 +1,137 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/drm/host/drm_device_connector.h"
+
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+#include "services/service_manager/public/cpp/connector.h"
+#include "services/ui/public/interfaces/constants.mojom.h"
+#include "ui/base/ui_base_features.h"
+#include "ui/ozone/platform/drm/host/host_drm_device.h"
+#include "ui/ozone/public/gpu_platform_support_host.h"
+
+namespace {
+// TODO(rjkroege): In the future when ozone/drm is always mojo-based, remove
+// this utility code.
+using BinderCallback = ui::GpuPlatformSupportHost::GpuHostBindInterfaceCallback;
+
+void BindInterfaceInGpuProcess(const std::string& interface_name,
+ mojo::ScopedMessagePipeHandle interface_pipe,
+ const BinderCallback& binder_callback) {
+ return binder_callback.Run(interface_name, std::move(interface_pipe));
+}
+
+template <typename Interface>
+void BindInterfaceInGpuProcess(mojo::InterfaceRequest<Interface> request,
+ const BinderCallback& binder_callback) {
+ BindInterfaceInGpuProcess(
+ Interface::Name_, std::move(request.PassMessagePipe()), binder_callback);
+}
+
+} // namespace
+
+namespace ui {
+
+DrmDeviceConnector::DrmDeviceConnector(
+ service_manager::Connector* connector,
+ scoped_refptr<HostDrmDevice> host_drm_device_)
+ : connector_(connector),
+ host_drm_device_(host_drm_device_),
+ ws_runner_(base::ThreadTaskRunnerHandle::IsSet()
+ ? base::ThreadTaskRunnerHandle::Get()
+ : nullptr) {
+ // Invariant: we only have a runner at startup if executing in mus mode.
+ DCHECK((ws_runner_ && features::IsMusEnabled()) ||
+ (!ws_runner_ && !features::IsMusEnabled()));
+}
+
+DrmDeviceConnector::~DrmDeviceConnector() {}
+
+void DrmDeviceConnector::OnGpuProcessLaunched(
+ int host_id,
+ scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> send_runner,
+ const base::RepeatingCallback<void(IPC::Message*)>& send_callback) {
+ NOTREACHED();
+}
+
+void DrmDeviceConnector::OnChannelDestroyed(int host_id) {
+ // TODO(rjkroege): Handle Viz restarting.
+ NOTIMPLEMENTED();
+}
+
+void DrmDeviceConnector::OnGpuServiceLaunched(
+ scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_runner,
+ GpuHostBindInterfaceCallback binder) {
+ // We need to preserve |binder| to let us bind interfaces later.
+ binder_callback_ = std::move(binder);
+ if (am_running_in_ws_mode()) {
+ ui::ozone::mojom::DrmDevicePtr drm_device_ptr_ui, drm_device_ptr_ws;
+ ui::ozone::mojom::DeviceCursorPtr cursor_ptr_ws, cursor_ptr_io;
+
+ BindInterfaceDrmDevice(&drm_device_ptr_ui);
+ BindInterfaceDrmDevice(&drm_device_ptr_ws);
+ BindInterfaceDeviceCursor(&cursor_ptr_ws);
+ BindInterfaceDeviceCursor(&cursor_ptr_io);
+
+ ws_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&HostDrmDevice::OnGpuServiceLaunched, host_drm_device_,
+ std::move(drm_device_ptr_ws), std::move(cursor_ptr_ws),
+ std::move(cursor_ptr_io)));
+
+ ui_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&HostDrmDevice::OnGpuServiceLaunchedCompositor,
+ host_drm_device_, std::move(drm_device_ptr_ui)));
+
+ } else {
+ ui::ozone::mojom::DrmDevicePtr drm_device_ptr_ui;
+ ui::ozone::mojom::DeviceCursorPtr cursor_ptr_ui, cursor_ptr_io;
+
+ BindInterfaceDrmDevice(&drm_device_ptr_ui);
+ BindInterfaceDeviceCursor(&cursor_ptr_ui);
+ BindInterfaceDeviceCursor(&cursor_ptr_io);
+
+ ui_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&HostDrmDevice::OnGpuServiceLaunched, host_drm_device_,
+ std::move(drm_device_ptr_ui), std::move(cursor_ptr_ui),
+ std::move(cursor_ptr_io)));
+
+ ui_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(&HostDrmDevice::OnGpuServiceLaunchedCompositor,
+ host_drm_device_, std::move(drm_device_ptr_ui)));
+ }
+}
+
+void DrmDeviceConnector::OnMessageReceived(const IPC::Message& message) {
+ NOTREACHED() << "This class should only be used with mojo transport but here "
+ "we're wrongly getting invoked to handle IPC communication.";
+}
+
+void DrmDeviceConnector::BindInterfaceDrmDevice(
+ ui::ozone::mojom::DrmDevicePtr* drm_device_ptr) const {
+ if (connector_) {
+ connector_->BindInterface(ui::mojom::kServiceName, drm_device_ptr);
+ } else {
+ auto request = mojo::MakeRequest(drm_device_ptr);
+ BindInterfaceInGpuProcess(std::move(request), binder_callback_);
+ }
+}
+
+void DrmDeviceConnector::BindInterfaceDeviceCursor(
+ ui::ozone::mojom::DeviceCursorPtr* cursor_ptr) const {
+ if (connector_) {
+ connector_->BindInterface(ui::mojom::kServiceName, cursor_ptr);
+ } else {
+ auto request = mojo::MakeRequest(cursor_ptr);
+ BindInterfaceInGpuProcess(std::move(request), binder_callback_);
+ }
+}
+
+} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/host/drm_device_connector.h b/chromium/ui/ozone/platform/drm/host/drm_device_connector.h
new file mode 100644
index 00000000000..16659f78674
--- /dev/null
+++ b/chromium/ui/ozone/platform/drm/host/drm_device_connector.h
@@ -0,0 +1,73 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_DRM_HOST_DRM_DEVICE_CONNECTOR_H_
+#define UI_OZONE_PLATFORM_DRM_HOST_DRM_DEVICE_CONNECTOR_H_
+
+#include "ui/ozone/public/gpu_platform_support_host.h"
+#include "ui/ozone/public/interfaces/device_cursor.mojom.h"
+#include "ui/ozone/public/interfaces/drm_device.mojom.h"
+
+namespace service_manager {
+class Connector;
+}
+
+namespace ui {
+class HostDrmDevice;
+
+// DrmDeviceConnector sets up mojo pipes connecting the Viz host to the DRM
+// service. It operates in two modes: running on the I/O thread when invoked
+// from content and running on the VizHost main thread when operating with a
+// service_manager.
+class DrmDeviceConnector : public GpuPlatformSupportHost {
+ public:
+ DrmDeviceConnector(service_manager::Connector* connector,
+ scoped_refptr<HostDrmDevice> host_drm_device_);
+ ~DrmDeviceConnector() override;
+
+ // GpuPlatformSupportHost:
+ void OnGpuProcessLaunched(
+ int host_id,
+ scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> send_runner,
+ const base::RepeatingCallback<void(IPC::Message*)>& send_callback)
+ override;
+ void OnChannelDestroyed(int host_id) override;
+ void OnMessageReceived(const IPC::Message& message) override;
+ void OnGpuServiceLaunched(
+ scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_runner,
+ GpuHostBindInterfaceCallback binder) override;
+
+ // BindInterface arranges for the drm_device_ptr to be connected.
+ void BindInterfaceDrmDevice(
+ ui::ozone::mojom::DrmDevicePtr* drm_device_ptr) const;
+
+ // BindInterface arranges for the cursor_ptr to be wired up.
+ void BindInterfaceDeviceCursor(
+ ui::ozone::mojom::DeviceCursorPtr* cursor_ptr) const;
+
+ // BindableNow returns true if this DrmDeviceConnector is capable of binding a
+ // mojo endpoint for the DrmDevice service.
+ bool BindableNow() const { return !!connector_; }
+
+ private:
+ bool am_running_in_ws_mode() { return !!ws_runner_; }
+
+ // This will be present if the Viz host has a service manager.
+ service_manager::Connector* connector_;
+
+ // This will be used if we are operating under content/gpu without a service
+ // manager.
+ GpuHostBindInterfaceCallback binder_callback_;
+
+ scoped_refptr<HostDrmDevice> host_drm_device_;
+ scoped_refptr<base::SingleThreadTaskRunner> ws_runner_;
+
+ DISALLOW_COPY_AND_ASSIGN(DrmDeviceConnector);
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_PLATFORM_DRM_HOST_DRM_DEVICE_CONNECTOR_H_ \ No newline at end of file
diff --git a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
index c8267a2b827..6c7f4f4b510 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
+++ b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
+#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/ozone/common/gpu/ozone_gpu_message_params.h"
#include "ui/ozone/common/gpu/ozone_gpu_messages.h"
@@ -94,7 +95,7 @@ DrmGpuPlatformSupportHost::DrmGpuPlatformSupportHost(DrmCursor* cursor)
if (ui_runner_) {
weak_ptr_ = weak_ptr_factory_.GetWeakPtr();
} else {
- DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kMus));
+ DCHECK(!features::IsMusEnabled());
}
}
@@ -117,6 +118,14 @@ bool DrmGpuPlatformSupportHost::IsConnected() {
return host_id_ >= 0 && channel_established_;
}
+void DrmGpuPlatformSupportHost::OnGpuServiceLaunched(
+ scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_runner,
+ GpuHostBindInterfaceCallback binder) {
+ NOTREACHED() << "DrmGpuPlatformSupportHost::OnGpuServiceLaunched shouldn't "
+ "be used with pre-mojo IPC";
+}
+
void DrmGpuPlatformSupportHost::OnGpuProcessLaunched(
int host_id,
scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
diff --git a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
index 1de15cee1cb..ebcb9d5ea0d 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
+++ b/chromium/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
@@ -41,6 +41,10 @@ class DrmGpuPlatformSupportHost : public GpuPlatformSupportHost,
scoped_refptr<base::SingleThreadTaskRunner> send_runner,
const base::Callback<void(IPC::Message*)>& send_callback) override;
void OnChannelDestroyed(int host_id) override;
+ void OnGpuServiceLaunched(
+ scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_runner,
+ GpuHostBindInterfaceCallback binder) override;
void OnMessageReceived(const IPC::Message& message) override;
diff --git a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.h b/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.h
index 03b5e6619a5..1dd9aa15595 100644
--- a/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.h
+++ b/chromium/ui/ozone/platform/drm/host/drm_overlay_manager.h
@@ -71,7 +71,7 @@ class DrmOverlayManager : public OverlayManagerOzone {
base::MRUCache<OverlaySurfaceCandidateList, OverlayValidationCacheValue>
cache_;
// The cache can be accessed from multiple threads in some cases (e.g. with
- // --mus, it can be accessed from the UI thread, and the window-service
+ // mus, it can be accessed from the UI thread, and the window-service
// thread.)
// TODO(rjkroege): In the future (with --enable-viz), this code will not need
// the lock, but will require farther refactoring.
diff --git a/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc
index ba5baeec450..fa2880dcb27 100644
--- a/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc
+++ b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.cc
@@ -6,15 +6,17 @@
#include "services/service_manager/public/cpp/connector.h"
#include "services/ui/public/interfaces/constants.mojom.h"
+#include "ui/ozone/public/gpu_platform_support_host.h"
namespace ui {
-// We assume that this is invoked only on the UI thread.
-HostCursorProxy::HostCursorProxy(service_manager::Connector* connector)
- : connector_(connector->Clone()) {
- ui_thread_ref_ = base::PlatformThread::CurrentRef();
- connector->BindInterface(ui::mojom::kServiceName, &main_cursor_ptr_);
-}
+// We assume that this is invoked only on the Mus/UI thread.
+HostCursorProxy::HostCursorProxy(
+ ui::ozone::mojom::DeviceCursorPtr main_cursor_ptr,
+ ui::ozone::mojom::DeviceCursorPtr evdev_cursor_ptr)
+ : main_cursor_ptr_(std::move(main_cursor_ptr)),
+ evdev_cursor_ptr_(std::move(evdev_cursor_ptr)),
+ ui_thread_ref_(base::PlatformThread::CurrentRef()) {}
HostCursorProxy::~HostCursorProxy() {}
@@ -46,8 +48,14 @@ void HostCursorProxy::Move(gfx::AcceleratedWidget widget,
// when the GpuThread/DrmThread pair are once again running), we need to run it
// on cursor motions.
void HostCursorProxy::InitializeOnEvdevIfNecessary() {
+ // TODO(rjkroege): Rebind on Viz process restart.
+ if (evdev_bound_)
+ return;
+
if (ui_thread_ref_ != base::PlatformThread::CurrentRef()) {
- connector_->BindInterface(ui::mojom::kServiceName, &evdev_cursor_ptr_);
+ // Rebind the mojo pipe on the current thread. We expect this to be the
+ // thread running EVDEV.
+ evdev_cursor_ptr_.Bind(evdev_cursor_ptr_.PassInterface());
}
}
diff --git a/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h
index 42feece0e0e..87115dd28d7 100644
--- a/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h
+++ b/chromium/ui/ozone/platform/drm/host/host_cursor_proxy.h
@@ -9,10 +9,6 @@
#include "ui/ozone/platform/drm/host/drm_cursor.h"
#include "ui/ozone/public/interfaces/device_cursor.mojom.h"
-namespace service_manager {
-class Connector;
-}
-
namespace ui {
// Ozone requires a IPC from the browser (or mus-ws) process to the gpu (or
@@ -22,7 +18,8 @@ namespace ui {
// priviledged process.
class HostCursorProxy : public DrmCursorProxy {
public:
- explicit HostCursorProxy(service_manager::Connector* connector);
+ HostCursorProxy(ui::ozone::mojom::DeviceCursorPtr main_cursor_ptr,
+ ui::ozone::mojom::DeviceCursorPtr evdev_cursor_ptr);
~HostCursorProxy() override;
private:
@@ -34,13 +31,13 @@ class HostCursorProxy : public DrmCursorProxy {
void Move(gfx::AcceleratedWidget window, const gfx::Point& point) override;
void InitializeOnEvdevIfNecessary() override;
- std::unique_ptr<service_manager::Connector> connector_;
-
// Mojo implementation of the DrmCursorProxy.
- ui::ozone::mojom::DeviceCursorPtr main_cursor_ptr_;
- ui::ozone::mojom::DeviceCursorPtr evdev_cursor_ptr_;
+ ui::ozone::mojom::DeviceCursorPtr main_cursor_ptr_ = nullptr;
+ ui::ozone::mojom::DeviceCursorPtr evdev_cursor_ptr_ = nullptr;
base::PlatformThreadRef ui_thread_ref_;
+ bool evdev_bound_ = false;
+
DISALLOW_COPY_AND_ASSIGN(HostCursorProxy);
};
diff --git a/chromium/ui/ozone/platform/drm/host/host_drm_device.cc b/chromium/ui/ozone/platform/drm/host/host_drm_device.cc
index 9d1311b89a5..36ff79ce673 100644
--- a/chromium/ui/ozone/platform/drm/host/host_drm_device.cc
+++ b/chromium/ui/ozone/platform/drm/host/host_drm_device.cc
@@ -13,19 +13,15 @@
#include "services/ui/public/interfaces/constants.mojom.h"
#include "ui/display/types/display_snapshot.h"
#include "ui/ozone/platform/drm/common/drm_util.h"
+#include "ui/ozone/platform/drm/host/drm_device_connector.h"
#include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
#include "ui/ozone/platform/drm/host/drm_overlay_manager.h"
#include "ui/ozone/platform/drm/host/host_cursor_proxy.h"
namespace ui {
-HostDrmDevice::HostDrmDevice(DrmCursor* cursor,
- service_manager::Connector* connector)
- : cursor_(cursor), connector_(connector), weak_ptr_factory_(this) {
- // Bind the viz process pointer here.
- // TODO(rjkroege): Reconnect on error as that would indicate that the Viz
- // process has failed.
- connector->BindInterface(ui::mojom::kServiceName, &drm_device_ptr_);
+HostDrmDevice::HostDrmDevice(DrmCursor* cursor) : cursor_(cursor) {
+ DETACH_FROM_THREAD(on_io_thread_);
}
HostDrmDevice::~HostDrmDevice() {
@@ -34,15 +30,39 @@ HostDrmDevice::~HostDrmDevice() {
observer.OnGpuThreadRetired();
}
-void HostDrmDevice::AsyncStartDrmDevice() {
- auto callback = base::BindOnce(&HostDrmDevice::OnDrmServiceStartedCallback,
- weak_ptr_factory_.GetWeakPtr());
+// Setup the DRM device if we are using the ServiceManager.
+void HostDrmDevice::AsyncStartDrmDevice(const DrmDeviceConnector& connector) {
+ DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
+
+ // We bind here using the provided connector object.
+ if (!connector.BindableNow())
+ return;
+
+ connector.BindInterfaceDrmDevice(&drm_device_ptr_);
+
+ // Launch the DRM thread.
+ auto callback =
+ base::BindOnce(&HostDrmDevice::OnDrmServiceStartedCallback, this);
drm_device_ptr_->StartDrmDevice(std::move(callback));
+
+ // Bind the cursor interface pointers.
+ ui::ozone::mojom::DeviceCursorPtr cursor_ptr_ui, cursor_ptr_io;
+ connector.BindInterfaceDeviceCursor(&cursor_ptr_ui);
+
+ // This interface pointer is bound on the wrong thread. But that's OK because
+ // we'll re-bind it the first time that it's used from the I/O thread in
+ // HostCursorProxy.
+ connector.BindInterfaceDeviceCursor(&cursor_ptr_io);
+
+ // Stash the cursor_proxy so that we can install it in the callback.
+ cursor_proxy_ = std::make_unique<HostCursorProxy>(std::move(cursor_ptr_ui),
+ std::move(cursor_ptr_io));
}
+// TODO(rjkroege): Remove the need for this entry point.
void HostDrmDevice::BlockingStartDrmDevice() {
// Wait until startup related tasks posted to this thread that must precede
- // blocking on
+ // blocking.
base::RunLoop().RunUntilIdle();
bool success;
@@ -54,15 +74,20 @@ void HostDrmDevice::BlockingStartDrmDevice() {
return;
}
+// The callback is executed in response to getting back a message from a
+// DrmDevice service that we launched earlier via ServiceManager.
void HostDrmDevice::OnDrmServiceStartedCallback(bool success) {
// This can be called multiple times in the course of single-threaded startup.
+ // Ignore invocations after we've started.
if (connected_)
return;
+
if (success == true) {
connected_ = true;
RunObservers();
}
- // TODO(rjkroege): Handle failure of launching a viz process.
+ // TODO(rjkroege): Handle failure of launching a viz process with the
+ // ServiceManager.
}
void HostDrmDevice::ProvideManagers(DrmDisplayHostManager* display_manager,
@@ -78,10 +103,9 @@ void HostDrmDevice::RunObservers() {
observer.OnGpuThreadReady();
}
- // The cursor is special since it will process input events on the IO thread
- // and can by-pass the UI thread. This means that we need to special case it
- // and notify it after all other observers/handlers are notified.
- cursor_->SetDrmCursorProxy(std::make_unique<HostCursorProxy>(connector_));
+ DCHECK(cursor_proxy_)
+ << "We should have already created a cursor proxy previously";
+ cursor_->SetDrmCursorProxy(std::move(cursor_proxy_));
// TODO(rjkroege): Call ResetDrmCursorProxy when the mojo connection to the
// DRM thread is broken.
@@ -146,36 +170,37 @@ bool HostDrmDevice::GpuWindowBoundsChanged(gfx::AcceleratedWidget widget,
return false;
drm_device_ptr_->SetWindowBounds(widget, bounds);
+
return true;
}
// Services needed for DrmOverlayManager.
void HostDrmDevice::RegisterHandlerForDrmOverlayManager(
DrmOverlayManager* handler) {
- // TODO(rjkroege): Permit overlay manager to run in viz when the display
- // compositor runs in viz.
- DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
+ // TODO(rjkroege): Permit overlay manager to run in Viz when the display
+ // compositor runs in Viz.
+ DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
overlay_manager_ = handler;
}
void HostDrmDevice::UnRegisterHandlerForDrmOverlayManager() {
- DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
+ DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
overlay_manager_ = nullptr;
}
bool HostDrmDevice::GpuCheckOverlayCapabilities(
gfx::AcceleratedWidget widget,
const OverlaySurfaceCandidateList& overlays) {
- DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
+ DCHECK_CALLED_ON_VALID_THREAD(on_ui_thread_);
if (!IsConnected())
return false;
auto callback =
- base::BindOnce(&HostDrmDevice::GpuCheckOverlayCapabilitiesCallback,
- weak_ptr_factory_.GetWeakPtr());
+ base::BindOnce(&HostDrmDevice::GpuCheckOverlayCapabilitiesCallback, this);
+
+ drm_device_ptr_compositor_->CheckOverlayCapabilities(widget, overlays,
+ std::move(callback));
- drm_device_ptr_->CheckOverlayCapabilities(widget, overlays,
- std::move(callback));
return true;
}
@@ -183,10 +208,11 @@ bool HostDrmDevice::GpuRefreshNativeDisplays() {
DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
if (!IsConnected())
return false;
+
auto callback =
- base::BindOnce(&HostDrmDevice::GpuRefreshNativeDisplaysCallback,
- weak_ptr_factory_.GetWeakPtr());
+ base::BindOnce(&HostDrmDevice::GpuRefreshNativeDisplaysCallback, this);
drm_device_ptr_->RefreshNativeDisplays(std::move(callback));
+
return true;
}
@@ -200,11 +226,11 @@ bool HostDrmDevice::GpuConfigureNativeDisplay(int64_t id,
// TODO(rjkroege): Remove the use of mode here.
auto mode = CreateDisplayModeFromParams(pmode);
auto callback =
- base::BindOnce(&HostDrmDevice::GpuConfigureNativeDisplayCallback,
- weak_ptr_factory_.GetWeakPtr());
+ base::BindOnce(&HostDrmDevice::GpuConfigureNativeDisplayCallback, this);
drm_device_ptr_->ConfigureNativeDisplay(id, std::move(mode), origin,
std::move(callback));
+
return true;
}
@@ -213,9 +239,10 @@ bool HostDrmDevice::GpuDisableNativeDisplay(int64_t id) {
if (!IsConnected())
return false;
auto callback =
- base::BindOnce(&HostDrmDevice::GpuDisableNativeDisplayCallback,
- weak_ptr_factory_.GetWeakPtr());
+ base::BindOnce(&HostDrmDevice::GpuDisableNativeDisplayCallback, this);
+
drm_device_ptr_->DisableNativeDisplay(id, std::move(callback));
+
return true;
}
@@ -223,9 +250,11 @@ bool HostDrmDevice::GpuTakeDisplayControl() {
DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
if (!IsConnected())
return false;
- auto callback = base::BindOnce(&HostDrmDevice::GpuTakeDisplayControlCallback,
- weak_ptr_factory_.GetWeakPtr());
+ auto callback =
+ base::BindOnce(&HostDrmDevice::GpuTakeDisplayControlCallback, this);
+
drm_device_ptr_->TakeDisplayControl(std::move(callback));
+
return true;
}
@@ -234,9 +263,10 @@ bool HostDrmDevice::GpuRelinquishDisplayControl() {
if (!IsConnected())
return false;
auto callback =
- base::BindOnce(&HostDrmDevice::GpuRelinquishDisplayControlCallback,
- weak_ptr_factory_.GetWeakPtr());
+ base::BindOnce(&HostDrmDevice::GpuRelinquishDisplayControlCallback, this);
+
drm_device_ptr_->RelinquishDisplayControl(std::move(callback));
+
return true;
}
@@ -246,7 +276,9 @@ bool HostDrmDevice::GpuAddGraphicsDevice(const base::FilePath& path,
if (!IsConnected())
return false;
base::File file(fd.release());
+
drm_device_ptr_->AddGraphicsDevice(path, std::move(file));
+
return true;
}
@@ -254,7 +286,9 @@ bool HostDrmDevice::GpuRemoveGraphicsDevice(const base::FilePath& path) {
DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
if (!IsConnected())
return false;
+
drm_device_ptr_->RemoveGraphicsDevice(std::move(path));
+
return true;
}
@@ -262,9 +296,10 @@ bool HostDrmDevice::GpuGetHDCPState(int64_t display_id) {
DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
if (!IsConnected())
return false;
- auto callback = base::BindOnce(&HostDrmDevice::GpuGetHDCPStateCallback,
- weak_ptr_factory_.GetWeakPtr());
+ auto callback = base::BindOnce(&HostDrmDevice::GpuGetHDCPStateCallback, this);
+
drm_device_ptr_->GetHDCPState(display_id, std::move(callback));
+
return true;
}
@@ -273,9 +308,10 @@ bool HostDrmDevice::GpuSetHDCPState(int64_t display_id,
DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
if (!IsConnected())
return false;
- auto callback = base::BindOnce(&HostDrmDevice::GpuSetHDCPStateCallback,
- weak_ptr_factory_.GetWeakPtr());
+ auto callback = base::BindOnce(&HostDrmDevice::GpuSetHDCPStateCallback, this);
+
drm_device_ptr_->SetHDCPState(display_id, state, std::move(callback));
+
return true;
}
@@ -345,4 +381,37 @@ void HostDrmDevice::GpuSetHDCPStateCallback(int64_t display_id,
display_manager_->GpuUpdatedHDCPState(display_id, success);
}
+// Invoked in response to the successful launching of the GPU service.
+void HostDrmDevice::OnGpuServiceLaunched(
+ ui::ozone::mojom::DrmDevicePtr drm_device_ptr,
+ ui::ozone::mojom::DeviceCursorPtr cursor_ptr_ui,
+ ui::ozone::mojom::DeviceCursorPtr cursor_ptr_io) {
+ DCHECK_CALLED_ON_VALID_THREAD(on_window_server_thread_);
+
+ // Rebind InterfacePtrs to the window server thread.
+ cursor_ptr_ui.Bind(cursor_ptr_ui.PassInterface());
+ drm_device_ptr.Bind(drm_device_ptr.PassInterface());
+
+ drm_device_ptr_ = std::move(drm_device_ptr);
+
+ // Make sure that we've launched the DRM device service in the Viz process.
+ auto callback =
+ base::BindOnce(&HostDrmDevice::OnDrmServiceStartedCallback, this);
+ drm_device_ptr_->StartDrmDevice(std::move(callback));
+
+ // The cursor is special since it will process input events on the IO thread
+ // and can by-pass the UI thread. As a result, it has an InterfacePtr for both
+ // the window server and I/O thread. cursor_ptr_io is already bound correctly
+ // to an I/O thread by GpuProcessHost.
+ cursor_proxy_ = std::make_unique<HostCursorProxy>(std::move(cursor_ptr_ui),
+ std::move(cursor_ptr_io));
+}
+
+void HostDrmDevice::OnGpuServiceLaunchedCompositor(
+ ui::ozone::mojom::DrmDevicePtr drm_device_ptr_compositor) {
+ DETACH_FROM_THREAD(on_ui_thread_);
+ drm_device_ptr_compositor.Bind(drm_device_ptr_compositor.PassInterface());
+ drm_device_ptr_compositor_ = std::move(drm_device_ptr_compositor);
+}
+
} // namespace ui
diff --git a/chromium/ui/ozone/platform/drm/host/host_drm_device.h b/chromium/ui/ozone/platform/drm/host/host_drm_device.h
index 47c5b18170d..0a5b41c8df2 100644
--- a/chromium/ui/ozone/platform/drm/host/host_drm_device.h
+++ b/chromium/ui/ozone/platform/drm/host/host_drm_device.h
@@ -14,6 +14,7 @@
#include "ui/gfx/native_widget_types.h"
#include "ui/ozone/platform/drm/host/drm_cursor.h"
#include "ui/ozone/platform/drm/host/gpu_thread_adapter.h"
+#include "ui/ozone/public/gpu_platform_support_host.h"
#include "ui/ozone/public/interfaces/device_cursor.mojom.h"
#include "ui/ozone/public/interfaces/drm_device.mojom.h"
@@ -21,25 +22,23 @@ namespace display {
class DisplaySnapshot;
}
-namespace service_manager {
-class Connector;
-}
-
namespace ui {
class DrmDisplayHostManager;
class DrmOverlayManager;
class GpuThreadObserver;
+class DrmDeviceConnector;
+class HostCursorProxy;
// This is the Viz host-side library for the DRM device service provided by the
// viz process.
-class HostDrmDevice : public GpuThreadAdapter {
+class HostDrmDevice : public base::RefCountedThreadSafe<HostDrmDevice>,
+ public GpuThreadAdapter {
public:
- HostDrmDevice(DrmCursor* cursor, service_manager::Connector* connector);
- ~HostDrmDevice() override;
+ explicit HostDrmDevice(DrmCursor* cursor);
// Start the DRM service. Runs the |OnDrmServiceStartedCallback| when the
// service has launched and initiates the remaining startup.
- void AsyncStartDrmDevice();
+ void AsyncStartDrmDevice(const DrmDeviceConnector& connector);
// Blocks until the DRM service has come up. Use this entry point only when
// supporting launch of the service where the ozone UI and GPU
@@ -49,6 +48,13 @@ class HostDrmDevice : public GpuThreadAdapter {
void ProvideManagers(DrmDisplayHostManager* display_manager,
DrmOverlayManager* overlay_manager);
+ void OnGpuServiceLaunched(ui::ozone::mojom::DrmDevicePtr drm_device_ptr,
+ ui::ozone::mojom::DeviceCursorPtr cursor_ptr_ui,
+ ui::ozone::mojom::DeviceCursorPtr cursor_ptr_io);
+
+ void OnGpuServiceLaunchedCompositor(
+ ui::ozone::mojom::DrmDevicePtr drm_device_ptr_compositor);
+
// GpuThreadAdapter
void AddGpuThreadObserver(GpuThreadObserver* observer) override;
void RemoveGpuThreadObserver(GpuThreadObserver* observer) override;
@@ -93,8 +99,24 @@ class HostDrmDevice : public GpuThreadAdapter {
const gfx::Rect& bounds) override;
private:
+ friend class base::RefCountedThreadSafe<HostDrmDevice>;
+ ~HostDrmDevice() override;
+
+ void HostOnGpuServiceLaunched();
+
+ // BindInterface arranges for the drm_device_ptr to be wired up.
+ void BindInterfaceDrmDevice(
+ ui::ozone::mojom::DrmDevicePtr* drm_device_ptr) const;
+
+ // BindInterface arranges for the cursor_ptr to be wired up.
+ void BindInterfaceDeviceCursor(
+ ui::ozone::mojom::DeviceCursorPtr* cursor_ptr) const;
+
void OnDrmServiceStartedCallback(bool success);
+
+ // TODO(rjkroege): Get rid of the need for this method in a subsequent CL.
void PollForSingleThreadReady(int previous_delay);
+
void RunObservers();
void GpuCheckOverlayCapabilitiesCallback(
@@ -115,21 +137,31 @@ class HostDrmDevice : public GpuThreadAdapter {
display::HDCPState state) const;
void GpuSetHDCPStateCallback(int64_t display_id, bool success) const;
- // Mojo implementation of the DrmDevice.
+ // Mojo implementation of the DrmDevice. Will be bound on the "main" thread.
ui::ozone::mojom::DrmDevicePtr drm_device_ptr_;
+ // When running under mus, this is the UI thread specific DrmDevice ptr for
+ // use by the compositor.
+ ui::ozone::mojom::DrmDevicePtr drm_device_ptr_compositor_;
+
DrmDisplayHostManager* display_manager_; // Not owned.
DrmOverlayManager* overlay_manager_; // Not owned.
DrmCursor* cursor_; // Not owned.
- service_manager::Connector* connector_;
+ std::unique_ptr<HostCursorProxy> cursor_proxy_;
+
+ THREAD_CHECKER(on_io_thread_); // Needs to be rebound as is allocated on the
+ // window server thread.
THREAD_CHECKER(on_window_server_thread_);
+ // When running under mus, some entry points are used from the mus thread
+ // and some are used from the ui thread. In general. In that case, the
+ // on_ui_thread_ and on_window_server_thread_ will differ. In particular,
+ // entry points used by the compositor use the ui thread.
+ THREAD_CHECKER(on_ui_thread_);
bool connected_ = false;
base::ObserverList<GpuThreadObserver> gpu_thread_observers_;
- base::WeakPtrFactory<HostDrmDevice> weak_ptr_factory_;
-
DISALLOW_COPY_AND_ASSIGN(HostDrmDevice);
};
diff --git a/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc b/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc
index 3ad0de48ed2..963f77e8804 100644
--- a/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc
+++ b/chromium/ui/ozone/platform/drm/ozone_platform_gbm.cc
@@ -4,8 +4,6 @@
#include "ui/ozone/platform/drm/ozone_platform_gbm.h"
-#include <dlfcn.h>
-#include <fcntl.h>
#include <gbm.h>
#include <stdlib.h>
#include <xf86drm.h>
@@ -37,6 +35,7 @@
#include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
#include "ui/ozone/platform/drm/gpu/screen_manager.h"
#include "ui/ozone/platform/drm/host/drm_cursor.h"
+#include "ui/ozone/platform/drm/host/drm_device_connector.h"
#include "ui/ozone/platform/drm/host/drm_display_host_manager.h"
#include "ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h"
#include "ui/ozone/platform/drm/host/drm_native_display_delegate.h"
@@ -60,26 +59,6 @@ namespace ui {
namespace {
-class GlApiLoader {
- public:
- GlApiLoader()
- : glapi_lib_(dlopen("libglapi.so.0", RTLD_LAZY | RTLD_GLOBAL)) {}
-
- ~GlApiLoader() {
- if (glapi_lib_)
- dlclose(glapi_lib_);
- }
-
- private:
- // HACK: gbm drivers have broken linkage. The Mesa DRI driver references
- // symbols in the libglapi library however it does not explicitly link against
- // it. That caused linkage errors when running an application that does not
- // explicitly link against libglapi.
- void* glapi_lib_;
-
- DISALLOW_COPY_AND_ASSIGN(GlApiLoader);
-};
-
class OzonePlatformGbm : public OzonePlatform {
public:
OzonePlatformGbm()
@@ -100,47 +79,85 @@ class OzonePlatformGbm : public OzonePlatform {
return event_factory_ozone_->input_controller();
}
IPC::MessageFilter* GetGpuMessageFilter() override {
- return gpu_message_filter_.get();
+ if (using_mojo_) {
+ return nullptr;
+ } else {
+ return gpu_message_filter_.get();
+ }
}
+
GpuPlatformSupportHost* GetGpuPlatformSupportHost() override {
- return gpu_platform_support_host_.get();
+ if (using_mojo_) {
+ return drm_device_connector_.get();
+ } else {
+ return gpu_platform_support_host_.get();
+ }
}
+
std::unique_ptr<SystemInputInjector> CreateSystemInputInjector() override {
return event_factory_ozone_->CreateSystemInputInjector();
}
+ // In multi-process mode, this function must be executed in Viz as it sets up
+ // the callbacks needed for Mojo bindings. In single process mode, it may be
+ // called on any thread. It must follow one of |InitializeUI| or
+ // |InitializeGPU|. Invocations of this method when not using mojo will be
+ // ignored. While the caller may choose to invoke this method before entering
+ // the sandbox, the actual interface adding has to happen on the DRM Device
+ // thread and so will be deferred until the DRM thread is running.
void AddInterfaces(
service_manager::BinderRegistryWithArgs<
const service_manager::BindSourceInfo&>* registry) override {
+ if (!using_mojo_)
+ return;
+
registry->AddInterface<ozone::mojom::DeviceCursor>(
base::Bind(&OzonePlatformGbm::CreateDeviceCursorBinding,
weak_factory_.GetWeakPtr()),
- gpu_task_runner_);
+ base::ThreadTaskRunnerHandle::Get());
registry->AddInterface<ozone::mojom::DrmDevice>(
base::Bind(&OzonePlatformGbm::CreateDrmDeviceBinding,
weak_factory_.GetWeakPtr()),
- gpu_task_runner_);
+ base::ThreadTaskRunnerHandle::Get());
}
+
+ // Runs on the thread where AddInterfaces was invoked. But the endpoint is
+ // always bound on the DRM thread.
void CreateDeviceCursorBinding(
ozone::mojom::DeviceCursorRequest request,
const service_manager::BindSourceInfo& source_info) {
- if (drm_thread_proxy_)
+ if (drm_thread_started_)
drm_thread_proxy_->AddBindingCursorDevice(std::move(request));
else
pending_cursor_requests_.push_back(std::move(request));
}
-
+ // Runs on the thread where AddInterfaces was invoked. But the endpoint is
+ // always bound on the DRM thread.
// service_manager::InterfaceFactory<ozone::mojom::DrmDevice>:
void CreateDrmDeviceBinding(
ozone::mojom::DrmDeviceRequest request,
const service_manager::BindSourceInfo& source_info) {
- if (drm_thread_proxy_)
+ if (drm_thread_started_)
drm_thread_proxy_->AddBindingDrmDevice(std::move(request));
else
pending_gpu_adapter_requests_.push_back(std::move(request));
}
+ // Runs on the thread that invoked |AddInterfaces| to drain the queue of
+ // binding requests that could not be satisfied until the DRM thread is
+ // available (i.e. if waiting until the sandbox has been entered.)
+ void DrainBindingRequests() {
+ for (auto& request : pending_cursor_requests_)
+ drm_thread_proxy_->AddBindingCursorDevice(std::move(request));
+ pending_cursor_requests_.clear();
+ for (auto& request : pending_gpu_adapter_requests_)
+ drm_thread_proxy_->AddBindingDrmDevice(std::move(request));
+ pending_gpu_adapter_requests_.clear();
+
+ drm_thread_started_ = true;
+ }
+
std::unique_ptr<PlatformWindow> CreatePlatformWindow(
PlatformWindowDelegate* delegate,
const gfx::Rect& bounds) override {
@@ -159,21 +176,31 @@ class OzonePlatformGbm : public OzonePlatform {
override {
return std::make_unique<DrmNativeDisplayDelegate>(display_manager_.get());
}
+
void InitializeUI(const InitParams& args) override {
- // Ozone drm can operate in three modes configured at runtime:
+ // Ozone drm can operate in four modes configured at
+ // runtime. Three process modes:
// 1. legacy mode where host and viz components communicate
// via param traits IPC.
// 2. single-process mode where host and viz components
- // communicate via in-process mojo.
+ // communicate via in-process mojo. Single-process mode can be single
+ // or multi-threaded.
// 3. multi-process mode where host and viz components communicate
// via mojo IPC.
+ //
+ // and 2 connection modes
+ // a. Viz is launched via content::GpuProcessHost and it notifies the
+ // ozone host when Viz becomes available. b. The ozone host uses a service
+ // manager to launch and connect to Viz.
+ //
+ // Combinations 1a, 2b, and 3a, and 3b are supported and expected to work.
+ // Combination 1a will hopefully be deprecated and replaced with 3a.
+ // Combination 2b adds undesirable code-debt and the intent is to remove it.
+
single_process_ = args.single_process;
- using_mojo_ = args.connector != nullptr;
+ using_mojo_ = args.using_mojo || args.connector != nullptr;
host_thread_ = base::PlatformThread::CurrentRef();
- DCHECK(!(using_mojo_ && !single_process_))
- << "Multiprocess Mojo is not supported yet.";
-
device_manager_ = CreateDeviceManager();
window_manager_.reset(new DrmWindowHostManager());
cursor_.reset(new DrmCursor(window_manager_.get()));
@@ -191,12 +218,10 @@ class OzonePlatformGbm : public OzonePlatform {
GpuThreadAdapter* adapter;
- if (single_process_)
- gl_api_loader_.reset(new GlApiLoader());
-
if (using_mojo_) {
- host_drm_device_ =
- std::make_unique<HostDrmDevice>(cursor_.get(), args.connector);
+ host_drm_device_ = base::MakeRefCounted<HostDrmDevice>(cursor_.get());
+ drm_device_connector_ = std::make_unique<DrmDeviceConnector>(
+ args.connector, host_drm_device_);
adapter = host_drm_device_.get();
} else {
gpu_platform_support_host_.reset(
@@ -214,22 +239,14 @@ class OzonePlatformGbm : public OzonePlatform {
if (using_mojo_) {
host_drm_device_->ProvideManagers(display_manager_.get(),
overlay_manager_.get());
- host_drm_device_->AsyncStartDrmDevice();
+ host_drm_device_->AsyncStartDrmDevice(*drm_device_connector_);
}
}
void InitializeGPU(const InitParams& args) override {
- // TODO(rjkroege): services/ui should initialize this with a connector.
- // However, in-progress refactorings in services/ui make it difficult to
- // require this at present. Set using_mojo_ like below once this is
- // complete.
- // TODO(rjk): Make it possible to turn this on.
- // using_mojo_ = args.connector != nullptr;
+ using_mojo_ = args.using_mojo;
gpu_task_runner_ = base::ThreadTaskRunnerHandle::Get();
- if (!single_process_)
- gl_api_loader_.reset(new GlApiLoader());
-
InterThreadMessagingProxy* itmp;
if (!using_mojo_) {
scoped_refptr<DrmThreadMessageProxy> message_proxy(
@@ -239,52 +256,53 @@ class OzonePlatformGbm : public OzonePlatform {
}
// NOTE: Can't start the thread here since this is called before sandbox
- // initialization in multi-process Chrome. In mus, we start the DRM thread.
+ // initialization in multi-process Chrome.
drm_thread_proxy_.reset(new DrmThreadProxy());
surface_factory_.reset(new GbmSurfaceFactory(drm_thread_proxy_.get()));
if (!using_mojo_) {
drm_thread_proxy_->BindThreadIntoMessagingProxy(itmp);
- } else {
- drm_thread_proxy_->StartDrmThread();
}
- // When the viz process (and hence the gpu portion of ozone/gbm) is
- // operating in a single process, the AddInterfaces method is best
- // invoked before the GPU thread launches. As a result, requests to add
- // mojom bindings to the as yet un-launched service will fail so we queue
- // incoming binding requests until the GPU thread is running and play them
- // back here.
- for (auto& request : pending_cursor_requests_)
- drm_thread_proxy_->AddBindingCursorDevice(std::move(request));
- pending_cursor_requests_.clear();
- for (auto& request : pending_gpu_adapter_requests_)
- drm_thread_proxy_->AddBindingDrmDevice(std::move(request));
- pending_gpu_adapter_requests_.clear();
-
// If InitializeGPU and InitializeUI are invoked on the same thread, startup
// sequencing is complicated because tasks are queued on the unbound mojo
// pipe connecting the UI (the host) to the DRM thread before the DRM thread
- // is launched above. Special case this sequence vis the
+ // is launched above. Special case this sequence via the
// BlockingStartDrmDevice API.
// TODO(rjkroege): In a future when we have completed splitting Viz, it will
// be possible to simplify this logic.
- if (using_mojo_ && single_process_ &&
- host_thread_ == base::PlatformThread::CurrentRef()) {
+ if (using_mojo_ && single_process_) {
CHECK(host_drm_device_)
<< "Mojo single-process mode requires a HostDrmDevice.";
- host_drm_device_->BlockingStartDrmDevice();
+
+ // Wait here if host and gpu are one and the same thread.
+ if (host_thread_ == base::PlatformThread::CurrentRef()) {
+ // One-thread exection does not permit use of the sandbox.
+ AfterSandboxEntry();
+ host_drm_device_->BlockingStartDrmDevice();
+ }
}
}
+ // The DRM thread needs to be started late because we need to wait for the
+ // sandbox to start. This entry point in the Ozne API gives platforms
+ // flexibility in handing this requirement.
+ void AfterSandboxEntry() override {
+ CHECK(drm_thread_proxy_) << "AfterSandboxEntry before InitializeForGPU is "
+ "invalid startup order.\n";
+ // Defer the actual startup of the DRM thread to here.
+ auto safe_binding_resquest_drainer = CreateSafeOnceCallback(base::BindOnce(
+ &OzonePlatformGbm::DrainBindingRequests, weak_factory_.GetWeakPtr()));
+
+ drm_thread_proxy_->StartDrmThread(std::move(safe_binding_resquest_drainer));
+ }
+
private:
bool using_mojo_;
bool single_process_;
- base::PlatformThreadRef host_thread_;
// Objects in the GPU process.
std::unique_ptr<DrmThreadProxy> drm_thread_proxy_;
- std::unique_ptr<GlApiLoader> gl_api_loader_;
std::unique_ptr<GbmSurfaceFactory> surface_factory_;
scoped_refptr<IPC::MessageFilter> gpu_message_filter_;
scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner_;
@@ -293,6 +311,7 @@ class OzonePlatformGbm : public OzonePlatform {
// running in single process mode.
std::vector<ozone::mojom::DeviceCursorRequest> pending_cursor_requests_;
std::vector<ozone::mojom::DrmDeviceRequest> pending_gpu_adapter_requests_;
+ bool drm_thread_started_;
// gpu_platform_support_host_ is the IPC bridge to the GPU process while
// host_drm_device_ is the mojo bridge to the Viz process. Only one can be in
@@ -304,9 +323,11 @@ class OzonePlatformGbm : public OzonePlatform {
// To avoid a use after free, the following two members should be declared
// before the two managers, so that they're deleted after them.
std::unique_ptr<DrmGpuPlatformSupportHost> gpu_platform_support_host_;
- std::unique_ptr<HostDrmDevice> host_drm_device_;
- // Objects in the Browser process.
+ // Objects in the host process.
+ std::unique_ptr<DrmDeviceConnector> drm_device_connector_;
+ scoped_refptr<HostDrmDevice> host_drm_device_;
+ base::PlatformThreadRef host_thread_;
std::unique_ptr<DeviceManager> device_manager_;
std::unique_ptr<BitmapCursorFactoryOzone> cursor_factory_ozone_;
std::unique_ptr<DrmWindowHostManager> window_manager_;
diff --git a/chromium/ui/ozone/platform/wayland/BUILD.gn b/chromium/ui/ozone/platform/wayland/BUILD.gn
index b8566cfd5ee..01957d3740f 100644
--- a/chromium/ui/ozone/platform/wayland/BUILD.gn
+++ b/chromium/ui/ozone/platform/wayland/BUILD.gn
@@ -32,6 +32,8 @@ source_set("wayland") {
"wayland_pointer.h",
"wayland_surface_factory.cc",
"wayland_surface_factory.h",
+ "wayland_touch.cc",
+ "wayland_touch.h",
"wayland_window.cc",
"wayland_window.h",
"xdg_surface_wrapper.cc",
@@ -61,6 +63,7 @@ source_set("wayland") {
"//ui/display/manager",
"//ui/events",
"//ui/events:dom_keycode_converter",
+ "//ui/events/ozone:events_ozone",
"//ui/events/ozone:events_ozone_layout",
"//ui/events/platform",
"//ui/gfx",
@@ -90,6 +93,7 @@ source_set("wayland_unittests") {
"wayland_surface_factory_unittest.cc",
"wayland_test.cc",
"wayland_test.h",
+ "wayland_touch_unittest.cc",
"wayland_window_unittest.cc",
]
@@ -107,10 +111,6 @@ source_set("wayland_unittests") {
import("//ui/base/ui_features.gni")
if (use_xkbcommon) {
- sources += [
- "mock_wayland_xkb_keyboard_layout_engine.cc",
- "mock_wayland_xkb_keyboard_layout_engine.h",
- ]
deps += [ "//ui/events/keycodes:xkb" ]
}
diff --git a/chromium/ui/ozone/platform/wayland/fake_server.cc b/chromium/ui/ozone/platform/wayland/fake_server.cc
index 8e9199889e4..7adfe81029e 100644
--- a/chromium/ui/ozone/platform/wayland/fake_server.cc
+++ b/chromium/ui/ozone/platform/wayland/fake_server.cc
@@ -152,10 +152,21 @@ void GetKeyboard(wl_client* client, wl_resource* resource, uint32_t id) {
seat->keyboard.reset(new MockKeyboard(keyboard_resource));
}
+void GetTouch(wl_client* client, wl_resource* resource, uint32_t id) {
+ auto* seat = static_cast<MockSeat*>(wl_resource_get_user_data(resource));
+ wl_resource* touch_resource = wl_resource_create(
+ client, &wl_touch_interface, wl_resource_get_version(resource), id);
+ if (!touch_resource) {
+ wl_client_post_no_memory(client);
+ return;
+ }
+ seat->touch.reset(new MockTouch(touch_resource));
+}
+
const struct wl_seat_interface seat_impl = {
&GetPointer, // get_pointer
&GetKeyboard, // get_keyboard
- nullptr, // get_touch,
+ &GetTouch, // get_touch,
&DestroyResource, // release
};
@@ -172,6 +183,12 @@ const struct wl_pointer_interface pointer_impl = {
&DestroyResource, // release
};
+// wl_touch
+
+const struct wl_touch_interface touch_impl = {
+ &DestroyResource, // release
+};
+
// xdg_surface, zxdg_surface_v6 and zxdg_toplevel shared methods.
void SetTitle(wl_client* client, wl_resource* resource, const char* title) {
@@ -395,6 +412,13 @@ MockKeyboard::MockKeyboard(wl_resource* resource) : ServerObject(resource) {
MockKeyboard::~MockKeyboard() {}
+MockTouch::MockTouch(wl_resource* resource) : ServerObject(resource) {
+ wl_resource_set_implementation(resource, &touch_impl, this,
+ &ServerObject::OnResourceDestroyed);
+}
+
+MockTouch::~MockTouch() {}
+
void GlobalDeleter::operator()(wl_global* global) {
wl_global_destroy(global);
}
diff --git a/chromium/ui/ozone/platform/wayland/fake_server.h b/chromium/ui/ozone/platform/wayland/fake_server.h
index 3b09bdb9c36..816f5815e6f 100644
--- a/chromium/ui/ozone/platform/wayland/fake_server.h
+++ b/chromium/ui/ozone/platform/wayland/fake_server.h
@@ -119,6 +119,15 @@ class MockKeyboard : public ServerObject {
DISALLOW_COPY_AND_ASSIGN(MockKeyboard);
};
+class MockTouch : public ServerObject {
+ public:
+ explicit MockTouch(wl_resource* resource);
+ ~MockTouch() override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockTouch);
+};
+
struct GlobalDeleter {
void operator()(wl_global* global);
};
@@ -188,7 +197,11 @@ class MockOutput : public Global {
DISALLOW_COPY_AND_ASSIGN(MockOutput);
};
-// Manage wl_seat object: group of input devices.
+// Manage wl_seat object. A seat is a group of keyboards, pointer and touch
+// devices. This object is published as a global during start up, or when such a
+// device is hot plugged. A seat typically has a pointer and maintains a
+// keyboard focus and a pointer focus.
+// https://people.freedesktop.org/~whot/wayland-doxygen/wayland/Server/structwl__seat__interface.html
class MockSeat : public Global {
public:
MockSeat();
@@ -196,6 +209,7 @@ class MockSeat : public Global {
std::unique_ptr<MockPointer> pointer;
std::unique_ptr<MockKeyboard> keyboard;
+ std::unique_ptr<MockTouch> touch;
private:
DISALLOW_COPY_AND_ASSIGN(MockSeat);
diff --git a/chromium/ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.cc b/chromium/ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.cc
deleted file mode 100644
index 4dd5c352778..00000000000
--- a/chromium/ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.h"
-#include "ui/events/keycodes/keyboard_code_conversion.h"
-
-#if !BUILDFLAG(USE_XKBCOMMON)
-#error "This file should only be compiled if USE_XKBCOMMON is enabled."
-#endif
-
-namespace ui {
-
-bool MockWaylandXkbKeyboardLayoutEngine::Lookup(
- ui::DomCode dom_code,
- int event_flags,
- ui::DomKey* dom_key,
- ui::KeyboardCode* key_code) const {
- return DomCodeToUsLayoutDomKey(dom_code, event_flags, dom_key, key_code);
-}
-
-} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.h b/chromium/ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.h
deleted file mode 100644
index 8d60d2bbe32..00000000000
--- a/chromium/ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_OZONE_PLATFORM_WAYLAND_MOCK_WAYLAND_XKB_KEYBOARD_LAYOUT_ENGINE_H_
-#define UI_OZONE_PLATFORM_WAYLAND_MOCK_WAYLAND_XKB_KEYBOARD_LAYOUT_ENGINE_H_
-
-#include "ui/base/ui_features.h"
-
-#if !BUILDFLAG(USE_XKBCOMMON)
-#error "This file should only be included if USE_XKBCOMMON is enabled."
-#endif
-
-#include "ui/events/ozone/layout/xkb/xkb_evdev_codes.h"
-#include "ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h"
-
-namespace ui {
-
-class MockWaylandXkbKeyboardLayoutEngine
- : public ui::WaylandXkbKeyboardLayoutEngine {
- public:
- MockWaylandXkbKeyboardLayoutEngine(const ui::XkbKeyCodeConverter& converter)
- : WaylandXkbKeyboardLayoutEngine(converter) {}
-
- void UpdateModifiers(uint32_t depressed_mods,
- uint32_t latched_mods,
- uint32_t locked_mods,
- uint32_t group) override {}
- void SetEventModifiers(ui::EventModifiers* event_modifiers) override {}
-
- private:
- bool Lookup(ui::DomCode dom_code,
- int event_flags,
- ui::DomKey* dom_key,
- ui::KeyboardCode* key_code) const override;
-
- DISALLOW_COPY_AND_ASSIGN(MockWaylandXkbKeyboardLayoutEngine);
-};
-
-} // namespace ui
-
-#endif // UI_OZONE_PLATFORM_WAYLAND_MOCK_WAYLAND_XKB_KEYBOARD_LAYOUT_ENGINE_H_
diff --git a/chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc
index e94ef56855f..843d7c99fdf 100644
--- a/chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc
+++ b/chromium/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -77,7 +77,7 @@ class OzonePlatformWayland : public OzonePlatform {
void InitializeUI(const InitParams& args) override {
#if BUILDFLAG(USE_XKBCOMMON)
KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
- std::make_unique<WaylandXkbKeyboardLayoutEngineImpl>(
+ std::make_unique<WaylandXkbKeyboardLayoutEngine>(
xkb_evdev_code_converter_));
#else
KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
diff --git a/chromium/ui/ozone/platform/wayland/wayland_connection.cc b/chromium/ui/ozone/platform/wayland/wayland_connection.cc
index c36a990ad13..89cf855b386 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_connection.cc
+++ b/chromium/ui/ozone/platform/wayland/wayland_connection.cc
@@ -107,6 +107,8 @@ void WaylandConnection::AddWindow(gfx::AcceleratedWidget widget,
}
void WaylandConnection::RemoveWindow(gfx::AcceleratedWidget widget) {
+ if (touch_)
+ touch_->RemoveTouchPoints(window_map_[widget]);
window_map_.erase(widget);
}
@@ -273,6 +275,21 @@ void WaylandConnection::Capabilities(void* data,
} else if (connection->keyboard_) {
connection->keyboard_.reset();
}
+ if (capabilities & WL_SEAT_CAPABILITY_TOUCH) {
+ if (!connection->touch_) {
+ wl_touch* touch = wl_seat_get_touch(connection->seat_.get());
+ if (!touch) {
+ LOG(ERROR) << "Failed to get wl_touch from seat";
+ return;
+ }
+ connection->touch_ = std::make_unique<WaylandTouch>(
+ touch, base::Bind(&WaylandConnection::DispatchUiEvent,
+ base::Unretained(connection)));
+ connection->touch_->set_connection(connection);
+ }
+ } else if (connection->touch_) {
+ connection->touch_.reset();
+ }
connection->ScheduleFlush();
}
diff --git a/chromium/ui/ozone/platform/wayland/wayland_connection.h b/chromium/ui/ozone/platform/wayland/wayland_connection.h
index 50019bbff0e..e745efd5b6b 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_connection.h
+++ b/chromium/ui/ozone/platform/wayland/wayland_connection.h
@@ -14,6 +14,7 @@
#include "ui/ozone/platform/wayland/wayland_object.h"
#include "ui/ozone/platform/wayland/wayland_output.h"
#include "ui/ozone/platform/wayland/wayland_pointer.h"
+#include "ui/ozone/platform/wayland/wayland_touch.h"
namespace ui {
@@ -93,6 +94,7 @@ class WaylandConnection : public PlatformEventSource,
std::unique_ptr<WaylandPointer> pointer_;
std::unique_ptr<WaylandKeyboard> keyboard_;
+ std::unique_ptr<WaylandTouch> touch_;
bool scheduled_flush_ = false;
bool watching_ = false;
diff --git a/chromium/ui/ozone/platform/wayland/wayland_keyboard.cc b/chromium/ui/ozone/platform/wayland/wayland_keyboard.cc
index a033e2dc81a..a2b2329dfe8 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_keyboard.cc
+++ b/chromium/ui/ozone/platform/wayland/wayland_keyboard.cc
@@ -5,7 +5,6 @@
#include "ui/ozone/platform/wayland/wayland_keyboard.h"
#include <sys/mman.h>
-#include <wayland-client.h>
#include "base/files/scoped_file.h"
#include "ui/base/ui_features.h"
@@ -30,9 +29,14 @@ const int kXkbKeycodeOffset = 8;
} // namespace
+// static
+const wl_callback_listener WaylandKeyboard::callback_listener_ = {
+ WaylandKeyboard::SyncCallback,
+};
+
WaylandKeyboard::WaylandKeyboard(wl_keyboard* keyboard,
const EventDispatchCallback& callback)
- : obj_(keyboard), callback_(callback) {
+ : obj_(keyboard), callback_(callback), auto_repeat_handler_(this) {
static const wl_keyboard_listener listener = {
&WaylandKeyboard::Keymap, &WaylandKeyboard::Enter,
&WaylandKeyboard::Leave, &WaylandKeyboard::Key,
@@ -86,6 +90,12 @@ void WaylandKeyboard::Leave(void* data,
uint32_t serial,
wl_surface* surface) {
WaylandWindow::FromSurface(surface)->set_keyboard_focus(false);
+
+ WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data);
+ DCHECK(keyboard);
+
+ // Upon window focus lose, reset the key repeat timers.
+ keyboard->auto_repeat_handler_.StopKeyRepeat();
}
void WaylandKeyboard::Key(void* data,
@@ -95,32 +105,20 @@ void WaylandKeyboard::Key(void* data,
uint32_t key,
uint32_t state) {
WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data);
- keyboard->connection_->set_serial(serial);
+ DCHECK(keyboard);
- DomCode dom_code =
- KeycodeConverter::NativeKeycodeToDomCode(key + kXkbKeycodeOffset);
- if (dom_code == ui::DomCode::NONE)
- return;
-
- uint8_t flags = keyboard->event_modifiers_.GetModifierFlags();
- DomKey dom_key;
- KeyboardCode key_code;
- if (!KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup(
- dom_code, flags, &dom_key, &key_code))
- return;
+ keyboard->connection_->set_serial(serial);
bool down = state == WL_KEYBOARD_KEY_STATE_PRESSED;
+ int device_id = keyboard->obj_.id();
- // TODO(tonikitoo,msisov): only the two lines below if not handling repeat.
- int flag = ModifierDomKeyToEventFlag(dom_key);
- keyboard->UpdateModifier(flag, down);
+ keyboard->auto_repeat_handler_.UpdateKeyRepeat(
+ key, down, false /*suppress_auto_repeat*/, device_id);
- ui::KeyEvent event(
- down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code, dom_code,
- keyboard->event_modifiers_.GetModifierFlags(), dom_key,
- base::TimeTicks() + base::TimeDelta::FromMilliseconds(time));
- event.set_source_device_id(keyboard->obj_.id());
- keyboard->callback_.Run(&event);
+ // TODO(tonikitoo,msisov): Handler 'repeat' parameter below.
+ keyboard->DispatchKey(
+ key, down, false /*repeat*/,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(time), device_id);
}
void WaylandKeyboard::Modifiers(void* data,
@@ -141,8 +139,66 @@ void WaylandKeyboard::RepeatInfo(void* data,
wl_keyboard* obj,
int32_t rate,
int32_t delay) {
- // TODO(tonikitoo): Implement proper repeat handling.
- NOTIMPLEMENTED();
+ WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data);
+ DCHECK(keyboard);
+
+ keyboard->auto_repeat_handler_.SetAutoRepeatRate(
+ base::TimeDelta::FromMilliseconds(delay),
+ base::TimeDelta::FromMilliseconds(rate));
+}
+
+void WaylandKeyboard::FlushInput(base::OnceClosure closure) {
+ if (sync_callback_)
+ return;
+
+ auto_repeat_closure_ = std::move(closure);
+
+ // wl_display_sync gives a chance for any key "up" events to arrive.
+ // With a well behaved wayland compositor this should ensure we never
+ // get spurious repeats.
+ sync_callback_.reset(wl_display_sync(connection_->display()));
+ wl_callback_add_listener(sync_callback_.get(), &callback_listener_, this);
+ wl_display_flush(connection_->display());
+}
+
+void WaylandKeyboard::DispatchKey(uint32_t key,
+ bool down,
+ bool repeat,
+ base::TimeTicks timestamp,
+ int device_id) {
+ DomCode dom_code =
+ KeycodeConverter::NativeKeycodeToDomCode(key + kXkbKeycodeOffset);
+ if (dom_code == ui::DomCode::NONE)
+ return;
+
+ uint8_t flags = event_modifiers_.GetModifierFlags();
+ DomKey dom_key;
+ KeyboardCode key_code;
+ if (!KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup(
+ dom_code, flags, &dom_key, &key_code))
+ return;
+
+ if (!repeat) {
+ int flag = ModifierDomKeyToEventFlag(dom_key);
+ UpdateModifier(flag, down);
+ }
+
+ ui::KeyEvent event(down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code,
+ dom_code, event_modifiers_.GetModifierFlags(), dom_key,
+ timestamp);
+ event.set_source_device_id(device_id);
+ callback_.Run(&event);
+}
+
+void WaylandKeyboard::SyncCallback(void* data,
+ struct wl_callback* cb,
+ uint32_t time) {
+ WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data);
+ DCHECK(keyboard);
+
+ std::move(keyboard->auto_repeat_closure_).Run();
+ DCHECK(keyboard->auto_repeat_closure_.is_null());
+ keyboard->sync_callback_.reset();
}
void WaylandKeyboard::UpdateModifier(int modifier_flag, bool down) {
diff --git a/chromium/ui/ozone/platform/wayland/wayland_keyboard.h b/chromium/ui/ozone/platform/wayland/wayland_keyboard.h
index 727a9930a58..18b535a6051 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_keyboard.h
+++ b/chromium/ui/ozone/platform/wayland/wayland_keyboard.h
@@ -5,15 +5,18 @@
#ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_KEYBOARD_H_
#define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_KEYBOARD_H_
+#include <wayland-client.h>
+
#include "ui/events/event_modifiers.h"
#include "ui/events/ozone/evdev/event_dispatch_callback.h"
+#include "ui/events/ozone/keyboard/event_auto_repeat_handler.h"
#include "ui/ozone/platform/wayland/wayland_object.h"
namespace ui {
class WaylandConnection;
-class WaylandKeyboard {
+class WaylandKeyboard : public EventAutoRepeatHandler::Delegate {
public:
WaylandKeyboard(wl_keyboard* keyboard, const EventDispatchCallback& callback);
virtual ~WaylandKeyboard();
@@ -58,12 +61,28 @@ class WaylandKeyboard {
int32_t rate,
int32_t delay);
+ static void SyncCallback(void* data, struct wl_callback* cb, uint32_t time);
+
void UpdateModifier(int modifier_flag, bool down);
+ // EventAutoRepeatHandler::Delegate
+ void FlushInput(base::OnceClosure closure) override;
+ void DispatchKey(unsigned int key,
+ bool down,
+ bool repeat,
+ base::TimeTicks timestamp,
+ int device_id) override;
+
WaylandConnection* connection_ = nullptr;
wl::Object<wl_keyboard> obj_;
EventDispatchCallback callback_;
EventModifiers event_modifiers_;
+
+ // Key repeat handler.
+ static const wl_callback_listener callback_listener_;
+ EventAutoRepeatHandler auto_repeat_handler_;
+ base::OnceClosure auto_repeat_closure_;
+ wl::Object<wl_callback> sync_callback_;
};
} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/wayland_keyboard_unittest.cc b/chromium/ui/ozone/platform/wayland/wayland_keyboard_unittest.cc
index f5a7d801f8d..7ce077a7e97 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_keyboard_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/wayland_keyboard_unittest.cc
@@ -5,13 +5,13 @@
#include <linux/input.h>
#include <wayland-server.h>
+#include "base/test/test_mock_time_task_runner.h"
+#include "base/timer/timer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/event.h"
#include "ui/ozone/platform/wayland/fake_server.h"
#include "ui/ozone/platform/wayland/wayland_test.h"
-#include "ui/ozone/platform/wayland/wayland_window.h"
-#include "ui/ozone/test/mock_platform_window_delegate.h"
#if BUILDFLAG(USE_XKBCOMMON)
#include "base/memory/free_deleter.h"
@@ -326,6 +326,138 @@ TEST_P(WaylandKeyboardTest, CapsLockModifier) {
}
#endif
+TEST_P(WaylandKeyboardTest, EventAutoRepeat) {
+ struct wl_array empty;
+ wl_array_init(&empty);
+
+ wl_keyboard_send_enter(keyboard->resource(), 1, surface->resource(), &empty);
+ wl_array_release(&empty);
+
+ // Auto repeat info in ms.
+ uint32_t rate = 75;
+ uint32_t delay = 25;
+
+ wl_keyboard_send_repeat_info(keyboard->resource(), rate, delay);
+
+ wl_keyboard_send_key(keyboard->resource(), 2, 0, 30 /* a */,
+ WL_KEYBOARD_KEY_STATE_PRESSED);
+
+ std::unique_ptr<Event> event;
+ EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+
+ Sync();
+
+ {
+ scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner =
+ new base::TestMockTimeTaskRunner();
+ base::TestMockTimeTaskRunner::ScopedContext scoped_context(
+ mock_time_task_runner.get());
+
+ // Keep it pressed for doubled the rate time, to ensure events get fired.
+ mock_time_task_runner->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(rate * 2));
+ }
+
+ Sync();
+
+ std::unique_ptr<Event> event2;
+ EXPECT_CALL(delegate, DispatchEvent(_)).WillRepeatedly(CloneEvent(&event2));
+
+ wl_keyboard_send_key(keyboard->resource(), 3, 0, 30 /* a */,
+ WL_KEYBOARD_KEY_STATE_RELEASED);
+ Sync();
+}
+
+TEST_P(WaylandKeyboardTest, NoEventAutoRepeatOnLeave) {
+ struct wl_array empty;
+ wl_array_init(&empty);
+
+ wl_keyboard_send_enter(keyboard->resource(), 1, surface->resource(), &empty);
+ wl_array_release(&empty);
+
+ // Auto repeat info in ms.
+ uint32_t rate = 75;
+ uint32_t delay = 25;
+
+ wl_keyboard_send_repeat_info(keyboard->resource(), rate, delay);
+
+ wl_keyboard_send_key(keyboard->resource(), 2, 0, 30 /* a */,
+ WL_KEYBOARD_KEY_STATE_PRESSED);
+
+ std::unique_ptr<Event> event;
+ EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+
+ Sync();
+
+ {
+ scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner =
+ new base::TestMockTimeTaskRunner();
+ base::TestMockTimeTaskRunner::ScopedContext scoped_context(
+ mock_time_task_runner.get());
+
+ // Keep it pressed for doubled the rate time, to ensure events get fired.
+ mock_time_task_runner->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(rate * 2));
+ }
+
+ wl_keyboard_send_leave(keyboard->resource(), 3, surface->resource());
+
+ Sync();
+
+ EXPECT_CALL(delegate, DispatchEvent(_)).Times(0);
+
+ wl_keyboard_send_key(keyboard->resource(), 4, 0, 30 /* a */,
+ WL_KEYBOARD_KEY_STATE_RELEASED);
+ Sync();
+}
+
+TEST_P(WaylandKeyboardTest, NoEventAutoRepeatBeforeTimeout) {
+ struct wl_array empty;
+ wl_array_init(&empty);
+
+ wl_keyboard_send_enter(keyboard->resource(), 1, surface->resource(), &empty);
+ wl_array_release(&empty);
+
+ // Auto repeat info in ms.
+ uint32_t rate = 500;
+ uint32_t delay = 50;
+
+ wl_keyboard_send_repeat_info(keyboard->resource(), rate, delay);
+
+ wl_keyboard_send_key(keyboard->resource(), 2, 0, 30 /* a */,
+ WL_KEYBOARD_KEY_STATE_PRESSED);
+
+ std::unique_ptr<Event> event;
+ EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event));
+
+ Sync();
+
+ {
+ scoped_refptr<base::TestMockTimeTaskRunner> mock_time_task_runner =
+ new base::TestMockTimeTaskRunner();
+ base::TestMockTimeTaskRunner::ScopedContext scoped_context(
+ mock_time_task_runner.get());
+
+ // Keep it pressed for a fifth of the rate time, and no auto repeat events
+ // should get dispatched.
+ mock_time_task_runner->FastForwardBy(
+ base::TimeDelta::FromMilliseconds(rate / 5));
+ }
+
+ wl_keyboard_send_key(keyboard->resource(), 4, 0, 30 /* a */,
+ WL_KEYBOARD_KEY_STATE_RELEASED);
+
+ std::unique_ptr<Event> event2;
+ EXPECT_CALL(delegate, DispatchEvent(_)).WillOnce(CloneEvent(&event2));
+
+ Sync();
+ ASSERT_TRUE(event2);
+ ASSERT_TRUE(event2->IsKeyEvent());
+
+ auto* key_event2 = event2->AsKeyEvent();
+ EXPECT_EQ(ET_KEY_RELEASED, key_event2->type());
+}
+
INSTANTIATE_TEST_CASE_P(XdgVersionV5Test,
WaylandKeyboardTest,
::testing::Values(kXdgShellV5));
diff --git a/chromium/ui/ozone/platform/wayland/wayland_object.cc b/chromium/ui/ozone/platform/wayland/wayland_object.cc
index f800a9cd994..056175f2957 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_object.cc
+++ b/chromium/ui/ozone/platform/wayland/wayland_object.cc
@@ -32,11 +32,22 @@ void delete_seat(wl_seat* seat) {
wl_seat_destroy(seat);
}
+void delete_touch(wl_touch* touch) {
+ if (wl_touch_get_version(touch) >= WL_TOUCH_RELEASE_SINCE_VERSION)
+ wl_touch_release(touch);
+ else
+ wl_touch_destroy(touch);
+}
+
} // namespace
const wl_interface* ObjectTraits<wl_buffer>::interface = &wl_buffer_interface;
void (*ObjectTraits<wl_buffer>::deleter)(wl_buffer*) = &wl_buffer_destroy;
+const wl_interface* ObjectTraits<wl_callback>::interface =
+ &wl_callback_interface;
+void (*ObjectTraits<wl_callback>::deleter)(wl_callback*) = &wl_callback_destroy;
+
const wl_interface* ObjectTraits<wl_compositor>::interface =
&wl_compositor_interface;
void (*ObjectTraits<wl_compositor>::deleter)(wl_compositor*) =
@@ -72,6 +83,9 @@ void (*ObjectTraits<wl_shm_pool>::deleter)(wl_shm_pool*) = &wl_shm_pool_destroy;
const wl_interface* ObjectTraits<wl_surface>::interface = &wl_surface_interface;
void (*ObjectTraits<wl_surface>::deleter)(wl_surface*) = &wl_surface_destroy;
+const wl_interface* ObjectTraits<wl_touch>::interface = &wl_touch_interface;
+void (*ObjectTraits<wl_touch>::deleter)(wl_touch*) = &delete_touch;
+
const wl_interface* ObjectTraits<xdg_shell>::interface = &xdg_shell_interface;
void (*ObjectTraits<xdg_shell>::deleter)(xdg_shell*) = &xdg_shell_destroy;
diff --git a/chromium/ui/ozone/platform/wayland/wayland_object.h b/chromium/ui/ozone/platform/wayland/wayland_object.h
index d6512fb682a..6c6d4316695 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_object.h
+++ b/chromium/ui/ozone/platform/wayland/wayland_object.h
@@ -10,6 +10,7 @@
#include <memory>
struct wl_buffer;
+struct wl_callback;
struct wl_compositor;
struct wl_keyboard;
struct wl_output;
@@ -19,6 +20,7 @@ struct wl_seat;
struct wl_shm;
struct wl_shm_pool;
struct wl_surface;
+struct wl_touch;
struct xdg_shell;
struct xdg_surface;
struct zxdg_shell_v6;
@@ -37,6 +39,12 @@ struct ObjectTraits<wl_buffer> {
};
template <>
+struct ObjectTraits<wl_callback> {
+ static const wl_interface* interface;
+ static void (*deleter)(wl_callback*);
+};
+
+template <>
struct ObjectTraits<wl_compositor> {
static const wl_interface* interface;
static void (*deleter)(wl_compositor*);
@@ -97,6 +105,12 @@ struct ObjectTraits<wl_surface> {
};
template <>
+struct ObjectTraits<wl_touch> {
+ static const wl_interface* interface;
+ static void (*deleter)(wl_touch*);
+};
+
+template <>
struct ObjectTraits<xdg_shell> {
static const wl_interface* interface;
static void (*deleter)(xdg_shell*);
diff --git a/chromium/ui/ozone/platform/wayland/wayland_test.cc b/chromium/ui/ozone/platform/wayland/wayland_test.cc
index 19814dfb01c..7bc6c91e462 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_test.cc
+++ b/chromium/ui/ozone/platform/wayland/wayland_test.cc
@@ -8,7 +8,7 @@
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#if BUILDFLAG(USE_XKBCOMMON)
-#include "ui/ozone/platform/wayland/mock_wayland_xkb_keyboard_layout_engine.h"
+#include "ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h"
#else
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
#endif
@@ -21,7 +21,7 @@ namespace ui {
WaylandTest::WaylandTest() {
#if BUILDFLAG(USE_XKBCOMMON)
KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
- std::make_unique<WaylandXkbKeyboardLayoutEngineImpl>(
+ std::make_unique<WaylandXkbKeyboardLayoutEngine>(
xkb_evdev_code_converter_));
#else
KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
diff --git a/chromium/ui/ozone/platform/wayland/wayland_touch.cc b/chromium/ui/ozone/platform/wayland/wayland_touch.cc
new file mode 100644
index 00000000000..b8dc5437f79
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/wayland_touch.cc
@@ -0,0 +1,167 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/ozone/platform/wayland/wayland_touch.h"
+
+#include <sys/mman.h>
+#include <wayland-client.h>
+
+#include "base/files/scoped_file.h"
+#include "base/memory/ptr_util.h"
+#include "ui/base/ui_features.h"
+#include "ui/events/event.h"
+#include "ui/ozone/platform/wayland/wayland_connection.h"
+#include "ui/ozone/platform/wayland/wayland_window.h"
+
+namespace ui {
+
+WaylandTouch::TouchPoint::TouchPoint() = default;
+
+WaylandTouch::TouchPoint::TouchPoint(gfx::Point location,
+ wl_surface* current_surface)
+ : surface(current_surface), last_known_location(location) {}
+
+WaylandTouch::TouchPoint::~TouchPoint() = default;
+
+//-----------------------------------------------------------------------------
+
+WaylandTouch::WaylandTouch(wl_touch* touch,
+ const EventDispatchCallback& callback)
+ : obj_(touch), callback_(callback) {
+ static const wl_touch_listener listener = {
+ &WaylandTouch::Down, &WaylandTouch::Up, &WaylandTouch::Motion,
+ &WaylandTouch::Frame, &WaylandTouch::Cancel,
+ };
+
+ wl_touch_add_listener(obj_.get(), &listener, this);
+}
+
+WaylandTouch::~WaylandTouch() {
+ DCHECK(current_points_.empty());
+}
+
+void WaylandTouch::RemoveTouchPoints(const WaylandWindow* window) {
+ base::EraseIf(current_points_,
+ [window](const TouchPoints::value_type& point) {
+ return point.second.surface == window->surface();
+ });
+}
+
+void WaylandTouch::MaybeUnsetFocus(const WaylandTouch::TouchPoints& points,
+ int32_t id,
+ wl_surface* surface) {
+ for (const auto& point : points) {
+ // Return early on the first other point having this surface.
+ if (surface == point.second.surface && id != point.first)
+ return;
+ }
+ DCHECK(surface);
+ WaylandWindow::FromSurface(surface)->set_touch_focus(false);
+}
+
+void WaylandTouch::Down(void* data,
+ wl_touch* obj,
+ uint32_t serial,
+ uint32_t time,
+ struct wl_surface* surface,
+ int32_t id,
+ wl_fixed_t x,
+ wl_fixed_t y) {
+ if (!surface)
+ return;
+ WaylandTouch* touch = static_cast<WaylandTouch*>(data);
+ DCHECK(touch);
+ touch->connection_->set_serial(serial);
+ WaylandWindow::FromSurface(surface)->set_touch_focus(true);
+
+ // Make sure this touch point wasn't present before.
+ if (touch->current_points_.find(id) != touch->current_points_.end()) {
+ LOG(WARNING) << "Touch down fired with wrong id";
+ return;
+ }
+
+ EventType type = ET_TOUCH_PRESSED;
+ gfx::Point location(wl_fixed_to_double(x), wl_fixed_to_double(y));
+ base::TimeTicks time_stamp =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(time);
+ PointerDetails pointer_details(EventPointerType::POINTER_TYPE_TOUCH, id);
+ TouchEvent event(type, location, time_stamp, pointer_details);
+ touch->callback_.Run(&event);
+
+ touch->current_points_[id] = TouchPoint(location, surface);
+}
+
+void WaylandTouch::Up(void* data,
+ wl_touch* obj,
+ uint32_t serial,
+ uint32_t time,
+ int32_t id) {
+ WaylandTouch* touch = static_cast<WaylandTouch*>(data);
+ DCHECK(touch);
+ const auto iterator = touch->current_points_.find(id);
+
+ // Make sure this touch point was present before.
+ if (iterator == touch->current_points_.end()) {
+ LOG(WARNING) << "Touch up fired with no matching touch down";
+ return;
+ }
+
+ EventType type = ET_TOUCH_RELEASED;
+ base::TimeTicks time_stamp =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(time);
+ PointerDetails pointer_details(EventPointerType::POINTER_TYPE_TOUCH, id);
+ TouchEvent event(type, touch->current_points_[id].last_known_location,
+ time_stamp, pointer_details);
+ touch->callback_.Run(&event);
+
+ touch->MaybeUnsetFocus(touch->current_points_, id,
+ touch->current_points_[id].surface);
+ touch->current_points_.erase(iterator);
+}
+
+void WaylandTouch::Motion(void* data,
+ wl_touch* obj,
+ uint32_t time,
+ int32_t id,
+ wl_fixed_t x,
+ wl_fixed_t y) {
+ WaylandTouch* touch = static_cast<WaylandTouch*>(data);
+ DCHECK(touch);
+
+ // Make sure this touch point wasn't present before.
+ if (touch->current_points_.find(id) == touch->current_points_.end()) {
+ LOG(WARNING) << "Touch event fired with wrong id";
+ return;
+ }
+
+ EventType type = ET_TOUCH_MOVED;
+ gfx::Point location(wl_fixed_to_double(x), wl_fixed_to_double(y));
+ base::TimeTicks time_stamp =
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(time);
+ PointerDetails pointer_details(EventPointerType::POINTER_TYPE_TOUCH, id);
+ TouchEvent event(type, location, time_stamp, pointer_details);
+ touch->callback_.Run(&event);
+ touch->current_points_[id].last_known_location = location;
+}
+
+void WaylandTouch::Frame(void* data, wl_touch* obj) {}
+
+void WaylandTouch::Cancel(void* data, wl_touch* obj) {
+ WaylandTouch* touch = static_cast<WaylandTouch*>(data);
+ DCHECK(touch);
+ for (auto& point : touch->current_points_) {
+ int32_t id = point.first;
+
+ EventType type = ET_TOUCH_CANCELLED;
+ base::TimeTicks time_stamp = base::TimeTicks::Now();
+ PointerDetails pointer_details(EventPointerType::POINTER_TYPE_TOUCH, id);
+ TouchEvent event(type, gfx::Point(), time_stamp, pointer_details);
+ touch->callback_.Run(&event);
+
+ WaylandWindow::FromSurface(point.second.surface)->set_touch_focus(false);
+ }
+ touch->current_points_.clear();
+}
+
+} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/wayland_touch.h b/chromium/ui/ozone/platform/wayland/wayland_touch.h
new file mode 100644
index 00000000000..ae097fd05a5
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/wayland_touch.h
@@ -0,0 +1,80 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_TOUCH_H_
+#define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_TOUCH_H_
+
+#include <memory>
+
+#include "base/containers/flat_map.h"
+#include "ui/events/ozone/evdev/event_dispatch_callback.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/ozone/platform/wayland/wayland_object.h"
+
+namespace ui {
+
+class WaylandConnection;
+class WaylandWindow;
+
+class WaylandTouch {
+ public:
+ WaylandTouch(wl_touch* touch, const EventDispatchCallback& callback);
+ virtual ~WaylandTouch();
+
+ void set_connection(WaylandConnection* connection) {
+ connection_ = connection;
+ }
+
+ void RemoveTouchPoints(const WaylandWindow* window);
+
+ private:
+ struct TouchPoint {
+ TouchPoint();
+ TouchPoint(gfx::Point location, wl_surface* current_surface);
+ ~TouchPoint();
+
+ wl_surface* surface = nullptr;
+ gfx::Point last_known_location;
+ };
+
+ using TouchPoints = base::flat_map<int32_t, TouchPoint>;
+
+ void MaybeUnsetFocus(const TouchPoints& points,
+ int32_t id,
+ wl_surface* surface);
+
+ // wl_touch_listener
+ static void Down(void* data,
+ wl_touch* obj,
+ uint32_t serial,
+ uint32_t time,
+ struct wl_surface* surface,
+ int32_t id,
+ wl_fixed_t x,
+ wl_fixed_t y);
+ static void Up(void* data,
+ wl_touch* obj,
+ uint32_t serial,
+ uint32_t time,
+ int32_t id);
+ static void Motion(void* data,
+ wl_touch* obj,
+ uint32_t time,
+ int32_t id,
+ wl_fixed_t x,
+ wl_fixed_t y);
+ static void Frame(void* data, wl_touch* obj);
+ static void Cancel(void* data, wl_touch* obj);
+
+ WaylandConnection* connection_ = nullptr;
+ wl::Object<wl_touch> obj_;
+ EventDispatchCallback callback_;
+ TouchPoints current_points_;
+
+ DISALLOW_COPY_AND_ASSIGN(WaylandTouch);
+};
+
+} // namespace ui
+
+#endif // UI_OZONE_PLATFORM_WAYLAND_WAYLAND_TOUCH_H_
diff --git a/chromium/ui/ozone/platform/wayland/wayland_touch_unittest.cc b/chromium/ui/ozone/platform/wayland/wayland_touch_unittest.cc
new file mode 100644
index 00000000000..c9afacb6a22
--- /dev/null
+++ b/chromium/ui/ozone/platform/wayland/wayland_touch_unittest.cc
@@ -0,0 +1,89 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <linux/input.h>
+#include <wayland-server.h>
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/event.h"
+#include "ui/ozone/platform/wayland/fake_server.h"
+#include "ui/ozone/platform/wayland/wayland_test.h"
+#include "ui/ozone/platform/wayland/wayland_window.h"
+#include "ui/ozone/test/mock_platform_window_delegate.h"
+
+using ::testing::SaveArg;
+using ::testing::_;
+
+namespace ui {
+
+namespace {
+
+ACTION_P(CloneEvent, ptr) {
+ *ptr = Event::Clone(*arg0);
+}
+
+} // namespace
+
+class WaylandTouchTest : public WaylandTest {
+ public:
+ WaylandTouchTest() {}
+
+ void SetUp() override {
+ WaylandTest::SetUp();
+
+ wl_seat_send_capabilities(server.seat()->resource(),
+ WL_SEAT_CAPABILITY_TOUCH);
+
+ Sync();
+
+ touch = server.seat()->touch.get();
+ ASSERT_TRUE(touch);
+ }
+
+ protected:
+ void CheckEventType(ui::EventType event_type, ui::Event* event) {
+ ASSERT_TRUE(event);
+ ASSERT_TRUE(event->IsTouchEvent());
+
+ auto* key_event = event->AsTouchEvent();
+ EXPECT_EQ(event_type, key_event->type());
+ }
+
+ wl::MockTouch* touch;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(WaylandTouchTest);
+};
+
+TEST_P(WaylandTouchTest, KeypressAndMotion) {
+ std::unique_ptr<Event> event;
+ EXPECT_CALL(delegate, DispatchEvent(_)).WillRepeatedly(CloneEvent(&event));
+
+ wl_touch_send_down(touch->resource(), 1, 0, surface->resource(), 0 /* id */,
+ wl_fixed_from_int(50), wl_fixed_from_int(100));
+
+ Sync();
+ CheckEventType(ui::ET_TOUCH_PRESSED, event.get());
+
+ wl_touch_send_motion(touch->resource(), 500, 0 /* id */,
+ wl_fixed_from_int(100), wl_fixed_from_int(100));
+
+ Sync();
+ CheckEventType(ui::ET_TOUCH_MOVED, event.get());
+
+ wl_touch_send_up(touch->resource(), 1, 1000, 0 /* id */);
+
+ Sync();
+ CheckEventType(ui::ET_TOUCH_RELEASED, event.get());
+}
+
+INSTANTIATE_TEST_CASE_P(XdgVersionV5Test,
+ WaylandTouchTest,
+ ::testing::Values(kXdgShellV5));
+INSTANTIATE_TEST_CASE_P(XdgVersionV6Test,
+ WaylandTouchTest,
+ ::testing::Values(kXdgShellV6));
+
+} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/wayland_window.cc b/chromium/ui/ozone/platform/wayland/wayland_window.cc
index 88881bf042a..bed831b995c 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_window.cc
+++ b/chromium/ui/ozone/platform/wayland/wayland_window.cc
@@ -48,7 +48,7 @@ WaylandWindow::WaylandWindow(PlatformWindowDelegate* delegate,
connection_(connection),
xdg_shell_objects_factory_(new XDGShellObjectFactory()),
bounds_(bounds),
- state_(ui::PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN) {}
+ state_(PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN) {}
WaylandWindow::~WaylandWindow() {
if (xdg_surface_) {
@@ -143,32 +143,47 @@ void WaylandWindow::ReleaseCapture() {
void WaylandWindow::ToggleFullscreen() {
DCHECK(xdg_surface_);
- DCHECK(!IsMinimized());
// TODO(msisov, tonikitoo): add multiscreen support. As the documentation says
// if xdg_surface_set_fullscreen() is not provided with wl_output, it's up to
// the compositor to choose which display will be used to map this surface.
- if (!IsFullscreen())
+ if (!IsFullscreen()) {
+ // Client might have requested a fullscreen state while the window was in
+ // a maximized state. Thus, |restored_bounds_| can contain the bounds of a
+ // "normal" state before the window was maximized. We don't override them
+ // unless they are empty, because |bounds_| can contain bounds of a
+ // maximized window instead.
+ if (restored_bounds_.IsEmpty())
+ restored_bounds_ = bounds_;
xdg_surface_->SetFullscreen();
- else
+ } else {
xdg_surface_->UnSetFullscreen();
+ }
+
connection_->ScheduleFlush();
}
void WaylandWindow::Maximize() {
DCHECK(xdg_surface_);
- DCHECK(!IsMaximized());
if (IsFullscreen())
ToggleFullscreen();
+ // Keeps track of the previous bounds, which are used to restore a window
+ // after unmaximize call. We don't override |restored_bounds_| if they have
+ // already had value, which means the previous state has been a fullscreen
+ // state. That is, the bounds can be stored during a change from a normal
+ // state to a maximize state, and then preserved to be the same, when changing
+ // from maximized to fullscreen and back to a maximized state.
+ if (restored_bounds_.IsEmpty())
+ restored_bounds_ = bounds_;
+
xdg_surface_->SetMaximized();
connection_->ScheduleFlush();
}
void WaylandWindow::Minimize() {
DCHECK(xdg_surface_);
- DCHECK(!IsMinimized());
DCHECK(xdg_surface_);
xdg_surface_->SetMinimized();
@@ -177,7 +192,7 @@ void WaylandWindow::Minimize() {
// Wayland doesn't say if a window is minimized. Handle this case manually
// here. We can track if the window was unminimized once wayland sends the
// window is activated, and the previous state was minimized.
- state_ = ui::PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED;
+ state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED;
}
void WaylandWindow::Restore() {
@@ -225,6 +240,8 @@ bool WaylandWindow::CanDispatchEvent(const PlatformEvent& native_event) {
return has_pointer_focus_;
if (event->IsKeyEvent())
return has_keyboard_focus_;
+ if (event->IsTouchEvent())
+ return has_touch_focus_;
return false;
}
@@ -240,34 +257,25 @@ void WaylandWindow::HandleSurfaceConfigure(int32_t width,
bool is_maximized,
bool is_fullscreen,
bool is_activated) {
- // Change the window state only if the window is activated, because it's the
- // only way to know if the window is not minimized.
- if (is_activated) {
- bool was_minimized = IsMinimized();
-
- state_ = ui::PlatformWindowState::PLATFORM_WINDOW_STATE_NORMAL;
- if (is_maximized && !is_fullscreen)
- state_ = ui::PlatformWindowState::PLATFORM_WINDOW_STATE_MAXIMIZED;
- else if (is_fullscreen)
- state_ = ui::PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN;
-
- // Do not flood the WindowServer unless the previous state was minimized.
- if (was_minimized)
- delegate_->OnWindowStateChanged(state_);
- }
+ // Propagate the window state information to the client.
+ PlatformWindowState old_state = state_;
+ if (IsMinimized() && !is_activated)
+ state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED;
+ else if (is_fullscreen)
+ state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN;
+ else if (is_maximized)
+ state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_MAXIMIZED;
+ else
+ state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_NORMAL;
- // Width or height set 0 means that we should decide on width and height by
- // ourselves, but we don't want to set to anything else. Use previous size.
- if (width == 0 || height == 0) {
- width = GetBounds().width();
- height = GetBounds().height();
- }
+ if (old_state != state_)
+ delegate_->OnWindowStateChanged(state_);
// Rather than call SetBounds here for every configure event, just save the
// most recent bounds, and have WaylandConnection call ApplyPendingBounds
// when it has finished processing events. We may get many configure events
// in a row during an interactive resize, and only the last one matters.
- pending_bounds_ = gfx::Rect(0, 0, width, height);
+ SetPendingBounds(width, height);
}
void WaylandWindow::OnCloseRequest() {
@@ -275,15 +283,36 @@ void WaylandWindow::OnCloseRequest() {
}
bool WaylandWindow::IsMinimized() const {
- return state_ == ui::PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED;
+ return state_ == PlatformWindowState::PLATFORM_WINDOW_STATE_MINIMIZED;
}
bool WaylandWindow::IsMaximized() const {
- return state_ == ui::PlatformWindowState::PLATFORM_WINDOW_STATE_MAXIMIZED;
+ return state_ == PlatformWindowState::PLATFORM_WINDOW_STATE_MAXIMIZED;
}
bool WaylandWindow::IsFullscreen() const {
- return state_ == ui::PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN;
+ return state_ == PlatformWindowState::PLATFORM_WINDOW_STATE_FULLSCREEN;
+}
+
+void WaylandWindow::SetPendingBounds(int32_t width, int32_t height) {
+ // Width or height set to 0 means that we should decide on width and height by
+ // ourselves, but we don't want to set them to anything else. Use restored
+ // bounds size or the current bounds.
+ //
+ // Note: if the browser was started with --start-fullscreen and a user exits
+ // the fullscreen mode, wayland may set the width and height to be 1. Instead,
+ // explicitly set the bounds to the current desired ones or the previous
+ // bounds.
+ if (width <= 1 || height <= 1) {
+ pending_bounds_.set_size(restored_bounds_.IsEmpty()
+ ? GetBounds().size()
+ : restored_bounds_.size());
+ } else {
+ pending_bounds_ = gfx::Rect(0, 0, width, height);
+ }
+
+ if (!IsFullscreen() && !IsMaximized())
+ restored_bounds_ = gfx::Rect();
}
} // namespace ui
diff --git a/chromium/ui/ozone/platform/wayland/wayland_window.h b/chromium/ui/ozone/platform/wayland/wayland_window.h
index a4485911414..8d205fa48b4 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_window.h
+++ b/chromium/ui/ozone/platform/wayland/wayland_window.h
@@ -35,7 +35,7 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
bool Initialize();
- wl_surface* surface() { return surface_.get(); }
+ wl_surface* surface() const { return surface_.get(); }
// Apply the bounds specified in the most recent configure event. This should
// be called after processing all pending events in the wayland connection.
@@ -47,6 +47,9 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
// Set whether this window has keyboard focus and should dispatch key events.
void set_keyboard_focus(bool focus) { has_keyboard_focus_ = focus; }
+ // Set whether this window has touch focus and should dispatch touch events.
+ void set_touch_focus(bool focus) { has_touch_focus_ = focus; }
+
// PlatformWindow
void Show() override;
void Hide() override;
@@ -83,6 +86,8 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
bool IsMaximized() const;
bool IsFullscreen() const;
+ void SetPendingBounds(int32_t width, int32_t height);
+
// Creates a surface window, which is visible as a main window.
void CreateXdgSurface();
@@ -103,8 +108,11 @@ class WaylandWindow : public PlatformWindow, public PlatformEventDispatcher {
gfx::Rect bounds_;
gfx::Rect pending_bounds_;
+ // The bounds of our window before we were maximized or fullscreen.
+ gfx::Rect restored_bounds_;
bool has_pointer_focus_ = false;
bool has_keyboard_focus_ = false;
+ bool has_touch_focus_ = false;
// Stores current states of the window.
ui::PlatformWindowState state_;
diff --git a/chromium/ui/ozone/platform/wayland/wayland_window_unittest.cc b/chromium/ui/ozone/platform/wayland/wayland_window_unittest.cc
index a36d769370f..2c2e2679a2a 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_window_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/wayland_window_unittest.cc
@@ -94,24 +94,47 @@ TEST_P(WaylandWindowTest, SetTitle) {
}
TEST_P(WaylandWindowTest, MaximizeAndRestore) {
- uint32_t serial = 12;
wl_array states;
InitializeWlArrayWithActivatedState(&states);
+ EXPECT_CALL(delegate,
+ OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_MAXIMIZED)));
SetWlArrayWithState(XDG_SURFACE_STATE_MAXIMIZED, &states);
EXPECT_CALL(*GetXdgSurface(), SetMaximized());
- EXPECT_CALL(*GetXdgSurface(), UnsetMaximized());
window->Maximize();
- SendConfigureEvent(0, 0, serial, &states);
+ SendConfigureEvent(0, 0, 1, &states);
Sync();
+ EXPECT_CALL(delegate, OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_NORMAL)));
+ EXPECT_CALL(*GetXdgSurface(), UnsetMaximized());
window->Restore();
+ // Reinitialize wl_array, which removes previous old states.
+ InitializeWlArrayWithActivatedState(&states);
+ SendConfigureEvent(0, 0, 2, &states);
+ Sync();
}
TEST_P(WaylandWindowTest, Minimize) {
+ wl_array states;
+ wl_array_init(&states);
+
+ // Initialize to normal first.
+ EXPECT_CALL(delegate, OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_NORMAL)));
+ SendConfigureEvent(0, 0, 1, &states);
+ Sync();
+
EXPECT_CALL(*GetXdgSurface(), SetMinimized());
+ // The state of the window must retain minimized, which means we are not
+ // notified about the state, because 1) minimized state was set manually
+ // in WaylandWindow, and it has been confirmed in a back call from the server,
+ // which resulted in the same state as before.
+ EXPECT_CALL(delegate, OnWindowStateChanged(_)).Times(0);
window->Minimize();
+ // Reinitialize wl_array, which removes previous old states.
+ wl_array_init(&states);
+ SendConfigureEvent(0, 0, 2, &states);
+ Sync();
}
TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
@@ -121,34 +144,173 @@ TEST_P(WaylandWindowTest, SetFullscreenAndRestore) {
SetWlArrayWithState(XDG_SURFACE_STATE_FULLSCREEN, &states);
EXPECT_CALL(*GetXdgSurface(), SetFullscreen());
- EXPECT_CALL(*GetXdgSurface(), UnsetFullscreen());
+ EXPECT_CALL(delegate,
+ OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_FULLSCREEN)));
window->ToggleFullscreen();
SendConfigureEvent(0, 0, 1, &states);
Sync();
+ EXPECT_CALL(*GetXdgSurface(), UnsetFullscreen());
+ EXPECT_CALL(delegate, OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_NORMAL)));
window->Restore();
+ // Reinitialize wl_array, which removes previous old states.
+ InitializeWlArrayWithActivatedState(&states);
+ SendConfigureEvent(0, 0, 2, &states);
+ Sync();
}
TEST_P(WaylandWindowTest, SetMaximizedFullscreenAndRestore) {
wl_array states;
InitializeWlArrayWithActivatedState(&states);
+ EXPECT_CALL(*GetXdgSurface(), SetMaximized());
+ EXPECT_CALL(delegate,
+ OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_MAXIMIZED)));
+ window->Maximize();
+ SetWlArrayWithState(XDG_SURFACE_STATE_MAXIMIZED, &states);
+ SendConfigureEvent(0, 0, 2, &states);
+ Sync();
+
EXPECT_CALL(*GetXdgSurface(), SetFullscreen());
+ EXPECT_CALL(delegate,
+ OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_FULLSCREEN)));
+ window->ToggleFullscreen();
+ SetWlArrayWithState(XDG_SURFACE_STATE_FULLSCREEN, &states);
+ SendConfigureEvent(0, 0, 3, &states);
+ Sync();
+
EXPECT_CALL(*GetXdgSurface(), UnsetFullscreen());
- EXPECT_CALL(*GetXdgSurface(), SetMaximized());
EXPECT_CALL(*GetXdgSurface(), UnsetMaximized());
+ EXPECT_CALL(delegate, OnWindowStateChanged(Eq(PLATFORM_WINDOW_STATE_NORMAL)));
+ window->Restore();
+ // Reinitialize wl_array, which removes previous old states.
+ InitializeWlArrayWithActivatedState(&states);
+ SendConfigureEvent(0, 0, 4, &states);
+ Sync();
+}
+TEST_P(WaylandWindowTest, RestoreBoundsAfterMaximize) {
+ const gfx::Rect current_bounds = window->GetBounds();
+
+ wl_array states;
+ InitializeWlArrayWithActivatedState(&states);
+
+ const gfx::Rect maximized_bounds = gfx::Rect(0, 0, 1024, 768);
+ EXPECT_CALL(delegate, OnBoundsChanged(Eq(maximized_bounds)));
window->Maximize();
SetWlArrayWithState(XDG_SURFACE_STATE_MAXIMIZED, &states);
+ SendConfigureEvent(maximized_bounds.width(), maximized_bounds.height(), 1,
+ &states);
+ Sync();
+
+ EXPECT_CALL(delegate, OnBoundsChanged(Eq(current_bounds)));
+ // Both in XdgV5 and XdgV6, surfaces implement SetWindowGeometry method.
+ // Thus, using a toplevel object in XdgV6 case is not right thing. Use a
+ // surface here instead.
+ EXPECT_CALL(*xdg_surface, SetWindowGeometry(0, 0, current_bounds.width(),
+ current_bounds.height()));
+ window->Restore();
+ // Reinitialize wl_array, which removes previous old states.
+ InitializeWlArrayWithActivatedState(&states);
SendConfigureEvent(0, 0, 2, &states);
Sync();
+}
+
+TEST_P(WaylandWindowTest, RestoreBoundsAfterFullscreen) {
+ const gfx::Rect current_bounds = window->GetBounds();
+
+ wl_array states;
+ InitializeWlArrayWithActivatedState(&states);
+ const gfx::Rect fullscreen_bounds = gfx::Rect(0, 0, 1280, 720);
+ EXPECT_CALL(delegate, OnBoundsChanged(Eq(fullscreen_bounds)));
window->ToggleFullscreen();
SetWlArrayWithState(XDG_SURFACE_STATE_FULLSCREEN, &states);
- SendConfigureEvent(0, 0, 3, &states);
+ SendConfigureEvent(fullscreen_bounds.width(), fullscreen_bounds.height(), 1,
+ &states);
Sync();
+ EXPECT_CALL(delegate, OnBoundsChanged(Eq(current_bounds)));
+ // Both in XdgV5 and XdgV6, surfaces implement SetWindowGeometry method.
+ // Thus, using a toplevel object in XdgV6 case is not right thing. Use a
+ // surface here instead.
+ EXPECT_CALL(*xdg_surface, SetWindowGeometry(0, 0, current_bounds.width(),
+ current_bounds.height()));
window->Restore();
+ // Reinitialize wl_array, which removes previous old states.
+ InitializeWlArrayWithActivatedState(&states);
+ SendConfigureEvent(0, 0, 2, &states);
+ Sync();
+}
+
+TEST_P(WaylandWindowTest, RestoreBoundsAfterMaximizeAndFullscreen) {
+ const gfx::Rect current_bounds = window->GetBounds();
+
+ wl_array states;
+ InitializeWlArrayWithActivatedState(&states);
+
+ const gfx::Rect maximized_bounds = gfx::Rect(0, 0, 1024, 768);
+ EXPECT_CALL(delegate, OnBoundsChanged(Eq(maximized_bounds)));
+ window->Maximize();
+ SetWlArrayWithState(XDG_SURFACE_STATE_MAXIMIZED, &states);
+ SendConfigureEvent(maximized_bounds.width(), maximized_bounds.height(), 1,
+ &states);
+ Sync();
+
+ const gfx::Rect fullscreen_bounds = gfx::Rect(0, 0, 1280, 720);
+ EXPECT_CALL(delegate, OnBoundsChanged(Eq(fullscreen_bounds)));
+ window->ToggleFullscreen();
+ SetWlArrayWithState(XDG_SURFACE_STATE_FULLSCREEN, &states);
+ SendConfigureEvent(fullscreen_bounds.width(), fullscreen_bounds.height(), 2,
+ &states);
+ Sync();
+
+ EXPECT_CALL(delegate, OnBoundsChanged(Eq(maximized_bounds)));
+ window->Maximize();
+ // Reinitialize wl_array, which removes previous old states.
+ InitializeWlArrayWithActivatedState(&states);
+ SetWlArrayWithState(XDG_SURFACE_STATE_MAXIMIZED, &states);
+ SendConfigureEvent(maximized_bounds.width(), maximized_bounds.height(), 3,
+ &states);
+ Sync();
+
+ EXPECT_CALL(delegate, OnBoundsChanged(Eq(current_bounds)));
+ // Both in XdgV5 and XdgV6, surfaces implement SetWindowGeometry method.
+ // Thus, using a toplevel object in XdgV6 case is not right thing. Use a
+ // surface here instead.
+ EXPECT_CALL(*xdg_surface, SetWindowGeometry(0, 0, current_bounds.width(),
+ current_bounds.height()));
+ window->Restore();
+ // Reinitialize wl_array, which removes previous old states.
+ InitializeWlArrayWithActivatedState(&states);
+ SendConfigureEvent(0, 0, 4, &states);
+ Sync();
+}
+
+TEST_P(WaylandWindowTest, SendsBoundsOnRequest) {
+ const gfx::Rect initial_bounds = window->GetBounds();
+
+ const gfx::Rect new_bounds = gfx::Rect(0, 0, initial_bounds.width() + 10,
+ initial_bounds.height() + 10);
+ EXPECT_CALL(delegate, OnBoundsChanged(Eq(new_bounds)));
+ window->SetBounds(new_bounds);
+
+ wl_array states;
+ InitializeWlArrayWithActivatedState(&states);
+
+ // First case is when Wayland sends a configure event with 0,0 height and
+ // widht.
+ EXPECT_CALL(*xdg_surface,
+ SetWindowGeometry(0, 0, new_bounds.width(), new_bounds.height()))
+ .Times(2);
+ SendConfigureEvent(0, 0, 2, &states);
+ Sync();
+
+ // Second case is when Wayland sends a configure event with 1, 1 height and
+ // width. It looks more like a bug in Gnome Shell with Wayland as long as the
+ // documentation says it must be set to 0, 0, when wayland requests bounds.
+ SendConfigureEvent(0, 0, 3, &states);
+ Sync();
}
TEST_P(WaylandWindowTest, CanDispatchMouseEventDefault) {
diff --git a/chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.cc b/chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.cc
index 367eb621e1f..b2600adbbd7 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.cc
+++ b/chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.cc
@@ -9,11 +9,7 @@
namespace ui {
-WaylandXkbKeyboardLayoutEngineImpl::WaylandXkbKeyboardLayoutEngineImpl(
- const XkbKeyCodeConverter& converter)
- : WaylandXkbKeyboardLayoutEngine(converter) {}
-
-void WaylandXkbKeyboardLayoutEngineImpl::SetKeymap(xkb_keymap* keymap) {
+void WaylandXkbKeyboardLayoutEngine::SetKeymap(xkb_keymap* keymap) {
XkbKeyboardLayoutEngine::SetKeymap(keymap);
xkb_mod_indexes_.control =
@@ -23,11 +19,10 @@ void WaylandXkbKeyboardLayoutEngineImpl::SetKeymap(xkb_keymap* keymap) {
xkb_mod_indexes_.caps = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
}
-void WaylandXkbKeyboardLayoutEngineImpl::UpdateModifiers(
- uint32_t depressed_mods,
- uint32_t latched_mods,
- uint32_t locked_mods,
- uint32_t group) {
+void WaylandXkbKeyboardLayoutEngine::UpdateModifiers(uint32_t depressed_mods,
+ uint32_t latched_mods,
+ uint32_t locked_mods,
+ uint32_t group) {
xkb_state_update_mask(xkb_state_.get(), depressed_mods, latched_mods,
locked_mods, 0, 0, group);
@@ -55,7 +50,7 @@ void WaylandXkbKeyboardLayoutEngineImpl::UpdateModifiers(
event_modifiers_->SetModifierLock(MODIFIER_CAPS_LOCK, false);
}
-void WaylandXkbKeyboardLayoutEngineImpl::SetEventModifiers(
+void WaylandXkbKeyboardLayoutEngine::SetEventModifiers(
EventModifiers* event_modifiers) {
event_modifiers_ = event_modifiers;
}
diff --git a/chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h b/chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h
index ccb02e91bf2..18c8f8c53a6 100644
--- a/chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h
+++ b/chromium/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h
@@ -20,24 +20,12 @@ class WaylandXkbKeyboardLayoutEngine : public XkbKeyboardLayoutEngine {
// Used to sync up client side 'xkb_state' instance with modifiers status
// update from the compositor.
- virtual void UpdateModifiers(uint32_t depressed_mods,
- uint32_t latched_mods,
- uint32_t locked_mods,
- uint32_t group) = 0;
- virtual void SetEventModifiers(EventModifiers* event_modifiers) = 0;
-};
-
-class WaylandXkbKeyboardLayoutEngineImpl
- : public WaylandXkbKeyboardLayoutEngine {
- public:
- WaylandXkbKeyboardLayoutEngineImpl(const XkbKeyCodeConverter& converter);
-
void UpdateModifiers(uint32_t depressed_mods,
uint32_t latched_mods,
uint32_t locked_mods,
- uint32_t group) override;
+ uint32_t group);
- void SetEventModifiers(EventModifiers* event_modifiers) override;
+ void SetEventModifiers(EventModifiers* event_modifiers);
private:
void SetKeymap(xkb_keymap* keymap) override;
diff --git a/chromium/ui/ozone/platform/x11/BUILD.gn b/chromium/ui/ozone/platform/x11/BUILD.gn
index a060b1fb592..e73f2cf063b 100644
--- a/chromium/ui/ozone/platform/x11/BUILD.gn
+++ b/chromium/ui/ozone/platform/x11/BUILD.gn
@@ -18,14 +18,21 @@ source_set("x11") {
"ozone_platform_x11.h",
"x11_cursor_factory_ozone.cc",
"x11_cursor_factory_ozone.h",
+ "x11_cursor_ozone.cc",
+ "x11_cursor_ozone.h",
"x11_surface_factory.cc",
"x11_surface_factory.h",
+ "x11_window_manager_ozone.cc",
+ "x11_window_manager_ozone.h",
+ "x11_window_ozone.cc",
+ "x11_window_ozone.h",
]
deps = [
"//base",
"//skia",
"//ui/base",
+ "//ui/base/x",
"//ui/display/manager",
"//ui/events",
"//ui/events/devices",
diff --git a/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc b/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc
index 05910639099..476f69ff287 100644
--- a/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc
+++ b/chromium/ui/ozone/platform/x11/ozone_platform_x11.cc
@@ -19,12 +19,12 @@
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/platform/x11/x11_cursor_factory_ozone.h"
#include "ui/ozone/platform/x11/x11_surface_factory.h"
+#include "ui/ozone/platform/x11/x11_window_manager_ozone.h"
+#include "ui/ozone/platform/x11/x11_window_ozone.h"
#include "ui/ozone/public/gpu_platform_support_host.h"
#include "ui/ozone/public/input_controller.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/platform_window/platform_window.h"
-#include "ui/platform_window/x11/x11_window_manager_ozone.h"
-#include "ui/platform_window/x11/x11_window_ozone.h"
namespace ui {
diff --git a/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h b/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h
index f564fe4d6ae..48859f4bfd5 100644
--- a/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h
+++ b/chromium/ui/ozone/platform/x11/x11_cursor_factory_ozone.h
@@ -12,8 +12,8 @@
#include "base/macros.h"
#include "ui/base/cursor/cursor.h"
#include "ui/gfx/x/x11.h"
+#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
#include "ui/ozone/public/cursor_factory_ozone.h"
-#include "ui/platform_window/x11/x11_cursor_ozone.h"
namespace ui {
diff --git a/chromium/ui/platform_window/x11/x11_cursor_ozone.cc b/chromium/ui/ozone/platform/x11/x11_cursor_ozone.cc
index 003634144e3..2790329148f 100644
--- a/chromium/ui/platform_window/x11/x11_cursor_ozone.cc
+++ b/chromium/ui/ozone/platform/x11/x11_cursor_ozone.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/platform_window/x11/x11_cursor_ozone.h"
+#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
#include "base/logging.h"
#include "third_party/skia/include/core/SkBitmap.h"
diff --git a/chromium/ui/platform_window/x11/x11_cursor_ozone.h b/chromium/ui/ozone/platform/x11/x11_cursor_ozone.h
index 347db15c6c6..fae79f9cf5d 100644
--- a/chromium/ui/platform_window/x11/x11_cursor_ozone.h
+++ b/chromium/ui/ozone/platform/x11/x11_cursor_ozone.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_PLATFORM_WINDOW_X11_X11_CURSOR_OZONE_H_
-#define UI_PLATFORM_WINDOW_X11_X11_CURSOR_OZONE_H_
+#ifndef UI_OZONE_PLATFORM_X11_X11_CURSOR_OZONE_H_
+#define UI_OZONE_PLATFORM_X11_X11_CURSOR_OZONE_H_
#include <vector>
@@ -11,7 +11,6 @@
#include "base/memory/ref_counted.h"
#include "ui/base/cursor/cursor.h"
#include "ui/gfx/x/x11.h"
-#include "ui/platform_window/x11/x11_window_export.h"
class SkBitmap;
@@ -23,8 +22,7 @@ namespace ui {
// Ref counted class to hold an X11 cursor resource. Handles creating X11 cursor
// resources from SkBitmap/hotspot and clears the X11 resources on destruction.
-class X11_WINDOW_EXPORT X11CursorOzone
- : public base::RefCounted<X11CursorOzone> {
+class X11CursorOzone : public base::RefCounted<X11CursorOzone> {
public:
X11CursorOzone(const SkBitmap& bitmap, const gfx::Point& hotspot);
X11CursorOzone(const std::vector<SkBitmap>& bitmaps,
@@ -34,7 +32,7 @@ class X11_WINDOW_EXPORT X11CursorOzone
// Creates a new cursor that is invisible.
static scoped_refptr<X11CursorOzone> CreateInvisible();
- ::Cursor xcursor() const { return xcursor_; }
+ XID xcursor() const { return xcursor_; }
private:
friend class base::RefCounted<X11CursorOzone>;
@@ -42,10 +40,11 @@ class X11_WINDOW_EXPORT X11CursorOzone
X11CursorOzone();
~X11CursorOzone();
- ::Cursor xcursor_ = x11::None;
+ XID xcursor_ = x11::None;
DISALLOW_COPY_AND_ASSIGN(X11CursorOzone);
};
} // namespace ui
-#endif // UI_PLATFORM_WINDOW_X11_X11_CURSOR_OZONE_H_
+
+#endif // UI_OZONE_PLATFORM_X11_X11_CURSOR_OZONE_H_
diff --git a/chromium/ui/platform_window/x11/x11_window_manager_ozone.cc b/chromium/ui/ozone/platform/x11/x11_window_manager_ozone.cc
index d47d1725ed8..494c43cd6f2 100644
--- a/chromium/ui/platform_window/x11/x11_window_manager_ozone.cc
+++ b/chromium/ui/ozone/platform/x11/x11_window_manager_ozone.cc
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/platform_window/x11/x11_window_manager_ozone.h"
+#include "ui/ozone/platform/x11/x11_window_manager_ozone.h"
+
+#include "ui/ozone/platform/x11/x11_window_ozone.h"
namespace ui {
diff --git a/chromium/ui/platform_window/x11/x11_window_manager_ozone.h b/chromium/ui/ozone/platform/x11/x11_window_manager_ozone.h
index e3cfca34372..884425c8571 100644
--- a/chromium/ui/platform_window/x11/x11_window_manager_ozone.h
+++ b/chromium/ui/ozone/platform/x11/x11_window_manager_ozone.h
@@ -2,17 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_PLATFORM_WINDOW_X11_X11_WINDOW_MANAGER_OZONE_H_
-#define UI_PLATFORM_WINDOW_X11_X11_WINDOW_MANAGER_OZONE_H_
+#ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_OZONE_H_
+#define UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_OZONE_H_
#include "base/macros.h"
-#include "ui/platform_window/x11/x11_window_export.h"
namespace ui {
class X11WindowOzone;
-class X11_WINDOW_EXPORT X11WindowManagerOzone {
+class X11WindowManagerOzone {
public:
X11WindowManagerOzone();
~X11WindowManagerOzone();
@@ -35,4 +34,4 @@ class X11_WINDOW_EXPORT X11WindowManagerOzone {
} // namespace ui
-#endif // UI_PLATFORM_WINDOW_X11_X11_WINDOW_MANAGER_OZONE_H_
+#endif // UI_OZONE_PLATFORM_X11_X11_WINDOW_MANAGER_OZONE_H_
diff --git a/chromium/ui/platform_window/x11/x11_window_ozone.cc b/chromium/ui/ozone/platform/x11/x11_window_ozone.cc
index d62184a7a7c..1ce459877dc 100644
--- a/chromium/ui/platform_window/x11/x11_window_ozone.cc
+++ b/chromium/ui/ozone/platform/x11/x11_window_ozone.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "ui/platform_window/x11/x11_window_ozone.h"
+#include "ui/ozone/platform/x11/x11_window_ozone.h"
#include "base/bind.h"
#include "ui/events/event.h"
@@ -10,8 +10,8 @@
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/x/x11.h"
-#include "ui/platform_window/x11/x11_cursor_ozone.h"
-#include "ui/platform_window/x11/x11_window_manager_ozone.h"
+#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
+#include "ui/ozone/platform/x11/x11_window_manager_ozone.h"
namespace ui {
diff --git a/chromium/ui/platform_window/x11/x11_window_ozone.h b/chromium/ui/ozone/platform/x11/x11_window_ozone.h
index 8405aac49b1..48568ca420c 100644
--- a/chromium/ui/platform_window/x11/x11_window_ozone.h
+++ b/chromium/ui/ozone/platform/x11/x11_window_ozone.h
@@ -2,23 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef UI_PLATFORM_WINDOW_X11_X11_WINDOW_OZONE_H_
-#define UI_PLATFORM_WINDOW_X11_X11_WINDOW_OZONE_H_
+#ifndef UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_H_
+#define UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_H_
#include "base/macros.h"
#include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/events/platform/x11/x11_event_source_libevent.h"
#include "ui/platform_window/x11/x11_window_base.h"
-#include "ui/platform_window/x11/x11_window_export.h"
namespace ui {
class X11WindowManagerOzone;
// PlatformWindow implementation for X11 Ozone. PlatformEvents are ui::Events.
-class X11_WINDOW_EXPORT X11WindowOzone : public X11WindowBase,
- public PlatformEventDispatcher,
- public XEventDispatcher {
+class X11WindowOzone : public X11WindowBase,
+ public PlatformEventDispatcher,
+ public XEventDispatcher {
public:
X11WindowOzone(X11WindowManagerOzone* window_manager,
PlatformWindowDelegate* delegate,
@@ -54,4 +53,4 @@ class X11_WINDOW_EXPORT X11WindowOzone : public X11WindowBase,
} // namespace ui
-#endif // UI_PLATFORM_WINDOW_X11_X11_WINDOW_OZONE_H_
+#endif // UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_H_
diff --git a/chromium/ui/ozone/public/interfaces/DEPS b/chromium/ui/ozone/public/DEPS
index ef8ad28d9d4..ef8ad28d9d4 100644
--- a/chromium/ui/ozone/public/interfaces/DEPS
+++ b/chromium/ui/ozone/public/DEPS
diff --git a/chromium/ui/ozone/public/client_native_pixmap_factory_ozone.cc b/chromium/ui/ozone/public/client_native_pixmap_factory_ozone.cc
index 7d6428b48d8..110f816c557 100644
--- a/chromium/ui/ozone/public/client_native_pixmap_factory_ozone.cc
+++ b/chromium/ui/ozone/public/client_native_pixmap_factory_ozone.cc
@@ -4,17 +4,50 @@
#include "ui/ozone/public/client_native_pixmap_factory_ozone.h"
+#include <memory>
+
+#include "base/memory/singleton.h"
#include "base/trace_event/trace_event.h"
+#include "ui/gfx/client_native_pixmap_factory.h"
#include "ui/ozone/platform_object.h"
#include "ui/ozone/platform_selection.h"
namespace ui {
+namespace {
+
+// Thread-safe owner of the gfx::ClientNativePixmapFactory. Not a LazyInstance
+// because it uses PlatformObject<>::Create() for factory construction.
+// TODO(jamescook|spang): This exists to solve a startup race for chrome with
+// mash http://crbug.com/807781. Removing the factory entirely would be better,
+// with something like http://crrev.com/c/899949.
+class PixmapFactorySingleton {
+ public:
+ static PixmapFactorySingleton* GetInstance() {
+ return base::Singleton<PixmapFactorySingleton>::get();
+ }
+
+ private:
+ friend struct base::DefaultSingletonTraits<PixmapFactorySingleton>;
+
+ PixmapFactorySingleton() {
+ TRACE_EVENT1("ozone", "CreateClientNativePixmapFactoryOzone", "platform",
+ GetOzonePlatformName());
+ pixmap_factory_ = PlatformObject<gfx::ClientNativePixmapFactory>::Create();
+ gfx::ClientNativePixmapFactory::SetInstance(pixmap_factory_.get());
+ }
+
+ std::unique_ptr<gfx::ClientNativePixmapFactory> pixmap_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PixmapFactorySingleton);
+};
+
+} // namespace
-std::unique_ptr<gfx::ClientNativePixmapFactory>
-CreateClientNativePixmapFactoryOzone() {
- TRACE_EVENT1("ozone", "CreateClientNativePixmapFactoryOzone", "platform",
- GetOzonePlatformName());
- return PlatformObject<gfx::ClientNativePixmapFactory>::Create();
+void CreateClientNativePixmapFactoryOzone() {
+ // Multiple threads may race to create the factory (e.g. when the UI service
+ // and ash service are running in the same process). Create the object as a
+ // side effect of a thread-safe singleton.
+ PixmapFactorySingleton::GetInstance();
}
} // namespace ui
diff --git a/chromium/ui/ozone/public/client_native_pixmap_factory_ozone.h b/chromium/ui/ozone/public/client_native_pixmap_factory_ozone.h
index 744e868ad85..29d6b5019e4 100644
--- a/chromium/ui/ozone/public/client_native_pixmap_factory_ozone.h
+++ b/chromium/ui/ozone/public/client_native_pixmap_factory_ozone.h
@@ -5,13 +5,14 @@
#ifndef UI_OZONE_PUBLIC_CLIENT_NATIVE_PIXMAP_FACTORY_OZONE_H_
#define UI_OZONE_PUBLIC_CLIENT_NATIVE_PIXMAP_FACTORY_OZONE_H_
-#include "ui/gfx/client_native_pixmap_factory.h"
#include "ui/ozone/ozone_export.h"
namespace ui {
-OZONE_EXPORT std::unique_ptr<gfx::ClientNativePixmapFactory>
-CreateClientNativePixmapFactoryOzone();
+// Creates a factory for pixmaps that can use be transported from the client to
+// the GPU process using a low-level ozone-provided platform specific mechanism.
+// The factory is installed as the gfx::ClientNativePixmapFactory instance.
+OZONE_EXPORT void CreateClientNativePixmapFactoryOzone();
} // namespace ui
diff --git a/chromium/ui/ozone/public/gpu_platform_support_host.cc b/chromium/ui/ozone/public/gpu_platform_support_host.cc
index 98a23b1965c..586186c093f 100644
--- a/chromium/ui/ozone/public/gpu_platform_support_host.cc
+++ b/chromium/ui/ozone/public/gpu_platform_support_host.cc
@@ -23,6 +23,10 @@ class StubGpuPlatformSupportHost : public GpuPlatformSupportHost {
void OnChannelDestroyed(int host_id) override {}
void OnMessageReceived(const IPC::Message&) override {}
+ void OnGpuServiceLaunched(
+ scoped_refptr<base::SingleThreadTaskRunner> ui_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_runner,
+ GpuHostBindInterfaceCallback binder) override {}
};
} // namespace
diff --git a/chromium/ui/ozone/public/gpu_platform_support_host.h b/chromium/ui/ozone/public/gpu_platform_support_host.h
index 50db642788d..f1120e74751 100644
--- a/chromium/ui/ozone/public/gpu_platform_support_host.h
+++ b/chromium/ui/ozone/public/gpu_platform_support_host.h
@@ -5,10 +5,13 @@
#ifndef UI_OZONE_PUBLIC_GPU_PLATFORM_SUPPORT_HOST_H_
#define UI_OZONE_PUBLIC_GPU_PLATFORM_SUPPORT_HOST_H_
+#include <string>
+
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
#include "ipc/ipc_listener.h"
#include "ipc/ipc_sender.h"
+#include "mojo/public/cpp/bindings/binding.h"
#include "ui/ozone/ozone_base_export.h"
namespace ui {
@@ -24,6 +27,10 @@ namespace ui {
// to support additional messages needed by specific platforms.
class OZONE_BASE_EXPORT GpuPlatformSupportHost {
public:
+ using GpuHostBindInterfaceCallback =
+ base::RepeatingCallback<void(const std::string&,
+ mojo::ScopedMessagePipeHandle)>;
+
GpuPlatformSupportHost();
virtual ~GpuPlatformSupportHost();
@@ -42,6 +49,13 @@ class OZONE_BASE_EXPORT GpuPlatformSupportHost {
// Called to handle an IPC message. Note that this can be called from any
// thread.
virtual void OnMessageReceived(const IPC::Message& message) = 0;
+
+ // Called when the GPU service is launched.
+ // Called from the browser IO thread.
+ virtual void OnGpuServiceLaunched(
+ scoped_refptr<base::SingleThreadTaskRunner> host_runner,
+ scoped_refptr<base::SingleThreadTaskRunner> io_runner,
+ GpuHostBindInterfaceCallback binder) = 0;
};
// create a stub implementation.
diff --git a/chromium/ui/ozone/public/ozone_platform.cc b/chromium/ui/ozone/public/ozone_platform.cc
index 8b41780f5db..58c114ba430 100644
--- a/chromium/ui/ozone/public/ozone_platform.cc
+++ b/chromium/ui/ozone/public/ozone_platform.cc
@@ -125,4 +125,6 @@ void OzonePlatform::AddInterfaces(
service_manager::BinderRegistryWithArgs<
const service_manager::BindSourceInfo&>* registry) {}
+void OzonePlatform::AfterSandboxEntry() {}
+
} // namespace ui
diff --git a/chromium/ui/ozone/public/ozone_platform.h b/chromium/ui/ozone/public/ozone_platform.h
index b6335ea7246..f715a6af03a 100644
--- a/chromium/ui/ozone/public/ozone_platform.h
+++ b/chromium/ui/ozone/public/ozone_platform.h
@@ -13,6 +13,7 @@
#include "services/service_manager/public/cpp/binder_registry.h"
#include "ui/events/system_input_injector.h"
#include "ui/ozone/ozone_export.h"
+//#include "ui/ozone/public/interfaces/drm_device.mojom.h"
namespace display {
class NativeDisplayDelegate;
@@ -64,14 +65,23 @@ class OZONE_EXPORT OzonePlatform {
// retain a reference to this structure.
struct InitParams {
// Ozone may retain this pointer for later use. An Ozone platform embedder
- // must set this parameter in order for the Ozone platform implementation to
- // be able to use Mojo.
+ // may set this value if operating in the idiomatic mojo fashion with a
+ // service manager. Mojo transport does not require a service manager but in
+ // that case ozone will not be able to connect to the DRM and cursor
+ // services. Instead the host must invoke |OnGpuServiceLaunched| as
+ // described in ui/ozone/public/gpu_platform_support_host.h to inform the
+ // ozone host that a process containing these services is running.
service_manager::Connector* connector = nullptr;
// Setting this to true indicates that the platform implementation should
// operate as a single process for platforms (i.e. drm) that are usually
- // split between a main and gpu specific portion.
+ // split between a host and viz specific portion.
bool single_process = false;
+
+ // Setting this to true indicates that the platform implementation should
+ // use mojo. Setting this to true requires calling |AddInterfaces|
+ // afterwards in the Viz process and providing a connector as part
+ bool using_mojo = false;
};
// Ensures the OzonePlatform instance without doing any initialization.
@@ -131,11 +141,23 @@ class OZONE_EXPORT OzonePlatform {
// service_manager::BinderRegistry* pointer to export all Mojo interfaces
// defined within Ozone.
//
+ // Requests arriving before they can be immediately handled will be queued and
+ // executed later.
+ //
// A default do-nothing implementation is provided to permit platform
// implementations to opt out of implementing any Mojo interfaces.
virtual void AddInterfaces(service_manager::BinderRegistryWithArgs<
const service_manager::BindSourceInfo&>* registry);
+ // The GPU-specific portion of Ozone would typically run in a sandboxed
+ // process for additional security. Some startup might need to wait until
+ // after the sandbox has been configured. The embedder should use this method
+ // to specify that the sandbox is configured and that GPU-side setup should
+ // complete. A default do-nothing implementation is provided to permit
+ // platform implementations to ignore sandboxing and any associated launch
+ // ordering issues.
+ virtual void AfterSandboxEntry();
+
private:
virtual void InitializeUI(const InitParams& params) = 0;
virtual void InitializeGPU(const InitParams& params) = 0;
diff --git a/chromium/ui/ozone/public/ozone_switches.cc b/chromium/ui/ozone/public/ozone_switches.cc
index f7a772a55de..4669cfa471a 100644
--- a/chromium/ui/ozone/public/ozone_switches.cc
+++ b/chromium/ui/ozone/public/ozone_switches.cc
@@ -15,4 +15,9 @@ const char kOzoneDumpFile[] = "ozone-dump-file";
// Try to enable drm atomic. This works only with drm platform.
const char kEnableDrmAtomic[] = "enable-drm-atomic";
+// Use mojo communication in the drm platform instead of paramtraits. Remove
+// this switch (and associated code) when the drm platform always uses mojo
+// communication.
+const char kEnableDrmMojo[] = "enable-drm-mojo";
+
} // namespace switches
diff --git a/chromium/ui/ozone/public/ozone_switches.h b/chromium/ui/ozone/public/ozone_switches.h
index e53912bf47c..b8360e803e4 100644
--- a/chromium/ui/ozone/public/ozone_switches.h
+++ b/chromium/ui/ozone/public/ozone_switches.h
@@ -16,6 +16,8 @@ OZONE_BASE_EXPORT extern const char kOzoneDumpFile[];
OZONE_BASE_EXPORT extern const char kEnableDrmAtomic[];
+OZONE_BASE_EXPORT extern const char kEnableDrmMojo[];
+
} // namespace switches
#endif // UI_OZONE_PUBLIC_OZONE_SWITCHES_H_
diff --git a/chromium/ui/platform_window/x11/BUILD.gn b/chromium/ui/platform_window/x11/BUILD.gn
index 09e5de517fc..3e46e8c94c9 100644
--- a/chromium/ui/platform_window/x11/BUILD.gn
+++ b/chromium/ui/platform_window/x11/BUILD.gn
@@ -34,20 +34,7 @@ jumbo_component("x11") {
"x11_window_export.h",
]
- if (ozone_platform_x11) {
- sources += [
- "x11_cursor_ozone.cc",
- "x11_cursor_ozone.h",
- "x11_window_manager_ozone.cc",
- "x11_window_manager_ozone.h",
- "x11_window_ozone.cc",
- "x11_window_ozone.h",
- ]
- deps += [
- "//ui/base",
- "//ui/base/x",
- ]
- } else if (use_x11) {
+ if (use_x11) {
sources += [
"x11_window.cc",
"x11_window.h",
diff --git a/chromium/ui/platform_window/x11/x11_window.cc b/chromium/ui/platform_window/x11/x11_window.cc
index b5eaf13af85..d63c67e16d3 100644
--- a/chromium/ui/platform_window/x11/x11_window.cc
+++ b/chromium/ui/platform_window/x11/x11_window.cc
@@ -127,7 +127,7 @@ uint32_t X11Window::DispatchEvent(const PlatformEvent& event) {
}
case Expose:
- case FocusOut:
+ case x11::FocusOut:
case ConfigureNotify:
case ClientMessage: {
ProcessXWindowEvent(xev);
diff --git a/chromium/ui/platform_window/x11/x11_window_base.cc b/chromium/ui/platform_window/x11/x11_window_base.cc
index cb6d8e6e5e8..75cc3eef6ab 100644
--- a/chromium/ui/platform_window/x11/x11_window_base.cc
+++ b/chromium/ui/platform_window/x11/x11_window_base.cc
@@ -36,15 +36,16 @@ X11WindowBase::X11WindowBase(PlatformWindowDelegate* delegate,
const gfx::Rect& bounds)
: delegate_(delegate),
xdisplay_(gfx::GetXDisplay()),
- xwindow_(x11::None),
xroot_window_(DefaultRootWindow(xdisplay_)),
bounds_(bounds),
state_(ui::PlatformWindowState::PLATFORM_WINDOW_STATE_UNKNOWN) {
DCHECK(delegate_);
Create();
+ pointer_barriers_.fill(x11::None);
}
X11WindowBase::~X11WindowBase() {
+ UnConfineCursor();
Destroy();
}
@@ -257,12 +258,49 @@ void X11WindowBase::MoveCursorTo(const gfx::Point& location) {
bounds_.x() + location.x(), bounds_.y() + location.y());
}
-void X11WindowBase::ConfineCursorToBounds(const gfx::Rect& bounds) {}
+void X11WindowBase::ConfineCursorToBounds(const gfx::Rect& bounds) {
+ UnConfineCursor();
+
+ if (bounds.IsEmpty())
+ return;
+
+ gfx::Rect barrier = bounds + bounds_.OffsetFromOrigin();
+
+ // Top horizontal barrier.
+ pointer_barriers_[0] = XFixesCreatePointerBarrier(
+ xdisplay_, xroot_window_, barrier.x(), barrier.y(), barrier.right(),
+ barrier.y(), BarrierPositiveY, 0, XIAllDevices);
+ // Bottom horizontal barrier.
+ pointer_barriers_[1] = XFixesCreatePointerBarrier(
+ xdisplay_, xroot_window_, barrier.x(), barrier.bottom(), barrier.right(),
+ barrier.bottom(), BarrierNegativeY, 0, XIAllDevices);
+ // Left vertical barrier.
+ pointer_barriers_[2] = XFixesCreatePointerBarrier(
+ xdisplay_, xroot_window_, barrier.x(), barrier.y(), barrier.x(),
+ barrier.bottom(), BarrierPositiveX, 0, XIAllDevices);
+ // Right vertical barrier.
+ pointer_barriers_[3] = XFixesCreatePointerBarrier(
+ xdisplay_, xroot_window_, barrier.right(), barrier.y(), barrier.right(),
+ barrier.bottom(), BarrierNegativeX, 0, XIAllDevices);
+
+ has_pointer_barriers_ = true;
+}
PlatformImeController* X11WindowBase::GetPlatformImeController() {
return nullptr;
}
+void X11WindowBase::UnConfineCursor() {
+ if (!has_pointer_barriers_)
+ return;
+
+ for (XID pointer_barrier : pointer_barriers_)
+ XFixesDestroyPointerBarrier(xdisplay_, pointer_barrier);
+ pointer_barriers_.fill(x11::None);
+
+ has_pointer_barriers_ = false;
+}
+
bool X11WindowBase::IsEventForXWindow(const XEvent& xev) const {
return xwindow_ != x11::None && FindXEventTarget(xev) == xwindow_;
}
@@ -276,7 +314,7 @@ void X11WindowBase::ProcessXWindowEvent(XEvent* xev) {
break;
}
- case FocusOut:
+ case x11::FocusOut:
if (xev->xfocus.mode != NotifyGrab)
delegate_->OnLostCapture();
break;
diff --git a/chromium/ui/platform_window/x11/x11_window_base.h b/chromium/ui/platform_window/x11/x11_window_base.h
index 70761af9580..b419dc19e8f 100644
--- a/chromium/ui/platform_window/x11/x11_window_base.h
+++ b/chromium/ui/platform_window/x11/x11_window_base.h
@@ -7,6 +7,8 @@
#include <stdint.h>
+#include <array>
+
#include "base/callback.h"
#include "base/containers/flat_set.h"
#include "base/macros.h"
@@ -55,6 +57,8 @@ class X11_WINDOW_EXPORT X11WindowBase : public PlatformWindow {
XDisplay* xdisplay() { return xdisplay_; }
XID xwindow() const { return xwindow_; }
+ void UnConfineCursor();
+
// Checks if XEvent is for this XWindow.
bool IsEventForXWindow(const XEvent& xev) const;
@@ -69,10 +73,10 @@ class X11_WINDOW_EXPORT X11WindowBase : public PlatformWindow {
bool IsMaximized() const;
bool IsFullscreen() const;
- PlatformWindowDelegate* delegate_;
+ PlatformWindowDelegate* const delegate_;
XDisplay* xdisplay_;
- XID xwindow_;
+ XID xwindow_ = x11::None;
XID xroot_window_;
std::unique_ptr<ui::XScopedEventSelector> xwindow_events_;
@@ -87,6 +91,10 @@ class X11_WINDOW_EXPORT X11WindowBase : public PlatformWindow {
// Stores current state of this window.
ui::PlatformWindowState state_;
+ // Keep track of barriers to confine cursor.
+ bool has_pointer_barriers_ = false;
+ std::array<XID, 4> pointer_barriers_;
+
bool window_mapped_ = false;
DISALLOW_COPY_AND_ASSIGN(X11WindowBase);
diff --git a/chromium/ui/resources/default_100_percent/common/easy_unlock_spinner.png b/chromium/ui/resources/default_100_percent/common/easy_unlock_spinner.png
index 4371d8293f6..2a6be6a5a1e 100644
--- a/chromium/ui/resources/default_100_percent/common/easy_unlock_spinner.png
+++ b/chromium/ui/resources/default_100_percent/common/easy_unlock_spinner.png
Binary files differ
diff --git a/chromium/ui/resources/default_100_percent/common/menu_overflow_down.png b/chromium/ui/resources/default_100_percent/common/menu_overflow_down.png
index 0657fe93842..f5a7faeaa7b 100644
--- a/chromium/ui/resources/default_100_percent/common/menu_overflow_down.png
+++ b/chromium/ui/resources/default_100_percent/common/menu_overflow_down.png
Binary files differ
diff --git a/chromium/ui/resources/default_100_percent/common/menu_overflow_up.png b/chromium/ui/resources/default_100_percent/common/menu_overflow_up.png
index 85ef5b21218..d356baf2076 100644
--- a/chromium/ui/resources/default_100_percent/common/menu_overflow_up.png
+++ b/chromium/ui/resources/default_100_percent/common/menu_overflow_up.png
Binary files differ
diff --git a/chromium/ui/resources/default_100_percent/common/pointers/crosshair.png b/chromium/ui/resources/default_100_percent/common/pointers/crosshair.png
index a1c55ab14dc..0162e16e830 100644
--- a/chromium/ui/resources/default_100_percent/common/pointers/crosshair.png
+++ b/chromium/ui/resources/default_100_percent/common/pointers/crosshair.png
Binary files differ
diff --git a/chromium/ui/resources/default_100_percent/common/pointers/crosshair_big.png b/chromium/ui/resources/default_100_percent/common/pointers/crosshair_big.png
index 99f8746c771..148be7d495c 100644
--- a/chromium/ui/resources/default_100_percent/common/pointers/crosshair_big.png
+++ b/chromium/ui/resources/default_100_percent/common/pointers/crosshair_big.png
Binary files differ
diff --git a/chromium/ui/resources/default_100_percent/common/pointers/xterm.png b/chromium/ui/resources/default_100_percent/common/pointers/xterm.png
index a3d5b95739e..2990d102469 100644
--- a/chromium/ui/resources/default_100_percent/common/pointers/xterm.png
+++ b/chromium/ui/resources/default_100_percent/common/pointers/xterm.png
Binary files differ
diff --git a/chromium/ui/resources/default_100_percent/common/pointers/xterm_big.png b/chromium/ui/resources/default_100_percent/common/pointers/xterm_big.png
index c8ca97d3075..6d3a20142b1 100644
--- a/chromium/ui/resources/default_100_percent/common/pointers/xterm_big.png
+++ b/chromium/ui/resources/default_100_percent/common/pointers/xterm_big.png
Binary files differ
diff --git a/chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz.png b/chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz.png
index 26384774fe1..6f960ce03cd 100644
--- a/chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz.png
+++ b/chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz.png
Binary files differ
diff --git a/chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz_big.png b/chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz_big.png
index 33f8addd43a..26e13bd2ff7 100644
--- a/chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz_big.png
+++ b/chromium/ui/resources/default_100_percent/common/pointers/xterm_horiz_big.png
Binary files differ
diff --git a/chromium/ui/resources/default_200_percent/common/default_favicon.png b/chromium/ui/resources/default_200_percent/common/default_favicon.png
index 033ea1a0315..35eb3916231 100644
--- a/chromium/ui/resources/default_200_percent/common/default_favicon.png
+++ b/chromium/ui/resources/default_200_percent/common/default_favicon.png
Binary files differ
diff --git a/chromium/ui/resources/default_200_percent/common/easy_unlock_spinner.png b/chromium/ui/resources/default_200_percent/common/easy_unlock_spinner.png
index 9fdee1025da..8538f6a8136 100644
--- a/chromium/ui/resources/default_200_percent/common/easy_unlock_spinner.png
+++ b/chromium/ui/resources/default_200_percent/common/easy_unlock_spinner.png
Binary files differ
diff --git a/chromium/ui/resources/default_200_percent/common/menu_overflow_down.png b/chromium/ui/resources/default_200_percent/common/menu_overflow_down.png
index ba7b149c7b3..659dab6ae7e 100644
--- a/chromium/ui/resources/default_200_percent/common/menu_overflow_down.png
+++ b/chromium/ui/resources/default_200_percent/common/menu_overflow_down.png
Binary files differ
diff --git a/chromium/ui/resources/default_200_percent/common/pointers/crosshair.png b/chromium/ui/resources/default_200_percent/common/pointers/crosshair.png
index 8f5dca512a4..34b6a7c95f4 100644
--- a/chromium/ui/resources/default_200_percent/common/pointers/crosshair.png
+++ b/chromium/ui/resources/default_200_percent/common/pointers/crosshair.png
Binary files differ
diff --git a/chromium/ui/resources/default_200_percent/common/pointers/xterm.png b/chromium/ui/resources/default_200_percent/common/pointers/xterm.png
index 07871cf378a..83a661caf65 100644
--- a/chromium/ui/resources/default_200_percent/common/pointers/xterm.png
+++ b/chromium/ui/resources/default_200_percent/common/pointers/xterm.png
Binary files differ
diff --git a/chromium/ui/resources/default_200_percent/common/pointers/xterm_horiz.png b/chromium/ui/resources/default_200_percent/common/pointers/xterm_horiz.png
index a4d4ba9f0d1..afb370f5648 100644
--- a/chromium/ui/resources/default_200_percent/common/pointers/xterm_horiz.png
+++ b/chromium/ui/resources/default_200_percent/common/pointers/xterm_horiz.png
Binary files differ
diff --git a/chromium/ui/resources/default_300_percent/common/default_favicon_64.png b/chromium/ui/resources/default_300_percent/common/default_favicon_64.png
index 0c1e2bba7f9..2b28de54683 100644
--- a/chromium/ui/resources/default_300_percent/common/default_favicon_64.png
+++ b/chromium/ui/resources/default_300_percent/common/default_favicon_64.png
Binary files differ
diff --git a/chromium/ui/resources/ui_resources.grd b/chromium/ui/resources/ui_resources.grd
index 708caaf373a..10be1c5aa10 100644
--- a/chromium/ui/resources/ui_resources.grd
+++ b/chromium/ui/resources/ui_resources.grd
@@ -118,7 +118,7 @@
<structure type="chrome_scaled_image" name="IDR_MENU_HIERARCHY_ARROW" file="mac/menu_hierarchy_arrow.png" />
</if>
<structure type="chrome_scaled_image" name="IDR_MENU_DROPARROW" file="cros/menu_droparrow.png" />
- <if expr="toolkit_views or is_macosx or is_ios">
+ <if expr="toolkit_views or is_ios">
<if expr="is_win">
<structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE" file="win/notification_close.png"/>
<structure type="chrome_scaled_image" name="IDR_NOTIFICATION_CLOSE_HOVER" file="win/notification_close_hover.png"/>
diff --git a/chromium/ui/shell_dialogs/BUILD.gn b/chromium/ui/shell_dialogs/BUILD.gn
index 762859b1750..e5018b276b1 100644
--- a/chromium/ui/shell_dialogs/BUILD.gn
+++ b/chromium/ui/shell_dialogs/BUILD.gn
@@ -8,6 +8,9 @@ import("//testing/test.gni")
if (is_android) {
import("//build/config/android/config.gni")
}
+if (is_mac) {
+ import("//build/config/mac/rules.gni")
+}
jumbo_component("shell_dialogs") {
sources = [
@@ -76,11 +79,30 @@ jumbo_component("shell_dialogs") {
}
}
+if (is_mac) {
+ mac_xib_bundle_data("shell_dialogs_unittests_xibs") {
+ testonly = true
+ sources = [
+ "//chrome/app/nibs/SaveAccessoryView.xib",
+ ]
+ }
+
+ mac_framework_bundle("shell_dialogs_unittests_bundle") {
+ testonly = true
+ info_plist = "//ui/base/test/framework-Info.plist"
+ deps = [
+ ":shell_dialogs_unittests_xibs",
+ "//ui/resources:ui_test_pak_bundle_data",
+ ]
+ extra_substitutions = [ "CHROMIUM_BUNDLE_ID=$target_name" ]
+ }
+}
+
test("shell_dialogs_unittests") {
+ testonly = true
sources = [
- # TODO(karandeepb) : Revisit this once gn gets mac bundle support.
- # "select_file_dialog_mac_unittest.mm",
"run_all_unittests.cc",
+ "select_file_dialog_mac_unittest.mm",
"select_file_dialog_unittest.cc",
"select_file_dialog_win_unittest.cc",
]
@@ -92,4 +114,8 @@ test("shell_dialogs_unittests") {
"//testing/gtest",
"//ui/base:base",
]
+
+ if (is_mac) {
+ deps += [ ":shell_dialogs_unittests_bundle" ]
+ }
}
diff --git a/chromium/ui/shell_dialogs/run_all_unittests.cc b/chromium/ui/shell_dialogs/run_all_unittests.cc
index 1f5b39d8082..6b5b9bf19fb 100644
--- a/chromium/ui/shell_dialogs/run_all_unittests.cc
+++ b/chromium/ui/shell_dialogs/run_all_unittests.cc
@@ -44,9 +44,8 @@ void ShellDialogsTestSuite::Initialize() {
// Set up framework bundle so that tests on Mac can access nib files.
base::FilePath path;
PathService::Get(base::DIR_EXE, &path);
- // The three DirName() calls strip "Contents/MacOS/<binary>" from the path.
- path = path.DirName().DirName().DirName();
- path = path.Append(FILE_PATH_LITERAL("shell_dialogs_unittests.app"));
+ path = path.Append(
+ FILE_PATH_LITERAL("shell_dialogs_unittests_bundle.framework"));
base::mac::SetOverrideFrameworkBundlePath(path);
// Setup resource bundle.
diff --git a/chromium/ui/shell_dialogs/select_file_dialog_android.cc b/chromium/ui/shell_dialogs/select_file_dialog_android.cc
index 954e19c34d9..5a4fa530ce4 100644
--- a/chromium/ui/shell_dialogs/select_file_dialog_android.cc
+++ b/chromium/ui/shell_dialogs/select_file_dialog_android.cc
@@ -63,13 +63,16 @@ void SelectFileDialogImpl::OnMultipleFilesSelected(
jsize length = env->GetArrayLength(filepaths);
DCHECK(length == env->GetArrayLength(display_names));
for (int i = 0; i < length; ++i) {
- std::string path = ConvertJavaStringToUTF8(
+ ScopedJavaLocalRef<jstring> path_ref(
env, static_cast<jstring>(env->GetObjectArrayElement(filepaths, i)));
- std::string display_name = ConvertJavaStringToUTF8(
+ base::FilePath file_path =
+ base::FilePath(ConvertJavaStringToUTF8(env, path_ref));
+
+ ScopedJavaLocalRef<jstring> display_name_ref(
env,
static_cast<jstring>(env->GetObjectArrayElement(display_names, i)));
-
- base::FilePath file_path = base::FilePath(path);
+ std::string display_name =
+ ConvertJavaStringToUTF8(env, display_name_ref.obj());
ui::SelectedFileInfo file_info;
file_info.file_path = file_path;
diff --git a/chromium/ui/shell_dialogs/select_file_dialog_mac.mm b/chromium/ui/shell_dialogs/select_file_dialog_mac.mm
index e408e2158c9..cd747823e37 100644
--- a/chromium/ui/shell_dialogs/select_file_dialog_mac.mm
+++ b/chromium/ui/shell_dialogs/select_file_dialog_mac.mm
@@ -59,6 +59,7 @@ NSString* GetDescriptionFromExtension(const base::FilePath::StringType& ext) {
}
- (id)initWithSelectFileDialogImpl:(ui::SelectFileDialogImpl*)s;
+- (void)selectFileDialogImplWillBeDestroyed;
- (void)endedPanel:(NSSavePanel*)panel
didCancel:(bool)did_cancel
type:(ui::SelectFileDialog::Type)type
@@ -209,7 +210,7 @@ void SelectFileDialogImpl::SelectFileImpl(
[dialog setCanSelectHiddenExtension:YES];
}
} else {
- NSOpenPanel* open_dialog = (NSOpenPanel*)dialog;
+ NSOpenPanel* open_dialog = base::mac::ObjCCastStrict<NSOpenPanel>(dialog);
if (type == SELECT_OPEN_MULTI_FILE)
[open_dialog setAllowsMultipleSelection:YES];
@@ -235,13 +236,23 @@ void SelectFileDialogImpl::SelectFileImpl(
[dialog setDirectoryURL:[NSURL fileURLWithPath:default_dir]];
if (default_filename)
[dialog setNameFieldStringValue:default_filename];
+
+ // Ensure the bridge (rather than |this|) is retained by the block.
+ SelectFileDialogBridge* bridge = bridge_.get();
[dialog beginSheetModalForWindow:owning_window
completionHandler:^(NSInteger result) {
- [bridge_.get() endedPanel:dialog
- didCancel:result != NSFileHandlingPanelOKButton
- type:type
- parentWindow:owning_window];
- }];
+ [bridge endedPanel:dialog
+ didCancel:result != NSFileHandlingPanelOKButton
+ type:type
+ parentWindow:owning_window];
+
+ // Balance the setDelegate above. Note this should usually
+ // have been done already in FileWasSelected().
+ [dialog setDelegate:nil];
+
+ // Balance the retain at the start of SelectFileImpl().
+ [dialog release];
+ }];
}
SelectFileDialogImpl::DialogData::DialogData(
@@ -263,6 +274,12 @@ SelectFileDialogImpl::~SelectFileDialogImpl() {
for (const auto& panel : panels)
[panel cancel:panel];
+
+ // Running |cancel| on all the panels should have run all the completion
+ // handlers, but retaining references to C++ objects inside an NSObject can
+ // result in subtle problems. Ensure the reference to |this| is cleared.
+ DCHECK(dialog_data_map_.empty());
+ [bridge_ selectFileDialogImplWillBeDestroyed];
}
// static
@@ -384,10 +401,17 @@ SelectFileDialog* CreateSelectFileDialog(
return self;
}
+- (void)selectFileDialogImplWillBeDestroyed {
+ selectFileDialogImpl_ = nullptr;
+}
+
- (void)endedPanel:(NSSavePanel*)panel
didCancel:(bool)did_cancel
type:(ui::SelectFileDialog::Type)type
parentWindow:(NSWindow*)parentWindow {
+ if (!selectFileDialogImpl_)
+ return;
+
int index = 0;
std::vector<base::FilePath> paths;
if (!did_cancel) {
@@ -422,13 +446,24 @@ SelectFileDialog* CreateSelectFileDialog(
isMulti,
paths,
index);
- [panel release];
}
- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url {
return [url isFileURL];
}
+- (BOOL)panel:(id)sender validateURL:(NSURL*)url error:(NSError**)outError {
+ // Refuse to accept users closing the dialog with a key repeat, since the key
+ // may have been first pressed while the user was looking at insecure content.
+ // See https://crbug.com/637098.
+ if ([[NSApp currentEvent] type] == NSKeyDown &&
+ [[NSApp currentEvent] isARepeat]) {
+ return NO;
+ }
+
+ return YES;
+}
+
@end
@implementation ExtensionDropdownHandler
diff --git a/chromium/ui/shell_dialogs/select_file_dialog_mac_unittest.mm b/chromium/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
index a9ad635e1a1..732d331e1ac 100644
--- a/chromium/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
+++ b/chromium/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
@@ -13,6 +13,7 @@
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/shell_dialogs/select_file_policy.h"
#define EXPECT_EQ_BOOL(a, b) \
EXPECT_EQ(static_cast<bool>(a), static_cast<bool>(b))
@@ -305,9 +306,12 @@ TEST_F(SelectFileDialogMacTest, EmptyDescription) {
GetExtensionDescriptionList(popup);
EXPECT_EQ(3lu, extension_descriptions.size());
// Verify that the correct system description is produced for known file types
- // like pdf if no extension description is provided by the client.
- EXPECT_EQ(base::ASCIIToUTF16("Portable Document Format (PDF)"),
- extension_descriptions[0]);
+ // like pdf if no extension description is provided by the client. Search the
+ // string for "PDF" as the system may display:
+ // - Portable Document Format (PDF)
+ // - PDF document
+ EXPECT_NE(base::string16::npos,
+ extension_descriptions[0].find(base::ASCIIToUTF16("PDF")));
EXPECT_EQ(base::ASCIIToUTF16("Image"), extension_descriptions[1]);
// Verify the description for unknown file types if no extension description
// is provided by the client.
@@ -440,6 +444,8 @@ TEST_F(SelectFileDialogMacTest, DefaultPath) {
SelectFileWithParams(args);
NSSavePanel* panel = GetPanel();
+ [panel setExtensionHidden:NO];
+
EXPECT_EQ(args.default_path.DirName(),
base::mac::NSStringToFilePath([[panel directoryURL] path]));
EXPECT_EQ(args.default_path.BaseName(),
@@ -466,5 +472,34 @@ TEST_F(SelectFileDialogMacTest, MultipleExtension) {
EXPECT_FALSE([panel isExtensionHidden]);
}
+// Test to ensure lifetime is sound if a reference to the panel outlives the
+// delegate.
+TEST_F(SelectFileDialogMacTest, Lifetime) {
+ base::scoped_nsobject<NSSavePanel> panel;
+ @autoreleasepool {
+ auto args = GetDefaultArguments();
+ // Set a type (Save dialogs do not have a delegate).
+ args.type = SelectFileDialog::SELECT_OPEN_MULTI_FILE;
+ SelectFileWithParams(args);
+ panel.reset([GetPanel() retain]);
+
+ EXPECT_TRUE([panel isVisible]);
+ EXPECT_NE(nil, [panel delegate]);
+
+ // Newer versions of AppKit may clear out weak delegate pointers when
+ // dealloc is called on the delegate. Put a ref into the autorelease pool to
+ // simulate what happens on older versions.
+ [[[panel delegate] retain] autorelease];
+
+ ResetDialog();
+
+ // The SelectFileDialogImpl destructor invokes [panel cancel]. That should
+ // close the panel, and run the completion handler.
+ EXPECT_EQ(nil, [panel delegate]);
+ EXPECT_FALSE([panel isVisible]);
+ }
+ EXPECT_EQ(nil, [panel delegate]);
+}
+
} // namespace test
} // namespace ui
diff --git a/chromium/ui/snapshot/BUILD.gn b/chromium/ui/snapshot/BUILD.gn
index d48f92aaded..f2379880561 100644
--- a/chromium/ui/snapshot/BUILD.gn
+++ b/chromium/ui/snapshot/BUILD.gn
@@ -10,7 +10,6 @@ jumbo_component("snapshot") {
sources = [
"screenshot_grabber.cc",
"screenshot_grabber.h",
- "screenshot_grabber_observer.h",
"snapshot.cc",
"snapshot.h",
"snapshot_android.cc",
diff --git a/chromium/ui/snapshot/screenshot_grabber.cc b/chromium/ui/snapshot/screenshot_grabber.cc
index bd563946dac..6f0e6c1ce7d 100644
--- a/chromium/ui/snapshot/screenshot_grabber.cc
+++ b/chromium/ui/snapshot/screenshot_grabber.cc
@@ -9,8 +9,8 @@
#include <climits>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/callback.h"
-#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
@@ -18,10 +18,8 @@
#include "base/single_thread_task_runner.h"
#include "base/task_runner.h"
#include "base/task_scheduler/post_task.h"
-#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
-#include "ui/gfx/image/image.h"
#include "ui/snapshot/snapshot.h"
#if defined(USE_AURA)
@@ -36,80 +34,8 @@ namespace {
// more than 1000 to prevent the conflict of filenames.
const int kScreenshotMinimumIntervalInMS = 1000;
-using ShowNotificationCallback =
- base::Callback<void(ScreenshotGrabberObserver::Result screenshot_result,
- const base::FilePath& screenshot_path)>;
-
-void SaveScreenshot(scoped_refptr<base::TaskRunner> ui_task_runner,
- const ShowNotificationCallback& callback,
- const base::FilePath& screenshot_path,
- scoped_refptr<base::RefCountedMemory> png_data,
- ScreenshotGrabberDelegate::FileResult result,
- const base::FilePath& local_path) {
- DCHECK(!base::MessageLoopForUI::IsCurrent());
- DCHECK(!screenshot_path.empty());
-
- // Convert FileResult into ScreenshotGrabberObserver::Result.
- ScreenshotGrabberObserver::Result screenshot_result =
- ScreenshotGrabberObserver::SCREENSHOT_SUCCESS;
- switch (result) {
- case ScreenshotGrabberDelegate::FILE_SUCCESS:
- // Successfully got a local file to write to, write png data.
- DCHECK_GT(static_cast<int>(png_data->size()), 0);
- if (static_cast<size_t>(base::WriteFile(
- local_path, reinterpret_cast<const char*>(png_data->front()),
- static_cast<int>(png_data->size()))) != png_data->size()) {
- LOG(ERROR) << "Failed to save to " << local_path.value();
- screenshot_result =
- ScreenshotGrabberObserver::SCREENSHOT_WRITE_FILE_FAILED;
- }
- break;
- case ScreenshotGrabberDelegate::FILE_CHECK_DIR_FAILED:
- screenshot_result =
- ScreenshotGrabberObserver::SCREENSHOT_CHECK_DIR_FAILED;
- break;
- case ScreenshotGrabberDelegate::FILE_CREATE_DIR_FAILED:
- screenshot_result =
- ScreenshotGrabberObserver::SCREENSHOT_CREATE_DIR_FAILED;
- break;
- case ScreenshotGrabberDelegate::FILE_CREATE_FAILED:
- screenshot_result =
- ScreenshotGrabberObserver::SCREENSHOT_CREATE_FILE_FAILED;
- break;
- }
-
- // Report the result on the UI thread.
- ui_task_runner->PostTask(
- FROM_HERE, base::Bind(callback, screenshot_result, screenshot_path));
-}
-
-void EnsureLocalDirectoryExists(
- const base::FilePath& path,
- ScreenshotGrabberDelegate::FileCallback callback) {
- DCHECK(!base::MessageLoopForUI::IsCurrent());
- DCHECK(!path.empty());
-
- if (!base::CreateDirectory(path.DirName())) {
- LOG(ERROR) << "Failed to ensure the existence of "
- << path.DirName().value();
- callback.Run(ScreenshotGrabberDelegate::FILE_CREATE_DIR_FAILED, path);
- return;
- }
-
- callback.Run(ScreenshotGrabberDelegate::FILE_SUCCESS, path);
-}
-
} // namespace
-void ScreenshotGrabberDelegate::PrepareFileAndRunOnBlockingPool(
- const base::FilePath& path,
- const FileCallback& callback_on_blocking_pool) {
- base::PostTaskWithTraits(
- FROM_HERE,
- {base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
- base::Bind(EnsureLocalDirectoryExists, path, callback_on_blocking_pool));
-}
-
#if defined(USE_AURA)
class ScreenshotGrabber::ScopedCursorHider {
public:
@@ -139,15 +65,14 @@ class ScreenshotGrabber::ScopedCursorHider {
};
#endif
-ScreenshotGrabber::ScreenshotGrabber(ScreenshotGrabberDelegate* client)
- : client_(client), factory_(this) {}
+ScreenshotGrabber::ScreenshotGrabber() : factory_(this) {}
ScreenshotGrabber::~ScreenshotGrabber() {
}
void ScreenshotGrabber::TakeScreenshot(gfx::NativeWindow window,
const gfx::Rect& rect,
- const base::FilePath& screenshot_path) {
+ ScreenshotCallback callback) {
DCHECK(base::MessageLoopForUI::IsCurrent());
last_screenshot_timestamp_ = base::TimeTicks::Now();
@@ -166,8 +91,8 @@ void ScreenshotGrabber::TakeScreenshot(gfx::NativeWindow window,
ui::GrabWindowSnapshotAsyncPNG(
window, rect,
base::Bind(&ScreenshotGrabber::GrabWindowSnapshotAsyncCallback,
- factory_.GetWeakPtr(), window_identifier, screenshot_path,
- is_partial));
+ factory_.GetWeakPtr(), window_identifier, is_partial,
+ base::Passed(&callback)));
}
bool ScreenshotGrabber::CanTakeScreenshot() {
@@ -176,58 +101,32 @@ bool ScreenshotGrabber::CanTakeScreenshot() {
base::TimeDelta::FromMilliseconds(kScreenshotMinimumIntervalInMS);
}
-void ScreenshotGrabber::NotifyScreenshotCompleted(
- ScreenshotGrabberObserver::Result screenshot_result,
- const base::FilePath& screenshot_path) {
- DCHECK(base::MessageLoopForUI::IsCurrent());
-#if defined(USE_AURA)
- cursor_hider_.reset();
-#endif
- for (ScreenshotGrabberObserver& observer : observers_)
- observer.OnScreenshotCompleted(screenshot_result, screenshot_path);
-}
-
-void ScreenshotGrabber::AddObserver(ScreenshotGrabberObserver* observer) {
- observers_.AddObserver(observer);
-}
-
-void ScreenshotGrabber::RemoveObserver(ScreenshotGrabberObserver* observer) {
- observers_.RemoveObserver(observer);
-}
-
-bool ScreenshotGrabber::HasObserver(
- const ScreenshotGrabberObserver* observer) const {
- return observers_.HasObserver(observer);
-}
-
void ScreenshotGrabber::GrabWindowSnapshotAsyncCallback(
const std::string& window_identifier,
- base::FilePath screenshot_path,
bool is_partial,
+ ScreenshotCallback callback,
scoped_refptr<base::RefCountedMemory> png_data) {
DCHECK(base::MessageLoopForUI::IsCurrent());
+
+#if defined(USE_AURA)
+ cursor_hider_.reset();
+#endif
+
if (!png_data.get()) {
if (is_partial) {
LOG(ERROR) << "Failed to grab the window screenshot";
- NotifyScreenshotCompleted(
- ScreenshotGrabberObserver::SCREENSHOT_GRABWINDOW_PARTIAL_FAILED,
- screenshot_path);
+ std::move(callback).Run(ScreenshotResult::GRABWINDOW_PARTIAL_FAILED,
+ nullptr);
} else {
LOG(ERROR) << "Failed to grab the window screenshot for "
<< window_identifier;
- NotifyScreenshotCompleted(
- ScreenshotGrabberObserver::SCREENSHOT_GRABWINDOW_FULL_FAILED,
- screenshot_path);
+ std::move(callback).Run(ScreenshotResult::GRABWINDOW_FULL_FAILED,
+ nullptr);
}
return;
}
- ShowNotificationCallback notification_callback(base::Bind(
- &ScreenshotGrabber::NotifyScreenshotCompleted, factory_.GetWeakPtr()));
- client_->PrepareFileAndRunOnBlockingPool(
- screenshot_path,
- base::Bind(&SaveScreenshot, base::ThreadTaskRunnerHandle::Get(),
- notification_callback, screenshot_path, png_data));
+ std::move(callback).Run(ScreenshotResult::SUCCESS, std::move(png_data));
}
} // namespace ui
diff --git a/chromium/ui/snapshot/screenshot_grabber.h b/chromium/ui/snapshot/screenshot_grabber.h
index 8cf7723d47d..d942d1018de 100644
--- a/chromium/ui/snapshot/screenshot_grabber.h
+++ b/chromium/ui/snapshot/screenshot_grabber.h
@@ -14,61 +14,44 @@
#include "base/macros.h"
#include "base/memory/ref_counted_memory.h"
#include "base/memory/weak_ptr.h"
-#include "base/observer_list.h"
#include "base/time/time.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/native_widget_types.h"
-#include "ui/snapshot/screenshot_grabber_observer.h"
#include "ui/snapshot/snapshot_export.h"
namespace ui {
-// TODO(flackr): Componentize google drive so that we don't need the
-// ScreenshotGrabberDelegate.
-class SNAPSHOT_EXPORT ScreenshotGrabberDelegate {
- public:
- enum FileResult {
- FILE_SUCCESS,
- FILE_CHECK_DIR_FAILED,
- FILE_CREATE_DIR_FAILED,
- FILE_CREATE_FAILED
- };
-
- // Callback called with the |result| of trying to create a local writable
- // |path| for the possibly remote path.
- using FileCallback =
- base::Callback<void(FileResult result, const base::FilePath& path)>;
-
- ScreenshotGrabberDelegate() {}
- virtual ~ScreenshotGrabberDelegate() {}
-
- // Prepares a writable file for |path|. If |path| is a non-local path (i.e.
- // Google drive) and it is supported this will create a local cached copy of
- // the remote file and call the callback with the local path.
- virtual void PrepareFileAndRunOnBlockingPool(
- const base::FilePath& path,
- const FileCallback& callback_on_blocking_pool);
+// Result of the entire screenshotting attempt. This enum is fat for various
+// file operations which could happen in the chrome layer.
+enum class ScreenshotResult {
+ SUCCESS,
+ GRABWINDOW_PARTIAL_FAILED,
+ GRABWINDOW_FULL_FAILED,
+ CREATE_DIR_FAILED,
+ GET_DIR_FAILED,
+ CHECK_DIR_FAILED,
+ CREATE_FILE_FAILED,
+ WRITE_FILE_FAILED,
+ DISABLED
};
class SNAPSHOT_EXPORT ScreenshotGrabber {
public:
- explicit ScreenshotGrabber(ScreenshotGrabberDelegate* client);
+ ScreenshotGrabber();
~ScreenshotGrabber();
+ // Callback for the new system, which ignores the observer crud.
+ using ScreenshotCallback =
+ base::OnceCallback<void(ui::ScreenshotResult screenshot_result,
+ scoped_refptr<base::RefCountedMemory> png_data)>;
+
// Takes a screenshot of |rect| in |window| in that window's coordinate space
- // saving the result to |screenshot_path|.
+ // and return it to |callback|.
void TakeScreenshot(gfx::NativeWindow window,
const gfx::Rect& rect,
- const base::FilePath& screenshot_path);
- bool CanTakeScreenshot();
+ ScreenshotCallback callback);
- void NotifyScreenshotCompleted(
- ScreenshotGrabberObserver::Result screenshot_result,
- const base::FilePath& screenshot_path);
-
- void AddObserver(ScreenshotGrabberObserver* observer);
- void RemoveObserver(ScreenshotGrabberObserver* observer);
- bool HasObserver(const ScreenshotGrabberObserver* observer) const;
+ bool CanTakeScreenshot();
private:
#if defined(USE_AURA)
@@ -77,13 +60,10 @@ class SNAPSHOT_EXPORT ScreenshotGrabber {
void GrabWindowSnapshotAsyncCallback(
const std::string& window_identifier,
- base::FilePath screenshot_path,
bool is_partial,
+ ScreenshotCallback callback,
scoped_refptr<base::RefCountedMemory> png_data);
- // A weak pointer to the screenshot taker client.
- ScreenshotGrabberDelegate* client_;
-
// The timestamp when the screenshot task was issued last time.
base::TimeTicks last_screenshot_timestamp_;
@@ -92,7 +72,6 @@ class SNAPSHOT_EXPORT ScreenshotGrabber {
std::unique_ptr<ScopedCursorHider> cursor_hider_;
#endif
- base::ObserverList<ScreenshotGrabberObserver> observers_;
base::WeakPtrFactory<ScreenshotGrabber> factory_;
DISALLOW_COPY_AND_ASSIGN(ScreenshotGrabber);
diff --git a/chromium/ui/snapshot/screenshot_grabber_observer.h b/chromium/ui/snapshot/screenshot_grabber_observer.h
deleted file mode 100644
index 4d90306bb79..00000000000
--- a/chromium/ui/snapshot/screenshot_grabber_observer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_SNAPSHOT_SCREENSHOT_GRABBER_OBSERVER_H_
-#define UI_SNAPSHOT_SCREENSHOT_GRABBER_OBSERVER_H_
-
-#include "base/files/file_path.h"
-#include "ui/snapshot/snapshot_export.h"
-
-namespace ui {
-
-class SNAPSHOT_EXPORT ScreenshotGrabberObserver {
- public:
- enum Result {
- SCREENSHOT_SUCCESS = 0,
- SCREENSHOT_GRABWINDOW_PARTIAL_FAILED,
- SCREENSHOT_GRABWINDOW_FULL_FAILED,
- SCREENSHOT_CREATE_DIR_FAILED,
- SCREENSHOT_GET_DIR_FAILED,
- SCREENSHOT_CHECK_DIR_FAILED,
- SCREENSHOT_CREATE_FILE_FAILED,
- SCREENSHOT_WRITE_FILE_FAILED,
- SCREENSHOTS_DISABLED,
- SCREENSHOT_RESULT_COUNT
- };
-
- // Dispatched after attempting to take a screenshot with the |result| and
- // |screenshot_path| of the taken screenshot (if successful).
- virtual void OnScreenshotCompleted(Result screenshot_result,
- const base::FilePath& screenshot_path) = 0;
-
- protected:
- virtual ~ScreenshotGrabberObserver() {}
-};
-
-} // namespace ui
-
-#endif // UI_SNAPSHOT_SCREENSHOT_GRABBER_OBSERVER_H_
diff --git a/chromium/ui/snapshot/snapshot.cc b/chromium/ui/snapshot/snapshot.cc
index 756f65dabf8..0c26ef287fb 100644
--- a/chromium/ui/snapshot/snapshot.cc
+++ b/chromium/ui/snapshot/snapshot.cc
@@ -21,6 +21,8 @@ namespace {
scoped_refptr<base::RefCountedMemory> EncodeImageAsPNG(
const gfx::Image& image) {
+ if (image.IsEmpty())
+ return nullptr;
std::vector<uint8_t> result;
DCHECK(!image.AsImageSkia().GetRepresentation(1.0f).is_null());
gfx::PNGCodec::FastEncodeBGRASkBitmap(image.AsBitmap(), true, &result);
diff --git a/chromium/ui/snapshot/snapshot_android.cc b/chromium/ui/snapshot/snapshot_android.cc
index 8151090a11d..dbf0a8903ac 100644
--- a/chromium/ui/snapshot/snapshot_android.cc
+++ b/chromium/ui/snapshot/snapshot_android.cc
@@ -38,6 +38,11 @@ static void MakeAsyncCopyRequest(
gfx::NativeWindow window,
const gfx::Rect& source_rect,
viz::CopyOutputRequest::CopyOutputRequestCallback callback) {
+ if (!window->GetCompositor()) {
+ std::move(callback).Run(std::make_unique<viz::CopyOutputResult>(
+ viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP, gfx::Rect()));
+ return;
+ }
std::unique_ptr<viz::CopyOutputRequest> request =
std::make_unique<viz::CopyOutputRequest>(
viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
diff --git a/chromium/ui/strings/translations/ui_strings_am.xtb b/chromium/ui/strings/translations/ui_strings_am.xtb
index 8bfaec53c6d..1927ae2550e 100644
--- a/chromium/ui/strings/translations/ui_strings_am.xtb
+++ b/chromium/ui/strings/translations/ui_strings_am.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">ስቀል</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">የሚመከሩ መተግበሪያዎች</translation>
+<translation id="1368832886055348810">ከግራ ወደ ቀኝ</translation>
<translation id="1398853756734560583">አስፋ</translation>
<translation id="1413622004203049571">ከ<ph name="NOTIFIER_NAME" /> የሚመጡ ማሳወቂያዎችን አሰናክል</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 ደቂቃ እና }one{# ደቂቃዎች እና }other{# ደቂቃዎች እና }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">የኮከብ ደረጃ <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 ሰዓት እና }one{# ሰዓቶች እና }other{# ሰዓቶች እና }}</translation>
<translation id="1842960171412779397">ምረጥ</translation>
+<translation id="1859234291848436338">የአፃፃፍ አቅጣጫ</translation>
<translation id="1860796786778352021">ማሳወቂያ ዝጋ</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">ወደላይ አንቀሳቅስ</translation>
<translation id="2190355936436201913">(ባዶ)</translation>
<translation id="219905428774326614">ማስጀመሪያ፣ ሁሉም መተግበሪያዎች</translation>
+<translation id="2267918077332197517">ከዚህ ጣቢያ የሚመጡ ሁሉንም ማሳወቂያዎች አግድ</translation>
<translation id="2289052229480071835">በማያ ገጽዎ ላይ ያሉት የንክኪ ዒላማዎችን መታ ያድርጉ።</translation>
<translation id="2295140143284145483">የዳሰሳ ጥናት</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> ቴባ/ሰ</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">ወደ እዚህ ሸብልል</translation>
<translation id="3234408098842461169">ዝቅዝቅ ቀስት</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 ቀን}one{# ቀኖች}other{# ቀኖች}}</translation>
+<translation id="335581015389089642">ንግግር</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 ቀን ቀርቷል}one{# ቀኖች ቀርቷል}other{# ቀኖች ቀርተዋል}}</translation>
+<translation id="3618849550573277856">«<ph name="LOOKUP_STRING" />»ን ፈልግ</translation>
<translation id="364720409959344976">የሚሰቀል ዓቃፊ ይምረጡ</translation>
<translation id="3660179305079774227">የላይ ቀስት</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> ጊባ/ሰ</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">ዝለል</translation>
<translation id="4250229828105606438">ቅጽበታዊ ገጽ እይታ</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{ከ1 ወር በፊት}one{ከ# ወሮች በፊት}other{ከ# ወሮች በፊት}}</translation>
+<translation id="4289300219472526559">መናገር ይጀምሩ</translation>
<translation id="4316910396681052118">ሁሉም መተግበሪያዎች</translation>
-<translation id="4320177379694898372">ምንም የበይነመረብ ግንኙነት የለም</translation>
<translation id="4588090240171750605">ወደ ቀኝ ሸብልል</translation>
<translation id="4724120544754982507">የማሳወቂያ ማዕከል፣ <ph name="UNREAD_NOTIFICATION_COUNT" /> ያልተነበቡ ማሳወቂያዎች</translation>
<translation id="4730374152663651037">በብዛት ጥቅም ላይ የዋለ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">የመተግበሪያ አስተያየት ጥቆማዎች</translation>
<translation id="6364916375976753737">ወደ ግራ ሸብልል</translation>
<translation id="6394627529324717982">ኮማ</translation>
+<translation id="6397363302884558537">መናገር አቁም</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 ሰከንድ በፊት}one{# ሰከንዶች በፊት}other{# ሰከንዶች በፊት}}</translation>
+<translation id="6430678249303439055">ከዚህ መተግበሪያ የሚመጡ ሁሉንም ማሳወቂያዎች አግድ</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{ከ1 ሰከንድ በፊት}one{ከ# ሰከንዶች በፊት}other{ከ# ሰከንዶች በፊት}}</translation>
<translation id="654149438358937226">ሁሉንም ማሳወቂያዎች አግድ</translation>
<translation id="6567071839949112727">ዘር ማንዘርን ጠቅ አድርግ</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 ዓመት ቀርቷል}one{# ዓመቶች ቀርተዋል}other{# ዓመቶች ቀርተዋል}}</translation>
<translation id="6945221475159498467">ይምረጡ</translation>
<translation id="6965382102122355670">እሺ</translation>
+<translation id="6974053822202609517">ከቀኝ ወደ ግራ</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">የመሆን ዕድላቸው ከፍ ያለ ነው</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">የግራ ጠርዝ</translation>
<translation id="8331626408530291785">ወደ ላይ ሸብልል</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 አመት}one{# ዓመቶች}other{# ዓመቶች}}</translation>
-<translation id="8371695176452482769">አሁን ይናገሩ</translation>
<translation id="838869780401515933">አመልክት</translation>
<translation id="8393700583063109961">መልዕክት ይላኩ</translation>
<translation id="8394908167088220973">ሚዲያ አጫውት/ለአፍታ አቁም</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> ተጨማሪ</translation>
<translation id="8730621377337864115">ተከናውኗል</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1ሰ}one{#ሰ}other{#ሰ}}</translation>
+<translation id="8798099450830957504">እንደወረደ</translation>
<translation id="8806053966018712535">አቃፊ <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">ምስልን አብራራ</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> ኪባ</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_ar.xtb b/chromium/ui/strings/translations/ui_strings_ar.xtb
index 234c1badbeb..228d5cd924a 100644
--- a/chromium/ui/strings/translations/ui_strings_ar.xtb
+++ b/chromium/ui/strings/translations/ui_strings_ar.xtb
@@ -8,8 +8,9 @@
<translation id="1243314992276662751">تحميل</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">تطبيقات مقترحة</translation>
+<translation id="1368832886055348810">من اليسار لليمين</translation>
<translation id="1398853756734560583">تكبير</translation>
-<translation id="1413622004203049571">تعطيل الإشعارات من <ph name="NOTIFIER_NAME" /></translation>
+<translation id="1413622004203049571">إيقاف الإشعارات من <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{دقيقة واحدة و }zero{# من الدقائق و }two{دقيقتان (#) و }few{# دقائق و }many{# دقيقة و }other{# من الدقائق و }}</translation>
<translation id="1643823602425662293">الإشعار</translation>
<translation id="1710340000377843106">الآن</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">تقييم بالنجوم <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{ساعة واحدة و }zero{# من الساعات و }two{ساعتان (#) و }few{# ساعات و }many{# ساعة و }other{# من الساعات و }}</translation>
<translation id="1842960171412779397">الاختيار</translation>
+<translation id="1859234291848436338">اتجاه الكتابة</translation>
<translation id="1860796786778352021">إغلاق الإشعار</translation>
<translation id="1871244248791675517">‏مفتاح Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">صفحة إلى أعلى</translation>
<translation id="2190355936436201913">(فارغ)</translation>
<translation id="219905428774326614">‏Launcher، جميع التطبيقات</translation>
+<translation id="2267918077332197517">حظر جميع الإشعارات الواردة من هذا الموقع</translation>
<translation id="2289052229480071835">انقر على أهداف اللمس على شاشتك.</translation>
<translation id="2295140143284145483">الاستطلاع</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> تيرابايت/ثانية</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">التمرير إلى هنا</translation>
<translation id="3234408098842461169">مفتاح سهم إلى أسفل</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{يوم واحد}zero{# من الأيام}two{يومان (#)}few{# أيام}many{# يومًا}other{# من الأيام}}</translation>
+<translation id="335581015389089642">الحديث</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{يتبقى يوم واحد}zero{يتبقى عدد # من الأيام}two{يتبقى يومان (#)}few{يتبقى # أيام}many{يتبقى # يومًا}other{يتبقى # من الأيام}}</translation>
+<translation id="3618849550573277856">البحث عن "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">حدد مجلدًا للتحميل</translation>
<translation id="3660179305079774227">مفتاح سهم إلى أعلى</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> غيغابايت/ثانية</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">الدخول</translation>
<translation id="4250229828105606438">لقطة شاشة</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{قبل شهر واحد}zero{قبل # شهر}two{قبل شهرين (#)}few{قبل # أشهر}many{قبل # شهرًا}other{قبل # شهر}}</translation>
+<translation id="4289300219472526559">بدء التحدث</translation>
<translation id="4316910396681052118">جميع التطبيقات</translation>
-<translation id="4320177379694898372">لا يتوفر اتصال بالإنترنت</translation>
<translation id="4588090240171750605">التمرير إلى اليسار</translation>
<translation id="4724120544754982507">مركز الإشعارات، <ph name="UNREAD_NOTIFICATION_COUNT" /> من الإشعارات غير المقروءة</translation>
<translation id="4730374152663651037">التطبيقات المستخدمة بشكل متكرر</translation>
@@ -93,7 +98,7 @@
<translation id="6012623610530968780">صفحة <ph name="SELECTED_PAGE" /> من <ph name="TOTAL_PAGE_NUM" /></translation>
<translation id="6022924867608035986">محو نص مربع البحث</translation>
<translation id="6040143037577758943">إغلاق</translation>
-<translation id="6119846243427417423">تنشيط</translation>
+<translation id="6119846243427417423">تفعيل</translation>
<translation id="6129953537138746214">مسافة</translation>
<translation id="6135826906199951471">‏مفتاح Del (حذف)</translation>
<translation id="6142413573757616983"><ph name="QUANTITY" /> بايت/ثانية</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">اقتراحات التطبيقات</translation>
<translation id="6364916375976753737">التمرير إلى اليمين</translation>
<translation id="6394627529324717982">فاصلة</translation>
+<translation id="6397363302884558537">إيقاف التحدث</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{قبل ثانية واحدة}zero{ قبل # من الثواني}two{ قبل ثانيتين (#)}few{قبل # ثوانٍ}many{قبل # ثانية}other{قبل # من الثواني}}</translation>
+<translation id="6430678249303439055">حظر جميع الإشعارات الواردة من هذا التطبيق</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{قبل ثانية واحدة}zero{قبل # ثانية}two{قبل ثانيتين (#)}few{قبل # ثوانٍ}many{قبل # ثانية}other{قبل # ثانية}}</translation>
<translation id="654149438358937226">حظر جميع الإشعارات</translation>
<translation id="6567071839949112727">النقر على العنصر الأصل</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{تتبقى سنة واحدة}zero{تتبقى # سنة}two{تتبقى سنتين (#)}few{تتبقى # سنوات}many{تتبقى # سنةً}other{تتبقى # سنة}}</translation>
<translation id="6945221475159498467">تحديد</translation>
<translation id="6965382102122355670">موافق</translation>
+<translation id="6974053822202609517">من اليمين لليسار</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">التطبيقات التي يرجح النقر عليها</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">الحافة اليمنى</translation>
<translation id="8331626408530291785">التمرير إلى أعلى</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{سنة واحدة}zero{# سنة}two{سنتان (#)}few{# سنوات}many{# سنةً}other{# سنة}}</translation>
-<translation id="8371695176452482769">تحدث الآن</translation>
<translation id="838869780401515933">الاختيار</translation>
<translation id="8393700583063109961">إرسال رسالة</translation>
<translation id="8394908167088220973">تشغيل/إيقاف الوسائط</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204"><ph name="NUMBER" />+ أخرى</translation>
<translation id="8730621377337864115">تم</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{ساعة واحدة}zero{# ساعة}two{ساعتان (#)}few{# ساعات}many{# ساعةً}other{# ساعة}}</translation>
+<translation id="8798099450830957504">التلقائي</translation>
<translation id="8806053966018712535">مجلد <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">إضافة تعليق توضيحي على الصورة</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> كيلوبايت</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_bg.xtb b/chromium/ui/strings/translations/ui_strings_bg.xtb
index 3c8d551c6ca..bab7796969d 100644
--- a/chromium/ui/strings/translations/ui_strings_bg.xtb
+++ b/chromium/ui/strings/translations/ui_strings_bg.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Качване</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ПРЕПОРЪЧАНИ ПРИЛОЖЕНИЯ</translation>
+<translation id="1368832886055348810">Отляво надясно</translation>
<translation id="1398853756734560583">Увеличаване</translation>
<translation id="1413622004203049571">Деактивиране на известията от <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 минута и }other{# минути и }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Оценка със звезди: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 час и }other{# часа и }}</translation>
<translation id="1842960171412779397">Избиране</translation>
+<translation id="1859234291848436338">Посока на писане</translation>
<translation id="1860796786778352021">Затваряне на известието</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Страница нагоре</translation>
<translation id="2190355936436201913">(празно)</translation>
<translation id="219905428774326614">Стартов панел, всички приложения</translation>
+<translation id="2267918077332197517">Блокиране на всички известия от този сайт</translation>
<translation id="2289052229480071835">Докоснете съответните цели на екрана.</translation>
<translation id="2295140143284145483">Анкета</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> ТБ/сек</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Превъртане до тук</translation>
<translation id="3234408098842461169">Стрелка надолу</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 ден}other{# дни}}</translation>
+<translation id="335581015389089642">Speech</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Остава 1 ден}other{Остават # дни}}</translation>
+<translation id="3618849550573277856">Търсене на „<ph name="LOOKUP_STRING" />“</translation>
<translation id="364720409959344976">Избиране на папка за качване</translation>
<translation id="3660179305079774227">Стрелка нагоре</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> ГБ/сек</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">преминаване</translation>
<translation id="4250229828105606438">Eкранна снимка</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Преди 1 месец}other{Преди # месеца}}</translation>
+<translation id="4289300219472526559">Start Speaking</translation>
<translation id="4316910396681052118">ВСИЧКИ ПРИЛОЖЕНИЯ</translation>
-<translation id="4320177379694898372">Няма връзка с интернет</translation>
<translation id="4588090240171750605">Превъртане надясно</translation>
<translation id="4724120544754982507">Център за известия, <ph name="UNREAD_NOTIFICATION_COUNT" /> непрочетени</translation>
<translation id="4730374152663651037">ЧЕСТО ИЗПОЛЗВАНИ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ПРЕДЛОЖЕНИЯ ЗА ПРИЛОЖЕНИЯ</translation>
<translation id="6364916375976753737">Превъртане наляво</translation>
<translation id="6394627529324717982">Запетая</translation>
+<translation id="6397363302884558537">Stop Speaking</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Преди 1 сек}other{Преди # сек}}</translation>
+<translation id="6430678249303439055">Блокиране на всички известия от това приложение</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Преди 1 секунда}other{Преди # секунди}}</translation>
<translation id="654149438358937226">Блокиране на всички известия</translation>
<translation id="6567071839949112727">кликване върху елемента предшественик</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Остава 1 година}other{Остават # години}}</translation>
<translation id="6945221475159498467">Изберете</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Отдясно наляво</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">НАЙ-ВЕРОЯТЕН ИЗБОР</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Ляв край</translation>
<translation id="8331626408530291785">Превъртане нагоре</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 година}other{# години}}</translation>
-<translation id="8371695176452482769">Говорете сега</translation>
<translation id="838869780401515933">отмятане</translation>
<translation id="8393700583063109961">Изпратете съобщение</translation>
<translation id="8394908167088220973">Мултимедия, пускане/пауза</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+ още <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Готово</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 ч}other{# ч}}</translation>
+<translation id="8798099450830957504">По подразбиране</translation>
<translation id="8806053966018712535">Папка „<ph name="FOLDER_NAME" />“</translation>
<translation id="883911313571074303">Добавяне на пояснение към изображението</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KБ</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_bn.xtb b/chromium/ui/strings/translations/ui_strings_bn.xtb
index 2b0e65c5b70..b9f1648d1fe 100644
--- a/chromium/ui/strings/translations/ui_strings_bn.xtb
+++ b/chromium/ui/strings/translations/ui_strings_bn.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">আপলোড</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">প্রস্তাবিত অ্যাপ</translation>
+<translation id="1368832886055348810">বাঁ থেকে ডান</translation>
<translation id="1398853756734560583">বড় করুন</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> এর থেকে বিজ্ঞপ্তিগুলি অক্ষম করুন</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{১ মিনিট এবং }one{# মিনিট এবং }other{# মিনিট এবং }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144"><ph name="RATING_SCORE" /> তারা রেটিং দিন</translation>
<translation id="1830179671306812954">{HOURS,plural, =1{১ ঘণ্টা এবং }one{# ঘণ্টা এবং }other{# ঘণ্টা এবং }}</translation>
<translation id="1842960171412779397">বেছে নিন</translation>
+<translation id="1859234291848436338">লিখন নির্দেশনা</translation>
<translation id="1860796786778352021">বিজ্ঞপ্তি বন্ধ করা হয়েছে</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">পৃষ্ঠা নিচে</translation>
<translation id="2190355936436201913">(খালি)</translation>
<translation id="219905428774326614">লঞ্চার, সমস্ত অ্যাপ</translation>
+<translation id="2267918077332197517">এই সাইটের সমস্ত বিজ্ঞপ্তি ব্লক করুন</translation>
<translation id="2289052229480071835">আপনার স্ক্রীনে স্পর্শ লক্ষ্যগুলি আলতা চাপুন।</translation>
<translation id="2295140143284145483">সমীক্ষা</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">এখান পর্যন্ত স্ক্রোল করুন</translation>
<translation id="3234408098842461169">Down Arrow</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{১ দিন}one{# দিন}other{# দিন}}</translation>
+<translation id="335581015389089642">স্পিচ</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{১ দিন বাকি}one{# দিন বাকি}other{# দিন বাকি}}</translation>
+<translation id="3618849550573277856">“<ph name="LOOKUP_STRING" />” খুঁজে দেখুন</translation>
<translation id="364720409959344976">আপলোড করার জন্য ফোল্ডার বেছে নিন</translation>
<translation id="3660179305079774227">Up Arrow</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">লাফ দিন</translation>
<translation id="4250229828105606438">স্ক্রীনশট</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{১ মাস আগে}one{# মাস আগে}other{# মাস আগে}}</translation>
+<translation id="4289300219472526559">কথা বলা শুরু করুন</translation>
<translation id="4316910396681052118">সব অ্যাপ</translation>
-<translation id="4320177379694898372">কোনো ইন্টারনেট সংযোগ নেই</translation>
<translation id="4588090240171750605">ডান দিকে স্ক্রোল করুন</translation>
<translation id="4724120544754982507">বিজ্ঞপ্তি কেন্দ্র, <ph name="UNREAD_NOTIFICATION_COUNT" />টি না পড়া বিজ্ঞপ্তি</translation>
<translation id="4730374152663651037">ঘন ঘন ব্যবহার করা হয়</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">অ্যাপের প্রস্তাবনা</translation>
<translation id="6364916375976753737">বাঁ দিকে স্ক্রোল করুন</translation>
<translation id="6394627529324717982">কমা</translation>
+<translation id="6397363302884558537">কথা বলা বন্ধ করুন</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{১ সেকেন্ড পূর্বে}one{# সেকেন্ড পূর্বে}other{# সেকেন্ড পূর্বে}}</translation>
+<translation id="6430678249303439055">এই অ্যাপ থেকে সমস্ত বিজ্ঞপ্তি ব্লক করুন</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{১ সেকেন্ড আগে}one{# সেকেন্ড আগে}other{# সেকেন্ড আগে}}</translation>
<translation id="654149438358937226">সমস্ত বিজ্ঞপ্তি ব্লক করুন</translation>
<translation id="6567071839949112727">এটি সম্পর্কিত একটি পুরানো আইটেমে ক্লিক করুন</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{১ বছর বাকি}one{# বছর বাকি}other{# বছর বাকি}}</translation>
<translation id="6945221475159498467">নির্বাচন</translation>
<translation id="6965382102122355670">ঠিক আছে</translation>
+<translation id="6974053822202609517">ডান থেকে বামে</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">সবথেকে বেশি সম্ভাবনা</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">বাঁ প্রান্ত</translation>
<translation id="8331626408530291785">উপরে স্ক্রোল করুন</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 বছর}one{# বছর}other{# বছর}}</translation>
-<translation id="8371695176452482769">এখনই বলুন</translation>
<translation id="838869780401515933">চেক করুন</translation>
<translation id="8393700583063109961">বার্তা পাঠান</translation>
<translation id="8394908167088220973">মিডিয়া প্লে করুন/বিরতি</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">আরও <ph name="NUMBER" />টি</translation>
<translation id="8730621377337864115">হয়ে গেছে</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{১ ঘণ্টা}one{# ঘণ্টা}other{# ঘণ্টা}}</translation>
+<translation id="8798099450830957504">ডিফল্ট</translation>
<translation id="8806053966018712535"><ph name="FOLDER_NAME" /> ফোল্ডার</translation>
<translation id="883911313571074303">চিত্রের জন্য টিকা লিখুন</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_ca.xtb b/chromium/ui/strings/translations/ui_strings_ca.xtb
index 41256e7f56a..b9815bdaf59 100644
--- a/chromium/ui/strings/translations/ui_strings_ca.xtb
+++ b/chromium/ui/strings/translations/ui_strings_ca.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Penja</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">APLICACIONS RECOMANADES</translation>
+<translation id="1368832886055348810">D'esquerra a dreta</translation>
<translation id="1398853756734560583">Maximitza</translation>
<translation id="1413622004203049571">Desactiva les notificacions de <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minut i }other{# minuts i }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Puntuació en estrelles: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 hora i }other{# hores i }}</translation>
<translation id="1842960171412779397">selecciona</translation>
+<translation id="1859234291848436338">Direcció de l'escriptura</translation>
<translation id="1860796786778352021">Tanca la notificació</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Re Pàg</translation>
<translation id="2190355936436201913">(buit)</translation>
<translation id="219905428774326614">Menú d'aplicacions, totes les aplicacions</translation>
+<translation id="2267918077332197517">Bloqueja totes les notificacions d'aquest lloc web</translation>
<translation id="2289052229480071835">Toca els elements tàctils a la pantalla.</translation>
<translation id="2295140143284145483">Enquesta</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Desplaçament fins aquí</translation>
<translation id="3234408098842461169">Fletxa avall</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 dia}other{# dies}}</translation>
+<translation id="335581015389089642">Veu</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 dia restant}other{# dies restants}}</translation>
+<translation id="3618849550573277856">Cerca "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Selecció d'una carpeta per penjar</translation>
<translation id="3660179305079774227">Fletxa amunt</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">salta</translation>
<translation id="4250229828105606438">Captura de pantalla</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Fa 1 mes}other{Fa # mesos}}</translation>
+<translation id="4289300219472526559">Comença a parlar</translation>
<translation id="4316910396681052118">TOTES LES APLICACIONS</translation>
-<translation id="4320177379694898372">No hi ha connexió a Internet</translation>
<translation id="4588090240171750605">Desplaçament a la dreta</translation>
<translation id="4724120544754982507">Centre de notificacions, <ph name="UNREAD_NOTIFICATION_COUNT" /> notificacions no llegides</translation>
<translation id="4730374152663651037">UTILITZADES FREQÜENTMENT</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SUGGERIMENTS D'APLICACIONS</translation>
<translation id="6364916375976753737">Desplaçament a l'esquerra</translation>
<translation id="6394627529324717982">Coma</translation>
+<translation id="6397363302884558537">Deixa de parlar</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{fa 1 s}other{fa # s}}</translation>
+<translation id="6430678249303439055">Bloqueja totes les notificacions d'aquesta aplicació</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Fa 1 segon}other{Fa # segons}}</translation>
<translation id="654149438358937226">Bloqueja totes les notificacions</translation>
<translation id="6567071839949112727">fes clic a l'antecedent</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{D'aquí a 1 any}other{D'aquí a # anys}}</translation>
<translation id="6945221475159498467">Selecciona</translation>
<translation id="6965382102122355670">D'acord</translation>
+<translation id="6974053822202609517">De dreta a esquerra</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">LES MÉS PROBABLES</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Extrem esquerre</translation>
<translation id="8331626408530291785">Desplaçament amunt</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 any}other{# anys}}</translation>
-<translation id="8371695176452482769">Parla ara</translation>
<translation id="838869780401515933">marca</translation>
<translation id="8393700583063109961">Envia el missatge</translation>
<translation id="8394908167088220973">Fitxer multimèdia: reprodueix/posa en pausa</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">i <ph name="NUMBER" /> més</translation>
<translation id="8730621377337864115">Fet</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}other{# h}}</translation>
+<translation id="8798099450830957504">Predeterminat</translation>
<translation id="8806053966018712535">Carpeta <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Afegeix una anotació a la imatge</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_cs.xtb b/chromium/ui/strings/translations/ui_strings_cs.xtb
index ad90798604c..b17832346ba 100644
--- a/chromium/ui/strings/translations/ui_strings_cs.xtb
+++ b/chromium/ui/strings/translations/ui_strings_cs.xtb
@@ -8,11 +8,12 @@
<translation id="1243314992276662751">Nahrát</translation>
<translation id="1293699935367580298">Klávesa Esc</translation>
<translation id="1306549533752902673">DOPORUČENÉ APLIKACE</translation>
+<translation id="1368832886055348810">Zleva doprava</translation>
<translation id="1398853756734560583">Maximalizovat</translation>
<translation id="1413622004203049571">Deaktivovat oznámení ze služby <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuta a }few{# minuty a }many{# minuty a }other{# minut a }}</translation>
<translation id="1643823602425662293">Oznámení</translation>
-<translation id="1710340000377843106">nyní</translation>
+<translation id="1710340000377843106">teď</translation>
<translation id="1752946267035950200">{MINUTES,plural, =1{1 minuta}few{# minuty}many{# minuty}other{# minut}}</translation>
<translation id="1761785978543082658"><ph name="QUANTITY" /> B</translation>
<translation id="1801827354178857021">Tečka</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Hodnocení hvězdičkami: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 hodina a }few{# hodiny a }many{# hodiny a }other{# hodin a }}</translation>
<translation id="1842960171412779397">zvolit</translation>
+<translation id="1859234291848436338">Směr textu</translation>
<translation id="1860796786778352021">Zavřít oznámení</translation>
<translation id="1871244248791675517">Klávesa Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Klávesa PageUp</translation>
<translation id="2190355936436201913">(prázdné)</translation>
<translation id="219905428774326614">Spouštěč, všechny aplikace</translation>
+<translation id="2267918077332197517">Blokovat všechna oznámení z tohoto webu</translation>
<translation id="2289052229480071835">Klepněte na cíle klepnutí na obrazovce.</translation>
<translation id="2295140143284145483">Průzkum</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Posunout sem</translation>
<translation id="3234408098842461169">Klávesa šipka dolů</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 den}few{# dny}many{# dne}other{# dnů}}</translation>
+<translation id="335581015389089642">Řeč</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Zbývá 1 den}few{Zbývají # dny}many{Zbývá # dne}other{Zbývá # dnů}}</translation>
+<translation id="3618849550573277856">Vyhledat „<ph name="LOOKUP_STRING" />“</translation>
<translation id="364720409959344976">Vyberte složku pro nahrávání</translation>
<translation id="3660179305079774227">Klávesa šipka nahoru</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">přejít</translation>
<translation id="4250229828105606438">Snímek obrazovky</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{před 1 měsícem}few{před # měsíci}many{před # měsíce}other{před # měsíci}}</translation>
+<translation id="4289300219472526559">Začít mluvit</translation>
<translation id="4316910396681052118">VŠECHNY APLIKACE</translation>
-<translation id="4320177379694898372">Žádné připojení k internetu</translation>
<translation id="4588090240171750605">Posuv doprava</translation>
<translation id="4724120544754982507">Centrum oznámení – nepřečtená oznámení: <ph name="UNREAD_NOTIFICATION_COUNT" /></translation>
<translation id="4730374152663651037">ČASTO POUŽÍVANÉ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">NÁVRHY APLIKACÍ</translation>
<translation id="6364916375976753737">Posuv doleva</translation>
<translation id="6394627529324717982">Čárka</translation>
+<translation id="6397363302884558537">Přestat mluvit</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Před 1 s}few{Před # s}many{Před # s}other{Před # s}}</translation>
+<translation id="6430678249303439055">Blokovat všechna oznámení z této aplikace</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{před sekundou}few{před # sekundami}many{před # sekundy}other{před # sekundami}}</translation>
<translation id="654149438358937226">Blokovat všechna oznámení</translation>
<translation id="6567071839949112727">kliknutí na nadřazený prvek</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{zbývá 1 rok}few{zbývají # roky}many{zbývá # roku}other{zbývá # let}}</translation>
<translation id="6945221475159498467">Vybrat</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Zprava doleva</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">NEJPRAVDĚPODOBNĚJŠÍ</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Levý okraj</translation>
<translation id="8331626408530291785">Posuv nahoru</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 rok}few{# roky}many{# roku}other{# let}}</translation>
-<translation id="8371695176452482769">Mluvte</translation>
<translation id="838869780401515933">zaškrtnout</translation>
<translation id="8393700583063109961">Odeslat zprávu</translation>
<translation id="8394908167088220973">Média – přehrát/pozastavit</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">a ještě <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Hotovo</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}few{# h}many{# h}other{# h}}</translation>
+<translation id="8798099450830957504">Výchozí</translation>
<translation id="8806053966018712535">Složka <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Přidat k obrázku poznámku</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_da.xtb b/chromium/ui/strings/translations/ui_strings_da.xtb
index 8185a98736d..7f9110a9eb2 100644
--- a/chromium/ui/strings/translations/ui_strings_da.xtb
+++ b/chromium/ui/strings/translations/ui_strings_da.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Upload</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ANBEFALEDE APPS</translation>
+<translation id="1368832886055348810">Venstre til højre</translation>
<translation id="1398853756734560583">Maksimér</translation>
<translation id="1413622004203049571">Deaktiver underretninger fra <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minut og }one{# minutter og }other{# minutter og }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Antal stjerner <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 time og }one{# timer og }other{# timer og }}</translation>
<translation id="1842960171412779397">vælg</translation>
+<translation id="1859234291848436338">Skriveretning</translation>
<translation id="1860796786778352021">Luk underretning</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Side op</translation>
<translation id="2190355936436201913">(tom)</translation>
<translation id="219905428774326614">Starter. Alle apps</translation>
+<translation id="2267918077332197517">Bloker alle underretninger fra dette website</translation>
<translation id="2289052229480071835">Tryk på de punkter på skærmen, der kan trykkes på.</translation>
<translation id="2295140143284145483">Undersøgelse</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/sek.</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Scroll hertil</translation>
<translation id="3234408098842461169">Pil nedad</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 dag}one{# dage}other{# dage}}</translation>
+<translation id="335581015389089642">Tale</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 dag tilbage}one{# dage tilbage}other{# dage tilbage}}</translation>
+<translation id="3618849550573277856">Slå "<ph name="LOOKUP_STRING" />" op</translation>
<translation id="364720409959344976">Vælg den mappe, der skal uploades</translation>
<translation id="3660179305079774227">Pil opad</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/sek.</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">hop</translation>
<translation id="4250229828105606438">Screenshot</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{For 1 måned siden}one{For # måned siden}other{For # måneder siden}}</translation>
+<translation id="4289300219472526559">Start indtaling</translation>
<translation id="4316910396681052118">ALLE APPS</translation>
-<translation id="4320177379694898372">Ingen internetforbindelse</translation>
<translation id="4588090240171750605">Scroll til højre</translation>
<translation id="4724120544754982507">Underretningscenter, <ph name="UNREAD_NOTIFICATION_COUNT" /> ulæste underretninger</translation>
<translation id="4730374152663651037">OFTE ANVENDT</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">APPFORSLAG</translation>
<translation id="6364916375976753737">Scroll Left</translation>
<translation id="6394627529324717982">Komma</translation>
+<translation id="6397363302884558537">Stop indtaling</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{for 1 sek. siden}one{for # sek. siden}other{for # sek. siden}}</translation>
+<translation id="6430678249303439055">Bloker alle underretninger fra denne app</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{For 1 sekund siden}one{For # sekund siden}other{For # sekunder siden}}</translation>
<translation id="654149438358937226">Bloker alle underretninger</translation>
<translation id="6567071839949112727">klik på overordnet element</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Der er 1 år tilbage}one{Der er # år tilbage}other{Der er # år tilbage}}</translation>
<translation id="6945221475159498467">Vælg</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Højre til venstre</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">HØJST SANDSYNLIGT</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Venstre kant</translation>
<translation id="8331626408530291785">Scroll Up</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 år}one{# år}other{# år}}</translation>
-<translation id="8371695176452482769">Indtal nu</translation>
<translation id="838869780401515933">markér</translation>
<translation id="8393700583063109961">Send en besked</translation>
<translation id="8394908167088220973">Medie: Afspil/Pause</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> mere</translation>
<translation id="8730621377337864115">Udfør</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 t}one{# t}other{# t}}</translation>
+<translation id="8798099450830957504">Standard</translation>
<translation id="8806053966018712535">Mappen <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Annoter billede</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_de.xtb b/chromium/ui/strings/translations/ui_strings_de.xtb
index bda412d2aae..f01349c2950 100644
--- a/chromium/ui/strings/translations/ui_strings_de.xtb
+++ b/chromium/ui/strings/translations/ui_strings_de.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Hochladen</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">EMPFOHLENE APPS</translation>
+<translation id="1368832886055348810">Rechtsläufig</translation>
<translation id="1398853756734560583">Vergrößern</translation>
<translation id="1413622004203049571">Benachrichtigungen von <ph name="NOTIFIER_NAME" /> deaktivieren</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 Minute und }other{# Minuten und }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Bewertung <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 Stunde und }other{# Stunden und }}</translation>
<translation id="1842960171412779397">auswählen</translation>
+<translation id="1859234291848436338">Schreibrichtung</translation>
<translation id="1860796786778352021">Benachrichtigung schließen</translation>
<translation id="1871244248791675517">Einfg</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Nach oben</translation>
<translation id="2190355936436201913">(leer)</translation>
<translation id="219905428774326614">Launcher, alle Apps</translation>
+<translation id="2267918077332197517">Alle Benachrichtigungen von dieser Website blockieren</translation>
<translation id="2289052229480071835">Tippen Sie auf die Zielelemente auf dem Bildschirm.</translation>
<translation id="2295140143284145483">Umfrage</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Hierher blättern</translation>
<translation id="3234408098842461169">Abwärtspfeil</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 Tag}other{# Tage}}</translation>
+<translation id="335581015389089642">Sprachausgabe</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 Tag übrig}other{# Tage übrig}}</translation>
+<translation id="3618849550573277856">"<ph name="LOOKUP_STRING" />" nachschlagen</translation>
<translation id="364720409959344976">Ordner zum Hochladen auswählen</translation>
<translation id="3660179305079774227">Aufwärtspfeil</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">springen</translation>
<translation id="4250229828105606438">Screenshot</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{vor 1 Monat}other{vor # Monaten}}</translation>
+<translation id="4289300219472526559">Sprachausgabe starten</translation>
<translation id="4316910396681052118">ALLE APPS</translation>
-<translation id="4320177379694898372">Keine Internetverbindung</translation>
<translation id="4588090240171750605">Nach rechts blättern</translation>
<translation id="4724120544754982507">Benachrichtigungscenter, <ph name="UNREAD_NOTIFICATION_COUNT" /> ungelesene Benachrichtigungen</translation>
<translation id="4730374152663651037">HÄUFIG VERWENDET</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">APP-VORSCHLÄGE</translation>
<translation id="6364916375976753737">Nach links blättern</translation>
<translation id="6394627529324717982">Komma</translation>
+<translation id="6397363302884558537">Sprachausgabe stoppen</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 Sek. her}other{# Sek. her}}</translation>
+<translation id="6430678249303439055">Alle Benachrichtigungen von dieser App blockieren</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Vor 1 Sekunde}other{Vor # Sekunden}}</translation>
<translation id="654149438358937226">Alle Benachrichtigungen blockieren</translation>
<translation id="6567071839949112727">Auf Vorgängerelement klicken</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{noch 1 Jahr}other{noch # Jahre}}</translation>
<translation id="6945221475159498467">Auswählen</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Linksläufig</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">HOHE WAHRSCHEINLICHKEIT</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Linker Rand</translation>
<translation id="8331626408530291785">Nach oben blättern</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 Jahr}other{# Jahre}}</translation>
-<translation id="8371695176452482769">Jetzt sprechen</translation>
<translation id="838869780401515933">auswählen</translation>
<translation id="8393700583063109961">Nachricht senden</translation>
<translation id="8394908167088220973">Medien – Wiedergabe/Pause</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> weitere</translation>
<translation id="8730621377337864115">Fertig</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}other{# h}}</translation>
+<translation id="8798099450830957504">Standardeinstellung</translation>
<translation id="8806053966018712535">Ordner <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Bild mit Anmerkung versehen</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_el.xtb b/chromium/ui/strings/translations/ui_strings_el.xtb
index a004e281818..1d1f001f571 100644
--- a/chromium/ui/strings/translations/ui_strings_el.xtb
+++ b/chromium/ui/strings/translations/ui_strings_el.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Μεταφόρτωση</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ΠΡΟΤΕΙΝΟΜΕΝΕΣ ΕΦΑΡΜΟΓΕΣ</translation>
+<translation id="1368832886055348810">Από αριστερά προς τα δεξιά</translation>
<translation id="1398853756734560583">Μεγιστοποίηση</translation>
<translation id="1413622004203049571">Απενεργοποίηση ειδοποιήσεων από <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 λεπτό και }other{# λεπτά και }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Αξιολόγηση με αστέρια <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 ώρα και }other{# ώρες και }}</translation>
<translation id="1842960171412779397">επιλογή</translation>
+<translation id="1859234291848436338">Κατεύθυνση γραφής</translation>
<translation id="1860796786778352021">Κλείσιμο ειδοποίησης</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Προηγούμενη σελίδα</translation>
<translation id="2190355936436201913">(κενό)</translation>
<translation id="219905428774326614">Εφαρμογή εκκίνησης, όλες οι εφαρμογές</translation>
+<translation id="2267918077332197517">Αποκλεισμός όλων των ειδοποιήσεων από αυτόν τον ιστότοπο</translation>
<translation id="2289052229480071835">Πατήστε τους στόχους αφής στην οθόνη σας.</translation>
<translation id="2295140143284145483">Έρευνα</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Κύλιση εδώ</translation>
<translation id="3234408098842461169">Κάτω βέλος</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 ημέρα}other{# ημέρες}}</translation>
+<translation id="335581015389089642">Ομιλία</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Απομένει 1 ημέρα}other{Απομένουν # ημέρες}}</translation>
+<translation id="3618849550573277856">Αναζήτηση "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Επιλέξτε φάκελο για μεταφόρτωση</translation>
<translation id="3660179305079774227">Πάνω βέλος</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">μεταπήδηση</translation>
<translation id="4250229828105606438">Στιγμιότυπο οθόνης</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Πριν από 1 μήνα}other{Πριν από # μήνες}}</translation>
+<translation id="4289300219472526559">Έναρξη ομιλίας</translation>
<translation id="4316910396681052118">ΟΛΕΣ ΟΙ ΕΦΑΡΜΟΓΕΣ</translation>
-<translation id="4320177379694898372">Χωρίς σύνδεση στο διαδίκτυο</translation>
<translation id="4588090240171750605">Κύλιση δεξιά</translation>
<translation id="4724120544754982507">Κέντρο ειδοποιήσεων, <ph name="UNREAD_NOTIFICATION_COUNT" /> μη αναγνωσμένες ειδοποιήσεις</translation>
<translation id="4730374152663651037">ΣΥΧΝΗ ΧΡΗΣΗ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ΠΡΟΤΑΣΕΙΣ ΕΦΑΡΜΟΓΩΝ</translation>
<translation id="6364916375976753737">Κύλιση αριστερά</translation>
<translation id="6394627529324717982">Κόμμα</translation>
+<translation id="6397363302884558537">Διακοπή ομιλίας</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Πριν από 1 δευτερόλεπτο}other{Πριν από # δευτερόλεπτα}}</translation>
+<translation id="6430678249303439055">Αποκλεισμός όλων των ειδοποιήσεων από αυτή την εφαρμογή</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Πριν από 1 δευτερόλεπτο}other{Πριν από # δευτερόλεπτα}}</translation>
<translation id="654149438358937226">Αποκλεισμός όλων των ειδοποιήσεων</translation>
<translation id="6567071839949112727">γονικό κλικ</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Απομένει 1 χρόνος}other{Απομένουν # χρόνια}}</translation>
<translation id="6945221475159498467">Επιλογή</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Από δεξιά προς τα αριστερά</translation>
<translation id="7052633198403197513">Πλήκτρο F1</translation>
<translation id="7130207228079676353">ΔΗΜΟΦΙΛΕΣΤΕΡΕΣ</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Αριστερή άκρη</translation>
<translation id="8331626408530291785">Κύλιση επάνω</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 χρόνος}other{# χρόνια}}</translation>
-<translation id="8371695176452482769">Μιλήστε τώρα</translation>
<translation id="838869780401515933">ενεργοποίηση</translation>
<translation id="8393700583063109961">Αποστολή μηνύματος</translation>
<translation id="8394908167088220973">Αναπαραγωγή/παύση πολυμέσων</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> ακόμη</translation>
<translation id="8730621377337864115">Ολοκληρώθηκε</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1ώρ.}other{#ώρ.}}</translation>
+<translation id="8798099450830957504">Προεπιλογή</translation>
<translation id="8806053966018712535">Φάκελος <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Σχολιασμός εικόνας</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_en-GB.xtb b/chromium/ui/strings/translations/ui_strings_en-GB.xtb
index ac82ea40d75..fd7b83c3ada 100644
--- a/chromium/ui/strings/translations/ui_strings_en-GB.xtb
+++ b/chromium/ui/strings/translations/ui_strings_en-GB.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Upload</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">RECOMMENDED APPS</translation>
+<translation id="1368832886055348810">Left to Right</translation>
<translation id="1398853756734560583">Maximise</translation>
<translation id="1413622004203049571">Disable notifications from <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minute and }other{# minutes and }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Star rating <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 hour and }other{# hours and }}</translation>
<translation id="1842960171412779397">select</translation>
+<translation id="1859234291848436338">Writing Direction</translation>
<translation id="1860796786778352021">Notification close</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Page Up</translation>
<translation id="2190355936436201913">(empty)</translation>
<translation id="219905428774326614">Launcher, all apps</translation>
+<translation id="2267918077332197517">Block all notifications from this site</translation>
<translation id="2289052229480071835">Tap the touch targets on your screen.</translation>
<translation id="2295140143284145483">Survey</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Scroll to Here</translation>
<translation id="3234408098842461169">Down Arrow</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 day}other{# days}}</translation>
+<translation id="335581015389089642">Speech</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 day left}other{# days left}}</translation>
+<translation id="3618849550573277856">Look Up “<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Select Folder to Upload</translation>
<translation id="3660179305079774227">Up Arrow</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">jump</translation>
<translation id="4250229828105606438">Screenshot</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 month ago}other{# months ago}}</translation>
+<translation id="4289300219472526559">Start Speaking</translation>
<translation id="4316910396681052118">ALL APPS</translation>
-<translation id="4320177379694898372">No internet connection</translation>
<translation id="4588090240171750605">Scroll Right</translation>
<translation id="4724120544754982507">Notification Centre, <ph name="UNREAD_NOTIFICATION_COUNT" /> unread notifications</translation>
<translation id="4730374152663651037">FREQUENTLY USED</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">APP SUGGESTIONS</translation>
<translation id="6364916375976753737">Scroll Left</translation>
<translation id="6394627529324717982">Comma</translation>
+<translation id="6397363302884558537">Stop Speaking</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 sec ago}other{# secs ago}}</translation>
+<translation id="6430678249303439055">Block all notifications from this app</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 second ago}other{# seconds ago}}</translation>
<translation id="654149438358937226">Block all notifications</translation>
<translation id="6567071839949112727">click ancestor</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 year left}other{# years left}}</translation>
<translation id="6945221475159498467">Select</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Right to Left</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">MOST LIKELY</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Left Edge</translation>
<translation id="8331626408530291785">Scroll Up</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 year}other{# years}}</translation>
-<translation id="8371695176452482769">Speak now</translation>
<translation id="838869780401515933">tick</translation>
<translation id="8393700583063109961">Send message</translation>
<translation id="8394908167088220973">Media Play/Pause</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> more</translation>
<translation id="8730621377337864115">Done</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1h}other{#h}}</translation>
+<translation id="8798099450830957504">Default</translation>
<translation id="8806053966018712535">Folder <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Annotate image</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_es-419.xtb b/chromium/ui/strings/translations/ui_strings_es-419.xtb
index 01a9478b5b4..2d51edc7332 100644
--- a/chromium/ui/strings/translations/ui_strings_es-419.xtb
+++ b/chromium/ui/strings/translations/ui_strings_es-419.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Cargar</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">APPS RECOMENDADAS</translation>
+<translation id="1368832886055348810">De izquierda a derecha</translation>
<translation id="1398853756734560583">Maximizar</translation>
<translation id="1413622004203049571">Inhabilitar notificaciones de <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuto y }other{# minutos y }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Calificación por estrellas <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 hora y }other{# horas y }}</translation>
<translation id="1842960171412779397">seleccionar</translation>
+<translation id="1859234291848436338">Sentido de la escritura</translation>
<translation id="1860796786778352021">Cerrar notificación</translation>
<translation id="1871244248791675517">Insert</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Retroceder página</translation>
<translation id="2190355936436201913">(vacío)</translation>
<translation id="219905428774326614">Launcher, todas las apps</translation>
+<translation id="2267918077332197517">No permitir las notificaciones de este sitio</translation>
<translation id="2289052229480071835">Presiona los objetivos táctiles en tu pantalla.</translation>
<translation id="2295140143284145483">Encuesta</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Desplazarse hasta aquí</translation>
<translation id="3234408098842461169">Flecha abajo</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 día}other{# días}}</translation>
+<translation id="335581015389089642">Voz</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Falta 1 día.}other{Faltan # días.}}</translation>
+<translation id="3618849550573277856">Buscar "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Seleccionar carpeta para cargar</translation>
<translation id="3660179305079774227">Flecha arriba</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">saltar</translation>
<translation id="4250229828105606438">Captura de pantalla</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Hace 1 mes}other{Hace # meses}}</translation>
+<translation id="4289300219472526559">Empezar a hablar</translation>
<translation id="4316910396681052118">TODAS LAS APPS</translation>
-<translation id="4320177379694898372">Sin conexión a Internet</translation>
<translation id="4588090240171750605">Desplazar a la derecha</translation>
<translation id="4724120544754982507">Centro de notificaciones, notificaciones sin leer: <ph name="UNREAD_NOTIFICATION_COUNT" /></translation>
<translation id="4730374152663651037">USADAS CON FRECUENCIA</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SUGERENCIAS DE APPS</translation>
<translation id="6364916375976753737">Desplazar hacia la izquierda</translation>
<translation id="6394627529324717982">Coma</translation>
+<translation id="6397363302884558537">Dejar de hablar</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Hace 1 s.}other{Hace # s.}}</translation>
+<translation id="6430678249303439055">No permitir las notificaciones de esta app</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Hace 1 segundo}other{Hace # segundos}}</translation>
<translation id="654149438358937226">Bloquear todas las notificaciones</translation>
<translation id="6567071839949112727">hacer clic en principal</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Queda 1 año}other{Quedan # años}}</translation>
<translation id="6945221475159498467">Seleccionar</translation>
<translation id="6965382102122355670">Aceptar</translation>
+<translation id="6974053822202609517">De derecha a izquierda</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">MUY PROBABLES</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Borde izquierdo</translation>
<translation id="8331626408530291785">Desplazar hacia arriba</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 año}other{# años}}</translation>
-<translation id="8371695176452482769">Hablar ahora</translation>
<translation id="838869780401515933">marcar</translation>
<translation id="8393700583063109961">Enviar mensaje</translation>
<translation id="8394908167088220973">Reproducir o pausar contenido multimedia</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204"><ph name="NUMBER" /> más</translation>
<translation id="8730621377337864115">Listo</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}other{# h}}</translation>
+<translation id="8798099450830957504">Predeterminado</translation>
<translation id="8806053966018712535">Carpeta <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Escribir en la imagen</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_es.xtb b/chromium/ui/strings/translations/ui_strings_es.xtb
index c8e5daf576c..8d22d321cd7 100644
--- a/chromium/ui/strings/translations/ui_strings_es.xtb
+++ b/chromium/ui/strings/translations/ui_strings_es.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Subir</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">APLICACIONES RECOMENDADAS</translation>
+<translation id="1368832886055348810">De izquierda a derecha</translation>
<translation id="1398853756734560583">Maximizar</translation>
<translation id="1413622004203049571">Inhabilitar notificaciones de <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuto y }other{# minutos y }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Valoración por estrellas <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 hora y }other{# horas y }}</translation>
<translation id="1842960171412779397">seleccionar</translation>
+<translation id="1859234291848436338">Sentido de la escritura</translation>
<translation id="1860796786778352021">Cerrar notificación</translation>
<translation id="1871244248791675517">Insert</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Retroceder página</translation>
<translation id="2190355936436201913">(vacío)</translation>
<translation id="219905428774326614">Menú de aplicaciones, todas las aplicaciones</translation>
+<translation id="2267918077332197517">Bloquear todas las notificaciones de este sitio web</translation>
<translation id="2289052229480071835">Toca los elementos táctiles en la pantalla.</translation>
<translation id="2295140143284145483">Encuesta</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Desplazarse hasta aquí</translation>
<translation id="3234408098842461169">Flecha abajo</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 día}other{# días}}</translation>
+<translation id="335581015389089642">Voz</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Queda 1 día}other{Quedan # días}}</translation>
+<translation id="3618849550573277856">Buscar <ph name="LOOKUP_STRING" /></translation>
<translation id="364720409959344976">Seleccionar una carpeta para subirla</translation>
<translation id="3660179305079774227">Flecha arriba</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">saltar</translation>
<translation id="4250229828105606438">Captura de pantalla</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Hace 1 mes}other{Hace # meses}}</translation>
+<translation id="4289300219472526559">Empezar a hablar</translation>
<translation id="4316910396681052118">TODAS LAS APLICACIONES</translation>
-<translation id="4320177379694898372">No hay conexión a Internet</translation>
<translation id="4588090240171750605">Desplazar a la derecha</translation>
<translation id="4724120544754982507">Centro de notificaciones: <ph name="UNREAD_NOTIFICATION_COUNT" /> notificaciones sin leer</translation>
<translation id="4730374152663651037">UTILIZADAS CON FRECUENCIA</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SUGERENCIAS DE APLICACIONES</translation>
<translation id="6364916375976753737">Desplazar hacia la izquierda</translation>
<translation id="6394627529324717982">Coma</translation>
+<translation id="6397363302884558537">Dejar de hablar</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Hace 1 s}other{Hace # s}}</translation>
+<translation id="6430678249303439055">Bloquear todas las notificaciones de esta aplicación</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Hace 1 segundo}other{Hace # segundos}}</translation>
<translation id="654149438358937226">Bloquear todas las notificaciones</translation>
<translation id="6567071839949112727">hacer clic en la superclase</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Queda 1 año}other{Quedan # años}}</translation>
<translation id="6945221475159498467">Seleccionar</translation>
<translation id="6965382102122355670">Aceptar</translation>
+<translation id="6974053822202609517">De derecha a izquierda</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">MÁS PROBABLES</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Borde izquierdo</translation>
<translation id="8331626408530291785">Desplazar hacia arriba</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 año}other{# años}}</translation>
-<translation id="8371695176452482769">Habla ahora</translation>
<translation id="838869780401515933">marcar</translation>
<translation id="8393700583063109961">Enviar mensaje</translation>
<translation id="8394908167088220973">Pausar/Reproducir contenido multimedia</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204"><ph name="NUMBER" /> más</translation>
<translation id="8730621377337864115">Listo</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}other{# h}}</translation>
+<translation id="8798099450830957504">Predeterminado</translation>
<translation id="8806053966018712535">Carpeta <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Anotar imagen</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_et.xtb b/chromium/ui/strings/translations/ui_strings_et.xtb
index f690752e3b1..f2da3fb29a3 100644
--- a/chromium/ui/strings/translations/ui_strings_et.xtb
+++ b/chromium/ui/strings/translations/ui_strings_et.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Laadi üles</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">SOOVITATUD RAKENDUSED</translation>
+<translation id="1368832886055348810">Left to Right (Vasakult paremale)</translation>
<translation id="1398853756734560583">Maksimeeri</translation>
<translation id="1413622004203049571">Keela märguanded: <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minut ja }other{# minutit ja }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Tärnhinnang <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 tund ja }other{# tundi ja }}</translation>
<translation id="1842960171412779397">vali</translation>
+<translation id="1859234291848436338">Writing Direction (Kirjutamise suund)</translation>
<translation id="1860796786778352021">Märguande sulgemine</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Lehekülje üles</translation>
<translation id="2190355936436201913">(tühi)</translation>
<translation id="219905428774326614">Käivitaja, kõik rakendused</translation>
+<translation id="2267918077332197517">Blokeeri kõik märguanded sellelt saidilt</translation>
<translation id="2289052229480071835">Puudutage ekraanil puutesihtmärke.</translation>
<translation id="2295140143284145483">Küsitlus</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Keri siia</translation>
<translation id="3234408098842461169">Allanool</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 päev}other{# päeva}}</translation>
+<translation id="335581015389089642">Kõne</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 päev on jäänud}other{# päeva on jäänud}}</translation>
+<translation id="3618849550573277856">Otsi terminit „<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Kausta valimine üleslaadimiseks</translation>
<translation id="3660179305079774227">Ülesnool</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">liigu</translation>
<translation id="4250229828105606438">Ekraanipilt</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 kuu tagasi}other{# kuud tagasi}}</translation>
+<translation id="4289300219472526559">Alusta rääkimist</translation>
<translation id="4316910396681052118">KÕIK RAKENDUSED</translation>
-<translation id="4320177379694898372">Interneti-ühendus puudub</translation>
<translation id="4588090240171750605">Keri paremale</translation>
<translation id="4724120544754982507">Märguandekeskus, <ph name="UNREAD_NOTIFICATION_COUNT" /> lugemata märguannet</translation>
<translation id="4730374152663651037">SAGELI KASUTATUD</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">RAKENDUSTE SOOVITUSED</translation>
<translation id="6364916375976753737">Keri vasakule</translation>
<translation id="6394627529324717982">Koma</translation>
+<translation id="6397363302884558537">Lõpeta rääkimine</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 s tagasi}other{# s tagasi}}</translation>
+<translation id="6430678249303439055">Blokeeri kõik märguanded sellelt rakenduselt</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 sekund tagasi}other{# sekundit tagasi}}</translation>
<translation id="654149438358937226">Blokeeri kõik märguanded</translation>
<translation id="6567071839949112727">kliki eellane</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 aasta jäänud}other{# aastat jäänud}}</translation>
<translation id="6945221475159498467">Vali</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Right to Left (Paremalt vasakule)</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">KÕIGE TÕENÄOLISEMAD</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Vasak serv</translation>
<translation id="8331626408530291785">Keri üles</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 aasta}other{# aastat}}</translation>
-<translation id="8371695176452482769">Alustage rääkimist</translation>
<translation id="838869780401515933">mrgista</translation>
<translation id="8393700583063109961">Saatke sõnum</translation>
<translation id="8394908167088220973">Meediumi esitamine/peatamine</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">ja veel <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Valmis</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1h}other{#h}}</translation>
+<translation id="8798099450830957504">Vaikimisi</translation>
<translation id="8806053966018712535">Kaust <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Lisa kujutisele märkused</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_fa.xtb b/chromium/ui/strings/translations/ui_strings_fa.xtb
index 094e2111ba0..ba3ceda90d6 100644
--- a/chromium/ui/strings/translations/ui_strings_fa.xtb
+++ b/chromium/ui/strings/translations/ui_strings_fa.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">بارگذاری</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">برنامه‌های توصیه‌شده</translation>
+<translation id="1368832886055348810">چپ به راست</translation>
<translation id="1398853756734560583">بزرگ کردن</translation>
<translation id="1413622004203049571">غیرفعال کردن اعلان‌ها از <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{۱ دقیقه و }one{# دقیقه و }other{# دقیقه و }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">رتبه‌بندی ستاره‌ای <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{۱ ساعت و }one{# ساعت و }other{# ساعت و }}</translation>
<translation id="1842960171412779397">انتخاب</translation>
+<translation id="1859234291848436338">جهت نوشتن</translation>
<translation id="1860796786778352021">بستن اعلان</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />٪</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">صفحه بالا</translation>
<translation id="2190355936436201913">(خالی)</translation>
<translation id="219905428774326614">راه‌انداز، همه برنامه‌ها</translation>
+<translation id="2267918077332197517">مسدود کردن همه اعلان‌های این سایت</translation>
<translation id="2289052229480071835">روی اهداف لمسی در صفحه‌تان ضربه بزنید.</translation>
<translation id="2295140143284145483">نظرسنجی</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> ترابایت/ثانیه</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">پیمایش به اینجا</translation>
<translation id="3234408098842461169">پیکان پایین</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{۱ روز}one{# روز}other{# روز}}</translation>
+<translation id="335581015389089642">صدا</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{۱ روز باقی مانده است}one{# روز باقی مانده است}other{# روز باقی مانده است}}</translation>
+<translation id="3618849550573277856">جستجوی «<ph name="LOOKUP_STRING" />»</translation>
<translation id="364720409959344976">انتخاب پوشه برای بارگذاری</translation>
<translation id="3660179305079774227">پیکان بالا</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> گیگابایت/ثانیه</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">پرش</translation>
<translation id="4250229828105606438">عکس صفحه‌نمایش</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{۱ ماه قبل}one{# ماه قبل}other{# ماه قبل}}</translation>
+<translation id="4289300219472526559">شروع صحبت</translation>
<translation id="4316910396681052118">همه برنامه‌ها</translation>
-<translation id="4320177379694898372">اتصال اینترنتی ندارید</translation>
<translation id="4588090240171750605">پیمایش به راست</translation>
<translation id="4724120544754982507">مرکز اعلان، <ph name="UNREAD_NOTIFICATION_COUNT" /> اعلان خوانده‌نشده</translation>
<translation id="4730374152663651037">مکرراً استفاده‌شده</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">پیشنهادات برنامه</translation>
<translation id="6364916375976753737">پیمایش به چپ</translation>
<translation id="6394627529324717982">کاما</translation>
+<translation id="6397363302884558537">توقف صحبت</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{۱ ثانیه قبل}one{# ثانیه قبل}other{# ثانیه قبل}}</translation>
+<translation id="6430678249303439055">مسدود کردن همه اعلان‌های این برنامه</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{۱ ثانیه قبل}one{# ثانیه قبل}other{# ثانیه قبل}}</translation>
<translation id="654149438358937226">مسدود کردن همه اعلان‌ها</translation>
<translation id="6567071839949112727">کلیک کردن روی نسخه اولیه</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{۱ سال باقی مانده است}one{#سال باقی مانده است}other{#سال باقی مانده است}}</translation>
<translation id="6945221475159498467">انتخاب</translation>
<translation id="6965382102122355670">قبول</translation>
+<translation id="6974053822202609517">راست به چپ</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">به احتمال خیلی زیاد</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">حاشیه چپ</translation>
<translation id="8331626408530291785">پیمایش به بالا</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{۱ سال}one{# سال}other{# سال}}</translation>
-<translation id="8371695176452482769">اکنون صحبت کنید</translation>
<translation id="838869780401515933">علامت‌گذاری</translation>
<translation id="8393700583063109961">ارسال پیام</translation>
<translation id="8394908167088220973">پخش/مکث رسانه</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204"><ph name="NUMBER" /> مورد دیگر</translation>
<translation id="8730621377337864115">تمام</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{۱ ساعت}one{# ساعت}other{# ساعت}}</translation>
+<translation id="8798099450830957504">پیش‌فرض</translation>
<translation id="8806053966018712535">پوشه <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">حاشیه‌نویسی تصویر</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> کیلوبایت</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_fi.xtb b/chromium/ui/strings/translations/ui_strings_fi.xtb
index 40462ce3795..8a415d066cb 100644
--- a/chromium/ui/strings/translations/ui_strings_fi.xtb
+++ b/chromium/ui/strings/translations/ui_strings_fi.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Lähetä</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">SOVELLUSSUOSITUKSET</translation>
+<translation id="1368832886055348810">Vasemmalta oikealle</translation>
<translation id="1398853756734560583">Suurenna</translation>
<translation id="1413622004203049571">Poista ilmoitukset käytöstä sovellukselta <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuutti ja }other{# minuuttia ja }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Tähtiluokitus: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 tunti ja }other{# tuntia ja }}</translation>
<translation id="1842960171412779397">Valitse</translation>
+<translation id="1859234291848436338">Kirjoitussuunta</translation>
<translation id="1860796786778352021">Ilmoitus sulje</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Sivu ylös</translation>
<translation id="2190355936436201913">(tyhjä)</translation>
<translation id="219905428774326614">Käynnistysohjelma, kaikki sovellukset</translation>
+<translation id="2267918077332197517">Estä kaikki tämän sivuston ilmoitukset</translation>
<translation id="2289052229480071835">Napauta näytölläsi olevia kosketettavia kohteita.</translation>
<translation id="2295140143284145483">Kysely</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> Tt/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Vieritä tähän</translation>
<translation id="3234408098842461169">Nuoli al.</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 päivä}other{# päivää}}</translation>
+<translation id="335581015389089642">Puhe</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 päivä jäljellä}other{# päivää jäljellä}}</translation>
+<translation id="3618849550573277856">Hae ”<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Valitse lähetettävä kansio</translation>
<translation id="3660179305079774227">Nuoli yl.</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> Gt/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">siirry</translation>
<translation id="4250229828105606438">Kuvakaappaus</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 kuukausi sitten}other{# kuukautta sitten}}</translation>
+<translation id="4289300219472526559">Aloita puhuminen</translation>
<translation id="4316910396681052118">KAIKKI SOVELLUKSET</translation>
-<translation id="4320177379694898372">Ei internetyhteyttä</translation>
<translation id="4588090240171750605">Vieritä oikealle</translation>
<translation id="4724120544754982507">Ilmoituskeskus, <ph name="UNREAD_NOTIFICATION_COUNT" /> lukematonta ilmoitusta</translation>
<translation id="4730374152663651037">USEIN KÄYTETYT</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SOVELLUSEHDOTUKSET</translation>
<translation id="6364916375976753737">Vieritä vasemmalle</translation>
<translation id="6394627529324717982">Pilkku</translation>
+<translation id="6397363302884558537">Lopeta puhuminen</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 s sitten}other{# s sitten}}</translation>
+<translation id="6430678249303439055">Estä kaikki tämän sovelluksen ilmoitukset</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 sekunti sitten}other{# sekuntia sitten}}</translation>
<translation id="654149438358937226">Estä kaikki ilmoitukset</translation>
<translation id="6567071839949112727">klikkaa edeltäjää</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 vuosi jäljellä}other{# vuotta jäljellä}}</translation>
<translation id="6945221475159498467">Valitse</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Oikealta vasemmalle</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">TODENNÄKÖISIMMÄT</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Vasen reuna</translation>
<translation id="8331626408530291785">Vieritä ylös</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 vuosi}other{# vuotta}}</translation>
-<translation id="8371695176452482769">Puhu nyt</translation>
<translation id="838869780401515933">valitse</translation>
<translation id="8393700583063109961">Lähetä viesti</translation>
<translation id="8394908167088220973">Media: toista/keskeytä</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> lisää</translation>
<translation id="8730621377337864115">Valmis</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}other{# h}}</translation>
+<translation id="8798099450830957504">Oletus</translation>
<translation id="8806053966018712535">Kansio <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Lisää kuvaan muistiinpano</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kt</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_fil.xtb b/chromium/ui/strings/translations/ui_strings_fil.xtb
index fe31e77dc93..6bee96d96f6 100644
--- a/chromium/ui/strings/translations/ui_strings_fil.xtb
+++ b/chromium/ui/strings/translations/ui_strings_fil.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">I-upload</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">MGA INIREREKOMENDANG APP</translation>
+<translation id="1368832886055348810">Kaliwa papuntang Kanan</translation>
<translation id="1398853756734560583">Maximize</translation>
<translation id="1413622004203049571">I-disable ang mga notification mula sa <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuto at }one{# minuto at }other{# na minuto at }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Star na rating <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 oras at }one{# oras at }other{# na oras at }}</translation>
<translation id="1842960171412779397">piliin</translation>
+<translation id="1859234291848436338">Pagsulat ng Direksyon</translation>
<translation id="1860796786778352021">Isara ang notification</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Pataas</translation>
<translation id="2190355936436201913">(walang laman)</translation>
<translation id="219905428774326614">Launcher, lahat ng app</translation>
+<translation id="2267918077332197517">I-block ang lahat ng notification mula sa site na ito</translation>
<translation id="2289052229480071835">I-tap ang mga target sa pagpindot sa iyong screen.</translation>
<translation id="2295140143284145483">Survey</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> (na) TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Mag-scroll dito</translation>
<translation id="3234408098842461169">Down Arrow</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 araw}one{# araw}other{# na araw}}</translation>
+<translation id="335581015389089642">Pananalita</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 araw na lang ang natitira}one{# araw na lang ang natitira}other{# na araw na lang ang natitira}}</translation>
+<translation id="3618849550573277856">Hanapin ang “<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Pumili ng Folder na I-a-upload</translation>
<translation id="3660179305079774227">Up Arrow</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> (na) GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">tumalon</translation>
<translation id="4250229828105606438">Screenshot</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 buwan ang nakalipas}one{# buwan ang nakalipas}other{# na buwan ang nakalipas}}</translation>
+<translation id="4289300219472526559">Simulan ang Pagsasalita</translation>
<translation id="4316910396681052118">LAHAT NG APP</translation>
-<translation id="4320177379694898372">Walang koneksyon sa internet</translation>
<translation id="4588090240171750605">Mag-scroll Pakanan</translation>
<translation id="4724120544754982507">Notification Center, <ph name="UNREAD_NOTIFICATION_COUNT" /> (na) hindi pa nababasang notification</translation>
<translation id="4730374152663651037">MADALAS GAMITIN</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">MGA IMINUMUNGKAHING APP</translation>
<translation id="6364916375976753737">Mag-scroll Pakaliwa</translation>
<translation id="6394627529324717982">Kuwit</translation>
+<translation id="6397363302884558537">Ihinto ang Pagsasalita</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 segundo ang nakalipas}one{# segundo ang nakalipas}other{# na segundo ang nakalipas}}</translation>
+<translation id="6430678249303439055">I-block ang lahat ng notification mula sa app na ito</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 segundo ang nakalipas}one{# segundo ang nakalipas}other{# na segundo ang nakalipas}}</translation>
<translation id="654149438358937226">I-block ang lahat ng notification</translation>
<translation id="6567071839949112727">i-click ang ancestor</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 taon ang natitira}one{# taon ang natitira}other{# na taon ang natitira}}</translation>
<translation id="6945221475159498467">Pumili</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Kanan papuntang Kaliwa</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">PINAKAMALAMANG</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Kalwang Edge</translation>
<translation id="8331626408530291785">Mag-scroll Pataas</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 taon}one{# taon}other{# na taon}}</translation>
-<translation id="8371695176452482769">Magsalita ngayon</translation>
<translation id="838869780401515933">I-tsek</translation>
<translation id="8393700583063109961">Ipadala ang mensahe</translation>
<translation id="8394908167088220973">I-Play/I-Pause ang Media</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> pa</translation>
<translation id="8730621377337864115">Tapos na</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 oras}one{# oras}other{# na oras}}</translation>
+<translation id="8798099450830957504">Default</translation>
<translation id="8806053966018712535">Folder <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">I-annotate ang larawan</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_fr.xtb b/chromium/ui/strings/translations/ui_strings_fr.xtb
index fe00aaa874d..7bc623e0894 100644
--- a/chromium/ui/strings/translations/ui_strings_fr.xtb
+++ b/chromium/ui/strings/translations/ui_strings_fr.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Importer</translation>
<translation id="1293699935367580298">Échap</translation>
<translation id="1306549533752902673">APPLICATIONS RECOMMANDÉES</translation>
+<translation id="1368832886055348810">De gauche à droite</translation>
<translation id="1398853756734560583">Agrandir</translation>
<translation id="1413622004203049571">Désactiver les notifications <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minute et }one{# minute et }other{# minutes et }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Note : <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 heure et }one{# heure et }other{# heures et }}</translation>
<translation id="1842960171412779397">sélectionner</translation>
+<translation id="1859234291848436338">Sens de l'écriture</translation>
<translation id="1860796786778352021">Fermer la notification</translation>
<translation id="1871244248791675517">Insér.</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Page précédente</translation>
<translation id="2190355936436201913">(vide)</translation>
<translation id="219905428774326614">Lanceur d'applications, toutes les applications</translation>
+<translation id="2267918077332197517">Bloquer toutes les notifications de ce site</translation>
<translation id="2289052229480071835">Appuyez sur les cibles tactiles affichées à l'écran.</translation>
<translation id="2295140143284145483">Enquête</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> To/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Défilement jusqu'ici</translation>
<translation id="3234408098842461169">Bas</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 jour}one{# jour}other{# jours}}</translation>
+<translation id="335581015389089642">Voix</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 jour restant}one{# jour restant}other{# jours restants}}</translation>
+<translation id="3618849550573277856">Rechercher "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Sélectionner le dossier d'importation</translation>
<translation id="3660179305079774227">Haut</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> Go/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">accéder</translation>
<translation id="4250229828105606438">Capture d'écran</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Il y a 1 mois}one{Il y a # mois}other{Il y a # mois}}</translation>
+<translation id="4289300219472526559">Commencer à parler</translation>
<translation id="4316910396681052118">TOUTES LES APPLICATIONS</translation>
-<translation id="4320177379694898372">Aucune connexion Internet.</translation>
<translation id="4588090240171750605">Défilement vers la droite</translation>
<translation id="4724120544754982507">Centre de notification, <ph name="UNREAD_NOTIFICATION_COUNT" /> notifications non lues</translation>
<translation id="4730374152663651037">SOUVENT UTILISÉES</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SUGGESTIONS D'APPLICATIONS</translation>
<translation id="6364916375976753737">Défilement vers la gauche</translation>
<translation id="6394627529324717982">Virgule</translation>
+<translation id="6397363302884558537">Arrêter de parler</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Il y a 1 s}one{Il y a # s}other{Il y a # s}}</translation>
+<translation id="6430678249303439055">Bloquer toutes les notifications de cette application</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Il y a une seconde}one{Il y a # seconde}other{Il y a # secondes}}</translation>
<translation id="654149438358937226">Bloquer toutes les notifications</translation>
<translation id="6567071839949112727">cliquer sur l'ancêtre</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 an restant}one{# an restant}other{# ans restants}}</translation>
<translation id="6945221475159498467">Sélectionner</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">De droite à gauche</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">CLIC PROBABLE</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Côté gauche</translation>
<translation id="8331626408530291785">Défilement vers le haut</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 an}one{# an}other{# ans}}</translation>
-<translation id="8371695176452482769">Parlez maintenant.</translation>
<translation id="838869780401515933">cocher</translation>
<translation id="8393700583063109961">Envoyer un message</translation>
<translation id="8394908167088220973">Contenu multimédia : lecture/pause</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204"><ph name="NUMBER" /> autres</translation>
<translation id="8730621377337864115">OK</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}one{# h}other{# h}}</translation>
+<translation id="8798099450830957504">Par défaut</translation>
<translation id="8806053966018712535">Dossier <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Annoter l'image</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> Ko</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_gu.xtb b/chromium/ui/strings/translations/ui_strings_gu.xtb
index 1ee0eab8dc8..10b2bc01571 100644
--- a/chromium/ui/strings/translations/ui_strings_gu.xtb
+++ b/chromium/ui/strings/translations/ui_strings_gu.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">અપલોડ કરો</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ભલામણ કરેલ ઍપ</translation>
+<translation id="1368832886055348810">ડાબેથી જમણે</translation>
<translation id="1398853756734560583">મોટું કરો</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> તરફથી સૂચનાઓ અક્ષમ કરો</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 મિનિટ અને }one{# મિનિટ અને }other{# મિનિટ અને }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">સ્ટાર રેટિંગ <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 કલાક અને }one{# કલાક અને }other{# કલાક અને }}</translation>
<translation id="1842960171412779397">પસંદ કરો</translation>
+<translation id="1859234291848436338">લેખનના દિશાનિર્દેશ</translation>
<translation id="1860796786778352021">સૂચના બંધ છે</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">પૃષ્ઠ ઉપર</translation>
<translation id="2190355936436201913">(ખાલી)</translation>
<translation id="219905428774326614">લૉન્ચર, બધી ઍપ</translation>
+<translation id="2267918077332197517">આ સાઇટના બધા નોટિફિકેશનો અવરોધિત કરો</translation>
<translation id="2289052229480071835">તમારી સ્ક્રીન પર ટચ કરવાના લક્ષ્યોને ટૅપ કરો.</translation>
<translation id="2295140143284145483">સર્વેક્ષણ</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">અહીં સુધી સ્ક્રોલ કરો</translation>
<translation id="3234408098842461169">નીચલો એરો</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 દિવસ}one{# દિવસ}other{# દિવસ}}</translation>
+<translation id="335581015389089642">ભાષા</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 દિવસ બાકી}one{# દિવસ બાકી}other{# દિવસ બાકી}}</translation>
+<translation id="3618849550573277856">“<ph name="LOOKUP_STRING" />” શોધો</translation>
<translation id="364720409959344976">અપલોડ કરવા માટે ફોલ્ડર પસંદ કરો</translation>
<translation id="3660179305079774227">ઉપર એરો</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">જંપ કરો</translation>
<translation id="4250229828105606438">સ્ક્રીનશૉટ</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 મહિના પહેલાં}one{# મહિના પહેલાં}other{# મહિના પહેલાં}}</translation>
+<translation id="4289300219472526559">બોલવાનું પ્રારંભ કરો</translation>
<translation id="4316910396681052118">બધી ઍપ્લિકેશનો</translation>
-<translation id="4320177379694898372">કોઈ ઇન્ટરનેટ કનેક્શન નથી</translation>
<translation id="4588090240171750605">જમણે સ્ક્રોલ કરો</translation>
<translation id="4724120544754982507">સૂચના કેન્દ્ર, વાંચ્યા વગરની <ph name="UNREAD_NOTIFICATION_COUNT" /> સૂચનાઓ</translation>
<translation id="4730374152663651037">વારંવાર વપરાયેલ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ઍપ સૂચનો</translation>
<translation id="6364916375976753737">ડાબે સ્ક્રોલ કરો</translation>
<translation id="6394627529324717982">અલ્પવિરામ</translation>
+<translation id="6397363302884558537">બોલવાનું રોકો</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 સે પહેલાં}one{# સે પહેલાં}other{# સે પહેલાં}}</translation>
+<translation id="6430678249303439055">આ ઍપના બધા નોટિફિકેશનો અવરોધિત કરો</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 સેકંડ પહેલાં}one{# સેકંડ પહેલાં}other{# સેકંડ પહેલાં}}</translation>
<translation id="654149438358937226">તમામ નોટિફિકેશનને બ્લૉક કરો</translation>
<translation id="6567071839949112727">ઍન્સેસ્ટર પર ક્લિક કરો</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 વર્ષ બાકી}one{# વર્ષ બાકી}other{# વર્ષ બાકી}}</translation>
<translation id="6945221475159498467">પસંદ કરો</translation>
<translation id="6965382102122355670">બરાબર, સમજાઇ ગયું</translation>
+<translation id="6974053822202609517">જમણેથી ડાબે</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">સૌથી વધુ શક્ય</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">ડાબી કિનારી</translation>
<translation id="8331626408530291785">ઉપર સ્ક્રોલ કરો</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 વર્ષ}one{# વર્ષ}other{# વર્ષ}}</translation>
-<translation id="8371695176452482769">હવે બોલો</translation>
<translation id="838869780401515933">તપાસો</translation>
<translation id="8393700583063109961">સંદેશ મોકલો</translation>
<translation id="8394908167088220973">મીડિયા ચલાવો/થોભાવો</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> વધુ</translation>
<translation id="8730621377337864115">થઈ ગયું</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 ક}one{# ક}other{# ક}}</translation>
+<translation id="8798099450830957504">ડિફૉલ્ટ</translation>
<translation id="8806053966018712535"><ph name="FOLDER_NAME" /> ફોલ્ડર</translation>
<translation id="883911313571074303">છબીમાં ટીકા કરો</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_hi.xtb b/chromium/ui/strings/translations/ui_strings_hi.xtb
index 27e6d7f4216..aa6556d2906 100644
--- a/chromium/ui/strings/translations/ui_strings_hi.xtb
+++ b/chromium/ui/strings/translations/ui_strings_hi.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">अपलोड करें</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">सुझाए गए ऐप्लिकेशन</translation>
+<translation id="1368832886055348810">बाएं से दाएं</translation>
<translation id="1398853756734560583">बड़ा करें</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> से सूचनाएं अक्षम करें</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 मिनट और }one{# मिनट और }other{# मिनट और }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">तारा रेटिंग <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 घंटा और }one{# घंटे और }other{# घंटे और }}</translation>
<translation id="1842960171412779397">चुनें</translation>
+<translation id="1859234291848436338">लिखने के निर्देश</translation>
<translation id="1860796786778352021">सूचना बंद करें</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">पेज ऊपर</translation>
<translation id="2190355936436201913">(खाली)</translation>
<translation id="219905428774326614">लॉन्चर, सभी ऐप्लिकेशन</translation>
+<translation id="2267918077332197517">इस साइट से सभी सूचनाएं रोकें</translation>
<translation id="2289052229480071835">अपनी स्क्रीन पर स्पर्श लक्ष्य पर टैप करें.</translation>
<translation id="2295140143284145483">सर्वे</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">यहां तक स्क्रॉल करें</translation>
<translation id="3234408098842461169">नीचे तीर</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 दिन}one{# दिन}other{# दिन}}</translation>
+<translation id="335581015389089642">बोली</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 दिन शेष}one{# दिन शेष}other{# दिन शेष}}</translation>
+<translation id="3618849550573277856">“<ph name="LOOKUP_STRING" />” को खोजें</translation>
<translation id="364720409959344976">अपलोड करने के लिए फ़ोल्‍डर चुनें</translation>
<translation id="3660179305079774227">ऊपर तीर</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">जाएं</translation>
<translation id="4250229828105606438">स्क्रीनशॉट</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 माह पहले}one{# माह पहले}other{# माह पहले}}</translation>
+<translation id="4289300219472526559">बोलना प्रारंभ करें</translation>
<translation id="4316910396681052118">सभी ऐप्लिकेशन</translation>
-<translation id="4320177379694898372">कोई इंटरनेट कनेक्‍शन नहीं</translation>
<translation id="4588090240171750605">दाएं स्क्रॉल करें</translation>
<translation id="4724120544754982507">सूचना केंद्र, <ph name="UNREAD_NOTIFICATION_COUNT" /> गैर-पढ़ी गई सूचनाएं</translation>
<translation id="4730374152663651037">अक्सर उपयोग किए गए</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ऐप्लिकेशन सुझाव</translation>
<translation id="6364916375976753737">बाएं स्क्रॉल करें</translation>
<translation id="6394627529324717982">अल्पविराम</translation>
+<translation id="6397363302884558537">बोलना रोकें</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 सेकंड पहले}one{# सेकंड पहले}other{# सेकंड पहले}}</translation>
+<translation id="6430678249303439055">इस ऐप्लिकेशन से सभी सूचनाएं रोकें</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 सेकंड पहले}one{# सेकंड पहले}other{# सेकंड पहले}}</translation>
<translation id="654149438358937226">सभी सूचनाएं ब्लॉक करें</translation>
<translation id="6567071839949112727">पहले वाले पर क्लिक करें</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 वर्ष शेष}one{# वर्ष शेष}other{# वर्ष शेष}}</translation>
<translation id="6945221475159498467">चुनें</translation>
<translation id="6965382102122355670">ठीक है</translation>
+<translation id="6974053822202609517">दाएं से बाएं</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">सबसे अधिक संभावना है</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">बायां सिरा</translation>
<translation id="8331626408530291785">ऊपर स्क्रॉल करें</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 वर्ष}one{# वर्ष}other{# वर्ष}}</translation>
-<translation id="8371695176452482769">अब बोलें</translation>
<translation id="838869780401515933">चेक करें</translation>
<translation id="8393700583063109961">संदेश भेजें</translation>
<translation id="8394908167088220973">मीडिया चलाएं/रोकें</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> और</translation>
<translation id="8730621377337864115">पूर्ण</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1h}one{#h}other{#h}}</translation>
+<translation id="8798099450830957504">सामान्य</translation>
<translation id="8806053966018712535"><ph name="FOLDER_NAME" /> फ़ोल्डर</translation>
<translation id="883911313571074303">व्याख्या चित्र</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_hr.xtb b/chromium/ui/strings/translations/ui_strings_hr.xtb
index 564a135cf43..6cf47fc3fa9 100644
--- a/chromium/ui/strings/translations/ui_strings_hr.xtb
+++ b/chromium/ui/strings/translations/ui_strings_hr.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Prenesi</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">PREPORUČENE APLIKACIJE</translation>
+<translation id="1368832886055348810">Slijeva udesno</translation>
<translation id="1398853756734560583">Maksimiziraj</translation>
<translation id="1413622004203049571">Onemogući obavijesti pošiljatelja <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuta i }one{# minuta i }few{# minute i }other{# minuta i }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Broj zvjezdica: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 sat i }one{# sat i }few{# sata i }other{# sati i }}</translation>
<translation id="1842960171412779397">odaberi</translation>
+<translation id="1859234291848436338">Smjer pisanja</translation>
<translation id="1860796786778352021">Zatvaranje obavijesti</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Stranica prema gore</translation>
<translation id="2190355936436201913">(prazno)</translation>
<translation id="219905428774326614">Pokretač, sve aplikacije</translation>
+<translation id="2267918077332197517">Blokiraj sve obavijesti te web-lokacije</translation>
<translation id="2289052229480071835">Dodirnite ciljeve dodira na zaslonu.</translation>
<translation id="2295140143284145483">Anketa</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Pomakni ovdje</translation>
<translation id="3234408098842461169">Strelica dolje</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 dan}one{# dan}few{# dana}other{# dana}}</translation>
+<translation id="335581015389089642">Govor</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Još 1 dan}one{Još # dan}few{Još # dana}other{Još # dana}}</translation>
+<translation id="3618849550573277856">Potraži "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Odabir mape za prijenos</translation>
<translation id="3660179305079774227">Strelica prema gore</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">skoči</translation>
<translation id="4250229828105606438">Snimka zaslona</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Prije mjesec dana}one{Prije # mjeseca}few{Prije # mjeseca}other{Prije # mjeseci}}</translation>
+<translation id="4289300219472526559">Počni govoriti</translation>
<translation id="4316910396681052118">SVE APLIKACIJE</translation>
-<translation id="4320177379694898372">Nema internetske veze</translation>
<translation id="4588090240171750605">Pomakni se desno</translation>
<translation id="4724120544754982507">Centar za obavijesti, nepročitanih obavijesti: <ph name="UNREAD_NOTIFICATION_COUNT" /></translation>
<translation id="4730374152663651037">ČESTO KORIŠTENO</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">PRIJEDLOZI APLIKACIJA</translation>
<translation id="6364916375976753737">Pomakni se lijevo</translation>
<translation id="6394627529324717982">Zarez</translation>
+<translation id="6397363302884558537">Prestani govoriti</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Prije 1 s}one{Prije # s}few{Prije # s}other{Prije # s}}</translation>
+<translation id="6430678249303439055">Blokiraj sve obavijesti te aplikacije</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Prije 1 sekunde}one{Prije # sekunde}few{Prije # sekunde}other{Prije # sekundi}}</translation>
<translation id="654149438358937226">Blokiraj sve obavijesti</translation>
<translation id="6567071839949112727">klikni nadređeni element</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Još godinu dana}one{Još # godinu}few{Još # godine}other{Još # godina}}</translation>
<translation id="6945221475159498467">Odaberi</translation>
<translation id="6965382102122355670">U redu</translation>
+<translation id="6974053822202609517">Zdesna ulijevo</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">NAJVJEROJATNIJE</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Lijevi rub</translation>
<translation id="8331626408530291785">Pomakni se gore</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 godina}one{# godina}few{# godine}other{# godina}}</translation>
-<translation id="8371695176452482769">Govorite sad</translation>
<translation id="838869780401515933">označi</translation>
<translation id="8393700583063109961">Pošaljite poruku</translation>
<translation id="8394908167088220973">Reproduciraj/pauziraj Medije</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">Još <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Gotovo</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}one{# h}few{# h}other{# h}}</translation>
+<translation id="8798099450830957504">Zadano</translation>
<translation id="8806053966018712535">Mapa <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Dodaj napomenu slici</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_hu.xtb b/chromium/ui/strings/translations/ui_strings_hu.xtb
index d1b0ad2d6e5..0fdafd9d858 100644
--- a/chromium/ui/strings/translations/ui_strings_hu.xtb
+++ b/chromium/ui/strings/translations/ui_strings_hu.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Feltöltés</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">AJÁNLOTT ALKALMAZÁSOK</translation>
+<translation id="1368832886055348810">Balról jobbra</translation>
<translation id="1398853756734560583">Teljes méret</translation>
<translation id="1413622004203049571">A(z) <ph name="NOTIFIER_NAME" /> értesítéseinek kikapcsolása</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 perc és }other{# perc és }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144"><ph name="RATING_SCORE" /> csillagos értékelés</translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 óra és }other{# óra és }}</translation>
<translation id="1842960171412779397">Kiválasztás</translation>
+<translation id="1859234291848436338">Írás iránya</translation>
<translation id="1860796786778352021">Értesítés bezárása</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Oldal fel</translation>
<translation id="2190355936436201913">(üres)</translation>
<translation id="219905428774326614">Indító, minden alkalmazás</translation>
+<translation id="2267918077332197517">Minden értesítés letiltása erről a webhelyről</translation>
<translation id="2289052229480071835">Koppintson a képernyőn az érintési célpontokra.</translation>
<translation id="2295140143284145483">Felmérés</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Görgessen ide</translation>
<translation id="3234408098842461169">Lefelé nyíl</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 nap}other{# nap}}</translation>
+<translation id="335581015389089642">Beszéd</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 nap van hátra}other{# nap van hátra}}</translation>
+<translation id="3618849550573277856">A(z) „<ph name="LOOKUP_STRING" />” keresése</translation>
<translation id="364720409959344976">Mappa kiválasztása a feltöltéshez</translation>
<translation id="3660179305079774227">Felfelé nyíl</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">Mehet</translation>
<translation id="4250229828105606438">Képernyőkép</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 hónapja}other{# hónapja}}</translation>
+<translation id="4289300219472526559">Beszéd megkezdése</translation>
<translation id="4316910396681052118">MINDEN ALKALMAZÁS</translation>
-<translation id="4320177379694898372">Nincs internetkapcsolat</translation>
<translation id="4588090240171750605">Görgetés jobbra</translation>
<translation id="4724120544754982507">Értesítési központ, <ph name="UNREAD_NOTIFICATION_COUNT" /> olvasatlan értesítés</translation>
<translation id="4730374152663651037">GYAKRAN HASZNÁLT</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ALKALMAZÁSJAVASLATOK</translation>
<translation id="6364916375976753737">Görgetés balra</translation>
<translation id="6394627529324717982">Vessző</translation>
+<translation id="6397363302884558537">Beszéd leállítása</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 másodperce}other{# másodperce}}</translation>
+<translation id="6430678249303439055">Minden értesítés letiltása ettől az alkalmazástól</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 másodperce}other{# másodperce}}</translation>
<translation id="654149438358937226">Minden értesítés letiltása</translation>
<translation id="6567071839949112727">kattintás az elődre</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{hátralévő idő: 1 év}other{hátralévő idő: # év}}</translation>
<translation id="6945221475159498467">Kiválasztás</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Jobbról balra</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">NAGY VALÓSZÍNŰSÉGGEL</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Bal sarok</translation>
<translation id="8331626408530291785">Görgetés felfelé</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 év}other{# év}}</translation>
-<translation id="8371695176452482769">Most beszéljen</translation>
<translation id="838869780401515933">Megjelölés</translation>
<translation id="8393700583063109961">Üzenet küldése</translation>
<translation id="8394908167088220973">Lejátszás/szüneteltetés</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">és <ph name="NUMBER" /> további</translation>
<translation id="8730621377337864115">Kész</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 ó}other{# ó}}</translation>
+<translation id="8798099450830957504">Alapértelmezett</translation>
<translation id="8806053966018712535"><ph name="FOLDER_NAME" /> mappa</translation>
<translation id="883911313571074303">Megjegyzés fűzése a képhez</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_id.xtb b/chromium/ui/strings/translations/ui_strings_id.xtb
index 391851af169..e1c9196b510 100644
--- a/chromium/ui/strings/translations/ui_strings_id.xtb
+++ b/chromium/ui/strings/translations/ui_strings_id.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Upload</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">APLIKASI YANG DIREKOMENDASIKAN</translation>
+<translation id="1368832886055348810">Kiri ke Kanan</translation>
<translation id="1398853756734560583">Perbesar</translation>
<translation id="1413622004203049571">Nonaktifkan pemberitahuan dari <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 menit dan }other{# menit dan }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Skor bintang <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 jam dan }other{# jam dan }}</translation>
<translation id="1842960171412779397">pilih</translation>
+<translation id="1859234291848436338">Arah Penulisan</translation>
<translation id="1860796786778352021">Tutup pemberitahuan</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Page Up</translation>
<translation id="2190355936436201913">(kosong)</translation>
<translation id="219905428774326614">Peluncur, semua aplikasi</translation>
+<translation id="2267918077332197517">Blokir semua notifikasi dari situs ini</translation>
<translation id="2289052229480071835">Tap target sentuh di layar.</translation>
<translation id="2295140143284145483">Survei</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/dtk</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Gulir ke Sini</translation>
<translation id="3234408098842461169">Panah Bawah</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 hari}other{# hari}}</translation>
+<translation id="335581015389089642">Ucapan</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 hari lagi}other{# hari lagi}}</translation>
+<translation id="3618849550573277856">Cari "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Pilih Folder untuk Diunggah</translation>
<translation id="3660179305079774227">Panah Atas</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/dtk</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">lompati</translation>
<translation id="4250229828105606438">Screenshot</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 bulan yang lalu}other{# bulan yang lalu}}</translation>
+<translation id="4289300219472526559">Mulai Berbicara</translation>
<translation id="4316910396681052118">SEMUA APLIKASI</translation>
-<translation id="4320177379694898372">Tidak ada sambungan internet</translation>
<translation id="4588090240171750605">Gulir ke Kanan</translation>
<translation id="4724120544754982507">Pusat Notifikasi, <ph name="UNREAD_NOTIFICATION_COUNT" /> notifikasi belum dibaca</translation>
<translation id="4730374152663651037">SERING DIGUNAKAN</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SARAN APLIKASI</translation>
<translation id="6364916375976753737">Gulir ke Kiri</translation>
<translation id="6394627529324717982">Koma</translation>
+<translation id="6397363302884558537">Berhenti Berbicara</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 dtk yang lalu}other{# dtk yang lalu}}</translation>
+<translation id="6430678249303439055">Blokir semua notifikasi dari aplikasi ini</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 detik yang lalu}other{# detik yang lalu}}</translation>
<translation id="654149438358937226">Blokir semua notifikasi</translation>
<translation id="6567071839949112727">klik ancestor</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 tahun lagi}other{# tahun lagi}}</translation>
<translation id="6945221475159498467">Pilih</translation>
<translation id="6965382102122355670">Oke</translation>
+<translation id="6974053822202609517">Kanan ke Kiri</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">MUNGKIN DICARI</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Tepi Kiri</translation>
<translation id="8331626408530291785">Gulir ke Atas</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 tahun}other{# tahun}}</translation>
-<translation id="8371695176452482769">Bicaralah sekarang</translation>
<translation id="838869780401515933">centangi</translation>
<translation id="8393700583063109961">Kirim pesan</translation>
<translation id="8394908167088220973">Putar/Jeda Media</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> lagi</translation>
<translation id="8730621377337864115">Selesai</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1j}other{#j}}</translation>
+<translation id="8798099450830957504">Default</translation>
<translation id="8806053966018712535">Folder <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Gambar anotasi</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_it.xtb b/chromium/ui/strings/translations/ui_strings_it.xtb
index ef6e1c7e37f..332b8572fe1 100644
--- a/chromium/ui/strings/translations/ui_strings_it.xtb
+++ b/chromium/ui/strings/translations/ui_strings_it.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Carica</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">APP CONSIGLIATE</translation>
+<translation id="1368832886055348810">Da sinistra a destra</translation>
<translation id="1398853756734560583">Ingrandisci</translation>
<translation id="1413622004203049571">Disabilita notifiche da <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuto e }other{# minuti e }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Valutazione a stelle: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 ora e }other{# ore e }}</translation>
<translation id="1842960171412779397">seleziona</translation>
+<translation id="1859234291848436338">Direzione di scrittura</translation>
<translation id="1860796786778352021">Chiusura notifica</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Pagina su</translation>
<translation id="2190355936436201913">(vuoto)</translation>
<translation id="219905428774326614">Avvio applicazioni, tutte le app</translation>
+<translation id="2267918077332197517">Blocca tutte le notifiche da questo sito</translation>
<translation id="2289052229480071835">Tocca i touch target sul tuo schermo.</translation>
<translation id="2295140143284145483">Sondaggio</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Scorri fino a qui</translation>
<translation id="3234408098842461169">Freccia GIÙ</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 giorno}other{# giorni}}</translation>
+<translation id="335581015389089642">Voce</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 giorno rimanente}other{# giorni rimanenti}}</translation>
+<translation id="3618849550573277856">Cerca "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Seleziona la cartella da caricare</translation>
<translation id="3660179305079774227">Freccia SU</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">vai</translation>
<translation id="4250229828105606438">Screenshot</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 mese fa}other{# mesi fa}}</translation>
+<translation id="4289300219472526559">Avvia comandi vocali</translation>
<translation id="4316910396681052118">TUTTE LE APP</translation>
-<translation id="4320177379694898372">Nessuna connessione Internet</translation>
<translation id="4588090240171750605">Scorri a destra</translation>
<translation id="4724120544754982507">Centro notifiche, <ph name="UNREAD_NOTIFICATION_COUNT" /> notifiche da leggere</translation>
<translation id="4730374152663651037">USATE SPESSO</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">APP SUGGERITE</translation>
<translation id="6364916375976753737">Scorri a sinistra</translation>
<translation id="6394627529324717982">Virgola</translation>
+<translation id="6397363302884558537">Interrompi comandi vocali</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 sec fa}other{# sec fa}}</translation>
+<translation id="6430678249303439055">Blocca tutte le notifiche da questa app</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 secondo fa}other{# secondi fa}}</translation>
<translation id="654149438358937226">Blocca tutte le notifiche</translation>
<translation id="6567071839949112727">fai clic su predecessore</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 anno rimasto}other{# anni rimasti}}</translation>
<translation id="6945221475159498467">Seleziona</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Da destra a sinistra</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">PIÙ PROBABILI</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Margine sinistro</translation>
<translation id="8331626408530291785">Scorri verso l'alto</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 anno}other{# anni}}</translation>
-<translation id="8371695176452482769">Parla adesso</translation>
<translation id="838869780401515933">seleziona</translation>
<translation id="8393700583063109961">Invia messaggio</translation>
<translation id="8394908167088220973">Play/Pausa contenuti multimediali</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+ altre <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Fine</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}other{# h}}</translation>
+<translation id="8798099450830957504">Predefinito</translation>
<translation id="8806053966018712535">Cartella <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Annota immagine</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_iw.xtb b/chromium/ui/strings/translations/ui_strings_iw.xtb
index ff517ff09f3..3bb12bb04df 100644
--- a/chromium/ui/strings/translations/ui_strings_iw.xtb
+++ b/chromium/ui/strings/translations/ui_strings_iw.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">העלה</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">אפליקציות מומלצות</translation>
+<translation id="1368832886055348810">משמאל לימין</translation>
<translation id="1398853756734560583">הגדל</translation>
<translation id="1413622004203049571">השבת הודעות מאת <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{דקה אחת ו }two{# דקות ו }many{# דקות ו }other{# דקות ו }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">דירוג כוכבים: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{שעה אחת ו }two{שעתיים ו }many{# שעות ו }other{# שעות ו }}</translation>
<translation id="1842960171412779397">בחר</translation>
+<translation id="1859234291848436338">כיוון כתיבה</translation>
<translation id="1860796786778352021">סגירת הודעה</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652">%<ph name="NUMBER" /></translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">דף למעלה</translation>
<translation id="2190355936436201913">(ריק)</translation>
<translation id="219905428774326614">מפעיל האפליקציות, כל האפליקציות</translation>
+<translation id="2267918077332197517">חסימת כל ההודעות מהאתר הזה</translation>
<translation id="2289052229480071835">הקש על יעדי המגע במסך.</translation>
<translation id="2295140143284145483">סקר</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">גלול ל'כאן'</translation>
<translation id="3234408098842461169">חץ למטה</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{יום אחד}two{יומיים}many{# ימים}other{# ימים}}</translation>
+<translation id="335581015389089642">דיבור</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{נותר יום אחד}two{נותרו יומיים}many{נותרו # ימים}other{נותרו # ימים}}</translation>
+<translation id="3618849550573277856">חפש “<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">בחירת תיקיה להעלאה</translation>
<translation id="3660179305079774227">חץ למעלה</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">קפוץ</translation>
<translation id="4250229828105606438">צילום מסך</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{לפני חודש אחד}two{לפני חודשיים}many{לפני # חודשים}other{לפני # חודשים}}</translation>
+<translation id="4289300219472526559">התחל לדבר</translation>
<translation id="4316910396681052118">כל האפליקציות</translation>
-<translation id="4320177379694898372">אין חיבור לאינטרנט</translation>
<translation id="4588090240171750605">גלול ימינה</translation>
<translation id="4724120544754982507">מרכז הודעות, <ph name="UNREAD_NOTIFICATION_COUNT" /> הודעות שלא נקראו</translation>
<translation id="4730374152663651037">בשימוש לעתים קרובות</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">הצעות לאפליקציות</translation>
<translation id="6364916375976753737">גלול שמאלה</translation>
<translation id="6394627529324717982">פסיק</translation>
+<translation id="6397363302884558537">הפסק לדבר</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{לפני שנ‘ אחת}two{לפני # שנ‘}many{לפני # שנ‘}other{לפני # שנ‘}}</translation>
+<translation id="6430678249303439055">חסימת כל ההודעות מהאפליקציה הזו</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{לפני שנייה אחת}two{לפני # שניות}many{לפני # שניות}other{לפני # שניות}}</translation>
<translation id="654149438358937226">חסימת כל ההודעות</translation>
<translation id="6567071839949112727">לחיצה על אב</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{נותרה שנה אחת}two{נותרו שנתיים}many{נותרו # שנים}other{נותרו # שנים}}</translation>
<translation id="6945221475159498467">בחר</translation>
<translation id="6965382102122355670">אישור</translation>
+<translation id="6974053822202609517">מימין לשמאל</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">סבירות גבוהה</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">קצה שמאלי</translation>
<translation id="8331626408530291785">גלול למעלה</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{שנה אחת}two{שנתיים}many{# שנים}other{# שנים}}</translation>
-<translation id="8371695176452482769">דבר עכשיו</translation>
<translation id="838869780401515933">סמן</translation>
<translation id="8393700583063109961">שלח הודעה</translation>
<translation id="8394908167088220973">הפעלה/השהיה של המדיה</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">ועוד <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">בוצע</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{שעה}two{# שע}many{# שע}other{# שע}}</translation>
+<translation id="8798099450830957504">ברירת מחדל</translation>
<translation id="8806053966018712535">תיקייה <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">רשום הערה לתמונה</translation>
<translation id="8901569739625249689">‏<ph name="QUANTITY" /> KB‏</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_ja.xtb b/chromium/ui/strings/translations/ui_strings_ja.xtb
index f34ab50f6ed..ff073ffb2b4 100644
--- a/chromium/ui/strings/translations/ui_strings_ja.xtb
+++ b/chromium/ui/strings/translations/ui_strings_ja.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">アップロード</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">おすすめのアプリ</translation>
+<translation id="1368832886055348810">左から右</translation>
<translation id="1398853756734560583">最大化</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> からの通知を無効にする</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 分 }other{# 分 }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">評価 <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 時間 }other{# 時間 }}</translation>
<translation id="1842960171412779397">選択</translation>
+<translation id="1859234291848436338">文章の方向</translation>
<translation id="1860796786778352021">通知を閉じる</translation>
<translation id="1871244248791675517">Insert</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">前のページへ</translation>
<translation id="2190355936436201913">(なし)</translation>
<translation id="219905428774326614">ランチャー、すべてのアプリ</translation>
+<translation id="2267918077332197517">このサイトからのすべての通知をブロックする</translation>
<translation id="2289052229480071835">画面に表示されるタップ ターゲットをタップします。</translation>
<translation id="2295140143284145483">アンケート</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/秒</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">ここまでスクロール</translation>
<translation id="3234408098842461169">下矢印キー</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 日}other{# 日}}</translation>
+<translation id="335581015389089642">スピーチ</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{残り 1 日}other{残り # 日}}</translation>
+<translation id="3618849550573277856">「<ph name="LOOKUP_STRING" />」を検索</translation>
<translation id="364720409959344976">アップロードするフォルダを選択</translation>
<translation id="3660179305079774227">上矢印キー</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/秒</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">ジャンプ</translation>
<translation id="4250229828105606438">スクリーンショット</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 か月前}other{# か月前}}</translation>
+<translation id="4289300219472526559">読み上げを開始</translation>
<translation id="4316910396681052118">すべてのアプリ</translation>
-<translation id="4320177379694898372">インターネットに接続されていません</translation>
<translation id="4588090240171750605">右にスクロール</translation>
<translation id="4724120544754982507">通知センター: <ph name="UNREAD_NOTIFICATION_COUNT" /> 件の未読通知</translation>
<translation id="4730374152663651037">よく使用するアプリ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">アプリの候補</translation>
<translation id="6364916375976753737">左にスクロール</translation>
<translation id="6394627529324717982">カンマ</translation>
+<translation id="6397363302884558537">読み上げを停止</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 秒前}other{# 秒前}}</translation>
+<translation id="6430678249303439055">このアプリからのすべての通知をブロックする</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 秒前}other{# 秒前}}</translation>
<translation id="654149438358937226">通知をすべてブロックする</translation>
<translation id="6567071839949112727">上位要素をクリック</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{残り 1 年}other{残り # 年}}</translation>
<translation id="6945221475159498467">選択</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">右から左</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">これですか?</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">左端</translation>
<translation id="8331626408530291785">上にスクロール</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 年}other{# 年}}</translation>
-<translation id="8371695176452482769">お話しください</translation>
<translation id="838869780401515933">チェックを付ける</translation>
<translation id="8393700583063109961">メッセージを送信</translation>
<translation id="8394908167088220973">メディアの再生/一時停止</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">他 <ph name="NUMBER" /> 件</translation>
<translation id="8730621377337864115">完了</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1時間}other{#時間}}</translation>
+<translation id="8798099450830957504">既定</translation>
<translation id="8806053966018712535">フォルダ <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">画像に注釈を付ける</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_kn.xtb b/chromium/ui/strings/translations/ui_strings_kn.xtb
index 4e9c9f7b35d..28bd579f118 100644
--- a/chromium/ui/strings/translations/ui_strings_kn.xtb
+++ b/chromium/ui/strings/translations/ui_strings_kn.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">ಅಪ್‌ಲೋಡ್</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ಶಿಫಾರಸು ಮಾಡಲಾದ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು</translation>
+<translation id="1368832886055348810">ಎಡದಿಂದ ಬಲಕ್ಕೆ</translation>
<translation id="1398853756734560583">ಗರಿಷ್ಠಗೊಳಿಸು</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> ಅವರ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 ನಿಮಿಷ ಮತ್ತು }one{# ನಿಮಿಷಗಳು ಮತ್ತು }other{# ನಿಮಿಷಗಳು ಮತ್ತು }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">ಸ್ಟಾರ್ ರೇಟಿಂಗ್ <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 ಗಂಟೆ ಮತ್ತು }one{# ಗಂಟೆಗಳು ಮತ್ತು }other{# ಗಂಟೆಗಳು ಮತ್ತು }}</translation>
<translation id="1842960171412779397">ಆಯ್ಕೆ ಮಾಡಿ</translation>
+<translation id="1859234291848436338">ಬರವಣಿಗೆ ನಿರ್ದೇಶನ</translation>
<translation id="1860796786778352021">ಅಧಿಸೂಚನೆ ಮುಚ್ಚು</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">ಪುಟ ಮೇಲೆ</translation>
<translation id="2190355936436201913">(ಖಾಲಿ)</translation>
<translation id="219905428774326614">ಲಾಂಚರ್‌, ಎಲ್ಲಾ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು</translation>
+<translation id="2267918077332197517">ಈ ಸೈಟ್‌ನಿಂದ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ</translation>
<translation id="2289052229480071835">ನಿಮ್ಮ ಪರದೆಯಲ್ಲಿ ಸ್ಪರ್ಶ ಟಾರ್ಗೆಟ್‌ಗಳನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ.</translation>
<translation id="2295140143284145483">ಸಮೀಕ್ಷೆ</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">ಇಲ್ಲಿಗೆ ಸ್ಕ್ರೋಲ್ ಮಾಡಿ</translation>
<translation id="3234408098842461169">ಕೆಳಗಿನ ಬಾಣದ ಗುರುತು</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 ದಿನ}one{# ದಿನಗಳು}other{# ದಿನಗಳು}}</translation>
+<translation id="335581015389089642">ಧ್ವನಿ</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 ದಿನ ಬಾಕಿ ಉಳಿದಿದೆ}one{# ದಿನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ}other{# ದಿನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ}}</translation>
+<translation id="3618849550573277856">“<ph name="LOOKUP_STRING" />” ನೋಡಿ</translation>
<translation id="364720409959344976">ಅಪ್‌ಲೋಡ್ ಮಾಡಲು ಫೋಲ್ಡರ್ ಆಯ್ಕೆಮಾಡಿ</translation>
<translation id="3660179305079774227">ಮೇಲಿನ ಬಾಣದ ಗುರುತು</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">ಹಾರು</translation>
<translation id="4250229828105606438">ಸ್ಕ್ರೀನ್‌ಶಾಟ್</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 ತಿಂಗಳ ಹಿಂದೆ}one{# ತಿಂಗಳುಗಳ ಹಿಂದೆ}other{# ತಿಂಗಳುಗಳ ಹಿಂದೆ}}</translation>
+<translation id="4289300219472526559">ಮಾತನಾಡುವುದನ್ನು ಪ್ರಾರಂಭಿಸಿ</translation>
<translation id="4316910396681052118">ಎಲ್ಲಾ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು</translation>
-<translation id="4320177379694898372">ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವಿಲ್ಲ</translation>
<translation id="4588090240171750605">ಬಲಕ್ಕೆ ಸ್ಕ್ರೋಲ್ ಮಾಡಿ</translation>
<translation id="4724120544754982507">ಅಧಿಸೂಚನೆ ಕೇಂದ್ರ, <ph name="UNREAD_NOTIFICATION_COUNT" /> ಓದದಿರುವ ಅಧಿಸೂಚನೆಗಳು</translation>
<translation id="4730374152663651037">ಪದೇ ಪದೇ ಬಳಸಿರುವುದು</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ಅಪ್ಲಿಕೇಶನ್ ಸಲಹೆಗಳು</translation>
<translation id="6364916375976753737">ಎಡಕ್ಕೆ ಸ್ಕ್ರೋಲ್ ಮಾಡಿ</translation>
<translation id="6394627529324717982">ಅರ್ಧವಿರಾಮ</translation>
+<translation id="6397363302884558537">ಮಾತನಾಡುವುದನ್ನು ನಿಲ್ಲಿಸಿ</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 ಸೆಕೆಂ ಹಿಂದೆ}one{# ಸೆಕೆಂಡುಗಳ ಹಿಂದೆ}other{# ಸೆಕೆಂಡುಗಳ ಹಿಂದೆ}}</translation>
+<translation id="6430678249303439055">ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಿಂದ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 ಸೆಕೆಂಡ್ ಹಿಂದೆ}one{# ಸೆಕೆಂಡುಗಳ ಹಿಂದೆ}other{# ಸೆಕೆಂಡುಗಳ ಹಿಂದೆ}}</translation>
<translation id="654149438358937226">ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿರ್ಬಂಧಿಸಿ</translation>
<translation id="6567071839949112727">ಪೂರ್ವಜರನ್ನು ಕ್ಲಿಕ್ ಮಾಡಿ</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 ವರ್ಷ ಉಳಿದಿದೆ}one{# ವರ್ಷಗಳು ಉಳಿದಿವೆ}other{# ವರ್ಷಗಳು ಉಳಿದಿವೆ}}</translation>
<translation id="6945221475159498467">ಆಯ್ಕೆಮಾಡಿ</translation>
<translation id="6965382102122355670">ಸರಿ</translation>
+<translation id="6974053822202609517">ಬಲದಿಂದ ಎಡಕ್ಕೆ</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">ಹೆಚ್ಚಿನ ಸಾಧ್ಯತೆ ಇದೆ</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">ಎಡ ಬದಿ</translation>
<translation id="8331626408530291785">ಮೇಲೆ ಸ್ಕ್ರೋಲ್ ಮಾಡು</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 ವರ್ಷ}one{# ವರ್ಷಗಳು}other{# ವರ್ಷಗಳು}}</translation>
-<translation id="8371695176452482769">ಈಗ ಮಾತನಾಡಿ</translation>
<translation id="838869780401515933">ಪರಿಶೀಲಿಸಿ</translation>
<translation id="8393700583063109961">ಸಂದೇಶ ಕಳುಹಿಸು</translation>
<translation id="8394908167088220973">ಮೀಡಿಯಾ ಪ್ಲೇ/ವಿರಾಮ</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+ <ph name="NUMBER" /> ಇನ್ನಷ್ಟು</translation>
<translation id="8730621377337864115">ಮುಗಿದಿದೆ</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1ಗಂ}one{#ಗಂ}other{#ಗಂ}}</translation>
+<translation id="8798099450830957504">ಡಿಫಾಲ್ಟ್</translation>
<translation id="8806053966018712535">ಫೋಲ್ಡರ್ <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">ಚಿತ್ರವನ್ನು ಟಿಪ್ಪಣಿ ಮಾಡಿ</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_ko.xtb b/chromium/ui/strings/translations/ui_strings_ko.xtb
index 851abf243bc..b0e7af9a5a5 100644
--- a/chromium/ui/strings/translations/ui_strings_ko.xtb
+++ b/chromium/ui/strings/translations/ui_strings_ko.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">업로드</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">추천 앱</translation>
+<translation id="1368832886055348810">왼쪽에서 오른쪽으로</translation>
<translation id="1398853756734560583">최대화</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" />의 알림 사용 중지</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1분 }other{#분 }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">별표 평점: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1시간 }other{#시간 }}</translation>
<translation id="1842960171412779397">선택</translation>
+<translation id="1859234291848436338">쓰기 방향</translation>
<translation id="1860796786778352021">알림 닫기</translation>
<translation id="1871244248791675517">Insert</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">페이지 위로</translation>
<translation id="2190355936436201913">(비어있음)</translation>
<translation id="219905428774326614">런처, 모든 앱</translation>
+<translation id="2267918077332197517">이 사이트의 모든 알림 차단</translation>
<translation id="2289052229480071835">화면에서 터치 대상을 탭하세요.</translation>
<translation id="2295140143284145483">설문조사</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" />TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">여기로 스크롤</translation>
<translation id="3234408098842461169">아래 화살표</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1일}other{#일}}</translation>
+<translation id="335581015389089642">음성</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1일 남음}other{#일 남음}}</translation>
+<translation id="3618849550573277856">'<ph name="LOOKUP_STRING" />' 찾기</translation>
<translation id="364720409959344976">업로드할 폴더 선택</translation>
<translation id="3660179305079774227">위쪽 화살표</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" />GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">건너뛰기</translation>
<translation id="4250229828105606438">캡처화면</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1개월 전}other{#개월 전}}</translation>
+<translation id="4289300219472526559">말하기 시작</translation>
<translation id="4316910396681052118">모든 앱</translation>
-<translation id="4320177379694898372">인터넷에 연결되지 않음</translation>
<translation id="4588090240171750605">오른쪽 스크롤</translation>
<translation id="4724120544754982507">알림 센터, 읽지 않은 알림 <ph name="UNREAD_NOTIFICATION_COUNT" />개</translation>
<translation id="4730374152663651037">자주 사용하는 앱</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">앱 추천</translation>
<translation id="6364916375976753737">왼쪽으로 스크롤</translation>
<translation id="6394627529324717982">콤마</translation>
+<translation id="6397363302884558537">말하기 중지</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1초 전}other{#초 전}}</translation>
+<translation id="6430678249303439055">이 앱의 모든 알림 차단</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1초 전}other{#초 전}}</translation>
<translation id="654149438358937226">모든 알림 차단</translation>
<translation id="6567071839949112727">상위 개체 클릭</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1년 남음}other{#년 남음}}</translation>
<translation id="6945221475159498467">선택</translation>
<translation id="6965382102122355670">확인</translation>
+<translation id="6974053822202609517">오른쪽에서 왼쪽으로</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">사용할 만한 앱</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">왼쪽 모서리</translation>
<translation id="8331626408530291785">위로 스크롤</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1년}other{#년}}</translation>
-<translation id="8371695176452482769">말하세요</translation>
<translation id="838869780401515933">선택</translation>
<translation id="8393700583063109961">메시지 보내기</translation>
<translation id="8394908167088220973">미디어 재생/일시중지</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" />개</translation>
<translation id="8730621377337864115">완료</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1시간}other{#시간}}</translation>
+<translation id="8798099450830957504">기본값</translation>
<translation id="8806053966018712535"><ph name="FOLDER_NAME" /> 폴더</translation>
<translation id="883911313571074303">이미지에 주석 달기</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" />KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_lt.xtb b/chromium/ui/strings/translations/ui_strings_lt.xtb
index a25a968e5f5..fe75e98d64e 100644
--- a/chromium/ui/strings/translations/ui_strings_lt.xtb
+++ b/chromium/ui/strings/translations/ui_strings_lt.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Įkelti</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">REKOMENDUOJAMOS PROGRAMOS</translation>
+<translation id="1368832886055348810">Iš kairės į dešinę</translation>
<translation id="1398853756734560583">Išskleisti</translation>
<translation id="1413622004203049571">Išjungti pranešimus nuo <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minutė ir }one{# minutė ir }few{# minutės ir }many{# minutės ir }other{# minučių ir }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Įvertinimas žvaigždutėmis <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 valanda ir }one{# valanda ir }few{# valandos ir }many{# valandos ir }other{# valandų ir }}</translation>
<translation id="1842960171412779397">pasirinkti</translation>
+<translation id="1859234291848436338">Rašymo nurodymas</translation>
<translation id="1860796786778352021">Uždaryti pranešimus</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Puslapį į viršų</translation>
<translation id="2190355936436201913">(tuščias)</translation>
<translation id="219905428774326614">Paleidimo priemonė, visos programos</translation>
+<translation id="2267918077332197517">Blokuoti visus šios svetainės pranešimus</translation>
<translation id="2289052229480071835">Palieskite jutiklines sritis ekrane.</translation>
<translation id="2295140143284145483">Apklausa</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Slinkti iki čia</translation>
<translation id="3234408098842461169">Rodyklė „Žemyn“</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 diena}one{# diena}few{# dienos}many{# dienos}other{# dienų}}</translation>
+<translation id="335581015389089642">Kalba</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Liko 1 diena}one{Liko # diena}few{Liko # dienos}many{Liko # dienos}other{Liko # dienų}}</translation>
+<translation id="3618849550573277856">Ieškoti „<ph name="LOOKUP_STRING" />“</translation>
<translation id="364720409959344976">Pasirinkite norimą įkelti aplanką</translation>
<translation id="3660179305079774227">Rodyklė „Aukštyn“</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">peršokti</translation>
<translation id="4250229828105606438">Ekrano kopija</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Prieš 1 mėnesį}one{Prieš # mėnesį}few{Prieš # mėnesius}many{Prieš # mėnesio}other{Prieš # mėnesių}}</translation>
+<translation id="4289300219472526559">Pradėti kalbėti</translation>
<translation id="4316910396681052118">VISOS PROGRAMOS</translation>
-<translation id="4320177379694898372">Nėra interneto ryšio</translation>
<translation id="4588090240171750605">Slinkti į dešinę</translation>
<translation id="4724120544754982507">Pranešimų centras, neskaitytų pranešimų: <ph name="UNREAD_NOTIFICATION_COUNT" /></translation>
<translation id="4730374152663651037">DAŽNAI NAUDOJAMOS PROGRAMOS</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">PROGRAMŲ PASIŪLYMAI</translation>
<translation id="6364916375976753737">Slinkti į kairę</translation>
<translation id="6394627529324717982">Kablelis</translation>
+<translation id="6397363302884558537">Baigti kalbėti</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Prieš 1 sek.}one{Prieš # sek.}few{Prieš # sek.}many{Prieš # sek.}other{Prieš # sek.}}</translation>
+<translation id="6430678249303439055">Blokuoti visus šios programos pranešimus</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Prieš 1 sekundę}one{Prieš # sekundę}few{Prieš # sekundes}many{Prieš # sekundės}other{Prieš # sekundžių}}</translation>
<translation id="654149438358937226">Blokuoti visus pranešimus</translation>
<translation id="6567071839949112727">spustelėti aukštesnio lygmens elementą</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Liko 1 metai}one{Liko # metai}few{Liko # metai}many{Liko # metų}other{Liko # metų}}</translation>
<translation id="6945221475159498467">Pasirinkti</translation>
<translation id="6965382102122355670">Gerai</translation>
+<translation id="6974053822202609517">Iš dešinės į kairę</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">TIKRIAUSIAI SPUSTELĖJAMOS PROGRAMOS</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Kairysis kraštas</translation>
<translation id="8331626408530291785">Slinkti į viršų</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 metai}one{# metai}few{# metai}many{# metų}other{# metų}}</translation>
-<translation id="8371695176452482769">Kalbėti dabar</translation>
<translation id="838869780401515933">tikrinti</translation>
<translation id="8393700583063109961">Siųsti pranešimą</translation>
<translation id="8394908167088220973">Leisti / pristabdyti mediją</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">Dar <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Atlikta</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 val.}one{# val.}few{# val.}many{# val.}other{# val.}}</translation>
+<translation id="8798099450830957504">Numatytasis</translation>
<translation id="8806053966018712535">Aplankas „<ph name="FOLDER_NAME" />“</translation>
<translation id="883911313571074303">Komentuoti vaizdą</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_lv.xtb b/chromium/ui/strings/translations/ui_strings_lv.xtb
index b375e7fe370..66b620dbcc7 100644
--- a/chromium/ui/strings/translations/ui_strings_lv.xtb
+++ b/chromium/ui/strings/translations/ui_strings_lv.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Augšupielādēt</translation>
<translation id="1293699935367580298">Atsolis</translation>
<translation id="1306549533752902673">IETEIKTĀS LIETOTNES</translation>
+<translation id="1368832886055348810">No kreisās uz labo pusi</translation>
<translation id="1398853756734560583">Maksimizēt</translation>
<translation id="1413622004203049571">Atspējot paziņojumu saņemšanu no: <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minūte un }zero{# minūtes un }one{# minūte un }other{# minūtes un }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Sākt vērtēt <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 stunda un }zero{# stundas un }one{# stunda un }other{# stundas un }}</translation>
<translation id="1842960171412779397">Atlasiet</translation>
+<translation id="1859234291848436338">Rakstīšanas virziens</translation>
<translation id="1860796786778352021">Paziņojuma aizvēršana</translation>
<translation id="1871244248791675517">Iespraušana</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Augšup</translation>
<translation id="2190355936436201913">(tukšs)</translation>
<translation id="219905428774326614">Palaišanas programma, visas lietotnes</translation>
+<translation id="2267918077332197517">Bloķēt visus paziņojumus no šīs vietnes</translation>
<translation id="2289052229480071835">Pieskarieties ekrānā redzamajiem pieskāriena mērķiem.</translation>
<translation id="2295140143284145483">Aptauja</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Ritināt šeit</translation>
<translation id="3234408098842461169">Bulta Lejup</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 diena}zero{# dienas}one{# diena}other{# dienas}}</translation>
+<translation id="335581015389089642">Runa</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Atlikusi 1 diena}zero{Atlikušas # dienas}one{Atlikusi # diena}other{Atlikušas # dienas}}</translation>
+<translation id="3618849550573277856">Meklēt “<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Augšupielādējamās mapes atlase</translation>
<translation id="3660179305079774227">Bulta augšup</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">lekt</translation>
<translation id="4250229828105606438">Ekrānuzņēmums</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Pirms 1 mēneša}zero{Pirms # mēnešiem}one{Pirms # mēneša}other{Pirms # mēnešiem}}</translation>
+<translation id="4289300219472526559">Sākt runāt</translation>
<translation id="4316910396681052118">VISAS LIETOTNES</translation>
-<translation id="4320177379694898372">Nav interneta savienojuma.</translation>
<translation id="4588090240171750605">Ritināt pa labi</translation>
<translation id="4724120544754982507">Paziņojumu centrs, <ph name="UNREAD_NOTIFICATION_COUNT" /> nelasīts(-i) paziņojums(-i)</translation>
<translation id="4730374152663651037">BIEŽI IZMANTOTĀS</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">LIETOTŅU IETEIKUMI</translation>
<translation id="6364916375976753737">Ritināt pa kreisi</translation>
<translation id="6394627529324717982">Komats</translation>
+<translation id="6397363302884558537">Pārtraukt runāt</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Pirms 1 s}zero{Pirms # s}one{Pirms # s}other{Pirms # s}}</translation>
+<translation id="6430678249303439055">Bloķēt visus paziņojumus no šīs lietotnes</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Pirms 1 sekundes}zero{Pirms # sekundēm}one{Pirms # sekundes}other{Pirms # sekundēm}}</translation>
<translation id="654149438358937226">Bloķēt visus paziņojumus</translation>
<translation id="6567071839949112727">noklikšķināt uz priekšteča</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Atlicis 1 gads}zero{Atlikuši # gadi}one{Atlicis # gads}other{Atlikuši # gadi}}</translation>
<translation id="6945221475159498467">Atlasīt</translation>
<translation id="6965382102122355670">Labi</translation>
+<translation id="6974053822202609517">No labās uz kreiso pusi</translation>
<translation id="7052633198403197513">taustiņš F1</translation>
<translation id="7130207228079676353">VISTICAMĀK</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Kreisā mala</translation>
<translation id="8331626408530291785">Ritināt augšup</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 gads}zero{# gadu}one{# gads}other{# gadi}}</translation>
-<translation id="8371695176452482769">Runājiet tūlīt</translation>
<translation id="838869780401515933">prbaudt</translation>
<translation id="8393700583063109961">Sūtīt ziņojumu</translation>
<translation id="8394908167088220973">Multivide — atskaņot/apturēt</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">vēl <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Gatavs</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}zero{# h}one{# h}other{# h}}</translation>
+<translation id="8798099450830957504">Noklusējums</translation>
<translation id="8806053966018712535">Mape <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Anotēt attēlu</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_ml.xtb b/chromium/ui/strings/translations/ui_strings_ml.xtb
index af6b8fc8961..e70bb0a838f 100644
--- a/chromium/ui/strings/translations/ui_strings_ml.xtb
+++ b/chromium/ui/strings/translations/ui_strings_ml.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">അപ്‌ലോഡുചെയ്യുക</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ശുപാർശിത ആപ്പുകൾ</translation>
+<translation id="1368832886055348810">ഇടതുനിന്ന് വലത്തേക്ക്</translation>
<translation id="1398853756734560583">വലുതാക്കുക</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> എന്നതിൽ നിന്നുള്ള അറിയിപ്പുകൾ പ്രവർത്തനരഹിതമാക്കുക</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{ഒരു മിനിറ്റും }other{# മിനിറ്റും }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">നക്ഷത്ര റേറ്റിംഗ് <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{ഒരു മണിക്കൂറും }other{# മണിക്കൂറും }}</translation>
<translation id="1842960171412779397">തിരഞ്ഞെടുക്കൂ</translation>
+<translation id="1859234291848436338">എഴുതേണ്ട ദിശ</translation>
<translation id="1860796786778352021">അറിയിപ്പ് അടയ്‌ക്കൽ</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">പേജ് മുകളിലേയ്ക്ക്</translation>
<translation id="2190355936436201913">(ശൂന്യം)</translation>
<translation id="219905428774326614">ലോഞ്ചർ, എല്ലാ ആപ്പുകളും</translation>
+<translation id="2267918077332197517">ഈ സൈറ്റിൽ നിന്നുള്ള എല്ലാ അറിയിപ്പുകളും ബ്ലോക്ക് ചെയ്യുക</translation>
<translation id="2289052229480071835">സ്‌ക്രീനിലുള്ള 'ടാർഗെറ്റുകൾ സ്‌പർശിക്കുക' ടാപ്പുചെയ്യുക.</translation>
<translation id="2295140143284145483">സർവ്വേ</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">ഇവിടെ സ്ക്രോള്‍ ചെയ്യുക</translation>
<translation id="3234408098842461169">താഴേക്കുള്ള ആരോ അടയാളം</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{ഒരു ദിവസം}other{# ദിവസം}}</translation>
+<translation id="335581015389089642">സംഭാഷണം</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{ഒരു ദിവസം ശേഷിക്കുന്നു}other{# ദിവസം ശേഷിക്കുന്നു}}</translation>
+<translation id="3618849550573277856">“<ph name="LOOKUP_STRING" />” തിരയുക</translation>
<translation id="364720409959344976">അപ്‌ലോഡുചെയ്യുന്നതിന് ഫോൾഡർ തിരഞ്ഞെടുക്കുക</translation>
<translation id="3660179305079774227">മുകളിലേക്കുള്ള അമ്പടയാളം</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">jump</translation>
<translation id="4250229828105606438">സ്‌ക്രീൻഷോട്ട്</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{ഒരു മാസം മുമ്പ്}other{# മാസം മുമ്പ്}}</translation>
+<translation id="4289300219472526559">സംഭാഷണം ആരംഭിക്കുക</translation>
<translation id="4316910396681052118">എല്ലാ ആപ്പുകളും</translation>
-<translation id="4320177379694898372">ഇന്റർനെറ്റ് കണക്ഷനൊന്നുമില്ല</translation>
<translation id="4588090240171750605">വലത്തോട്ട് സ്ക്രോള്‍ ചെയ്യുക</translation>
<translation id="4724120544754982507">അറിയിപ്പ് കേന്ദ്രം, <ph name="UNREAD_NOTIFICATION_COUNT" /> വായിക്കാത്ത അറിയിപ്പുകൾ</translation>
<translation id="4730374152663651037">പതിവായി ഉപയോഗിക്കുന്നത്</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ആപ്പ് നിർദ്ദേശങ്ങൾ</translation>
<translation id="6364916375976753737">ഇടത്തേക്ക് സ്ക്രോള്‍ ചെയ്യുക</translation>
<translation id="6394627529324717982">കോമ</translation>
+<translation id="6397363302884558537">സംഭാഷണം നിർത്തുക</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{ഒരു സെക്കൻഡ് മുമ്പ്}other{# സെക്കൻഡ് മുമ്പ്}}</translation>
+<translation id="6430678249303439055">ഈ ആപ്പിൽ നിന്നുള്ള എല്ലാ അറിയിപ്പുകളും ബ്ലോക്ക് ചെയ്യുക</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 സെക്കൻഡ് മുമ്പ്}other{# സെക്കൻഡ് മുമ്പ്}}</translation>
<translation id="654149438358937226">എല്ലാ അറിയിപ്പുകളും ബ്ലോക്ക് ചെയ്യുക</translation>
<translation id="6567071839949112727">ആൻസിസ്റ്ററിൽ ക്ലിക്ക് ചെയ്യുക</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{ഒരു വർഷം ശേഷിക്കുന്നു}other{# വർഷം ശേഷിക്കുന്നു}}</translation>
<translation id="6945221475159498467">തിരഞ്ഞെടുക്കുക</translation>
<translation id="6965382102122355670">ശരി</translation>
+<translation id="6974053822202609517">വലത്ത് നിന്ന് ഇടത്തേക്ക്</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">ഏറ്റവും കൂടുതൽ പേർ ലൈക്കുചെയ്‌‌തത്</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">ഇടത് അഗ്രം</translation>
<translation id="8331626408530291785">മുകളിലേക്ക് സ്ക്രോള്‍ ചെയ്യൂ</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{ഒരു വര്‍ഷം}other{# വർഷം}}</translation>
-<translation id="8371695176452482769">ഇപ്പോള്‍ സംസാരിക്കുക</translation>
<translation id="838869780401515933">പരിശോധിക്കൂ</translation>
<translation id="8393700583063109961">സന്ദേശം അയയ്ക്കുക</translation>
<translation id="8394908167088220973">മീഡിയ പ്ലേ ചെയ്യുക/താൽക്കാലികമായി നിർത്തുക</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204"><ph name="NUMBER" /> എണ്ണം കൂടി</translation>
<translation id="8730621377337864115">പൂർത്തിയാക്കി</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 മണിക്കൂർ}other{# മണിക്കൂർ}}</translation>
+<translation id="8798099450830957504">സ്ഥിരസ്ഥിതി</translation>
<translation id="8806053966018712535">ഫോൾഡർ <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">ചിത്രം വ്യാഖ്യാനിക്കുക</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_mr.xtb b/chromium/ui/strings/translations/ui_strings_mr.xtb
index 82a9e213f86..7ae05d047ca 100644
--- a/chromium/ui/strings/translations/ui_strings_mr.xtb
+++ b/chromium/ui/strings/translations/ui_strings_mr.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">अपलोड करा</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">शिफारस केलेले अ‍ॅप्स</translation>
+<translation id="1368832886055348810">डावीकडून उजवीकडे</translation>
<translation id="1398853756734560583">वाढवा</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> वरील सूचना अक्षम करा</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 मिनिट आणि }one{# मिनिट आणि }other{# मिनिटे आणि }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144"><ph name="RATING_SCORE" /> तारे रेटिंग</translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 तास आणि }one{# तास आणि }other{# तास आणि }}</translation>
<translation id="1842960171412779397">निवडा</translation>
+<translation id="1859234291848436338">लिहिण्याची दिशा</translation>
<translation id="1860796786778352021">सूचना बंद</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">पृष्ठ वर</translation>
<translation id="2190355936436201913">(रिक्त)</translation>
<translation id="219905428774326614">लाँचर, सर्व अ‍ॅप्स</translation>
+<translation id="2267918077332197517">या साइटच्या सर्व सूचना ब्‍लॉक करा</translation>
<translation id="2289052229480071835">आपल्या स्क्रीनवरील लक्ष्यांना स्पर्श करा टॅप करा.</translation>
<translation id="2295140143284145483">सर्वेक्षण</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">येथे स्क्रोल करा</translation>
<translation id="3234408098842461169">Down Arrow</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 दिवस}one{# दिवस}other{# दिवस}}</translation>
+<translation id="335581015389089642">भाषण</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 दिवस शिल्लक}one{# दिवस शिल्लक}other{# दिवस शिल्लक}}</translation>
+<translation id="3618849550573277856">“<ph name="LOOKUP_STRING" />” पहा</translation>
<translation id="364720409959344976">अपलोड करण्यासाठी फोल्डर निवडा</translation>
<translation id="3660179305079774227">Up Arrow</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">जंप करा</translation>
<translation id="4250229828105606438">स्क्रीनशॉट</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 महिन्यापूर्वी}one{# महिन्यापूर्वी}other{# महिन्यांपूर्वी}}</translation>
+<translation id="4289300219472526559">बोलणे प्रारंभ करा</translation>
<translation id="4316910396681052118">सर्व अ‍ॅप्स</translation>
-<translation id="4320177379694898372">कोणतेही इंटरनेट कनेक्शन नाही</translation>
<translation id="4588090240171750605">उजवे स्क्रोल करा</translation>
<translation id="4724120544754982507">सूचना केंद्र, <ph name="UNREAD_NOTIFICATION_COUNT" /> न वाचलेल्या सूचना</translation>
<translation id="4730374152663651037">वारंवार वापरलेले</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">अॅप सूचना</translation>
<translation id="6364916375976753737">डावीकडे स्क्रोल करा</translation>
<translation id="6394627529324717982">स्वल्पविराम</translation>
+<translation id="6397363302884558537">बोलणे थांबवा</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 सेकंदापूर्वी}one{# सेकंदापूर्वी}other{# सेकंदांपूर्वी}}</translation>
+<translation id="6430678249303439055">या अ‍ॅपच्या सर्व सूचना ब्‍लॉक करा</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 सेकंदापूर्वी}one{# सेकंदापूर्वी}other{# सेकंदांपूर्वी}}</translation>
<translation id="654149438358937226">सर्व सूचना ब्लॉक करा</translation>
<translation id="6567071839949112727">पूर्वजवर क्लिक करा</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 वर्ष राहिले}one{# वर्ष राहिले}other{# वर्षे राहिली}}</translation>
<translation id="6945221475159498467">निवडा</translation>
<translation id="6965382102122355670">ठीक आहे</translation>
+<translation id="6974053822202609517">उजवीकडून डावीकडे</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">सर्वाधिक शक्यता</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">डावे काठ</translation>
<translation id="8331626408530291785">वर स्क्रोल करा</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 वर्ष}one{# वर्ष}other{# वर्षे}}</translation>
-<translation id="8371695176452482769">आता बोला</translation>
<translation id="838869780401515933">तपासा</translation>
<translation id="8393700583063109961">संदेश पाठवा</translation>
<translation id="8394908167088220973">मीडिया प्ले करा/विराम द्या</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+आणखी <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">पूर्ण झाले</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1ता}one{#ता}other{#ता}}</translation>
+<translation id="8798099450830957504">डीफॉल्ट</translation>
<translation id="8806053966018712535"><ph name="FOLDER_NAME" /> फोल्डर</translation>
<translation id="883911313571074303">प्रतिमेवर भाष्य करा</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_ms.xtb b/chromium/ui/strings/translations/ui_strings_ms.xtb
index f93e134d165..de467150e5a 100644
--- a/chromium/ui/strings/translations/ui_strings_ms.xtb
+++ b/chromium/ui/strings/translations/ui_strings_ms.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Muat naik</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">APL YANG DISYORKAN</translation>
+<translation id="1368832886055348810">Kiri ke Kanan</translation>
<translation id="1398853756734560583">Maksimumkan</translation>
<translation id="1413622004203049571">Lumpuhkan pemberitahuan daripada <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minit dan }other{# minit dan }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Penilaian <ph name="RATING_SCORE" /> bintang</translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 jam dan }other{# jam dan }}</translation>
<translation id="1842960171412779397">pilih</translation>
+<translation id="1859234291848436338">Arah Penulisan</translation>
<translation id="1860796786778352021">Tutup Pemberitahuan</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Halaman Ke Atas</translation>
<translation id="2190355936436201913">(kosong)</translation>
<translation id="219905428774326614">Pelancar, semua apl</translation>
+<translation id="2267918077332197517">Sekat semua pemberitahuan daripada tapak ini</translation>
<translation id="2289052229480071835">Ketik sasaran sentuhan pada skrin anda.</translation>
<translation id="2295140143284145483">Tinjauan</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Tatal ke Sini</translation>
<translation id="3234408098842461169">Anak Panah Bawah</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 hari}other{# hari}}</translation>
+<translation id="335581015389089642">Pertuturan</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 hari lagi}other{# hari lagi}}</translation>
+<translation id="3618849550573277856">Cari “<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Pilih Folder untuk Dimuat Naik</translation>
<translation id="3660179305079774227">Anak Panah Atas</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">lompat</translation>
<translation id="4250229828105606438">Tangkapan skrin</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 bulan yang lalu}other{# bulan yang lalu}}</translation>
+<translation id="4289300219472526559">Mula Bercakap</translation>
<translation id="4316910396681052118">SEMUA APL</translation>
-<translation id="4320177379694898372">Tiada sambungan Internet</translation>
<translation id="4588090240171750605">Tatal ke Kanan</translation>
<translation id="4724120544754982507">Pusat Pemberitahuan, <ph name="UNREAD_NOTIFICATION_COUNT" /> pemberitahuan belum dibaca</translation>
<translation id="4730374152663651037">KERAP DIGUNAKAN</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">CADANGAN APL</translation>
<translation id="6364916375976753737">Tatal Ke Kiri</translation>
<translation id="6394627529324717982">Koma</translation>
+<translation id="6397363302884558537">Berhenti Bercakap</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 saat yang lalu}other{# saat yang lalu}}</translation>
+<translation id="6430678249303439055">Sekat semua pemberitahuan daripada apl ini</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Sesaat yang lalu}other{# saat yang lalu}}</translation>
<translation id="654149438358937226">Sekat semua pemberitahuan</translation>
<translation id="6567071839949112727">klik pewaris</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Berbaki 1 tahun}other{Berbaki # tahun}}</translation>
<translation id="6945221475159498467">Pilih</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Kanan ke Kiri</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">KEMUNGKINAN BESAR</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Tepi Kiri</translation>
<translation id="8331626408530291785">Tatal Ke Atas</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 tahun}other{# tahun}}</translation>
-<translation id="8371695176452482769">Cakap sekarang</translation>
<translation id="838869780401515933">periksa</translation>
<translation id="8393700583063109961">Hantar mesej</translation>
<translation id="8394908167088220973">Main/Jeda Media</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> lagi</translation>
<translation id="8730621377337864115">Selesai</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1j}other{#j}}</translation>
+<translation id="8798099450830957504">Lalai</translation>
<translation id="8806053966018712535">Folder <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Anotasikan imej</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_nl.xtb b/chromium/ui/strings/translations/ui_strings_nl.xtb
index 45b7b8b044b..8d248d1be85 100644
--- a/chromium/ui/strings/translations/ui_strings_nl.xtb
+++ b/chromium/ui/strings/translations/ui_strings_nl.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Uploaden</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">AANBEVOLEN APPS</translation>
+<translation id="1368832886055348810">Links naar rechts</translation>
<translation id="1398853756734560583">Maximaliseren</translation>
<translation id="1413622004203049571">Meldingen van <ph name="NOTIFIER_NAME" /> uitschakelen</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuut en }other{# minuten en }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Sterbeoordeling <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 uur en }other{# uur en }}</translation>
<translation id="1842960171412779397">Selecteren</translation>
+<translation id="1859234291848436338">Schrijfrichting</translation>
<translation id="1860796786778352021">Melding sluiten</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Pagina omhoog</translation>
<translation id="2190355936436201913">(leeg)</translation>
<translation id="219905428774326614">Launcher, alle apps</translation>
+<translation id="2267918077332197517">Alle meldingen van deze site blokkeren</translation>
<translation id="2289052229480071835">Tik op de tikdoelen op je scherm.</translation>
<translation id="2295140143284145483">Enquête</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Hiernaartoe bladeren</translation>
<translation id="3234408098842461169">Pijl-omlaag</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 dag}other{# dagen}}</translation>
+<translation id="335581015389089642">Spraak</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 dag resterend}other{# dagen resterend}}</translation>
+<translation id="3618849550573277856">'<ph name="LOOKUP_STRING" />' opzoeken</translation>
<translation id="364720409959344976">Map voor uploaden selecteren</translation>
<translation id="3660179305079774227">Pijl-omhoog</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">Gaan naar</translation>
<translation id="4250229828105606438">Screenshot</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 maand geleden}other{# maanden geleden}}</translation>
+<translation id="4289300219472526559">Inspreken starten</translation>
<translation id="4316910396681052118">ALLE APPS</translation>
-<translation id="4320177379694898372">Geen internetverbinding</translation>
<translation id="4588090240171750605">Naar rechts bladeren</translation>
<translation id="4724120544754982507">Meldingscentrum, <ph name="UNREAD_NOTIFICATION_COUNT" /> ongelezen meldingen</translation>
<translation id="4730374152663651037">VEELGEBRUIKT</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">APP-SUGGESTIES</translation>
<translation id="6364916375976753737">Naar links bladeren</translation>
<translation id="6394627529324717982">Komma</translation>
+<translation id="6397363302884558537">Inspreken stoppen</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 sec. geleden}other{# sec. geleden}}</translation>
+<translation id="6430678249303439055">Alle meldingen van deze app blokkeren</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 seconde geleden}other{# seconden geleden}}</translation>
<translation id="654149438358937226">Alle meldingen blokkeren</translation>
<translation id="6567071839949112727">klik via bovenliggende entiteit</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Nog 1 jaar}other{Nog # jaar}}</translation>
<translation id="6945221475159498467">Selecteren</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Rechts naar links</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">MEEST WAARSCHIJNLIJK</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Linkerzijde</translation>
<translation id="8331626408530291785">Omhoog bladeren</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 jaar}other{# jaar}}</translation>
-<translation id="8371695176452482769">Begin nu te spreken</translation>
<translation id="838869780401515933">Selecteren</translation>
<translation id="8393700583063109961">Bericht verzenden</translation>
<translation id="8394908167088220973">Media afspelen/onderbreken</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+ nog <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Gereed</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 u}other{# u}}</translation>
+<translation id="8798099450830957504">Standaard</translation>
<translation id="8806053966018712535">Map <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Afbeelding annoteren</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_no.xtb b/chromium/ui/strings/translations/ui_strings_no.xtb
index 335b9ce37a3..75a5e61eab4 100644
--- a/chromium/ui/strings/translations/ui_strings_no.xtb
+++ b/chromium/ui/strings/translations/ui_strings_no.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Last opp</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ANBEFALTE APPER</translation>
+<translation id="1368832886055348810">Venstre til høyre</translation>
<translation id="1398853756734560583">Maksimer</translation>
<translation id="1413622004203049571">Deaktiver varsler fra <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minutt og }other{# minutter og }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Stjernerangering <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 time og }other{# timer og }}</translation>
<translation id="1842960171412779397">velg</translation>
+<translation id="1859234291848436338">Skriveretning</translation>
<translation id="1860796786778352021">Lukk varsel</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Opp 1 s.</translation>
<translation id="2190355936436201913">(tom)</translation>
<translation id="219905428774326614">Appoversikt, alle apper</translation>
+<translation id="2267918077332197517">Blokkér alle varsler fra dette nettstedet</translation>
<translation id="2289052229480071835">Trykk på berøringsmålene på skjermen.</translation>
<translation id="2295140143284145483">Undersøkelse</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB per sek</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Rull hit</translation>
<translation id="3234408098842461169">Pil ned</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 dag}other{# dager}}</translation>
+<translation id="335581015389089642">Tale</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 dag igjen}other{# dager igjen}}</translation>
+<translation id="3618849550573277856">Slå opp «<ph name="LOOKUP_STRING" />»</translation>
<translation id="364720409959344976">Velg mappen du vil laste opp</translation>
<translation id="3660179305079774227">Pil opp</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB per sek</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">hopp</translation>
<translation id="4250229828105606438">Skjermdump</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{for 1 måned siden}other{for # måneder siden}}</translation>
+<translation id="4289300219472526559">Begynn å snakke</translation>
<translation id="4316910396681052118">ALLE APPER</translation>
-<translation id="4320177379694898372">Ingen Internett-tilkobling</translation>
<translation id="4588090240171750605">Rull mot høyre</translation>
<translation id="4724120544754982507">Varselsenter, <ph name="UNREAD_NOTIFICATION_COUNT" /> uleste varsler</translation>
<translation id="4730374152663651037">OFTE BRUKT</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">APPFORSLAG</translation>
<translation id="6364916375976753737">Rull mot venstre</translation>
<translation id="6394627529324717982">Komma</translation>
+<translation id="6397363302884558537">Stopp å snakke</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{For 1 sekund siden}other{For # sekunder siden}}</translation>
+<translation id="6430678249303439055">Blokkér alle varsler fra denne appen</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{for 1 sekund siden}other{for # sekunder siden}}</translation>
<translation id="654149438358937226">Blokkér alle varsler</translation>
<translation id="6567071839949112727">klikk på et overordnet element</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 år igjen}other{# år igjen}}</translation>
<translation id="6945221475159498467">Velg</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Høyre til venstre</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">MEST SANNSYNLIG</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Venstre kant</translation>
<translation id="8331626408530291785">Rull opp</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 år}other{# år}}</translation>
-<translation id="8371695176452482769">Snakk nå</translation>
<translation id="838869780401515933">merk av</translation>
<translation id="8393700583063109961">Send melding</translation>
<translation id="8394908167088220973">Media – spill av / pause</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+ <ph name="NUMBER" /> til</translation>
<translation id="8730621377337864115">Ferdig</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 t}other{# t}}</translation>
+<translation id="8798099450830957504">Standard</translation>
<translation id="8806053966018712535">Mappen <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Kommenter bildet</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_pl.xtb b/chromium/ui/strings/translations/ui_strings_pl.xtb
index 0a1002e79a7..122dabf9eaa 100644
--- a/chromium/ui/strings/translations/ui_strings_pl.xtb
+++ b/chromium/ui/strings/translations/ui_strings_pl.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Prześlij</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">POLECANE APLIKACJE</translation>
+<translation id="1368832886055348810">Od lewej do prawej</translation>
<translation id="1398853756734560583">Maksymalizuj</translation>
<translation id="1413622004203049571">Wyłącz powiadomienia z <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuta i }few{# minuty i }many{# minut i }other{# minuty i }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Ocena w gwiazdkach: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 godzina i }few{# godziny i }many{# godzin i }other{# godziny i }}</translation>
<translation id="1842960171412779397">wybierz</translation>
+<translation id="1859234291848436338">Kierunek pisania</translation>
<translation id="1860796786778352021">Zamknięcie powiadomienia</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Strona do góry</translation>
<translation id="2190355936436201913">(puste)</translation>
<translation id="219905428774326614">Menu ze wszystkimi aplikacjami</translation>
+<translation id="2267918077332197517">Blokuj wszystkie powiadomienia z tej strony internetowej</translation>
<translation id="2289052229480071835">Kliknij docelowe obszary kliknięcia na ekranie.</translation>
<translation id="2295140143284145483">Ankieta</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Przewiń tutaj</translation>
<translation id="3234408098842461169">Strzałka w dół</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 dzień}few{# dni}many{# dni}other{# dnia}}</translation>
+<translation id="335581015389089642">Mowa</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Pozostał 1 dzień}few{Pozostały # dni}many{Pozostało # dni}other{Pozostało # dnia}}</translation>
+<translation id="3618849550573277856">Sprawdź słowo „<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Wybierz folder do przesłania</translation>
<translation id="3660179305079774227">Strzałka w górę</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">przejdź</translation>
<translation id="4250229828105606438">Zrzut ekranu</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{miesiąc temu}few{# miesiące temu}many{# miesięcy temu}other{# miesiąca temu}}</translation>
+<translation id="4289300219472526559">Zacznij mówić</translation>
<translation id="4316910396681052118">WSZYSTKIE APLIKACJE</translation>
-<translation id="4320177379694898372">Brak połączenia z internetem</translation>
<translation id="4588090240171750605">Przewiń w prawo</translation>
<translation id="4724120544754982507">Centrum powiadomień, liczba nieprzeczytanych powiadomień: <ph name="UNREAD_NOTIFICATION_COUNT" /></translation>
<translation id="4730374152663651037">CZĘSTO UŻYWANE</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SUGEROWANE APLIKACJE</translation>
<translation id="6364916375976753737">Przewiń w lewo</translation>
<translation id="6394627529324717982">Przecinek</translation>
+<translation id="6397363302884558537">Przestań mówić</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 s temu}few{# s temu}many{# s temu}other{# s temu}}</translation>
+<translation id="6430678249303439055">Blokuj wszystkie powiadomienia z tej aplikacji</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{sekundę temu}few{# sekundy temu}many{# sekund temu}other{# sekundy temu}}</translation>
<translation id="654149438358937226">Blokuj wszystkie powiadomienia</translation>
<translation id="6567071839949112727">kliknij element nadrzędny</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Pozostał rok}few{Pozostały # lata}many{Pozostało # lat}other{Pozostało # roku}}</translation>
<translation id="6945221475159498467">Wybierz</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Od prawej do lewej</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">NAJBARDZIEJ PRAWDOPODOBNE</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Krawędź po lewej</translation>
<translation id="8331626408530291785">Przewiń w górę</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 rok}few{# lata}many{# lat}other{# roku}}</translation>
-<translation id="8371695176452482769">Mów teraz</translation>
<translation id="838869780401515933">zaznacz</translation>
<translation id="8393700583063109961">Wyślij wiadomość</translation>
<translation id="8394908167088220973">Odtwórz/wstrzymaj multimedia</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">i jeszcze <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Gotowe</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 godz.}few{# godz.}many{# godz.}other{# godz.}}</translation>
+<translation id="8798099450830957504">Domyślny</translation>
<translation id="8806053966018712535">Folder <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Dodaj notatkę na grafice</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_pt-BR.xtb b/chromium/ui/strings/translations/ui_strings_pt-BR.xtb
index 30cc147fc77..b6921f06ef2 100644
--- a/chromium/ui/strings/translations/ui_strings_pt-BR.xtb
+++ b/chromium/ui/strings/translations/ui_strings_pt-BR.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Fazer upload</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">APPS RECOMENDADOS</translation>
+<translation id="1368832886055348810">Da esquerda para a direita</translation>
<translation id="1398853756734560583">Maximizar</translation>
<translation id="1413622004203049571">Desativar notificações de <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{Um minuto e }one{# minutos e }other{# minutos e }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Avaliação com <ph name="RATING_SCORE" /> estrelas</translation>
<translation id="1830179671306812954">{HOURS,plural, =1{Uma hora e }one{# horas e }other{# horas e }}</translation>
<translation id="1842960171412779397">selecione</translation>
+<translation id="1859234291848436338">Direção de Gravação</translation>
<translation id="1860796786778352021">Fechar notificação</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Página para cima</translation>
<translation id="2190355936436201913">(vazio)</translation>
<translation id="219905428774326614">Tela de início, todos os apps</translation>
+<translation id="2267918077332197517">Bloquear todas as notificações emitidas por este site</translation>
<translation id="2289052229480071835">Toque nas áreas de toque da tela.</translation>
<translation id="2295140143284145483">Pesquisa</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Percorrer até aqui</translation>
<translation id="3234408098842461169">Seta para baixo</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{Um dia}one{# dias}other{# dias}}</translation>
+<translation id="335581015389089642">Voz</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Um dia restante}one{# dias restantes}other{# dias restantes}}</translation>
+<translation id="3618849550573277856">Pesquisar “<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Selecionar pasta para upload</translation>
<translation id="3660179305079774227">Seta para cima</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">pular</translation>
<translation id="4250229828105606438">Captura de tela</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 mês atrás}one{# mês atrás}other{# meses atrás}}</translation>
+<translation id="4289300219472526559">Comece a falar</translation>
<translation id="4316910396681052118">TODOS OS APPS</translation>
-<translation id="4320177379694898372">Sem conexão com a Internet</translation>
<translation id="4588090240171750605">Percorrer à direita</translation>
<translation id="4724120544754982507">Central de Notificações: <ph name="UNREAD_NOTIFICATION_COUNT" /> notificações não lidas</translation>
<translation id="4730374152663651037">USADOS FREQUENTEMENTE</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SUGESTÕES DE APPS</translation>
<translation id="6364916375976753737">Percorrer à esquerda</translation>
<translation id="6394627529324717982">Vírgula</translation>
+<translation id="6397363302884558537">Pare de falar</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Um segundo atrás}one{# segundos atrás}other{# segundos atrás}}</translation>
+<translation id="6430678249303439055">Bloquear todas as notificações emitidas por este app</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 segundo atrás}one{# segundo atrás}other{# segundos atrás}}</translation>
<translation id="654149438358937226">Bloquear todas as notificações</translation>
<translation id="6567071839949112727">clicar no predecessor</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 ano restante}one{# ano restante}other{# anos restantes}}</translation>
<translation id="6945221475159498467">Selecionar</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Da direita para a esquerda</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">MUITO PROVAVELMENTE</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Borda esquerda</translation>
<translation id="8331626408530291785">Percorrer para cima</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{ ano}one{# ano}other{# anos}}</translation>
-<translation id="8371695176452482769">Fale agora</translation>
<translation id="838869780401515933">marcar</translation>
<translation id="8393700583063109961">Enviar mensagem</translation>
<translation id="8394908167088220973">Reproduzir/pausar mídia</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">mais <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Concluído</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}one{# h}other{# h}}</translation>
+<translation id="8798099450830957504">Padrão</translation>
<translation id="8806053966018712535">Pasta <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Fazer anotações na imagem</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_pt-PT.xtb b/chromium/ui/strings/translations/ui_strings_pt-PT.xtb
index 3c8d2030360..161d2155cf8 100644
--- a/chromium/ui/strings/translations/ui_strings_pt-PT.xtb
+++ b/chromium/ui/strings/translations/ui_strings_pt-PT.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Carregar</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">APLICAÇÕES RECOMENDADAS</translation>
+<translation id="1368832886055348810">Da esquerda para a direita</translation>
<translation id="1398853756734560583">Maximizar</translation>
<translation id="1413622004203049571">Desativar notificações de <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minuto e }other{# minutos e }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Classificação de <ph name="RATING_SCORE" /> estrelas</translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 hora e }other{# horas e }}</translation>
<translation id="1842960171412779397">seleccionar</translation>
+<translation id="1859234291848436338">Direcção da escrita</translation>
<translation id="1860796786778352021">Fechar notificação</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Página para cima</translation>
<translation id="2190355936436201913">(vazio)</translation>
<translation id="219905428774326614">Iniciador, todas as aplicações</translation>
+<translation id="2267918077332197517">Bloquear todas as notificações deste site</translation>
<translation id="2289052229480071835">Toque nos alvos de toque no ecrã.</translation>
<translation id="2295140143284145483">Inquérito</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Deslocar-se para aqui</translation>
<translation id="3234408098842461169">Seta para baixo</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 dia}other{# dias}}</translation>
+<translation id="335581015389089642">Voz</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Falta 1 dia}other{Faltam # dias}}</translation>
+<translation id="3618849550573277856">Procurar "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Selecionar Pasta a Carregar</translation>
<translation id="3660179305079774227">Seta para cima</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">ir para</translation>
<translation id="4250229828105606438">Captura de ecrã</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Há 1 mês}other{Há # meses}}</translation>
+<translation id="4289300219472526559">Comece a Falar</translation>
<translation id="4316910396681052118">TODAS AS APLICAÇÕES</translation>
-<translation id="4320177379694898372">Sem ligação à Internet</translation>
<translation id="4588090240171750605">Deslocar-se para a direita</translation>
<translation id="4724120544754982507">Centro de notificações, <ph name="UNREAD_NOTIFICATION_COUNT" /> notificações não lidas</translation>
<translation id="4730374152663651037">UTILIZADAS FREQUENTEMENTE</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SUGESTÕES DE APLICAÇÕES</translation>
<translation id="6364916375976753737">Deslocar-se para a esquerda</translation>
<translation id="6394627529324717982">Vírgula</translation>
+<translation id="6397363302884558537">Pare de Falar</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Há 1 seg}other{Há # seg}}</translation>
+<translation id="6430678249303439055">Bloquear todas as notificações desta aplicação</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Há 1 segundo}other{Há # segundos}}</translation>
<translation id="654149438358937226">Bloquear todas as notificações</translation>
<translation id="6567071839949112727">clicar no predecessor</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Falta 1 ano}other{Faltam # anos}}</translation>
<translation id="6945221475159498467">Selecionar</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Da direita para a esquerda</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">MUITO PROVAVELMENTE</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Margem esquerda</translation>
<translation id="8331626408530291785">Deslocar-se para cima</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 ano}other{# anos}}</translation>
-<translation id="8371695176452482769">Falar agora</translation>
<translation id="838869780401515933">verificar</translation>
<translation id="8393700583063109961">Enviar mensagem</translation>
<translation id="8394908167088220973">Reproduzir/interromper multimédia</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Concluído</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}other{# h}}</translation>
+<translation id="8798099450830957504">Predefinição</translation>
<translation id="8806053966018712535">Pasta <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Anotar imagem</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_ro.xtb b/chromium/ui/strings/translations/ui_strings_ro.xtb
index 59c00398037..15f275f6fef 100644
--- a/chromium/ui/strings/translations/ui_strings_ro.xtb
+++ b/chromium/ui/strings/translations/ui_strings_ro.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Încărcați</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">APLICAȚII RECOMANDATE</translation>
+<translation id="1368832886055348810">De la stânga la dreapta</translation>
<translation id="1398853756734560583">Maximizează</translation>
<translation id="1413622004203049571">Dezactivați notificările de la <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{Un minut și }few{# minute și }other{# de minute și }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Evaluare cu stele: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{O oră și }few{# ore și }other{# de ore și }}</translation>
<translation id="1842960171412779397">selectează</translation>
+<translation id="1859234291848436338">Direcție de scriere</translation>
<translation id="1860796786778352021">Buton de închidere a notificării</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">O pagină mai sus</translation>
<translation id="2190355936436201913">(gol)</translation>
<translation id="219905428774326614">Lansator, toate aplicațiile</translation>
+<translation id="2267918077332197517">Blochează toate notificările de la acest site</translation>
<translation id="2289052229480071835">Atinge țintele de atingere de pe ecran.</translation>
<translation id="2295140143284145483">Sondaj</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Derulează până aici</translation>
<translation id="3234408098842461169">Săgeată în jos</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{O zi}few{# zile}other{# de zile}}</translation>
+<translation id="335581015389089642">Voce</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{O zi rămasă}few{# zile rămase}other{# de zile rămase}}</translation>
+<translation id="3618849550573277856">Caută „<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Selectați un dosar de încărcat</translation>
<translation id="3660179305079774227">Săgeată în sus</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">accesează</translation>
<translation id="4250229828105606438">Captură de ecran</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Acum 1 lună}few{Acum # luni}other{Acum # de luni}}</translation>
+<translation id="4289300219472526559">Începeți să vorbiți</translation>
<translation id="4316910396681052118">TOATE APLICAȚIILE</translation>
-<translation id="4320177379694898372">Fără conexiune la internet</translation>
<translation id="4588090240171750605">Derulează spre dreapta</translation>
<translation id="4724120544754982507">Centrul de notificări, <ph name="UNREAD_NOTIFICATION_COUNT" /> notificări necitite</translation>
<translation id="4730374152663651037">FOLOSITE FRECVENT</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">SUGESTII DE APLICAȚII</translation>
<translation id="6364916375976753737">Derulează spre stânga</translation>
<translation id="6394627529324717982">Virgulă</translation>
+<translation id="6397363302884558537">Opriți-vă din vorbit</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Acum o sec.}few{Acum # sec}other{Acum # sec}}</translation>
+<translation id="6430678249303439055">Blochează toate notificările de la această aplicație</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Acum 1 secundă}few{Acum # secunde}other{Acum # de secunde}}</translation>
<translation id="654149438358937226">Blochează toate notificările</translation>
<translation id="6567071839949112727">dă clic pe predecesor</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 an rămas}few{# ani rămași}other{# de ani rămași}}</translation>
<translation id="6945221475159498467">Selectează</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">De la dreapta la stânga</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">CEL MAI PROBABIL DE ACCESAT</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Marginea stângă</translation>
<translation id="8331626408530291785">Derulează în sus</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 an}few{# ani}other{# de ani}}</translation>
-<translation id="8371695176452482769">Rostește acum</translation>
<translation id="838869780401515933">bifează</translation>
<translation id="8393700583063109961">Trimite un mesaj</translation>
<translation id="8394908167088220973">Redați/întrerupeți conținutul media</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">Peste <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Terminat</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}few{# h}other{# h}}</translation>
+<translation id="8798099450830957504">Prestabilit</translation>
<translation id="8806053966018712535">Dosarul <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Adnotează imaginea</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KO</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_ru.xtb b/chromium/ui/strings/translations/ui_strings_ru.xtb
index 78fb522ae7e..b15eefc26da 100644
--- a/chromium/ui/strings/translations/ui_strings_ru.xtb
+++ b/chromium/ui/strings/translations/ui_strings_ru.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Загрузить</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">РЕКОМЕНДУЕМЫЕ ПРИЛОЖЕНИЯ</translation>
+<translation id="1368832886055348810">Слева направо</translation>
<translation id="1398853756734560583">Развернуть</translation>
<translation id="1413622004203049571">Отключить уведомления от <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 минута }one{# минута }few{# минуты }many{# минут }other{# минуты }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Оценка: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 час }one{# час }few{# часа }many{# часов }other{# часа }}</translation>
<translation id="1842960171412779397">выбрать</translation>
+<translation id="1859234291848436338">Направление письма</translation>
<translation id="1860796786778352021">Закрыть уведомление</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Вверх</translation>
<translation id="2190355936436201913">(пусто)</translation>
<translation id="219905428774326614">Панель запуска, все приложения</translation>
+<translation id="2267918077332197517">Блокировать все уведомления этого сайта</translation>
<translation id="2289052229480071835">Коснитесь интерактивных элементов на экране.</translation>
<translation id="2295140143284145483">Опрос</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> ТБ/с</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Прокрутить до этого места</translation>
<translation id="3234408098842461169">Стрелка вниз</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 день}one{# день}few{# дня}many{# дней}other{# дня}}</translation>
+<translation id="335581015389089642">Озвучить</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Остался 1 день}one{Остался # день}few{Осталось # дня}many{Осталось # дней}other{Осталось # дня}}</translation>
+<translation id="3618849550573277856">Найти "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Выберите папку для загрузки</translation>
<translation id="3660179305079774227">Стрелка вверх</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> ГБ/с</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">перейти</translation>
<translation id="4250229828105606438">Скриншот</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{месяц назад}one{# месяц назад}few{# месяца назад}many{# месяцев назад}other{# месяца назад}}</translation>
+<translation id="4289300219472526559">Начать голосовой ввод</translation>
<translation id="4316910396681052118">ВСЕ ПРИЛОЖЕНИЯ</translation>
-<translation id="4320177379694898372">Нет подключения к Интернету</translation>
<translation id="4588090240171750605">Прокрутка вправо</translation>
<translation id="4724120544754982507">Центр уведомлений. Непрочитанных: <ph name="UNREAD_NOTIFICATION_COUNT" />.</translation>
<translation id="4730374152663651037">ЧАСТО ИСПОЛЬЗУЕМЫЕ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ПРЕДЛАГАЕМЫЕ ПРИЛОЖЕНИЯ</translation>
<translation id="6364916375976753737">Прокрутка влево</translation>
<translation id="6394627529324717982">Запятая</translation>
+<translation id="6397363302884558537">Прекратить голосовой ввод</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 сек. назад}one{# сек. назад}few{# сек. назад}many{# сек. назад}other{# сек. назад}}</translation>
+<translation id="6430678249303439055">Блокировать все уведомления этого приложения</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{только что}one{# секунду назад}few{# секунды назад}many{# секунд назад}other{# секунды назад}}</translation>
<translation id="654149438358937226">Блокировать все уведомления</translation>
<translation id="6567071839949112727">нажмите на родительский элемент</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{остался 1 год}one{остался # год}few{осталось # года}many{осталось # лет}other{осталось # года}}</translation>
<translation id="6945221475159498467">Выбрать</translation>
<translation id="6965382102122355670">ОК</translation>
+<translation id="6974053822202609517">Справа налево</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">САМЫЕ ПОДХОДЯЩИЕ</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Левый край</translation>
<translation id="8331626408530291785">Прокрутка вверх</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 год}one{# год}few{# года}many{# лет}other{# года}}</translation>
-<translation id="8371695176452482769">Говорите</translation>
<translation id="838869780401515933">поставить галочку</translation>
<translation id="8393700583063109961">Отправить сообщение</translation>
<translation id="8394908167088220973">Воспроизведение/пауза</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">Ещё <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Готово</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 ч.}one{# ч.}few{# ч.}many{# ч.}other{# ч.}}</translation>
+<translation id="8798099450830957504">По умолчанию</translation>
<translation id="8806053966018712535">Папка <ph name="FOLDER_NAME" />.</translation>
<translation id="883911313571074303">Добавить примечание к изображению</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> КБ</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_sk.xtb b/chromium/ui/strings/translations/ui_strings_sk.xtb
index 200d6e56298..52a378f444e 100644
--- a/chromium/ui/strings/translations/ui_strings_sk.xtb
+++ b/chromium/ui/strings/translations/ui_strings_sk.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Nahrať</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ODPORÚČANÉ APLIKÁCIE</translation>
+<translation id="1368832886055348810">Zľava doprava</translation>
<translation id="1398853756734560583">Maximalizovať</translation>
<translation id="1413622004203049571">Zakázať upozornenia od <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minúta a }few{# minúty a }many{# minúty a }other{# minút a }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Hodnotenie: <ph name="RATING_SCORE" /> hviezd.</translation>
<translation id="1830179671306812954">{HOURS,plural, =1{Pred 1 hodinou a }few{Pred # hodinami a }many{Pred # hodinou a }other{Pred # hodinami a }}</translation>
<translation id="1842960171412779397">vybrať</translation>
+<translation id="1859234291848436338">Smer písania</translation>
<translation id="1860796786778352021">Zavrieť upozornenie</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Page Up</translation>
<translation id="2190355936436201913">(prázdne)</translation>
<translation id="219905428774326614">Spúšťač, všetky aplikácie</translation>
+<translation id="2267918077332197517">Blokovať všetky upozornenia z tohto webu</translation>
<translation id="2289052229480071835">Klepnite na dotykové ciele na obrazovke.</translation>
<translation id="2295140143284145483">Prieskum</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Rolovať na toto miesto</translation>
<translation id="3234408098842461169">Šípka nadol</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 deň}few{# dni}many{# dňa}other{# dní}}</translation>
+<translation id="335581015389089642">Reč</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Zostáva 1 deň}few{Zostávajú # dni}many{Zostáva # dňa}other{Zostáva # dní}}</translation>
+<translation id="3618849550573277856">Vyhľadať „<ph name="LOOKUP_STRING" />“</translation>
<translation id="364720409959344976">Výber priečinka na nahranie</translation>
<translation id="3660179305079774227">Šípka nahor</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">skok</translation>
<translation id="4250229828105606438">Snímka obrazovky</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{pred mesiacom}few{pred # mesiacmi}many{pred # mesiacom}other{pred # mesiacmi}}</translation>
+<translation id="4289300219472526559">Začať hovoriť</translation>
<translation id="4316910396681052118">VŠETKY APLIKÁCIE</translation>
-<translation id="4320177379694898372">Žiadne internetové pripojenie</translation>
<translation id="4588090240171750605">Rolovať doprava</translation>
<translation id="4724120544754982507">Centrum upozornení – počet neprečítaných upozornení: <ph name="UNREAD_NOTIFICATION_COUNT" /></translation>
<translation id="4730374152663651037">ČASTO POUŽÍVANÉ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">NÁVRHY APLIKÁCIÍ</translation>
<translation id="6364916375976753737">Rolovať doľava</translation>
<translation id="6394627529324717982">Čiarka</translation>
+<translation id="6397363302884558537">Prestať hovoriť</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Pred 1 s}few{Pred # s}many{Pred # s}other{Pred # s}}</translation>
+<translation id="6430678249303439055">Blokovať všetky upozornenia z tejto aplikácie</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{pred sekundou}few{pred # sekundami}many{pred # sekundami}other{pred # sekundami}}</translation>
<translation id="654149438358937226">Blokovať všetky upozornenia</translation>
<translation id="6567071839949112727">kliknúť na nadradený objekt</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{zostáva 1 rok}few{zostávajú # roky}many{zostáva # roka}other{zostáva # rokov}}</translation>
<translation id="6945221475159498467">Vybrať</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Sprava doľava</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">S NAJVÄČŠOU PRAVDEPODOBNOSŤOU</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Ľavý okraj</translation>
<translation id="8331626408530291785">Rolovať nahor</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 rok}few{# roky}many{# roka}other{# rokov}}</translation>
-<translation id="8371695176452482769">Hovorte…</translation>
<translation id="838869780401515933">označiť</translation>
<translation id="8393700583063109961">Odoslať správu</translation>
<translation id="8394908167088220973">Média – prehrať / pozastaviť</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">ďalšie (<ph name="NUMBER" />)</translation>
<translation id="8730621377337864115">Hotovo</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 h}few{# h}many{# h}other{# h}}</translation>
+<translation id="8798099450830957504">Predvolené</translation>
<translation id="8806053966018712535">Priečinok <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Pridať k obrázku poznámku</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_sl.xtb b/chromium/ui/strings/translations/ui_strings_sl.xtb
index d3718284bf4..9b23c7aee33 100644
--- a/chromium/ui/strings/translations/ui_strings_sl.xtb
+++ b/chromium/ui/strings/translations/ui_strings_sl.xtb
@@ -7,6 +7,7 @@
<translation id="1243314992276662751">Prenesi</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">PRIPOROČENE APLIKACIJE</translation>
+<translation id="1368832886055348810">Od leve proti desni</translation>
<translation id="1398853756734560583">Povečaj</translation>
<translation id="1413622004203049571">Izklop obvestil za <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 min in }one{# min in }two{# min in }few{# min in }other{# min in }}</translation>
@@ -19,6 +20,7 @@
<translation id="1812519734428420144">Ocena z zvezdicami (<ph name="RATING_SCORE" />)</translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 h in }one{# h in }two{# h in }few{# h in }other{# h in }}</translation>
<translation id="1842960171412779397">izberi</translation>
+<translation id="1859234291848436338">Smer pisanja</translation>
<translation id="1860796786778352021">Zapri obvestilo</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1901303067676059328">Izberi &amp;vse</translation>
@@ -26,6 +28,7 @@
<translation id="2168039046890040389">Stran gor</translation>
<translation id="2190355936436201913">(prazno)</translation>
<translation id="219905428774326614">Zaganjalnik, vse aplikacije</translation>
+<translation id="2267918077332197517">Blokiraj vsa obvestila s tega spletnega mesta</translation>
<translation id="2289052229480071835">Dotaknite se ciljev za dotik na zaslonu.</translation>
<translation id="2295140143284145483">Anketa</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -46,7 +49,9 @@
<translation id="3183922693828471536">Pomik do sem</translation>
<translation id="3234408098842461169">Puščica dol</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 dan}one{# dan}two{# dneva}few{# dni}other{# dni}}</translation>
+<translation id="335581015389089642">Speech</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Še 1 dan}one{Še # dan}two{Še # dneva}few{Še # dni}other{Še # dni}}</translation>
+<translation id="3618849550573277856">Poišči »<ph name="LOOKUP_STRING" />«</translation>
<translation id="364720409959344976">Izberite mapo, ki jo želite prenesti</translation>
<translation id="3660179305079774227">Puščica gor</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -59,8 +64,8 @@
<translation id="4202807286478387388">skoči</translation>
<translation id="4250229828105606438">Posnetek zaslona</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Pred 1 mesecem}one{Pred # mesecem}two{Pred # mesecema}few{Pred # meseci}other{Pred # meseci}}</translation>
+<translation id="4289300219472526559">Start Speaking</translation>
<translation id="4316910396681052118">VSE APLIKACIJE</translation>
-<translation id="4320177379694898372">Ni internetne povezave</translation>
<translation id="4588090240171750605">Pomik desno</translation>
<translation id="4724120544754982507">Središče za obvestila, št. neprebranih sporočil: <ph name="UNREAD_NOTIFICATION_COUNT" /></translation>
<translation id="4730374152663651037">POGOSTO UPORABLJENE</translation>
@@ -96,7 +101,9 @@
<translation id="6351032674660237738">PREDLOGI ZA APLIKACIJE</translation>
<translation id="6364916375976753737">Pomik levo</translation>
<translation id="6394627529324717982">Vejica</translation>
+<translation id="6397363302884558537">Stop Speaking</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Pred 1 s}one{Pred # s}two{Pred # s}few{Pred # s}other{Pred # s}}</translation>
+<translation id="6430678249303439055">Blokiraj vsa obvestila iz te aplikacije</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Pred 1 sekundo}one{Pred # sekundo}two{Pred # sekundama}few{Pred # sekundami}other{Pred # sekundami}}</translation>
<translation id="654149438358937226">Blokiraj vsa obvestila</translation>
<translation id="6567071839949112727">kliknite prednika</translation>
@@ -113,6 +120,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Še 1 leto}one{Še # leto}two{Še # leti}few{Še # leta}other{Še # let}}</translation>
<translation id="6945221475159498467">Izberi</translation>
<translation id="6965382102122355670">V redu</translation>
+<translation id="6974053822202609517">Od desne proti levi</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">NAJVERJETNEJŠE</translation>
<translation id="7222373446505536781">F11</translation>
@@ -135,7 +143,6 @@
<translation id="8328145009876646418">Levi rob</translation>
<translation id="8331626408530291785">Pomik gor</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 leto}one{# leto}two{# leti}few{# leta}other{# let}}</translation>
-<translation id="8371695176452482769">Začnite govoriti</translation>
<translation id="838869780401515933">potrdi</translation>
<translation id="8393700583063109961">Pošlji sporočilo</translation>
<translation id="8394908167088220973">Ustavitev/začasna ustavitev</translation>
@@ -143,6 +150,7 @@
<translation id="8602707065186045623">Datoteka <ph name="SAVEAS_EXTENSION_TYPE" /> (.<ph name="SAVEAS_EXTENSION_NAME" />)</translation>
<translation id="8677655579646609597"><ph name="QUANTITY" /> KB/s</translation>
<translation id="8730621377337864115">Končano</translation>
+<translation id="8798099450830957504">Privzeto</translation>
<translation id="8806053966018712535">Mapa <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Dodaj pripis sliki</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_sr.xtb b/chromium/ui/strings/translations/ui_strings_sr.xtb
index c07a2f2a253..bee93c7b1a1 100644
--- a/chromium/ui/strings/translations/ui_strings_sr.xtb
+++ b/chromium/ui/strings/translations/ui_strings_sr.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Отпреми</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ПРЕПОРУЧЕНЕ АПЛИКАЦИЈЕ</translation>
+<translation id="1368832886055348810">Слева надесно</translation>
<translation id="1398853756734560583">Увећај</translation>
<translation id="1413622004203049571">Онемогући обавештења од <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 минут и }one{# минут и }few{# минута и }other{# минута и }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Оцена у звездицама: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 сат и }one{# сат и }few{# сата и }other{# сати и }}</translation>
<translation id="1842960171412779397">изабери</translation>
+<translation id="1859234291848436338">Writing Direction (Смер писања)</translation>
<translation id="1860796786778352021">Затвори обавештење</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Страница нагоре</translation>
<translation id="2190355936436201913">(празно)</translation>
<translation id="219905428774326614">Покретач, све апликације</translation>
+<translation id="2267918077332197517">Блокирај сва обавештења са овог сајта</translation>
<translation id="2289052229480071835">Додирните циљна поља за додир на екрану.</translation>
<translation id="2295140143284145483">Анкета</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Помери се овде</translation>
<translation id="3234408098842461169">Стрелица надоле</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 дан}one{# дан}few{# дана}other{# дана}}</translation>
+<translation id="335581015389089642">Говор</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Још 1 дан}one{Још # дан}few{Још # дана}other{Још # дана}}</translation>
+<translation id="3618849550573277856">Потражи „<ph name="LOOKUP_STRING" />“</translation>
<translation id="364720409959344976">Избор директоријума за отпремање</translation>
<translation id="3660179305079774227">Стрелица нагоре</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">прескочи</translation>
<translation id="4250229828105606438">Снимак екрана</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Пре месец дана}one{Пре # месец}few{Пре # месеца}other{Пре # месеци}}</translation>
+<translation id="4289300219472526559">Почните да говорите</translation>
<translation id="4316910396681052118">СВЕ АПЛИКАЦИЈЕ</translation>
-<translation id="4320177379694898372">Нема интернет везе</translation>
<translation id="4588090240171750605">Помери надесно</translation>
<translation id="4724120544754982507">Центар за обавештења, непрочитаних обавештења: <ph name="UNREAD_NOTIFICATION_COUNT" /></translation>
<translation id="4730374152663651037">ЧЕСТО КОРИШЋЕНЕ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ПРЕДЛОЗИ АПЛИКАЦИЈА</translation>
<translation id="6364916375976753737">Помери налево</translation>
<translation id="6394627529324717982">Зарез</translation>
+<translation id="6397363302884558537">Престаните да говорите</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Пре 1 сек}one{Пре # сек}few{Пре # сек}other{Пре # сек}}</translation>
+<translation id="6430678249303439055">Блокирај сва обавештења из ове апликације</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Пре 1 секунду}one{Пре # секунду}few{Пре # секунде}other{Пре # секунди}}</translation>
<translation id="654149438358937226">Блокирај сва обавештења</translation>
<translation id="6567071839949112727">кликните на претходни елемент</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Још 1 година}one{Још # година}few{Још # године}other{Још # година}}</translation>
<translation id="6945221475159498467">Изабери</translation>
<translation id="6965382102122355670">Потврди</translation>
+<translation id="6974053822202609517">Здесна налево</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">НАЈВЕРОВАТНИЈЕ</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Лева ивица</translation>
<translation id="8331626408530291785">Помери нагоре</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 година}one{# година}few{# године}other{# година}}</translation>
-<translation id="8371695176452482769">Почните да говорите</translation>
<translation id="838869780401515933">изабери</translation>
<translation id="8393700583063109961">Пошаљите поруку</translation>
<translation id="8394908167088220973">Пуштање/паузирање медија</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">и још <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Готово</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 с}one{# с}few{# с}other{# с}}</translation>
+<translation id="8798099450830957504">Подразумевано</translation>
<translation id="8806053966018712535">Директоријум <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Додај напомену у слику</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_sv.xtb b/chromium/ui/strings/translations/ui_strings_sv.xtb
index 3d83c0af843..2dcdbb2375c 100644
--- a/chromium/ui/strings/translations/ui_strings_sv.xtb
+++ b/chromium/ui/strings/translations/ui_strings_sv.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Ladda upp</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">REKOMMENDERADE APPAR</translation>
+<translation id="1368832886055348810">Vänster till höger</translation>
<translation id="1398853756734560583">Maximera</translation>
<translation id="1413622004203049571">Inaktivera aviseringar från <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 minut och }other{# minuter och }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Betyg <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 timme och }other{# timmar och }}</translation>
<translation id="1842960171412779397">välj</translation>
+<translation id="1859234291848436338">Skrivriktning</translation>
<translation id="1860796786778352021">Meddelande om stängning</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Page Up</translation>
<translation id="2190355936436201913">(tom)</translation>
<translation id="219905428774326614">Startprogram, alla appar</translation>
+<translation id="2267918077332197517">Blockera alla aviseringar från den här webbplatsen</translation>
<translation id="2289052229480071835">Tryck på tryckområdena på skärmen.</translation>
<translation id="2295140143284145483">Enkät</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/sek</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Rulla hit</translation>
<translation id="3234408098842461169">Nedpil</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 dag}other{# dagar}}</translation>
+<translation id="335581015389089642">Tal</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 dag kvar}other{# dagar kvar}}</translation>
+<translation id="3618849550573277856">Sök efter ”<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Välj en mapp för uppladdning</translation>
<translation id="3660179305079774227">Uppil</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/sek</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">fortsätta</translation>
<translation id="4250229828105606438">Skärmdump</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 månad sedan}other{# månader sedan}}</translation>
+<translation id="4289300219472526559">Börja tala</translation>
<translation id="4316910396681052118">ALLA APPAR</translation>
-<translation id="4320177379694898372">Ingen internetanslutning</translation>
<translation id="4588090240171750605">Rulla åt höger</translation>
<translation id="4724120544754982507"><ph name="UNREAD_NOTIFICATION_COUNT" /> olästa aviseringar i meddelandecentret</translation>
<translation id="4730374152663651037">OFTA ANVÄNDA</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">APPFÖRSLAG</translation>
<translation id="6364916375976753737">Rulla åt vänster</translation>
<translation id="6394627529324717982">Komma</translation>
+<translation id="6397363302884558537">Sluta tala</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{för 1 sek sedan}other{för # sek sedan}}</translation>
+<translation id="6430678249303439055">Blockera alla aviseringar från den här appen</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 sekund sedan}other{# sekunder sedan}}</translation>
<translation id="654149438358937226">Blockera alla aviseringar</translation>
<translation id="6567071839949112727">klicka på det överordnade objektet</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 år kvar}other{# år kvar}}</translation>
<translation id="6945221475159498467">Välj</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Höger till vänster</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">MEST TROLIGA</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Vänsterkant</translation>
<translation id="8331626408530291785">Rulla uppåt</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 år}other{# år}}</translation>
-<translation id="8371695176452482769">Prata nu</translation>
<translation id="838869780401515933">kryssa för</translation>
<translation id="8393700583063109961">Skicka meddelande</translation>
<translation id="8394908167088220973">Spela upp/Pausa</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">och <ph name="NUMBER" /> till</translation>
<translation id="8730621377337864115">Klart</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 tim}other{# tim}}</translation>
+<translation id="8798099450830957504">Standard</translation>
<translation id="8806053966018712535">Mappen <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Kommentera bild</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> kB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_sw.xtb b/chromium/ui/strings/translations/ui_strings_sw.xtb
index 7d1ba36ef60..5cfc38c89f7 100644
--- a/chromium/ui/strings/translations/ui_strings_sw.xtb
+++ b/chromium/ui/strings/translations/ui_strings_sw.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Pakia</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">PROGRAMU ZINAZOPENDEKEZWA</translation>
+<translation id="1368832886055348810">Kushoto hadi Kulia</translation>
<translation id="1398853756734560583">Tanua</translation>
<translation id="1413622004203049571">Zima arifa kutoka <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{Dakika 1 na }other{Dakika # na }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Ukadiriaji wa nyota <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{Saa 1 na }other{Saa # na }}</translation>
<translation id="1842960171412779397">chagua</translation>
+<translation id="1859234291848436338">Mwelekeo wa Maandishi</translation>
<translation id="1860796786778352021">Funga arifa</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Ukurasa mmoja juu</translation>
<translation id="2190355936436201913">(tupu)</translation>
<translation id="219905428774326614">Kifungua Programu, programu zote</translation>
+<translation id="2267918077332197517">Zuia arifa zote kutoka tovuti hii</translation>
<translation id="2289052229480071835">Gusa viashirio vya kugusa kwenye skrini yako.</translation>
<translation id="2295140143284145483">Utafiti</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Sogeza Hadi Hapa</translation>
<translation id="3234408098842461169">Mshale Chini</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{Siku 1}other{Siku #}}</translation>
+<translation id="335581015389089642">Usemi</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Imesalia siku 1}other{Zimesalia siku #}}</translation>
+<translation id="3618849550573277856">Angalia “<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Chagua Folda ya Kupakia</translation>
<translation id="3660179305079774227">Mshale Juu</translation>
<translation id="3740362395218339114">GB/s <ph name="QUANTITY" /></translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">ruka</translation>
<translation id="4250229828105606438">Picha ya skrini</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{Mwezi 1 uliopita}other{Miezi # iliyopita}}</translation>
+<translation id="4289300219472526559">Anza Kuzungumza</translation>
<translation id="4316910396681052118">PROGRAMU ZOTE</translation>
-<translation id="4320177379694898372">Hakuna muunganisho wa intaneti</translation>
<translation id="4588090240171750605">Sogeza Kulia</translation>
<translation id="4724120544754982507">Kituo cha Arifa, arifa <ph name="UNREAD_NOTIFICATION_COUNT" /> ambazo hujasoma</translation>
<translation id="4730374152663651037">ZINAZOTUMIKA SANA</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">MAPENDEKEZO YA PROGRAMU</translation>
<translation id="6364916375976753737">Sogeza Kushoto</translation>
<translation id="6394627529324717982">Koma</translation>
+<translation id="6397363302884558537">Koma Kuongea</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{Sekunde 1 iliyopita}other{Sekunde # zilizopita}}</translation>
+<translation id="6430678249303439055">Zuia arifa zote kutoka programu hii</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{Sekunde 1 iliyopita}other{Sekunde # zilizopita}}</translation>
<translation id="654149438358937226">Zuia arifa zote</translation>
<translation id="6567071839949112727">bofya kipengee</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Umesalia mwaka 1}other{Imesalia miaka #}}</translation>
<translation id="6945221475159498467">Chagua</translation>
<translation id="6965382102122355670">Sawa</translation>
+<translation id="6974053822202609517">Kulia hadi Kushoto</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">UNAZOWEZA KUBOFYA SANA</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Ncha ya Kushoto</translation>
<translation id="8331626408530291785">Sogeza Juu</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{Mwaka 1}other{Miaka #}}</translation>
-<translation id="8371695176452482769">Ongea sasa</translation>
<translation id="838869780401515933">chunguza</translation>
<translation id="8393700583063109961">Tuma ujumbe</translation>
<translation id="8394908167088220973">Cheza Media/Sitisha</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> zaidi</translation>
<translation id="8730621377337864115">Nimemaliza</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{Saa 1}other{Saa #}}</translation>
+<translation id="8798099450830957504">Chaguo Msingi</translation>
<translation id="8806053966018712535">Folda ya <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Eleza kuhusu picha</translation>
<translation id="8901569739625249689">KB <ph name="QUANTITY" /></translation>
diff --git a/chromium/ui/strings/translations/ui_strings_ta.xtb b/chromium/ui/strings/translations/ui_strings_ta.xtb
index 711a614e82a..66df98a941f 100644
--- a/chromium/ui/strings/translations/ui_strings_ta.xtb
+++ b/chromium/ui/strings/translations/ui_strings_ta.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">பதிவேற்று</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">பரிந்துரைக்கப்படும் பயன்பாடுகள்</translation>
+<translation id="1368832886055348810">இடமிருந்து வலம்</translation>
<translation id="1398853756734560583">பெரிதாக்கு</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> இடமிருந்து வரும் அறிவிப்புகளை முடக்கு</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 நிமிடம், }other{# நிமிடங்கள், }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">நட்சத்திர மதிப்பீடு <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 மணிநேரம், }other{# மணிநேரம், }}</translation>
<translation id="1842960171412779397">தேர்ந்தெடு</translation>
+<translation id="1859234291848436338">எழுதும் திசை</translation>
<translation id="1860796786778352021">அறிவிப்பை மூடு</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">பக்கத்தின் மேலே</translation>
<translation id="2190355936436201913">(காலி)</translation>
<translation id="219905428774326614">துவக்கி, எல்லாப் பயன்பாடுகளும்</translation>
+<translation id="2267918077332197517">இந்தத் தளத்திலிருந்து எல்லா அறிவிப்புகளையும் தடு</translation>
<translation id="2289052229480071835">உங்கள் திரையில் இருக்கும் தொடுவதற்கான இலக்கிடங்களைத் தட்டவும்.</translation>
<translation id="2295140143284145483">கருத்துக்கணிப்பு</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> டெ.பை/வி</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">இங்கே உருட்டு</translation>
<translation id="3234408098842461169">கீழ்நோக்கிய அம்பு</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 நாள்}other{# நாட்கள்}}</translation>
+<translation id="335581015389089642">பேச்சு</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 நாள் உள்ளது}other{# நாட்கள் உள்ளன}}</translation>
+<translation id="3618849550573277856">“<ph name="LOOKUP_STRING" />” எனத் தேடு</translation>
<translation id="364720409959344976">பதிவேற்றுவதற்குக் கோப்புறையைத் தேர்ந்தெடு</translation>
<translation id="3660179305079774227">மேல்நோக்கிய அம்பு</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> ஜி.பை/வி</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">தாவு</translation>
<translation id="4250229828105606438">ஸ்கிரீன் ஷாட்</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 மாதத்திற்கு முன்}other{# மாதங்களுக்கு முன்}}</translation>
+<translation id="4289300219472526559">பேச்சைத் தொடங்கு</translation>
<translation id="4316910396681052118">எல்லாப் பயன்பாடுகளும்</translation>
-<translation id="4320177379694898372">இணைய இணைப்பு இல்லை</translation>
<translation id="4588090240171750605">வலப்புறம் உருட்டு</translation>
<translation id="4724120544754982507">அறிவிப்பு மையம், <ph name="UNREAD_NOTIFICATION_COUNT" /> படிக்காத அறிவிப்புகள்</translation>
<translation id="4730374152663651037">அடிக்கடிப் பயன்படுத்தியவை</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">பயன்பாட்டுப் பரிந்துரைகள்</translation>
<translation id="6364916375976753737">இடப்புறம் உருட்டு</translation>
<translation id="6394627529324717982">கமா</translation>
+<translation id="6397363302884558537">பேச்சை நிறுத்து</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 நிமிடம் முன்பு}other{# நிமிடங்கள் முன்பு}}</translation>
+<translation id="6430678249303439055">இந்தப் பயன்பாட்டிலிருந்து எல்லா அறிவிப்புகளையும் தடு</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 வினாடிக்கு முன்பு}other{# வினாடிகளுக்கு முன்பு}}</translation>
<translation id="654149438358937226">எல்லா அறிவிப்புகளையும் தடு</translation>
<translation id="6567071839949112727">ஆன்செஸ்டரைக் கிளிக் செய்</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 ஆண்டு உள்ளது}other{# ஆண்டுகள் உள்ளன}}</translation>
<translation id="6945221475159498467">தேர்ந்தெடு</translation>
<translation id="6965382102122355670">சரி</translation>
+<translation id="6974053822202609517">வலமிருந்து இடம்</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">அதிகச் சாத்தியமுள்ளவை</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">இடதுபுற முனை</translation>
<translation id="8331626408530291785">மேலே உருட்டு</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 ஆண்டு}other{# ஆண்டுகள்}}</translation>
-<translation id="8371695176452482769">இப்போது பேசுக</translation>
<translation id="838869780401515933">சரிபார்</translation>
<translation id="8393700583063109961">செய்தி அனுப்பு</translation>
<translation id="8394908167088220973">ஊடகத்தை இயக்கு/இடைநிறுத்து</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">மேலும் <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">முடிந்தது</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1ம}other{#ம}}</translation>
+<translation id="8798099450830957504">இயல்புநிலை</translation>
<translation id="8806053966018712535"><ph name="FOLDER_NAME" /> கோப்புறை</translation>
<translation id="883911313571074303">படத்தைக் குறிப்பிடு</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> கி.பை.</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_te.xtb b/chromium/ui/strings/translations/ui_strings_te.xtb
index 0dfea8a7858..4e84a0122b2 100644
--- a/chromium/ui/strings/translations/ui_strings_te.xtb
+++ b/chromium/ui/strings/translations/ui_strings_te.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">అప్‌లోడ్ చేయి</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">సిఫార్సు చేసిన యాప్‌లు</translation>
+<translation id="1368832886055348810">ఎడమ నుండి కుడికి</translation>
<translation id="1398853756734560583">గరిష్ఠీకరించు</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> నుండి వచ్చే నోటిఫికేషన్‌లను నిలిపివేయి</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 నిమిషం మరియు }other{# నిమిషాలు మరియు }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">నక్షత్ర రేటింగ్ <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 గంట మరియు }other{# గంటలు మరియు }}</translation>
<translation id="1842960171412779397">ఎంచుకోండి</translation>
+<translation id="1859234291848436338">వ్రాసే దిశ</translation>
<translation id="1860796786778352021">నోటిఫికేషన్‌ను మూసివేయి</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">పేజీ పైకి</translation>
<translation id="2190355936436201913">(ఖాళీ)</translation>
<translation id="219905428774326614">లాంచర్, అన్ని యాప్‌లు</translation>
+<translation id="2267918077332197517">ఈ సైట్ నుండి నోటిఫికేషన్‌లు అన్ని బ్లాక్ చేయండి</translation>
<translation id="2289052229480071835">మీ స్క్రీన్‌పై ఉన్న స్పర్శ లక్ష్యాలను నొక్కండి.</translation>
<translation id="2295140143284145483">సర్వే</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">ఇక్కడ స్క్రోల్ చెయ్యండి</translation>
<translation id="3234408098842461169">క్రింది బాణం</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 రోజు}other{# రోజులు}}</translation>
+<translation id="335581015389089642">ప్రసంగం</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 రోజు మిగిలి ఉంది}other{# రోజులు మిగిలి ఉన్నాయి}}</translation>
+<translation id="3618849550573277856">“<ph name="LOOKUP_STRING" />”ని వెతకండి</translation>
<translation id="364720409959344976">అప్‌లోడ్ చేయడానికి ఫోల్డర్‌ని ఎంచుకోండి</translation>
<translation id="3660179305079774227">ఎగువ బాణం</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">వెళ్ళు</translation>
<translation id="4250229828105606438">స్క్రీన్‌షాట్</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 నెల క్రితం}other{# నెలల క్రితం}}</translation>
+<translation id="4289300219472526559">మాట్లాడటాన్ని ప్రారంభించు</translation>
<translation id="4316910396681052118">అన్ని అనువర్తనాలు</translation>
-<translation id="4320177379694898372">ఇంటర్నెట్ కనెక్షన్ లేదు</translation>
<translation id="4588090240171750605">కుడికి స్క్రోల్ చెయ్యి</translation>
<translation id="4724120544754982507">నోటిఫికేషన్ కేంద్రం, <ph name="UNREAD_NOTIFICATION_COUNT" /> చదవని నోటిఫికేషన్‌లు</translation>
<translation id="4730374152663651037">తరచుగా ఉపయోగించేవి</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">యాప్ సూచనలు</translation>
<translation id="6364916375976753737">ఎడమకి స్క్రోల్ చేయి</translation>
<translation id="6394627529324717982">కామా</translation>
+<translation id="6397363302884558537">మాట్లాడటాన్ని ఆపివేయి</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 సెక. క్రితం}other{# సెక. క్రితం}}</translation>
+<translation id="6430678249303439055">ఈ యాప్ నుండి నోటిఫికేషన్‌లు అన్ని బ్లాక్ చేయండి</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 సెకను క్రితం}other{# సెకన్ల క్రితం}}</translation>
<translation id="654149438358937226">అన్ని నోటిఫికేషన్‌లను బ్లాక్ చేయి</translation>
<translation id="6567071839949112727">క్లిక్ మూలకం</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 సంవత్సరం మిగిలి ఉంది}other{# సంవత్సరాలు మిగిలి ఉన్నాయి}}</translation>
<translation id="6945221475159498467">ఎంచుకోండి</translation>
<translation id="6965382102122355670">సరే</translation>
+<translation id="6974053822202609517">కుడి నుండి ఎడమకు</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">అత్యంత ఇష్టపడేవి</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">ఎడమ హద్దు</translation>
<translation id="8331626408530291785">పైకి స్క్రోల్ చెయ్యి</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 సంవత్సరం}other{# సంవత్సరాలు}}</translation>
-<translation id="8371695176452482769">ఇప్పుడు మాట్లాడండి</translation>
<translation id="838869780401515933">తనిఖీ చెయ్యి</translation>
<translation id="8393700583063109961">సందేశాన్ని పంపండి</translation>
<translation id="8394908167088220973">మీడియా ప్లే/పాజ్</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+ మరో <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">పూర్తయింది</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1గం}other{#గం}}</translation>
+<translation id="8798099450830957504">డిఫాల్ట్</translation>
<translation id="8806053966018712535">ఫోల్డర్ <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">చిత్రాన్ని అనులేఖించు</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_th.xtb b/chromium/ui/strings/translations/ui_strings_th.xtb
index 484e557264f..7aa7da8ca72 100644
--- a/chromium/ui/strings/translations/ui_strings_th.xtb
+++ b/chromium/ui/strings/translations/ui_strings_th.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">อัปโหลด</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">แอปแนะนำ</translation>
+<translation id="1368832886055348810">ซ้ายไปขวา</translation>
<translation id="1398853756734560583">ย่อ</translation>
<translation id="1413622004203049571">ปิดการแจ้งเตือนจาก <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 นาทีกับอีก }other{# นาทีกับอีก }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">เริ่มให้คะแนน <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 ชั่วโมงกับอีก }other{# ชั่วโมงกับอีก }}</translation>
<translation id="1842960171412779397">เลือก</translation>
+<translation id="1859234291848436338">การเขียนเส้นทาง</translation>
<translation id="1860796786778352021">ปิดการแจ้งเตือน</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">เลื่อนหน้าขึ้น</translation>
<translation id="2190355936436201913">(ว่างเปล่า)</translation>
<translation id="219905428774326614">Launcher, แอปทั้งหมด</translation>
+<translation id="2267918077332197517">บล็อกการแจ้งเตือนทั้งหมดจากเว็บไซต์นี้</translation>
<translation id="2289052229480071835">แตะเป้าหมายการสัมผัสในหน้าจอ</translation>
<translation id="2295140143284145483">แบบสำรวจ</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/วินาที</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">เลื่อนมาที่นี่</translation>
<translation id="3234408098842461169">ลูกศรลง</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 วัน}other{# วัน}}</translation>
+<translation id="335581015389089642">คำพูด</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{เหลือ 1 วัน}other{เหลือ # วัน}}</translation>
+<translation id="3618849550573277856">ค้นหา “<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">เลือกโฟลเดอร์เพื่ออัปโหลด</translation>
<translation id="3660179305079774227">ลูกศรขึ้น</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/วินาที</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">ข้าม</translation>
<translation id="4250229828105606438">ภาพหน้าจอ</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 เดือนที่ผ่านมา}other{# เดือนที่ผ่านมา}}</translation>
+<translation id="4289300219472526559">เริ่มพูด</translation>
<translation id="4316910396681052118">แอปทั้งหมด</translation>
-<translation id="4320177379694898372">ไม่มีการเชื่อมต่ออินเทอร์เน็ต</translation>
<translation id="4588090240171750605">เลื่อนทางขวา</translation>
<translation id="4724120544754982507">ศูนย์การแจ้งเตือนมีการแจ้งเตือนที่ยังไม่อ่าน <ph name="UNREAD_NOTIFICATION_COUNT" /> รายการ</translation>
<translation id="4730374152663651037">แอปที่ใช้บ่อย</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">คำแนะนำเกี่ยวกับแอป</translation>
<translation id="6364916375976753737">เลื่อนทางซ้าย</translation>
<translation id="6394627529324717982">จุลภาค</translation>
+<translation id="6397363302884558537">หยุดพูด</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 วินาทีที่ผ่านมา}other{# วินาทีที่ผ่านมา}}</translation>
+<translation id="6430678249303439055">บล็อกการแจ้งเตือนทั้งหมดจากแอปนี้</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{ 1 วินาทีที่ผ่านมา}other{# วินาทีที่ผ่านมา}}</translation>
<translation id="654149438358937226">บล็อกการแจ้งเตือนทั้งหมด</translation>
<translation id="6567071839949112727">คลิกต้นตระกูล</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{เหลือ 1 ปี}other{เหลือ # ปี}}</translation>
<translation id="6945221475159498467">เลือก</translation>
<translation id="6965382102122355670">ตกลง</translation>
+<translation id="6974053822202609517">ขวาไปซ้าย</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">น่าจะใช้มากที่สุด</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">ขอบซ้าย</translation>
<translation id="8331626408530291785">เลื่อนขึ้น</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 ปี}other{# ปี}}</translation>
-<translation id="8371695176452482769">เชิญพูดเลย</translation>
<translation id="838869780401515933">ทำเครื่องหมาย</translation>
<translation id="8393700583063109961">ส่งข้อความ</translation>
<translation id="8394908167088220973">เล่น/หยุดสื่อชั่วคราว</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">และอีก <ph name="NUMBER" /> รายการ</translation>
<translation id="8730621377337864115">เสร็จสิ้น</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 ชม.}other{# ชม.}}</translation>
+<translation id="8798099450830957504">ค่าเริ่มต้น</translation>
<translation id="8806053966018712535">โฟลเดอร์ <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">ใส่หมายเหตุในรูปภาพ</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_tr.xtb b/chromium/ui/strings/translations/ui_strings_tr.xtb
index 6a12de1ae44..ff48f705d6d 100644
--- a/chromium/ui/strings/translations/ui_strings_tr.xtb
+++ b/chromium/ui/strings/translations/ui_strings_tr.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Yükle</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">ÖNERİLEN UYGULAMALAR</translation>
+<translation id="1368832886055348810">Soldan Sağa</translation>
<translation id="1398853756734560583">Büyüt</translation>
<translation id="1413622004203049571"><ph name="NOTIFIER_NAME" /> bildirimlerini devre dışı bırak</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 dakika ve }other{# dakika ve }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Yıldız puanı <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 saat }other{# saat ve }}</translation>
<translation id="1842960171412779397">seç</translation>
+<translation id="1859234291848436338">Yazma Yönü</translation>
<translation id="1860796786778352021">Bildirimi kapat</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652">%<ph name="NUMBER" /></translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Page Up</translation>
<translation id="2190355936436201913">(boş)</translation>
<translation id="219905428774326614">Launcher, tüm uygulamalar</translation>
+<translation id="2267918077332197517">Bu siteden gelen tüm bildirimleri engelle</translation>
<translation id="2289052229480071835">Ekranınızda dokunma hedeflerine dokunun.</translation>
<translation id="2295140143284145483">Anket</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/sn</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Buraya Kaydır</translation>
<translation id="3234408098842461169">Aşağı Ok</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 gün}other{# gün}}</translation>
+<translation id="335581015389089642">Konuşma</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{1 gün kaldı}other{# gün kaldı}}</translation>
+<translation id="3618849550573277856">“<ph name="LOOKUP_STRING" />” Araması Yap</translation>
<translation id="364720409959344976">Yüklenecek Klasörü Seçin</translation>
<translation id="3660179305079774227">Yukarı Ok</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/sn</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">git</translation>
<translation id="4250229828105606438">Ekran görüntüsü</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 ay önce}other{# ay önce}}</translation>
+<translation id="4289300219472526559">Konuşmaya Başla</translation>
<translation id="4316910396681052118">TÜM UYGULAMALAR</translation>
-<translation id="4320177379694898372">İnternet bağlantısı yok</translation>
<translation id="4588090240171750605">Sağa Kaydır</translation>
<translation id="4724120544754982507">Bildirim Merkezi, <ph name="UNREAD_NOTIFICATION_COUNT" /> okunmamış bildirim</translation>
<translation id="4730374152663651037">SIK KULLANILANLAR</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">UYGULAMA ÖNERİLERİ</translation>
<translation id="6364916375976753737">Sola Kaydır</translation>
<translation id="6394627529324717982">Virgül</translation>
+<translation id="6397363302884558537">Konuşmayı Durdur</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 sn. önce}other{# sn. önce}}</translation>
+<translation id="6430678249303439055">Bu uygulamadan gelen tüm bildirimleri engelle</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 saniye önce}other{# saniye önce}}</translation>
<translation id="654149438358937226">Tüm bildirimleri engelle</translation>
<translation id="6567071839949112727">üst öğeyi tıkla</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{1 yıl kaldı}other{# yıl kaldı}}</translation>
<translation id="6945221475159498467">Seç</translation>
<translation id="6965382102122355670">Tamam</translation>
+<translation id="6974053822202609517">Sağdan Sola</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">BÜYÜK İHTİMALLE</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Sol Kenar</translation>
<translation id="8331626408530291785">Yukarı Kaydır</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 yıl}other{# yıl}}</translation>
-<translation id="8371695176452482769">Şimdi konuşun</translation>
<translation id="838869780401515933">işaretle</translation>
<translation id="8393700583063109961">İleti gönder</translation>
<translation id="8394908167088220973">Medyayı Oynat/Duraklat</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204"><ph name="NUMBER" /> öğe daha</translation>
<translation id="8730621377337864115">Bitti</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 sa.}other{# sa.}}</translation>
+<translation id="8798099450830957504">Varsayılan</translation>
<translation id="8806053966018712535"><ph name="FOLDER_NAME" /> klasörü</translation>
<translation id="883911313571074303">Resme açıklama ekle</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_uk.xtb b/chromium/ui/strings/translations/ui_strings_uk.xtb
index 21b70f1d44e..e470d44a019 100644
--- a/chromium/ui/strings/translations/ui_strings_uk.xtb
+++ b/chromium/ui/strings/translations/ui_strings_uk.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">Завантажити</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">РЕКОМЕНДОВАНІ ПРОГРАМИ</translation>
+<translation id="1368832886055348810">Зліва направо</translation>
<translation id="1398853756734560583">Збільшити</translation>
<translation id="1413622004203049571">Вимкнути сповіщення від <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 хвилина та }one{# хвилина та }few{# хвилини та }many{# хвилин і }other{# хвилини та }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Рейтинг у зірочках: <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 година та }one{# година та }few{# години та }many{# годин і }other{# години та }}</translation>
<translation id="1842960171412779397">вибрати</translation>
+<translation id="1859234291848436338">Напрямок письма</translation>
<translation id="1860796786778352021">Закрити сповіщення</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" />%</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Сторінка вгору</translation>
<translation id="2190355936436201913">(пусто)</translation>
<translation id="219905428774326614">Панель запуску, усі додатки</translation>
+<translation id="2267918077332197517">Блокувати всі сповіщення від цього сайту</translation>
<translation id="2289052229480071835">Торкніться елементів для дотику на екрані.</translation>
<translation id="2295140143284145483">Опитування</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> ТБ/сек.</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Прокрутка до цього місця</translation>
<translation id="3234408098842461169">Курсор униз</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 день}one{# день}few{# дні}many{# днів}other{# дня}}</translation>
+<translation id="335581015389089642">Speech</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Залишився 1 день}one{Залишився # день}few{Залишилося # дні}many{Залишилося # днів}other{Залишилося # дня}}</translation>
+<translation id="3618849550573277856">Шукати "<ph name="LOOKUP_STRING" />"</translation>
<translation id="364720409959344976">Виберіть папку для завантаження</translation>
<translation id="3660179305079774227">Курсор угору</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> ГБ/сек.</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">перейти</translation>
<translation id="4250229828105606438">Знімок екрана</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 місяць тому}one{# місяць тому}few{# місяці тому}many{# місяців тому}other{# місяця тому}}</translation>
+<translation id="4289300219472526559">Start Speaking</translation>
<translation id="4316910396681052118">УСІ ДОДАТКИ</translation>
-<translation id="4320177379694898372">Немає з’єднання з Інтернетом</translation>
<translation id="4588090240171750605">Прокрутка вправо</translation>
<translation id="4724120544754982507">Центр сповіщень, непрочитаних сповіщень: <ph name="UNREAD_NOTIFICATION_COUNT" /></translation>
<translation id="4730374152663651037">ЧАСТО ВИКОРИСТОВУЮТЬСЯ</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ПРОПОЗИЦІЇ ДОДАТКІВ</translation>
<translation id="6364916375976753737">Прокрутка вліво</translation>
<translation id="6394627529324717982">Кома</translation>
+<translation id="6397363302884558537">Stop Speaking</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 с тому}one{# с тому}few{# с тому}many{# с тому}other{# с тому}}</translation>
+<translation id="6430678249303439055">Блокувати всі сповіщення від цього додатка</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 секунду тому}one{# секунду тому}few{# секунди тому}many{# секунд тому}other{# секунди тому}}</translation>
<translation id="654149438358937226">Блокувати всі сповіщення</translation>
<translation id="6567071839949112727">натиснути предок</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Залишився 1 рік}one{Залишився # рік}few{Залишилося # роки}many{Залишилося # років}other{Залишилося # року}}</translation>
<translation id="6945221475159498467">Вибрати</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Справа наліво</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">НАЙІМОВІРНІШЕ</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Лівий край</translation>
<translation id="8331626408530291785">Прокрутка вгору</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 рік}one{# рік}few{# роки}many{# років}other{# року}}</translation>
-<translation id="8371695176452482769">Диктуйте</translation>
<translation id="838869780401515933">установити прапорець</translation>
<translation id="8393700583063109961">Надіслати повідомлення</translation>
<translation id="8394908167088220973">Відтворити чи призупинити</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">і ще <ph name="NUMBER" /></translation>
<translation id="8730621377337864115">Готово</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 год}one{# год}few{# год}many{# год}other{# год}}</translation>
+<translation id="8798099450830957504">За умовчанням</translation>
<translation id="8806053966018712535">Папка <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Додати нотатку до зображення</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> КБ</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_vi.xtb b/chromium/ui/strings/translations/ui_strings_vi.xtb
index c28f846e344..0278c309ae6 100644
--- a/chromium/ui/strings/translations/ui_strings_vi.xtb
+++ b/chromium/ui/strings/translations/ui_strings_vi.xtb
@@ -7,7 +7,8 @@
<translation id="1169783199079129864">{MINUTES,plural, =1{1 phút}other{# phút}}</translation>
<translation id="1243314992276662751">Tải lên</translation>
<translation id="1293699935367580298">Thoát</translation>
-<translation id="1306549533752902673">ỨNG DỤNG ĐƯỢC ĐỀ XUẤT</translation>
+<translation id="1306549533752902673">ỨNG DỤNG ĐỀ XUẤT</translation>
+<translation id="1368832886055348810">Trái sang Phải</translation>
<translation id="1398853756734560583">Phóng to</translation>
<translation id="1413622004203049571">Tắt thông báo từ <ph name="NOTIFIER_NAME" /></translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 phút và }other{# phút và }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">Xếp hạng theo sao <ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 giờ và }other{# giờ và }}</translation>
<translation id="1842960171412779397">chọn</translation>
+<translation id="1859234291848436338">Hướng Ghi</translation>
<translation id="1860796786778352021">Đóng thông báo</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">Page Up</translation>
<translation id="2190355936436201913">(trống)</translation>
<translation id="219905428774326614">Trình khởi chạy, tất cả ứng dụng</translation>
+<translation id="2267918077332197517">Chặn tất cả thông báo từ trang web này</translation>
<translation id="2289052229480071835">Nhấn vào các mục tiêu cảm ứng trên màn hình của bạn.</translation>
<translation id="2295140143284145483">Khảo sát</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/giây</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">Cuộn tới Đây</translation>
<translation id="3234408098842461169">Phím mũi tên Xuống</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 ngày}other{# ngày}}</translation>
+<translation id="335581015389089642">Giọng nói</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{Còn 1 ngày}other{Còn # ngày}}</translation>
+<translation id="3618849550573277856">Tra cứu “<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">Chọn thư mục để tải lên</translation>
<translation id="3660179305079774227">Phím mũi tên Lên</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/giây</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">chuyển</translation>
<translation id="4250229828105606438">Ảnh chụp màn hình</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 tháng trước}other{# tháng trước}}</translation>
+<translation id="4289300219472526559">Bắt đầu nói</translation>
<translation id="4316910396681052118">TẤT CẢ ỨNG DỤNG</translation>
-<translation id="4320177379694898372">Không có kết nối Internet</translation>
<translation id="4588090240171750605">Cuộn qua Phải</translation>
<translation id="4724120544754982507">Trung tâm thông báo, <ph name="UNREAD_NOTIFICATION_COUNT" /> thông báo chưa đọc</translation>
<translation id="4730374152663651037">SỬ DỤNG THƯỜNG XUYÊN</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">ĐỀ XUẤT ỨNG DỤNG</translation>
<translation id="6364916375976753737">Cuộn qua Trái</translation>
<translation id="6394627529324717982">Dấu phẩy</translation>
+<translation id="6397363302884558537">Dừng nói</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 giây trước}other{# giây trước}}</translation>
+<translation id="6430678249303439055">Chặn tất cả thông báo từ ứng dụng này</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 giây trước}other{# giây trước}}</translation>
<translation id="654149438358937226">Chặn tất cả thông báo</translation>
<translation id="6567071839949112727">nhấp vào đối tượng cấp trên</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{Còn 1 năm}other{Còn # năm}}</translation>
<translation id="6945221475159498467">Chọn</translation>
<translation id="6965382102122355670">OK</translation>
+<translation id="6974053822202609517">Phải sang Trái</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">RẤT CÓ THỂ</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">Cạnh Bên trái</translation>
<translation id="8331626408530291785">Cuộn Lên</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 năm}other{# năm}}</translation>
-<translation id="8371695176452482769">Nói ngay bây giờ</translation>
<translation id="838869780401515933">chọn</translation>
<translation id="8393700583063109961">Gửi tin nhắn</translation>
<translation id="8394908167088220973">Phát/Tạm dừng trình phát phương tiện</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+<ph name="NUMBER" /> mục khác</translation>
<translation id="8730621377337864115">Hoàn tất</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 giờ}other{# giờ}}</translation>
+<translation id="8798099450830957504">Mặc định</translation>
<translation id="8806053966018712535">Thư mục <ph name="FOLDER_NAME" /></translation>
<translation id="883911313571074303">Chú thích hình ảnh</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
@@ -161,7 +169,7 @@
<translation id="9044832324875206639">{SECONDS,plural, =1{1 giây}other{# giây}}</translation>
<translation id="9059834730836941392">Thu gọn thông báo</translation>
<translation id="9150735707954472829">Tab</translation>
-<translation id="9161053988251441839">ỨNG DỤNG ĐƯỢC ĐỀ XUẤT</translation>
+<translation id="9161053988251441839">ỨNG DỤNG ĐỀ XUẤT</translation>
<translation id="9170848237812810038">H&amp;oàn tác</translation>
<translation id="932327136139879170">Trang chủ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/ui/strings/translations/ui_strings_zh-CN.xtb b/chromium/ui/strings/translations/ui_strings_zh-CN.xtb
index 1a9de3d2d67..1dc0dbb27d5 100644
--- a/chromium/ui/strings/translations/ui_strings_zh-CN.xtb
+++ b/chromium/ui/strings/translations/ui_strings_zh-CN.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">上传</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">推荐的应用</translation>
+<translation id="1368832886055348810">从左向右</translation>
<translation id="1398853756734560583">最大化</translation>
<translation id="1413622004203049571">停用来自“<ph name="NOTIFIER_NAME" />”的通知</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 分钟 }other{# 分钟 }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">星级:<ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 小时 }other{# 小时 }}</translation>
<translation id="1842960171412779397">选中</translation>
+<translation id="1859234291848436338">书写方向</translation>
<translation id="1860796786778352021">关闭通知</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">向上翻页</translation>
<translation id="2190355936436201913">(空)</translation>
<translation id="219905428774326614">启动器,所有应用</translation>
+<translation id="2267918077332197517">屏蔽来自此网站的所有通知</translation>
<translation id="2289052229480071835">点按您屏幕上的触摸目标。</translation>
<translation id="2295140143284145483">调查问卷</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/s</translation>
@@ -50,7 +53,9 @@
<translation id="3183922693828471536">滚动到此处</translation>
<translation id="3234408098842461169">向下箭头</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 天}other{# 天}}</translation>
+<translation id="335581015389089642">语音</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{还剩 1 天}other{还剩 # 天}}</translation>
+<translation id="3618849550573277856">查询“<ph name="LOOKUP_STRING" />”</translation>
<translation id="364720409959344976">选择要上传的文件夹</translation>
<translation id="3660179305079774227">向上箭头</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/s</translation>
@@ -63,8 +68,8 @@
<translation id="4202807286478387388">略过</translation>
<translation id="4250229828105606438">屏幕截图</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 个月前}other{# 个月前}}</translation>
+<translation id="4289300219472526559">开始讲话</translation>
<translation id="4316910396681052118">所有应用</translation>
-<translation id="4320177379694898372">未连接到互联网</translation>
<translation id="4588090240171750605">向右滚动</translation>
<translation id="4724120544754982507">通知中心,<ph name="UNREAD_NOTIFICATION_COUNT" /> 条未读通知</translation>
<translation id="4730374152663651037">常用应用</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">应用推荐</translation>
<translation id="6364916375976753737">向左滚动</translation>
<translation id="6394627529324717982">逗号</translation>
+<translation id="6397363302884558537">停止讲话</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 秒前}other{# 秒前}}</translation>
+<translation id="6430678249303439055">屏蔽来自此应用的所有通知</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 秒前}other{# 秒前}}</translation>
<translation id="654149438358937226">屏蔽所有通知</translation>
<translation id="6567071839949112727">点击祖先实体</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{还有 1 年的时间}other{还有 # 年的时间}}</translation>
<translation id="6945221475159498467">选择</translation>
<translation id="6965382102122355670">确定</translation>
+<translation id="6974053822202609517">从右向左</translation>
<translation id="7052633198403197513">F1</translation>
<translation id="7130207228079676353">很可能会点击的应用</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">左边缘</translation>
<translation id="8331626408530291785">向上滚动</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 年}other{# 年}}</translation>
-<translation id="8371695176452482769">请开始说话</translation>
<translation id="838869780401515933">选中</translation>
<translation id="8393700583063109961">发送消息</translation>
<translation id="8394908167088220973">媒体播放/暂停</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">+ 另外 <ph name="NUMBER" /> 项</translation>
<translation id="8730621377337864115">完成</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 小时}other{# 小时}}</translation>
+<translation id="8798099450830957504">默认</translation>
<translation id="8806053966018712535">文件夹“<ph name="FOLDER_NAME" />”</translation>
<translation id="883911313571074303">为图片添加注释</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/translations/ui_strings_zh-TW.xtb b/chromium/ui/strings/translations/ui_strings_zh-TW.xtb
index 381cb4a5685..ad478c47f7b 100644
--- a/chromium/ui/strings/translations/ui_strings_zh-TW.xtb
+++ b/chromium/ui/strings/translations/ui_strings_zh-TW.xtb
@@ -8,6 +8,7 @@
<translation id="1243314992276662751">上傳</translation>
<translation id="1293699935367580298">Esc</translation>
<translation id="1306549533752902673">推薦應用程式</translation>
+<translation id="1368832886055348810">由左至右</translation>
<translation id="1398853756734560583">放到最大</translation>
<translation id="1413622004203049571">停用「<ph name="NOTIFIER_NAME" />」的通知</translation>
<translation id="1591184457164800433">{MINUTES,plural, =1{1 分鐘 }other{# 分鐘 }}</translation>
@@ -21,6 +22,7 @@
<translation id="1812519734428420144">星級評等:<ph name="RATING_SCORE" /></translation>
<translation id="1830179671306812954">{HOURS,plural, =1{1 小時 }other{# 小時 }}</translation>
<translation id="1842960171412779397">選取</translation>
+<translation id="1859234291848436338">文字方向</translation>
<translation id="1860796786778352021">通知關閉</translation>
<translation id="1871244248791675517">Ins</translation>
<translation id="1884435127456172652"><ph name="NUMBER" /> %</translation>
@@ -30,6 +32,7 @@
<translation id="2168039046890040389">向上翻頁</translation>
<translation id="2190355936436201913">(空白)</translation>
<translation id="219905428774326614">啟動器,所有應用程式</translation>
+<translation id="2267918077332197517">一律封鎖來自這個網站的通知</translation>
<translation id="2289052229480071835">輕觸畫面上的觸控目標。</translation>
<translation id="2295140143284145483">問卷調查</translation>
<translation id="2297836609126180313"><ph name="QUANTITY" /> TB/秒</translation>
@@ -50,21 +53,23 @@
<translation id="3183922693828471536">捲動至此</translation>
<translation id="3234408098842461169">向下鍵</translation>
<translation id="3291688615589870984">{DAYS,plural, =1{1 天}other{# 天}}</translation>
+<translation id="335581015389089642">語音</translation>
<translation id="3600566671520689681">{DAYS,plural, =1{還剩 1 天}other{還剩 # 天}}</translation>
+<translation id="3618849550573277856">查詢「<ph name="LOOKUP_STRING" />」</translation>
<translation id="364720409959344976">選取要上傳的資料夾</translation>
<translation id="3660179305079774227">向上鍵</translation>
<translation id="3740362395218339114"><ph name="QUANTITY" /> GB/秒</translation>
<translation id="3757388668994797779"><ph name="QUANTITY" /> GB</translation>
<translation id="385051799172605136">返回</translation>
<translation id="3889424535448813030">向右鍵</translation>
-<translation id="3892641579809465218">内建顯示器</translation>
+<translation id="3892641579809465218">內建顯示器</translation>
<translation id="3909791450649380159">剪下(&amp;T)</translation>
<translation id="3990502903496589789">右邊緣</translation>
<translation id="4202807286478387388">跳至另一頁</translation>
<translation id="4250229828105606438">螢幕擷取畫面</translation>
<translation id="4266252015790371705">{MONTHS,plural, =1{1 個月前}other{# 個月前}}</translation>
+<translation id="4289300219472526559">Start Speaking</translation>
<translation id="4316910396681052118">所有應用程式</translation>
-<translation id="4320177379694898372">沒有網際網路連線</translation>
<translation id="4588090240171750605">向右捲動</translation>
<translation id="4724120544754982507">通知中心,<ph name="UNREAD_NOTIFICATION_COUNT" /> 則未讀通知</translation>
<translation id="4730374152663651037">常用的應用程式</translation>
@@ -102,7 +107,9 @@
<translation id="6351032674660237738">應用程式建議</translation>
<translation id="6364916375976753737">向左捲動</translation>
<translation id="6394627529324717982">逗號</translation>
+<translation id="6397363302884558537">Stop Speaking</translation>
<translation id="6404817160109697034">{SECONDS,plural, =1{1 秒前}other{# 秒前}}</translation>
+<translation id="6430678249303439055">一律封鎖來自這個應用程式的通知</translation>
<translation id="6483402905448010557">{SECONDS,plural, =1{1 秒前}other{# 秒前}}</translation>
<translation id="654149438358937226">封鎖所有通知</translation>
<translation id="6567071839949112727">點選上層項目</translation>
@@ -119,6 +126,7 @@
<translation id="6917971086528278418">{YEARS,plural, =1{還剩 1 年}other{還剩 # 年}}</translation>
<translation id="6945221475159498467">選取</translation>
<translation id="6965382102122355670">確定</translation>
+<translation id="6974053822202609517">由右至左</translation>
<translation id="7052633198403197513">F1 鍵</translation>
<translation id="7130207228079676353">最有可能選擇的應用程式</translation>
<translation id="7222373446505536781">F11</translation>
@@ -142,7 +150,6 @@
<translation id="8328145009876646418">左邊緣</translation>
<translation id="8331626408530291785">向上捲動</translation>
<translation id="8352146631962686268">{YEARS,plural, =1{1 年}other{# 年}}</translation>
-<translation id="8371695176452482769">請說話</translation>
<translation id="838869780401515933">選取</translation>
<translation id="8393700583063109961">傳送訊息</translation>
<translation id="8394908167088220973">媒體播放/暫停</translation>
@@ -153,6 +160,7 @@
<translation id="8725488761726303204">還有另外 <ph name="NUMBER" /> 個清單項目</translation>
<translation id="8730621377337864115">完成</translation>
<translation id="8772073294905169192">{HOURS,plural, =1{1 小時}other{# 小時}}</translation>
+<translation id="8798099450830957504">預設</translation>
<translation id="8806053966018712535"><ph name="FOLDER_NAME" />資料夾</translation>
<translation id="883911313571074303">為圖片加註</translation>
<translation id="8901569739625249689"><ph name="QUANTITY" /> KB</translation>
diff --git a/chromium/ui/strings/ui_strings.grd b/chromium/ui/strings/ui_strings.grd
index a58dd606522..3e0b41a4055 100644
--- a/chromium/ui/strings/ui_strings.grd
+++ b/chromium/ui/strings/ui_strings.grd
@@ -334,8 +334,37 @@ need to be translated for each locale.-->
<message name="IDS_SELECT_UPLOAD_FOLDER_BUTTON_TITLE" desc="The name of the Select button in the folder selection dialog for uploading.">
Upload
</message>
+
+ <!-- Edit::Speech submenu -->
+ <message name="IDS_SPEECH_MAC" desc="The Mac menu item for the 'Speech' submenu in the edit and context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, open the Edit menu and use the translation from there.">
+ Speech
+ </message>
+ <message name="IDS_SPEECH_START_SPEAKING_MAC" desc="The Mac menu item for the 'Start Speaking' item from the 'Speech' submenu in edit and context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, open the Edit menu and use the translation from there.">
+ Start Speaking
+ </message>
+ <message name="IDS_SPEECH_STOP_SPEAKING_MAC" desc="The Mac menu item for the 'Stop Speaking' item from the 'Speech' submenu in edit and context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, open the Edit menu and use the translation from there.">
+ Stop Speaking
+ </message>
+
+ <message name="IDS_CONTENT_CONTEXT_LOOK_UP" desc="The name of the 'Look Up “string”' item in the content area context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there.">
+ Look Up “<ph name="LOOKUP_STRING">$1<ex>orthogonal</ex></ph>”
+ </message>
+
</if>
+ <message name="IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU" desc="The name of the Writing Direction submenu in the content area context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there.">
+ Writing Direction
+ </message>
+ <message name="IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT" desc="The name of the 'default' item from the Writing Direction submenu in the content area context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there.">
+ Default
+ </message>
+ <message name="IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR" desc="The name of the 'Left to Right' item from the Writing Direction submenu in the content area context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there.">
+ Left to Right
+ </message>
+ <message name="IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL" desc="The name of the 'Right to Left' item from the Writing Direction submenu in the content area context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there.">
+ Right to Left
+ </message>
+
<!-- File chooser dialog default titles (only used on Linux) -->
<message name="IDS_SELECT_FOLDER_DIALOG_TITLE" desc="The default title for the Select Folder file chooser dialog.">
Select Folder
@@ -652,7 +681,13 @@ need to be translated for each locale.-->
<message name="IDS_MESSAGE_NOTIFICATION_DURATION_YEARS_SHORTEST" desc="Phrase describing a time duration using years that is as short as possible, preferrably one character. Should be same as AndroidPlatform msgId 7848711145196397042. (frameworks/base/core/res/res/values/strings.xml:plurals:duration_years_shortest) [ICU Syntax]">
{YEARS, plural, =1 {1y} other {#y}}
</message>
- <message name="IDS_MESSAGE_CENTER_BLOCK_ALL_NOTIFICATIONS" desc="The label for the radio button to block all the notifications from this notification origin.">
+ <message name="IDS_MESSAGE_CENTER_BLOCK_ALL_NOTIFICATIONS_SITE" desc="The label for the radio button to block all the notifications from this notification origin.">
+ Block all notifications from this site
+ </message>
+ <message name="IDS_MESSAGE_CENTER_BLOCK_ALL_NOTIFICATIONS_APP" desc="The label for the radio button to block all the notifications from this app.">
+ Block all notifications from this app
+ </message>
+ <message name="IDS_MESSAGE_CENTER_BLOCK_ALL_NOTIFICATIONS" desc="The label for the radio button to block all the notifications.">
Block all notifications
</message>
<message name="IDS_MESSAGE_CENTER_DONT_BLOCK_NOTIFICATIONS" desc="The label for the radio button to allow all the notifications from this notification origin.">
@@ -719,12 +754,6 @@ need to be translated for each locale.-->
<message name="IDS_APP_LIST_FOLDER_CLOSE_FOLDER_ACCESSIBILE_NAME" desc="The spoken feedback text for closing an app launcher folder">
Close folder
</message>
- <message name="IDS_APP_LIST_SPEECH_HINT_TEXT" desc="The text label in the speech recognition UI to ask the user to speak the search query">
- Speak now
- </message>
- <message name="IDS_APP_LIST_SPEECH_NETWORK_ERROR_HINT_TEXT" desc="The text label in the speech recognition UI to show the speech recognition can't start because of network error.">
- No internet connection
- </message>
<message name="IDS_APP_LIST_EXPAND_BUTTON" desc="Tooltip for the button that expands the app list from suggested apps to a fullscreen view which shows all apps.">
Expand to all apps
</message>
diff --git a/chromium/ui/touch_selection/longpress_drag_selector.cc b/chromium/ui/touch_selection/longpress_drag_selector.cc
index fdc3221118a..df96825cf43 100644
--- a/chromium/ui/touch_selection/longpress_drag_selector.cc
+++ b/chromium/ui/touch_selection/longpress_drag_selector.cc
@@ -28,19 +28,19 @@ LongPressDragSelector::~LongPressDragSelector() {
bool LongPressDragSelector::WillHandleTouchEvent(const MotionEvent& event) {
switch (event.GetAction()) {
- case MotionEvent::ACTION_DOWN:
+ case MotionEvent::Action::DOWN:
touch_down_position_.SetPoint(event.GetX(), event.GetY());
touch_down_time_ = event.GetEventTime();
has_longpress_drag_start_anchor_ = false;
SetState(LONGPRESS_PENDING);
return false;
- case MotionEvent::ACTION_UP:
- case MotionEvent::ACTION_CANCEL:
+ case MotionEvent::Action::UP:
+ case MotionEvent::Action::CANCEL:
SetState(INACTIVE);
return false;
- case MotionEvent::ACTION_MOVE:
+ case MotionEvent::Action::MOVE:
break;
default:
diff --git a/chromium/ui/touch_selection/touch_handle.cc b/chromium/ui/touch_selection/touch_handle.cc
index ee1c765d17e..65b1dba8e82 100644
--- a/chromium/ui/touch_selection/touch_handle.cc
+++ b/chromium/ui/touch_selection/touch_handle.cc
@@ -165,11 +165,11 @@ bool TouchHandle::WillHandleTouchEvent(const MotionEvent& event) {
if (!enabled_)
return false;
- if (!is_dragging_ && event.GetAction() != MotionEvent::ACTION_DOWN)
+ if (!is_dragging_ && event.GetAction() != MotionEvent::Action::DOWN)
return false;
switch (event.GetAction()) {
- case MotionEvent::ACTION_DOWN: {
+ case MotionEvent::Action::DOWN: {
if (!is_visible_)
return false;
const gfx::PointF touch_point(event.GetX(), event.GetY());
@@ -191,7 +191,7 @@ bool TouchHandle::WillHandleTouchEvent(const MotionEvent& event) {
BeginDrag();
} break;
- case MotionEvent::ACTION_MOVE: {
+ case MotionEvent::Action::MOVE: {
gfx::PointF touch_move_position(event.GetX(), event.GetY());
is_drag_within_tap_region_ &=
client_->IsWithinTapSlop(touch_down_position_ - touch_move_position);
@@ -201,7 +201,7 @@ bool TouchHandle::WillHandleTouchEvent(const MotionEvent& event) {
client_->OnDragUpdate(*this, touch_move_position + touch_drag_offset_);
} break;
- case MotionEvent::ACTION_UP: {
+ case MotionEvent::Action::UP: {
if (is_drag_within_tap_region_ &&
(event.GetEventTime() - touch_down_time_) <
client_->GetMaxTapDuration()) {
@@ -211,7 +211,7 @@ bool TouchHandle::WillHandleTouchEvent(const MotionEvent& event) {
EndDrag();
} break;
- case MotionEvent::ACTION_CANCEL:
+ case MotionEvent::Action::CANCEL:
EndDrag();
break;
diff --git a/chromium/ui/touch_selection/touch_handle_unittest.cc b/chromium/ui/touch_selection/touch_handle_unittest.cc
index 84c9db22b20..c723009d0f3 100644
--- a/chromium/ui/touch_selection/touch_handle_unittest.cc
+++ b/chromium/ui/touch_selection/touch_handle_unittest.cc
@@ -331,8 +331,8 @@ TEST_F(TouchHandleTest, Enabled) {
// Dragging should not be allowed while the handle is disabled.
base::TimeTicks event_time = base::TimeTicks::Now();
const float kOffset = kDefaultDrawableSize / 2.f;
- MockMotionEvent event(
- MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, kOffset,
+ kOffset);
EXPECT_FALSE(handle.WillHandleTouchEvent(event));
// Disabling mid-animation should cancel the animation.
@@ -366,50 +366,51 @@ TEST_F(TouchHandleTest, Drag) {
const float kOffset = kDefaultDrawableSize / 2.f;
// The handle must be visible to trigger drag.
- MockMotionEvent event(
- MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, kOffset,
+ kOffset);
EXPECT_FALSE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(IsDragging());
UpdateHandleVisibility(handle, true, TouchHandle::ANIMATION_NONE);
- // ACTION_DOWN must fall within the drawable region to trigger drag.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 50, 50);
+ // Action::DOWN must fall within the drawable region to trigger drag.
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 50, 50);
EXPECT_FALSE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(IsDragging());
- // Only ACTION_DOWN will trigger drag.
- event = MockMotionEvent(
- MockMotionEvent::ACTION_MOVE, event_time, kOffset, kOffset);
+ // Only Action::DOWN will trigger drag.
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, kOffset,
+ kOffset);
EXPECT_FALSE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(IsDragging());
// Start the drag.
- event = MockMotionEvent(
- MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, kOffset,
+ kOffset);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(IsDragging());
- event = MockMotionEvent(
- MockMotionEvent::ACTION_MOVE, event_time, kOffset + 10, kOffset + 15);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
+ kOffset + 10, kOffset + 15);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetHandleDragged());
EXPECT_TRUE(IsDragging());
EXPECT_EQ(gfx::PointF(10, 15), DragPosition());
- event = MockMotionEvent(
- MockMotionEvent::ACTION_MOVE, event_time, kOffset - 10, kOffset - 15);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
+ kOffset - 10, kOffset - 15);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetHandleDragged());
EXPECT_TRUE(IsDragging());
EXPECT_EQ(gfx::PointF(-10, -15), DragPosition());
- event = MockMotionEvent(MockMotionEvent::ACTION_UP);
+ event = MockMotionEvent(MockMotionEvent::Action::UP);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetHandleDragged());
EXPECT_FALSE(IsDragging());
- // Non-ACTION_DOWN events after the drag has terminated should not be handled.
- event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL);
+ // Non-Action::DOWN events after the drag has terminated should not be
+ // handled.
+ event = MockMotionEvent(MockMotionEvent::Action::CANCEL);
EXPECT_FALSE(handle.WillHandleTouchEvent(event));
}
@@ -418,7 +419,7 @@ TEST_F(TouchHandleTest, DragDefersOrientationChange) {
ASSERT_EQ(drawable().orientation, TouchHandleOrientation::RIGHT);
UpdateHandleVisibility(handle, true, TouchHandle::ANIMATION_NONE);
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(IsDragging());
@@ -426,13 +427,13 @@ TEST_F(TouchHandleTest, DragDefersOrientationChange) {
UpdateHandleOrientation(handle, TouchHandleOrientation::LEFT);
EXPECT_EQ(TouchHandleOrientation::RIGHT, drawable().orientation);
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetHandleDragged());
EXPECT_TRUE(IsDragging());
EXPECT_EQ(TouchHandleOrientation::RIGHT, drawable().orientation);
- event = MockMotionEvent(MockMotionEvent::ACTION_UP);
+ event = MockMotionEvent(MockMotionEvent::Action::UP);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetHandleDragged());
EXPECT_FALSE(IsDragging());
@@ -444,7 +445,7 @@ TEST_F(TouchHandleTest, DragDefersFade) {
kDefaultViewportRect);
UpdateHandleVisibility(handle, true, TouchHandle::ANIMATION_NONE);
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(IsDragging());
@@ -454,12 +455,12 @@ TEST_F(TouchHandleTest, DragDefersFade) {
EXPECT_TRUE(drawable().visible);
EXPECT_EQ(1.f, drawable().alpha);
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(NeedsAnimate());
EXPECT_TRUE(drawable().visible);
- event = MockMotionEvent(MockMotionEvent::ACTION_UP);
+ event = MockMotionEvent(MockMotionEvent::Action::UP);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(IsDragging());
EXPECT_TRUE(NeedsAnimate());
@@ -481,8 +482,7 @@ TEST_F(TouchHandleTest, DragTargettingUsesTouchSize) {
const float kTouchSize = 24.f;
const float kOffset = kDefaultDrawableSize + kTouchSize / 2.001f;
- MockMotionEvent event(
- MockMotionEvent::ACTION_DOWN, event_time, kOffset, 0);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, kOffset, 0);
event.SetTouchMajor(0.f);
EXPECT_FALSE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(IsDragging());
@@ -500,8 +500,8 @@ TEST_F(TouchHandleTest, DragTargettingUsesTouchSize) {
EXPECT_TRUE(IsDragging());
// The touch hit test region should be circular.
- event = MockMotionEvent(
- MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, kOffset,
+ kOffset);
event.SetTouchMajor(kTouchSize);
EXPECT_FALSE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(IsDragging());
@@ -515,17 +515,16 @@ TEST_F(TouchHandleTest, DragTargettingUsesTouchSize) {
EXPECT_TRUE(IsDragging());
// Ensure a touch size of 0 can still register a hit.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN,
- event_time,
- kDefaultDrawableSize / 2.f,
- kDefaultDrawableSize / 2.f);
+ event =
+ MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
+ kDefaultDrawableSize / 2.f, kDefaultDrawableSize / 2.f);
event.SetTouchMajor(0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(IsDragging());
// Touches centered above the handle region should never register a hit, even
// if the touch region intersects the handle region.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
kDefaultDrawableSize / 2.f, -kTouchSize / 3.f);
event.SetTouchMajor(kTouchSize);
EXPECT_FALSE(handle.WillHandleTouchEvent(event));
@@ -539,43 +538,43 @@ TEST_F(TouchHandleTest, Tap) {
base::TimeTicks event_time = base::TimeTicks::Now();
- // ACTION_CANCEL shouldn't trigger a tap.
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ // Action::CANCEL shouldn't trigger a tap.
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
event_time += base::TimeDelta::FromMilliseconds(50);
- event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::CANCEL, event_time, 0, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetHandleTapped());
// Long press shouldn't trigger a tap.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
event_time += 2 * GetMaxTapDuration();
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 0, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetHandleTapped());
// Only a brief tap within the slop region should trigger a tap.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
event_time += GetMaxTapDuration() / 2;
- event = MockMotionEvent(
- MockMotionEvent::ACTION_MOVE, event_time, kDefaultTapSlop / 2.f, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
+ kDefaultTapSlop / 2.f, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
- event = MockMotionEvent(
- MockMotionEvent::ACTION_UP, event_time, kDefaultTapSlop / 2.f, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
+ kDefaultTapSlop / 2.f, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetHandleTapped());
// Moving beyond the slop region shouldn't trigger a tap.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
event_time += GetMaxTapDuration() / 2;
- event = MockMotionEvent(
- MockMotionEvent::ACTION_MOVE, event_time, kDefaultTapSlop * 2.f, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
+ kDefaultTapSlop * 2.f, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
- event = MockMotionEvent(
- MockMotionEvent::ACTION_UP, event_time, kDefaultTapSlop * 2.f, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
+ kDefaultTapSlop * 2.f, 0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetHandleTapped());
}
@@ -639,7 +638,7 @@ TEST_F(TouchHandleTest, DragDefersMirrorChange) {
const float kOffset = kDefaultDrawableSize / 2.f;
// Start the drag.
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, kOffset,
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, kOffset,
kOffset);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(IsDragging());
@@ -652,7 +651,7 @@ TEST_F(TouchHandleTest, DragDefersMirrorChange) {
EXPECT_FALSE(drawable().mirror_horizontal);
// Mirror flag changes will be deferred until the drag ends.
- event = MockMotionEvent(MockMotionEvent::ACTION_UP);
+ event = MockMotionEvent(MockMotionEvent::Action::UP);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetHandleDragged());
EXPECT_FALSE(IsDragging());
diff --git a/chromium/ui/touch_selection/touch_selection_controller.cc b/chromium/ui/touch_selection/touch_selection_controller.cc
index 884ea9072bb..8ea5e0b5cac 100644
--- a/chromium/ui/touch_selection/touch_selection_controller.cc
+++ b/chromium/ui/touch_selection/touch_selection_controller.cc
@@ -88,12 +88,31 @@ void TouchSelectionController::OnSelectionBoundsChanged(
// Swap the Handles when the start and end selection points cross each other.
if (active_status_ == SELECTION_ACTIVE) {
- if ((start_selection_handle_->IsActive() &&
- end_.edge_bottom() == start.edge_bottom()) ||
- (end_selection_handle_->IsActive() &&
- end.edge_bottom() == start_.edge_bottom())) {
+ // Bounds have the same orientation.
+ bool need_swap = (start_selection_handle_->IsActive() &&
+ end_.edge_bottom() == start.edge_bottom()) ||
+ (end_selection_handle_->IsActive() &&
+ end.edge_bottom() == start_.edge_bottom());
+
+ // Bounds have different orientation.
+ // Specifically, for writing-mode: vertical-*, selection bounds are
+ // horizontal.
+ // When vertical-lr:
+ // - start bound is from right to left,
+ // - end bound is from left to right.
+ // When vertical-rl:
+ // - start bound is from left to right,
+ // - end bound is from right to left.
+ // So when previous start/end bound become current end/start bound,
+ // edge_top() and edge_bottom() are swapped. Therefore, we are comparing
+ // edge_bottom() with edge_top() here.
+ need_swap |= (start_selection_handle_->IsActive() &&
+ end_.edge_bottom() == start.edge_top()) ||
+ (end_selection_handle_->IsActive() &&
+ end.edge_bottom() == start_.edge_top());
+
+ if (need_swap)
start_selection_handle_.swap(end_selection_handle_);
- }
}
start_ = start;
@@ -153,13 +172,13 @@ void TouchSelectionController::OnViewportChanged(
bool TouchSelectionController::WillHandleTouchEvent(const MotionEvent& event) {
bool handled = WillHandleTouchEventImpl(event);
- // If ACTION_DOWN is consumed, the rest of touch sequence should be consumed,
+ // If Action::DOWN is consumed, the rest of touch sequence should be consumed,
// too, regardless of value of |handled|.
- // TODO(mohsen): This will consume touch events until the next ACTION_DOWN.
- // Ideally we should consume until the final ACTION_UP/ACTION_CANCEL.
- // But, apparently, we can't reliably determine the final ACTION_CANCEL in a
+ // TODO(mohsen): This will consume touch events until the next Action::DOWN.
+ // Ideally we should consume until the final Action::UP/Action::CANCEL.
+ // But, apparently, we can't reliably determine the final Action::CANCEL in a
// multi-touch scenario. See https://crbug.com/653212.
- if (event.GetAction() == MotionEvent::ACTION_DOWN)
+ if (event.GetAction() == MotionEvent::Action::DOWN)
consume_touch_sequence_ = handled;
return handled || consume_touch_sequence_;
}
@@ -260,7 +279,7 @@ gfx::RectF TouchSelectionController::GetEndHandleRect() const {
return gfx::RectF();
}
-gfx::PointF TouchSelectionController::GetActiveHandleBoundPoint() const {
+float TouchSelectionController::GetActiveHandleMiddleY() const {
const gfx::SelectionBound* bound = nullptr;
if (active_status_ == INSERTION_ACTIVE && insertion_handle_->IsActive())
bound = &start_;
@@ -272,11 +291,8 @@ gfx::PointF TouchSelectionController::GetActiveHandleBoundPoint() const {
}
if (!bound)
- return gfx::PointF(0.f, 0.f);
-
- float x = (bound->edge_top().x() + bound->edge_bottom().x()) / 2.f;
- float y = (bound->edge_top().y() + bound->edge_bottom().y()) / 2.f;
- return gfx::PointF(x, y);
+ return 0.f;
+ return (bound->edge_top().y() + bound->edge_bottom().y()) / 2.f;
}
const gfx::PointF& TouchSelectionController::GetStartPosition() const {
@@ -372,6 +388,13 @@ void TouchSelectionController::OnDragUpdate(
client_->MoveCaret(line_position);
else
client_->MoveRangeSelectionExtent(line_position);
+
+ // We use the bound middle point to restrict the ability to move up and down,
+ // but let user move it more freely in horizontal direction.
+ if (&draggable != &longpress_drag_selector_) {
+ float y = GetActiveHandleMiddleY();
+ client_->OnDragUpdate(gfx::PointF(drag_position.x(), y));
+ }
}
void TouchSelectionController::OnDragEnd(
diff --git a/chromium/ui/touch_selection/touch_selection_controller.h b/chromium/ui/touch_selection/touch_selection_controller.h
index 6ec985cee00..2214024f7ef 100644
--- a/chromium/ui/touch_selection/touch_selection_controller.h
+++ b/chromium/ui/touch_selection/touch_selection_controller.h
@@ -33,6 +33,7 @@ class UI_TOUCH_SELECTION_EXPORT TouchSelectionControllerClient {
virtual void SelectBetweenCoordinates(const gfx::PointF& base,
const gfx::PointF& extent) = 0;
virtual void OnSelectionEvent(SelectionEventType event) = 0;
+ virtual void OnDragUpdate(const gfx::PointF& position) = 0;
virtual std::unique_ptr<TouchHandleDrawable> CreateDrawable() = 0;
virtual void DidScroll() = 0;
};
@@ -120,10 +121,6 @@ class UI_TOUCH_SELECTION_EXPORT TouchSelectionController
gfx::RectF GetStartHandleRect() const;
gfx::RectF GetEndHandleRect() const;
- // Returns the middle point of selection bound corresponding to the active
- // selection or insertion handle. If there is no active handle, returns (0,0).
- gfx::PointF GetActiveHandleBoundPoint() const;
-
// Returns the focal point of the start and end bounds, as defined by
// their bottom coordinate.
const gfx::PointF& GetStartPosition() const;
@@ -174,6 +171,11 @@ class UI_TOUCH_SELECTION_EXPORT TouchSelectionController
void SetTemporarilyHiddenForLongPressDrag(bool hidden);
void RefreshHandleVisibility();
+ // Returns the y-coordinate of middle point of selection bound corresponding
+ // to the active selection or insertion handle. If there is no active handle,
+ // returns 0.0.
+ float GetActiveHandleMiddleY() const;
+
void HideHandles();
gfx::Vector2dF GetStartLineOffset() const;
diff --git a/chromium/ui/touch_selection/touch_selection_controller_unittest.cc b/chromium/ui/touch_selection/touch_selection_controller_unittest.cc
index 0056940cdf0..d0bf65b32bc 100644
--- a/chromium/ui/touch_selection/touch_selection_controller_unittest.cc
+++ b/chromium/ui/touch_selection/touch_selection_controller_unittest.cc
@@ -100,7 +100,10 @@ class TouchSelectionControllerTest : public testing::Test,
last_event_start_ = controller_->GetStartPosition();
last_event_end_ = controller_->GetEndPosition();
last_event_bounds_rect_ = controller_->GetRectBetweenBounds();
- last_event_handle_bound_middle_ = controller_->GetActiveHandleBoundPoint();
+ }
+
+ void OnDragUpdate(const gfx::PointF& position) override {
+ last_drag_update_position_ = position;
}
std::unique_ptr<TouchHandleDrawable> CreateDrawable() override {
@@ -147,6 +150,20 @@ class TouchSelectionControllerTest : public testing::Test,
controller_->OnSelectionBoundsChanged(start_bound, end_bound);
}
+ void ChangeVerticalSelection(const gfx::RectF& start_rect,
+ bool start_visible,
+ const gfx::RectF& end_rect,
+ bool end_visible) {
+ gfx::SelectionBound start_bound, end_bound;
+ start_bound.set_type(gfx::SelectionBound::RIGHT);
+ end_bound.set_type(gfx::SelectionBound::LEFT);
+ start_bound.SetEdge(start_rect.origin(), start_rect.bottom_right());
+ end_bound.SetEdge(end_rect.bottom_right(), end_rect.origin());
+ start_bound.set_visible(start_visible);
+ end_bound.set_visible(end_visible);
+ controller_->OnSelectionBoundsChanged(start_bound, end_bound);
+ }
+
void OnLongPressEvent() {
controller().HandleLongPressEvent(base::TimeTicks(),
kIgnoredPoint);
@@ -202,8 +219,8 @@ class TouchSelectionControllerTest : public testing::Test,
const gfx::RectF& GetLastEventBoundsRect() const {
return last_event_bounds_rect_;
}
- const gfx::PointF& GetLastEventHandleBoundMiddle() const {
- return last_event_handle_bound_middle_;
+ const gfx::PointF& GetLastDragUpdatePosition() const {
+ return last_drag_update_position_;
}
std::vector<SelectionEventType> GetAndResetEvents() {
@@ -232,7 +249,7 @@ class TouchSelectionControllerTest : public testing::Test,
gfx::PointF selection_start_;
gfx::PointF selection_end_;
gfx::RectF last_event_bounds_rect_;
- gfx::PointF last_event_handle_bound_middle_;
+ gfx::PointF last_drag_update_position_;
std::vector<SelectionEventType> events_;
bool caret_moved_;
bool selection_moved_;
@@ -311,7 +328,7 @@ TEST_F(TouchSelectionControllerTest, InsertionDragged) {
OnTapEvent();
// The touch sequence should not be handled if insertion is not active.
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_FALSE(controller().WillHandleTouchEvent(event));
float line_height = 10.f;
@@ -332,30 +349,30 @@ TEST_F(TouchSelectionControllerTest, InsertionDragged) {
// The MoveCaret() result should reflect the movement.
// The reported position is offset from the center of |start_rect|.
gfx::PointF start_offset = start_rect.CenterPoint();
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 0, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 0, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetCaretMoved());
EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastCaretPosition());
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 5, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 5, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetCaretMoved());
EXPECT_EQ(start_offset + gfx::Vector2dF(5, 5), GetLastCaretPosition());
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 10, 10);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 10);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetCaretMoved());
EXPECT_EQ(start_offset + gfx::Vector2dF(10, 10), GetLastCaretPosition());
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 10, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetCaretMoved());
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STOPPED));
- // Following ACTION_DOWN should not be consumed if it does not start handle
+ // Following Action::DOWN should not be consumed if it does not start handle
// dragging.
SetDraggingEnabled(false);
- event = MockMotionEvent(MotionEvent::ACTION_DOWN, event_time, 0, 0);
+ event = MockMotionEvent(MotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_FALSE(controller().WillHandleTouchEvent(event));
}
@@ -371,18 +388,18 @@ TEST_F(TouchSelectionControllerTest, InsertionDeactivatedWhileDragging) {
ElementsAre(INSERTION_HANDLE_SHOWN));
EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
- // Enable dragging so that the following ACTION_DOWN starts handle dragging.
+ // Enable dragging so that the following Action::DOWN starts handle dragging.
SetDraggingEnabled(true);
// Touch down to start dragging.
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetCaretMoved());
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED));
// Move the handle.
gfx::PointF start_offset = start_rect.CenterPoint();
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 0, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 0, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetCaretMoved());
EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastCaretPosition());
@@ -395,21 +412,21 @@ TEST_F(TouchSelectionControllerTest, InsertionDeactivatedWhileDragging) {
// Move the finger. There is no handle to move, so the cursor is not moved;
// but, the event is still consumed because the touch down that started the
// touch sequence was consumed.
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 5, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 5, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetCaretMoved());
EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastCaretPosition());
// Lift the finger to end the touch sequence.
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 5, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 5, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetCaretMoved());
EXPECT_THAT(GetAndResetEvents(), IsEmpty());
- // Following ACTION_DOWN should not be consumed if it does not start handle
+ // Following Action::DOWN should not be consumed if it does not start handle
// dragging.
SetDraggingEnabled(false);
- event = MockMotionEvent(MotionEvent::ACTION_DOWN, event_time, 0, 0);
+ event = MockMotionEvent(MotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_FALSE(controller().WillHandleTouchEvent(event));
}
@@ -424,11 +441,11 @@ TEST_F(TouchSelectionControllerTest, InsertionTapped) {
EXPECT_THAT(GetAndResetEvents(),
ElementsAre(INSERTION_HANDLE_SHOWN));
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED));
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_TAPPED,
INSERTION_HANDLE_DRAG_STOPPED));
@@ -441,12 +458,10 @@ TEST_F(TouchSelectionControllerTest, InsertionTapped) {
ElementsAre(INSERTION_HANDLE_CLEARED, INSERTION_HANDLE_SHOWN));
// No tap should be signalled if the time between DOWN and UP was too long.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
- event = MockMotionEvent(MockMotionEvent::ACTION_UP,
- event_time + base::TimeDelta::FromSeconds(1),
- 0,
- 0);
+ event = MockMotionEvent(MockMotionEvent::Action::UP,
+ event_time + base::TimeDelta::FromSeconds(1), 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED,
INSERTION_HANDLE_DRAG_STOPPED));
@@ -459,11 +474,11 @@ TEST_F(TouchSelectionControllerTest, InsertionTapped) {
ElementsAre(INSERTION_HANDLE_CLEARED, INSERTION_HANDLE_SHOWN));
// No tap should be signalled if the drag was too long.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 100, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 100, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 100, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 100, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED,
INSERTION_HANDLE_DRAG_STOPPED));
@@ -476,9 +491,9 @@ TEST_F(TouchSelectionControllerTest, InsertionTapped) {
ElementsAre(INSERTION_HANDLE_CLEARED, INSERTION_HANDLE_SHOWN));
// No tap should be signalled if the touch sequence is cancelled.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
- event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::CANCEL, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED,
INSERTION_HANDLE_DRAG_STOPPED));
@@ -614,7 +629,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDragged) {
OnLongPressEvent();
// The touch sequence should not be handled if selection is not active.
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_FALSE(controller().WillHandleTouchEvent(event));
float line_height = 10.f;
@@ -639,34 +654,34 @@ TEST_F(TouchSelectionControllerTest, SelectionDragged) {
// input rects (i.e., the middle of the corresponding text line).
gfx::PointF fixed_offset = end_rect.CenterPoint();
gfx::PointF start_offset = start_rect.CenterPoint();
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 0, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 0, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
EXPECT_TRUE(GetAndResetSelectionMoved());
EXPECT_EQ(fixed_offset, GetLastSelectionStart());
EXPECT_EQ(start_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 5, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 5, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetSelectionMoved());
EXPECT_EQ(fixed_offset, GetLastSelectionStart());
EXPECT_EQ(start_offset + gfx::Vector2dF(5, 5), GetLastSelectionEnd());
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 10, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetSelectionMoved());
EXPECT_EQ(fixed_offset, GetLastSelectionStart());
EXPECT_EQ(start_offset + gfx::Vector2dF(10, 5), GetLastSelectionEnd());
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 10, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
EXPECT_FALSE(GetAndResetSelectionMoved());
- // Following ACTION_DOWN should not be consumed if it does not start handle
+ // Following Action::DOWN should not be consumed if it does not start handle
// dragging.
SetDraggingEnabled(false);
- event = MockMotionEvent(MotionEvent::ACTION_DOWN, event_time, 0, 0);
+ event = MockMotionEvent(MotionEvent::Action::DOWN, event_time, 0, 0);
EXPECT_FALSE(controller().WillHandleTouchEvent(event));
}
@@ -683,27 +698,27 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedWithOverlap) {
ElementsAre(SELECTION_HANDLES_SHOWN));
EXPECT_EQ(start_rect.bottom_left(), GetLastEventStart());
- // The ACTION_DOWN should lock to the closest handle.
+ // The Action::DOWN should lock to the closest handle.
gfx::PointF end_offset = end_rect.CenterPoint();
gfx::PointF fixed_offset = start_rect.CenterPoint();
float touch_down_x = (end_offset.x() + fixed_offset.x()) / 2 + 1.f;
- MockMotionEvent event(
- MockMotionEvent::ACTION_DOWN, event_time, touch_down_x, 0);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, touch_down_x,
+ 0);
SetDraggingEnabled(true);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
EXPECT_FALSE(GetAndResetSelectionMoved());
- // Even though the ACTION_MOVE is over the start handle, it should continue
- // targetting the end handle that consumed the ACTION_DOWN.
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 0, 0);
+ // Even though the Action::MOVE is over the start handle, it should continue
+ // targetting the end handle that consumed the Action::DOWN.
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetSelectionMoved());
EXPECT_EQ(fixed_offset, GetLastSelectionStart());
EXPECT_EQ(end_offset - gfx::Vector2dF(touch_down_x, 0),
GetLastSelectionEnd());
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
EXPECT_FALSE(GetAndResetSelectionMoved());
@@ -725,15 +740,15 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
SetDraggingEnabled(true);
// Move the extent, not triggering a swap of points.
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time,
- end_rect.x(), end_rect.bottom());
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, end_rect.x(),
+ end_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetSelectionMoved());
EXPECT_FALSE(GetAndResetSelectionPointsSwapped());
gfx::PointF base_offset = start_rect.CenterPoint();
gfx::PointF extent_offset = end_rect.CenterPoint();
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
end_rect.x(), end_rect.bottom() + 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
@@ -742,7 +757,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
EXPECT_EQ(base_offset, GetLastSelectionStart());
EXPECT_EQ(extent_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 10, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
EXPECT_FALSE(GetAndResetSelectionMoved());
@@ -752,7 +767,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
// Move the base, triggering a swap of points.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
start_rect.x(), start_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetSelectionMoved());
@@ -760,7 +775,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
base_offset = end_rect.CenterPoint();
extent_offset = start_rect.CenterPoint();
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
start_rect.x(), start_rect.bottom() + 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
@@ -769,7 +784,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
EXPECT_EQ(base_offset, GetLastSelectionStart());
EXPECT_EQ(extent_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 10, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
EXPECT_FALSE(GetAndResetSelectionMoved());
@@ -779,7 +794,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
// Move the same point again, not triggering a swap of points.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
start_rect.x(), start_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetSelectionMoved());
@@ -787,7 +802,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
base_offset = end_rect.CenterPoint();
extent_offset = start_rect.CenterPoint();
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
start_rect.x(), start_rect.bottom() + 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
@@ -796,7 +811,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
EXPECT_EQ(base_offset, GetLastSelectionStart());
EXPECT_EQ(extent_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 10, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
EXPECT_FALSE(GetAndResetSelectionMoved());
@@ -806,7 +821,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
// Move the base, triggering a swap of points.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
end_rect.x(), end_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_FALSE(GetAndResetSelectionMoved());
@@ -814,7 +829,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
base_offset = start_rect.CenterPoint();
extent_offset = end_rect.CenterPoint();
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
end_rect.x(), end_rect.bottom() + 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
@@ -823,7 +838,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDraggedToSwitchBaseAndExtent) {
EXPECT_EQ(base_offset, GetLastSelectionStart());
EXPECT_EQ(extent_offset + gfx::Vector2dF(0, 5), GetLastSelectionEnd());
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 10, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
EXPECT_FALSE(GetAndResetSelectionMoved());
@@ -844,7 +859,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDragExtremeLineSize) {
EXPECT_EQ(small_line_rect.bottom_left(), GetLastEventStart());
// Start dragging the handle on the small line.
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time,
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time,
small_line_rect.x(), small_line_rect.y());
SetDraggingEnabled(true);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
@@ -858,7 +873,7 @@ TEST_F(TouchSelectionControllerTest, SelectionDragExtremeLineSize) {
EXPECT_EQ(small_line_rect.CenterPoint(), GetLastSelectionEnd());
small_line_rect += gfx::Vector2dF(25.f, 0);
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time,
small_line_rect.x(), small_line_rect.y());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_TRUE(GetAndResetSelectionMoved());
@@ -1169,7 +1184,7 @@ TEST_F(TouchSelectionControllerTest, SelectionNoOrientationChangeWhenSwapped) {
SetDraggingEnabled(true);
// Simulate moving the base, not triggering a swap of points.
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time,
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time,
start_rect.x(), start_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
@@ -1184,7 +1199,7 @@ TEST_F(TouchSelectionControllerTest, SelectionNoOrientationChangeWhenSwapped) {
TouchHandleOrientation::RIGHT);
event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
offset_rect.x(), offset_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
@@ -1194,7 +1209,7 @@ TEST_F(TouchSelectionControllerTest, SelectionNoOrientationChangeWhenSwapped) {
TouchHandleOrientation::RIGHT);
// Simulate moving the base, triggering a swap of points.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
offset_rect.x(), offset_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
@@ -1208,7 +1223,7 @@ TEST_F(TouchSelectionControllerTest, SelectionNoOrientationChangeWhenSwapped) {
TouchHandleOrientation::LEFT);
event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
offset_rect.x(), offset_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
@@ -1218,7 +1233,7 @@ TEST_F(TouchSelectionControllerTest, SelectionNoOrientationChangeWhenSwapped) {
TouchHandleOrientation::RIGHT);
// Simulate moving the anchor, not triggering a swap of points.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
offset_rect.x(), offset_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
@@ -1232,7 +1247,7 @@ TEST_F(TouchSelectionControllerTest, SelectionNoOrientationChangeWhenSwapped) {
TouchHandleOrientation::RIGHT);
event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
offset_rect.x(), offset_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
@@ -1242,7 +1257,7 @@ TEST_F(TouchSelectionControllerTest, SelectionNoOrientationChangeWhenSwapped) {
TouchHandleOrientation::RIGHT);
// Simulate moving the anchor, triggering a swap of points.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
offset_rect.x(), offset_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
@@ -1256,17 +1271,93 @@ TEST_F(TouchSelectionControllerTest, SelectionNoOrientationChangeWhenSwapped) {
TouchHandleOrientation::RIGHT);
event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time,
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
+ offset_rect.x(), offset_rect.bottom());
+ EXPECT_TRUE(controller().WillHandleTouchEvent(event));
+ EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
+ EXPECT_EQ(test_controller.GetStartHandleOrientation(),
+ TouchHandleOrientation::LEFT);
+ EXPECT_EQ(test_controller.GetEndHandleOrientation(),
+ TouchHandleOrientation::RIGHT);
+}
+
+TEST_F(TouchSelectionControllerTest, VerticalTextSelectionHandleSwap) {
+ TouchSelectionControllerTestApi test_controller(&controller());
+ base::TimeTicks event_time = base::TimeTicks::Now();
+ OnLongPressEvent();
+
+ // Horizontal bounds.
+ gfx::RectF start_rect(0, 50, 16, 0);
+ gfx::RectF end_rect(0, 100, 16, 0);
+
+ bool visible = true;
+ ChangeVerticalSelection(start_rect, visible, end_rect, visible);
+ EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_SHOWN));
+ EXPECT_EQ(start_rect.bottom_right(), GetLastEventStart());
+ EXPECT_EQ(test_controller.GetStartHandleOrientation(),
+ TouchHandleOrientation::RIGHT);
+ EXPECT_EQ(test_controller.GetEndHandleOrientation(),
+ TouchHandleOrientation::LEFT);
+
+ SetDraggingEnabled(true);
+
+ // Simulate moving the base, triggering a swap of points.
+ // Start to drag start handle.
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time,
+ start_rect.right(), start_rect.bottom());
+ EXPECT_TRUE(controller().WillHandleTouchEvent(event));
+ EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
+
+ // Move start handle down below end handle.
+ gfx::RectF offset_rect = end_rect;
+ offset_rect.Offset(gfx::Vector2dF(0, 20));
+ ChangeVerticalSelection(end_rect, visible, offset_rect, visible);
+ EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
+ EXPECT_EQ(test_controller.GetStartHandleOrientation(),
+ TouchHandleOrientation::RIGHT);
+ EXPECT_EQ(test_controller.GetEndHandleOrientation(),
+ TouchHandleOrientation::RIGHT);
+
+ // Release.
+ event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
offset_rect.x(), offset_rect.bottom());
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
EXPECT_EQ(test_controller.GetStartHandleOrientation(),
+ TouchHandleOrientation::RIGHT);
+ EXPECT_EQ(test_controller.GetEndHandleOrientation(),
+ TouchHandleOrientation::LEFT);
+
+ // Move end handle up.
+ // Start to drag end handle.
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time,
+ offset_rect.x(), offset_rect.bottom());
+ EXPECT_TRUE(controller().WillHandleTouchEvent(event));
+ EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
+
+ // Move up end handle up above the start handle.
+ offset_rect = start_rect;
+ ChangeVerticalSelection(offset_rect, visible, end_rect, visible);
+ EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
+ EXPECT_EQ(test_controller.GetStartHandleOrientation(),
TouchHandleOrientation::LEFT);
EXPECT_EQ(test_controller.GetEndHandleOrientation(),
+ TouchHandleOrientation::LEFT);
+
+ // Release.
+ event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time,
+ offset_rect.x(), offset_rect.bottom());
+ EXPECT_TRUE(controller().WillHandleTouchEvent(event));
+ EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
+ EXPECT_EQ(test_controller.GetStartHandleOrientation(),
TouchHandleOrientation::RIGHT);
+ EXPECT_EQ(test_controller.GetEndHandleOrientation(),
+ TouchHandleOrientation::LEFT);
}
-TEST_F(TouchSelectionControllerTest, InsertionActiveBoundMiddlePoint) {
+TEST_F(TouchSelectionControllerTest, InsertionUpdateDragPosition) {
base::TimeTicks event_time = base::TimeTicks::Now();
float line_height = 10.f;
gfx::RectF insertion_rect(10, 0, 0, line_height);
@@ -1275,38 +1366,43 @@ TEST_F(TouchSelectionControllerTest, InsertionActiveBoundMiddlePoint) {
OnTapEvent();
ChangeInsertion(insertion_rect, visible);
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_SHOWN));
- EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastEventHandleBoundMiddle());
+ EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastDragUpdatePosition());
SetDraggingEnabled(true);
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
+ EXPECT_TRUE(controller().WillHandleTouchEvent(event));
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STARTED));
- EXPECT_EQ(gfx::PointF(10.f, 5.f), GetLastEventHandleBoundMiddle());
+ EXPECT_EQ(gfx::PointF(10.f, 5.f), GetLastDragUpdatePosition());
insertion_rect.Offset(1, 0);
ChangeInsertion(insertion_rect, visible);
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 1, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 12, 6);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_MOVED));
- EXPECT_EQ(gfx::PointF(11.f, 5.f), GetLastEventHandleBoundMiddle());
+ // Don't follow the y-coordinate change but only x-coordinate change.
+ EXPECT_EQ(gfx::PointF(12.f, 5.f), GetLastDragUpdatePosition());
insertion_rect.Offset(0, 1);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 11, 6);
+ EXPECT_TRUE(controller().WillHandleTouchEvent(event));
ChangeInsertion(insertion_rect, visible);
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 0, 1);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 11, 7);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_MOVED));
- EXPECT_EQ(gfx::PointF(11.f, 6.f), GetLastEventHandleBoundMiddle());
+ // Don't follow the y-coordinate change.
+ EXPECT_EQ(gfx::PointF(11.f, 6.f), GetLastDragUpdatePosition());
event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 0, 0);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(INSERTION_HANDLE_DRAG_STOPPED));
- EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastEventHandleBoundMiddle());
SetDraggingEnabled(false);
}
-TEST_F(TouchSelectionControllerTest, SelectionActiveBoundMiddlePoint) {
+TEST_F(TouchSelectionControllerTest, SelectionUpdateDragPosition) {
base::TimeTicks event_time = base::TimeTicks::Now();
float line_height = 10.f;
gfx::RectF start_rect(10, 0, 0, line_height);
@@ -1316,46 +1412,49 @@ TEST_F(TouchSelectionControllerTest, SelectionActiveBoundMiddlePoint) {
ChangeSelection(start_rect, visible, end_rect, visible);
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_SHOWN));
- EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastEventHandleBoundMiddle());
+ EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastDragUpdatePosition());
// Left handle.
SetDraggingEnabled(true);
- MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 10, 5);
+ MockMotionEvent event(MockMotionEvent::Action::DOWN, event_time, 10, 5);
+ EXPECT_TRUE(controller().WillHandleTouchEvent(event));
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 10, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
- EXPECT_EQ(gfx::PointF(10.f, 5.f), GetLastEventHandleBoundMiddle());
+ EXPECT_EQ(gfx::PointF(10.f, 5.f), GetLastDragUpdatePosition());
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 15, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 16, 6);
start_rect.Offset(5, 0);
ChangeSelection(start_rect, visible, end_rect, visible);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
- EXPECT_EQ(gfx::PointF(15.f, 5.f), GetLastEventHandleBoundMiddle());
+ // Don't follow the y-coordinate change but only x-coordinate change.
+ EXPECT_EQ(gfx::PointF(16.f, 5.f), GetLastDragUpdatePosition());
event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 15, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 15, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
- EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastEventHandleBoundMiddle());
// Right handle.
- event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 50, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::DOWN, event_time, 50, 5);
+ EXPECT_TRUE(controller().WillHandleTouchEvent(event));
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 50, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STARTED));
- EXPECT_EQ(gfx::PointF(50.f, 5.f), GetLastEventHandleBoundMiddle());
+ EXPECT_EQ(gfx::PointF(50.f, 5.f), GetLastDragUpdatePosition());
- event = MockMotionEvent(MockMotionEvent::ACTION_MOVE, event_time, 45, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::MOVE, event_time, 45, 5);
end_rect.Offset(-5, 0);
ChangeSelection(start_rect, visible, end_rect, visible);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLES_MOVED));
- EXPECT_EQ(gfx::PointF(45.f, 5.f), GetLastEventHandleBoundMiddle());
+ EXPECT_EQ(gfx::PointF(45.f, 5.f), GetLastDragUpdatePosition());
event_time += base::TimeDelta::FromMilliseconds(2 * kDefaultTapTimeoutMs);
- event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 45, 5);
+ event = MockMotionEvent(MockMotionEvent::Action::UP, event_time, 45, 5);
EXPECT_TRUE(controller().WillHandleTouchEvent(event));
EXPECT_THAT(GetAndResetEvents(), ElementsAre(SELECTION_HANDLE_DRAG_STOPPED));
- EXPECT_EQ(gfx::PointF(0.f, 0.f), GetLastEventHandleBoundMiddle());
}
} // namespace ui
diff --git a/chromium/ui/views/BUILD.gn b/chromium/ui/views/BUILD.gn
index a845514bf92..8d72c2a2b31 100644
--- a/chromium/ui/views/BUILD.gn
+++ b/chromium/ui/views/BUILD.gn
@@ -167,6 +167,7 @@ jumbo_component("views") {
"controls/tree/tree_view.h",
"controls/tree/tree_view_controller.h",
"controls/tree/tree_view_drawing_provider.h",
+ "controls/views_text_services_context_menu.h",
"debug_utils.h",
"drag_controller.h",
"drag_utils.h",
@@ -355,6 +356,8 @@ jumbo_component("views") {
"controls/tree/tree_view.cc",
"controls/tree/tree_view_controller.cc",
"controls/tree/tree_view_drawing_provider.cc",
+ "controls/views_text_services_context_menu.cc",
+ "controls/views_text_services_context_menu_mac.mm",
"debug_utils.cc",
"drag_utils.cc",
"drag_utils_mac.mm",
@@ -464,7 +467,7 @@ jumbo_component("views") {
":views_vector_icons",
"//base",
"//components/vector_icons",
- "//ui/accessibility:ax_gen",
+ "//ui/accessibility:ax_enums_mojo",
"//ui/base",
"//ui/base/ime",
"//ui/compositor",
@@ -683,7 +686,9 @@ jumbo_component("views") {
}
if (is_mac) {
+ sources -= [ "controls/views_text_services_context_menu.cc" ]
deps += [
+ "//components/crash/core/common",
"//ui/accelerated_widget_mac",
"//ui/events:dom_keycode_converter",
]
@@ -918,6 +923,7 @@ source_set("views_unittests_sources") {
"controls/button/radio_button_unittest.cc",
"controls/button/toggle_button_unittest.cc",
"controls/combobox/combobox_unittest.cc",
+ "controls/image_view_unittest.cc",
"controls/label_unittest.cc",
"controls/menu/menu_controller_unittest.cc",
"controls/menu/menu_item_view_unittest.cc",
@@ -1188,7 +1194,13 @@ test("views_perftests") {
":test_support",
"//base/test:test_support",
"//cc/base:base",
+ "//mojo/edk/system",
"//testing/perf",
"//ui/resources:ui_test_pak",
]
+
+ data_deps = [
+ "//ui/resources:ui_test_pak_data",
+ "//testing:run_gtest_perf_test",
+ ]
}
diff --git a/chromium/ui/views/DEPS b/chromium/ui/views/DEPS
index 83326226e10..41eaa521433 100644
--- a/chromium/ui/views/DEPS
+++ b/chromium/ui/views/DEPS
@@ -1,5 +1,6 @@
include_rules = [
"+cc/paint",
+ "+components/crash/core/common/crash_key.h",
"+components/vector_icons",
"+services/ui/public/interfaces",
"+skia/ext",
diff --git a/chromium/ui/views/accessibility/ax_aura_obj_cache.cc b/chromium/ui/views/accessibility/ax_aura_obj_cache.cc
index 1372dd28de5..3fc1975935b 100644
--- a/chromium/ui/views/accessibility/ax_aura_obj_cache.cc
+++ b/chromium/ui/views/accessibility/ax_aura_obj_cache.cc
@@ -118,11 +118,11 @@ AXAuraObjWrapper* AXAuraObjCache::GetFocus() {
void AXAuraObjCache::OnFocusedViewChanged() {
View* view = GetFocusedView();
if (view)
- view->NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
+ view->NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true);
}
void AXAuraObjCache::FireEvent(AXAuraObjWrapper* aura_obj,
- ui::AXEvent event_type) {
+ ax::mojom::Event event_type) {
if (delegate_)
delegate_->OnEvent(aura_obj, event_type);
}
diff --git a/chromium/ui/views/accessibility/ax_aura_obj_cache.h b/chromium/ui/views/accessibility/ax_aura_obj_cache.h
index 69958c3d048..48be286a40c 100644
--- a/chromium/ui/views/accessibility/ax_aura_obj_cache.h
+++ b/chromium/ui/views/accessibility/ax_aura_obj_cache.h
@@ -13,7 +13,7 @@
#include <vector>
#include "base/macros.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/aura/client/focus_change_observer.h"
#include "ui/views/views_export.h"
@@ -40,7 +40,7 @@ class VIEWS_EXPORT AXAuraObjCache : public aura::client::FocusChangeObserver {
public:
virtual void OnChildWindowRemoved(AXAuraObjWrapper* parent) = 0;
virtual void OnEvent(AXAuraObjWrapper* aura_obj,
- ui::AXEvent event_type) = 0;
+ ax::mojom::Event event_type) = 0;
};
// Get or create an entry in the cache based on an Aura view.
@@ -80,7 +80,7 @@ class VIEWS_EXPORT AXAuraObjCache : public aura::client::FocusChangeObserver {
void OnFocusedViewChanged();
// Tell our delegate to fire an event on a given object.
- void FireEvent(AXAuraObjWrapper* aura_obj, ui::AXEvent event_type);
+ void FireEvent(AXAuraObjWrapper* aura_obj, ax::mojom::Event event_type);
// Indicates if this object's currently being destroyed.
bool is_destroying() { return is_destroying_; }
diff --git a/chromium/ui/views/accessibility/ax_view_obj_wrapper.cc b/chromium/ui/views/accessibility/ax_view_obj_wrapper.cc
index 2c0cb81523b..2645da529ef 100644
--- a/chromium/ui/views/accessibility/ax_view_obj_wrapper.cc
+++ b/chromium/ui/views/accessibility/ax_view_obj_wrapper.cc
@@ -35,6 +35,9 @@ AXAuraObjWrapper* AXViewObjWrapper::GetParent() {
void AXViewObjWrapper::GetChildren(
std::vector<AXAuraObjWrapper*>* out_children) {
+ if (view_->GetViewAccessibility().IsLeaf())
+ return;
+
// TODO(dtseng): Need to handle |Widget| child of |View|.
for (int i = 0; i < view_->child_count(); ++i) {
if (!view_->child_at(i)->visible())
diff --git a/chromium/ui/views/accessibility/ax_widget_obj_wrapper.cc b/chromium/ui/views/accessibility/ax_widget_obj_wrapper.cc
index bfb5725e752..43eb649aa24 100644
--- a/chromium/ui/views/accessibility/ax_widget_obj_wrapper.cc
+++ b/chromium/ui/views/accessibility/ax_widget_obj_wrapper.cc
@@ -46,7 +46,7 @@ void AXWidgetObjWrapper::Serialize(ui::AXNodeData* out_node_data) {
out_node_data->id = GetUniqueId().Get();
out_node_data->role = widget_->widget_delegate()->GetAccessibleWindowRole();
out_node_data->AddStringAttribute(
- ui::AX_ATTR_NAME,
+ ax::mojom::StringAttribute::kName,
base::UTF16ToUTF8(
widget_->widget_delegate()->GetAccessibleWindowTitle()));
out_node_data->location = gfx::RectF(widget_->GetWindowBoundsInScreen());
diff --git a/chromium/ui/views/accessibility/ax_window_obj_wrapper.cc b/chromium/ui/views/accessibility/ax_window_obj_wrapper.cc
index ab604049070..68aaca376d8 100644
--- a/chromium/ui/views/accessibility/ax_window_obj_wrapper.cc
+++ b/chromium/ui/views/accessibility/ax_window_obj_wrapper.cc
@@ -7,7 +7,7 @@
#include <stddef.h>
#include "base/strings/utf_string_conversions.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/platform/aura_window_properties.h"
#include "ui/accessibility/platform/ax_unique_id.h"
@@ -18,6 +18,28 @@
namespace views {
+void FireLocationChanges(aura::Window* window) {
+ AXAuraObjCache::GetInstance()->FireEvent(
+ AXAuraObjCache::GetInstance()->GetOrCreate(window),
+ ax::mojom::Event::kLocationChanged);
+
+ Widget* widget = Widget::GetWidgetForNativeView(window);
+ if (widget) {
+ AXAuraObjCache::GetInstance()->FireEvent(
+ AXAuraObjCache::GetInstance()->GetOrCreate(widget),
+ ax::mojom::Event::kLocationChanged);
+
+ views::View* root_view = widget->GetRootView();
+ if (root_view)
+ root_view->NotifyAccessibilityEvent(ax::mojom::Event::kLocationChanged,
+ true);
+ }
+
+ aura::Window::Windows children = window->children();
+ for (size_t i = 0; i < children.size(); ++i)
+ FireLocationChanges(children[i]);
+}
+
AXWindowObjWrapper::AXWindowObjWrapper(aura::Window* window)
: window_(window),
is_alert_(false),
@@ -59,22 +81,17 @@ void AXWindowObjWrapper::GetChildren(
void AXWindowObjWrapper::Serialize(ui::AXNodeData* out_node_data) {
out_node_data->id = GetUniqueId().Get();
- ui::AXRole role = window_->GetProperty(ui::kAXRoleOverride);
- if (role != ui::AX_ROLE_NONE)
+ ax::mojom::Role role = window_->GetProperty(ui::kAXRoleOverride);
+ if (role != ax::mojom::Role::kNone)
out_node_data->role = role;
else
- out_node_data->role = is_alert_ ? ui::AX_ROLE_ALERT : ui::AX_ROLE_WINDOW;
- out_node_data->AddStringAttribute(ui::AX_ATTR_NAME,
+ out_node_data->role =
+ is_alert_ ? ax::mojom::Role::kAlert : ax::mojom::Role::kWindow;
+ out_node_data->AddStringAttribute(ax::mojom::StringAttribute::kName,
base::UTF16ToUTF8(window_->GetTitle()));
if (!window_->IsVisible())
- out_node_data->AddState(ui::AX_STATE_INVISIBLE);
-
- out_node_data->location = gfx::RectF(window_->bounds());
- if (window_->parent()) {
- out_node_data->offset_container_id =
- AXAuraObjCache::GetInstance()->GetID(window_->parent());
- }
-
+ out_node_data->AddState(ax::mojom::State::kInvisible);
+ out_node_data->location = gfx::RectF(window_->GetBoundsInScreen());
ui::AXTreeIDRegistry::AXTreeID child_ax_tree_id =
window_->GetProperty(ui::kChildAXTreeID);
if (child_ax_tree_id != ui::AXTreeIDRegistry::kNoAXTreeID) {
@@ -89,7 +106,8 @@ void AXWindowObjWrapper::Serialize(ui::AXNodeData* out_node_data) {
return;
}
- out_node_data->AddIntAttribute(ui::AX_ATTR_CHILD_TREE_ID, child_ax_tree_id);
+ out_node_data->AddIntAttribute(ax::mojom::IntAttribute::kChildTreeId,
+ child_ax_tree_id);
}
}
@@ -121,26 +139,15 @@ void AXWindowObjWrapper::OnWindowBoundsChanged(
if (window != window_)
return;
- AXAuraObjCache::GetInstance()->FireEvent(this, ui::AX_EVENT_LOCATION_CHANGED);
-
- Widget* widget = Widget::GetWidgetForNativeView(window);
- if (widget) {
- AXAuraObjCache::GetInstance()->FireEvent(
- AXAuraObjCache::GetInstance()->GetOrCreate(widget),
- ui::AX_EVENT_LOCATION_CHANGED);
-
- views::View* root_view = widget->GetRootView();
- if (root_view)
- root_view->NotifyAccessibilityEvent(ui::AX_EVENT_LOCATION_CHANGED, true);
- }
+ FireLocationChanges(window_);
}
void AXWindowObjWrapper::OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) {
if (window == window_ && key == ui::kChildAXTreeID) {
- AXAuraObjCache::GetInstance()->FireEvent(this,
- ui::AX_EVENT_CHILDREN_CHANGED);
+ AXAuraObjCache::GetInstance()->FireEvent(
+ this, ax::mojom::Event::kChildrenChanged);
}
}
diff --git a/chromium/ui/views/accessibility/native_view_accessibility.h b/chromium/ui/views/accessibility/native_view_accessibility.h
index 803db433932..d2ed8c176f9 100644
--- a/chromium/ui/views/accessibility/native_view_accessibility.h
+++ b/chromium/ui/views/accessibility/native_view_accessibility.h
@@ -8,7 +8,7 @@
#include <memory>
#include "base/macros.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/views_export.h"
@@ -25,7 +25,7 @@ class VIEWS_EXPORT NativeViewAccessibility {
virtual ~NativeViewAccessibility() {}
virtual gfx::NativeViewAccessible GetNativeObject() = 0;
- virtual void NotifyAccessibilityEvent(ui::AXEvent event_type) = 0;
+ virtual void NotifyAccessibilityEvent(ax::mojom::Event event_type) = 0;
protected:
NativeViewAccessibility() {}
diff --git a/chromium/ui/views/accessibility/native_view_accessibility_auralinux.cc b/chromium/ui/views/accessibility/native_view_accessibility_auralinux.cc
index 7fbbca936cf..0be9b7cfd75 100644
--- a/chromium/ui/views/accessibility/native_view_accessibility_auralinux.cc
+++ b/chromium/ui/views/accessibility/native_view_accessibility_auralinux.cc
@@ -13,7 +13,7 @@
#include "base/memory/singleton.h"
#include "base/stl_util.h"
#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
#include "ui/accessibility/platform/ax_platform_node_delegate.h"
@@ -98,7 +98,10 @@ class AuraLinuxApplication
return widget->GetRootView()->GetNativeViewAccessible();
}
- gfx::Rect GetScreenBoundsRect() const override { return gfx::Rect(); }
+ gfx::Rect GetClippedScreenBoundsRect() const override { return gfx::Rect(); }
+ gfx::Rect GetUnclippedScreenBoundsRect() const override {
+ return gfx::Rect();
+ }
gfx::NativeViewAccessible HitTestSync(int x, int y) override {
return nullptr;
@@ -127,12 +130,12 @@ class AuraLinuxApplication
bool ShouldIgnoreHoveredStateForTesting() override { return false; }
- std::set<int32_t> GetReverseRelations(ui::AXIntAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntAttribute attr,
int32_t dst_id) override {
return std::set<int32_t>();
}
- std::set<int32_t> GetReverseRelations(ui::AXIntListAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntListAttribute attr,
int32_t dst_id) override {
return std::set<int32_t>();
}
@@ -141,11 +144,11 @@ class AuraLinuxApplication
friend struct base::DefaultSingletonTraits<AuraLinuxApplication>;
AuraLinuxApplication() {
- data_.role = ui::AX_ROLE_APPLICATION;
+ data_.role = ax::mojom::Role::kApplication;
platform_node_ = ui::AXPlatformNode::Create(this);
if (ViewsDelegate::GetInstance()) {
data_.AddStringAttribute(
- ui::AX_ATTR_NAME,
+ ax::mojom::StringAttribute::kName,
ViewsDelegate::GetInstance()->GetApplicationName());
}
ui::AXPlatformNodeAuraLinux::SetApplication(platform_node_);
diff --git a/chromium/ui/views/accessibility/native_view_accessibility_base.cc b/chromium/ui/views/accessibility/native_view_accessibility_base.cc
index d26a9ec8cee..9997f88dd95 100644
--- a/chromium/ui/views/accessibility/native_view_accessibility_base.cc
+++ b/chromium/ui/views/accessibility/native_view_accessibility_base.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <map>
+#include <memory>
+
#include "ui/views/accessibility/native_view_accessibility_base.h"
#include "base/memory/ptr_util.h"
@@ -16,6 +19,9 @@ namespace views {
namespace {
+base::LazyInstance<std::map<int32_t, ui::AXPlatformNode*>>::Leaky
+ g_unique_id_to_ax_platform_node = LAZY_INSTANCE_INITIALIZER;
+
bool IsAccessibilityFocusableWhenEnabled(View* view) {
return view->focus_behavior() != View::FocusBehavior::NEVER &&
view->IsDrawn();
@@ -24,7 +30,7 @@ bool IsAccessibilityFocusableWhenEnabled(View* view) {
// Used to determine if a View should be ignored by accessibility clients by
// being a non-keyboard-focusable child of a keyboard-focusable ancestor. E.g.,
// LabelButtons contain Labels, but a11y should just show that there's a button.
-bool IsViewUnfocusableChildOfFocusableAncestor(View* view) {
+bool IsViewUnfocusableDescendantOfFocusableAncestor(View* view) {
if (IsAccessibilityFocusableWhenEnabled(view))
return false;
@@ -66,9 +72,12 @@ NativeViewAccessibilityBase::NativeViewAccessibilityBase(View* view)
base::BindRepeating(&FromNativeWindow));
first_time = false;
}
+
+ g_unique_id_to_ax_platform_node.Get()[GetUniqueId().Get()] = ax_node_;
}
NativeViewAccessibilityBase::~NativeViewAccessibilityBase() {
+ g_unique_id_to_ax_platform_node.Get().erase(GetUniqueId().Get());
ax_node_->Destroy();
}
@@ -77,7 +86,7 @@ gfx::NativeViewAccessible NativeViewAccessibilityBase::GetNativeObject() {
}
void NativeViewAccessibilityBase::NotifyAccessibilityEvent(
- ui::AXEvent event_type) {
+ ax::mojom::Event event_type) {
ax_node_->NotifyAccessibilityEvent(event_type);
}
@@ -95,7 +104,7 @@ const ui::AXNodeData& NativeViewAccessibilityBase::GetData() const {
// This will require ensuring that Chrome OS invalidates the whole
// subtree when a View changes its visibility state.
if (!view()->IsDrawn())
- data_.AddState(ui::AX_STATE_INVISIBLE);
+ data_.AddState(ax::mojom::State::kInvisible);
// Make sure this element is excluded from the a11y tree if there's a
// focusable parent. All keyboard focusable elements should be leaf nodes.
@@ -105,8 +114,8 @@ const ui::AXNodeData& NativeViewAccessibilityBase::GetData() const {
// because we needed a way to mark a View as a leaf node in the
// accessibility tree. We need to replace this with a cross-platform
// solution that works for ChromeVox, too, and move it to ViewAccessibility.
- if (IsViewUnfocusableChildOfFocusableAncestor(view()))
- data_.role = ui::AX_ROLE_IGNORED;
+ if (IsViewUnfocusableDescendantOfFocusableAncestor(view()))
+ data_.role = ax::mojom::Role::kIgnored;
return data_;
}
@@ -117,6 +126,8 @@ const ui::AXTreeData& NativeViewAccessibilityBase::GetTreeData() const {
}
int NativeViewAccessibilityBase::GetChildCount() {
+ if (IsLeaf())
+ return 0;
int child_count = view()->child_count();
std::vector<Widget*> child_widgets;
@@ -127,6 +138,9 @@ int NativeViewAccessibilityBase::GetChildCount() {
}
gfx::NativeViewAccessible NativeViewAccessibilityBase::ChildAtIndex(int index) {
+ if (IsLeaf())
+ return nullptr;
+
// If this is a root view, our widget might have child widgets. Include
std::vector<Widget*> child_widgets;
PopulateChildWidgetVector(&child_widgets);
@@ -161,7 +175,12 @@ gfx::NativeViewAccessible NativeViewAccessibilityBase::GetParent() {
return nullptr;
}
-gfx::Rect NativeViewAccessibilityBase::GetScreenBoundsRect() const {
+gfx::Rect NativeViewAccessibilityBase::GetClippedScreenBoundsRect() const {
+ // We could optionally add clipping here if ever needed.
+ return view()->GetBoundsInScreen();
+}
+
+gfx::Rect NativeViewAccessibilityBase::GetUnclippedScreenBoundsRect() const {
return view()->GetBoundsInScreen();
}
@@ -170,6 +189,9 @@ gfx::NativeViewAccessible NativeViewAccessibilityBase::HitTestSync(int x,
if (!view() || !view()->GetWidget())
return nullptr;
+ if (IsLeaf())
+ return GetNativeObject();
+
// Search child widgets first, since they're on top in the z-order.
std::vector<Widget*> child_widgets;
PopulateChildWidgetVector(&child_widgets);
@@ -212,7 +234,14 @@ gfx::NativeViewAccessible NativeViewAccessibilityBase::GetFocus() {
}
ui::AXPlatformNode* NativeViewAccessibilityBase::GetFromNodeID(int32_t id) {
- return nullptr;
+ // Note: For Views, node IDs and unique IDs are the same - but that isn't
+ // necessarily true for all AXPlatformNodes.
+ auto it = g_unique_id_to_ax_platform_node.Get().find(id);
+
+ if (it == g_unique_id_to_ax_platform_node.Get().end())
+ return nullptr;
+
+ return it->second;
}
int NativeViewAccessibilityBase::GetIndexInParent() const {
@@ -239,13 +268,13 @@ bool NativeViewAccessibilityBase::IsOffscreen() const {
}
std::set<int32_t> NativeViewAccessibilityBase::GetReverseRelations(
- ui::AXIntAttribute attr,
+ ax::mojom::IntAttribute attr,
int32_t dst_id) {
return std::set<int32_t>();
}
std::set<int32_t> NativeViewAccessibilityBase::GetReverseRelations(
- ui::AXIntListAttribute attr,
+ ax::mojom::IntListAttribute attr,
int32_t dst_id) {
return std::set<int32_t>();
}
@@ -254,10 +283,6 @@ const ui::AXUniqueId& NativeViewAccessibilityBase::GetUniqueId() const {
return ViewAccessibility::GetUniqueId();
}
-gfx::RectF NativeViewAccessibilityBase::GetBoundsInScreen() const {
- return gfx::RectF(view()->GetBoundsInScreen());
-}
-
void NativeViewAccessibilityBase::PopulateChildWidgetVector(
std::vector<Widget*>* result_child_widgets) {
// Only attach child widgets to the root view.
diff --git a/chromium/ui/views/accessibility/native_view_accessibility_base.h b/chromium/ui/views/accessibility/native_view_accessibility_base.h
index 413a3a32af9..18fe003a7fc 100644
--- a/chromium/ui/views/accessibility/native_view_accessibility_base.h
+++ b/chromium/ui/views/accessibility/native_view_accessibility_base.h
@@ -36,7 +36,7 @@ class VIEWS_EXPORT NativeViewAccessibilityBase
// ViewAccessibility:
gfx::NativeViewAccessible GetNativeObject() override;
- void NotifyAccessibilityEvent(ui::AXEvent event_type) override;
+ void NotifyAccessibilityEvent(ax::mojom::Event event_type) override;
// ui::AXPlatformNodeDelegate
const ui::AXNodeData& GetData() const override;
@@ -45,7 +45,8 @@ class VIEWS_EXPORT NativeViewAccessibilityBase
gfx::NativeViewAccessible ChildAtIndex(int index) override;
gfx::NativeWindow GetTopLevelWidget() override;
gfx::NativeViewAccessible GetParent() override;
- gfx::Rect GetScreenBoundsRect() const override;
+ gfx::Rect GetClippedScreenBoundsRect() const override;
+ gfx::Rect GetUnclippedScreenBoundsRect() const override;
gfx::NativeViewAccessible HitTestSync(int x, int y) override;
gfx::NativeViewAccessible GetFocus() override;
ui::AXPlatformNode* GetFromNodeID(int32_t id) override;
@@ -56,17 +57,14 @@ class VIEWS_EXPORT NativeViewAccessibilityBase
bool IsOffscreen() const override;
const ui::AXUniqueId& GetUniqueId()
const override; // Also in ViewAccessibility
- std::set<int32_t> GetReverseRelations(ui::AXIntAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntAttribute attr,
int32_t dst_id) override;
- std::set<int32_t> GetReverseRelations(ui::AXIntListAttribute attr,
+ std::set<int32_t> GetReverseRelations(ax::mojom::IntListAttribute attr,
int32_t dst_id) override;
protected:
explicit NativeViewAccessibilityBase(View* view);
- protected:
- virtual gfx::RectF GetBoundsInScreen() const;
-
private:
void PopulateChildWidgetVector(std::vector<Widget*>* result_child_widgets);
diff --git a/chromium/ui/views/accessibility/native_view_accessibility_unittest.cc b/chromium/ui/views/accessibility/native_view_accessibility_unittest.cc
index 5bf1eaaf746..d146b33705f 100644
--- a/chromium/ui/views/accessibility/native_view_accessibility_unittest.cc
+++ b/chromium/ui/views/accessibility/native_view_accessibility_unittest.cc
@@ -71,7 +71,8 @@ class NativeViewAccessibilityTest : public ViewsTestBase {
bool SetFocused(NativeViewAccessibilityBase* view_accessibility,
bool focused) {
ui::AXActionData data;
- data.action = focused ? ui::AX_ACTION_FOCUS : ui::AX_ACTION_BLUR;
+ data.action =
+ focused ? ax::mojom::Action::kFocus : ax::mojom::Action::kBlur;
return view_accessibility->AccessibilityPerformAction(data);
}
@@ -84,22 +85,24 @@ class NativeViewAccessibilityTest : public ViewsTestBase {
};
TEST_F(NativeViewAccessibilityTest, RoleShouldMatch) {
- EXPECT_EQ(ui::AX_ROLE_BUTTON, button_accessibility()->GetData().role);
+ EXPECT_EQ(ax::mojom::Role::kButton, button_accessibility()->GetData().role);
// Since the label is a subview of |button_|, and the button is keyboard
// focusable, the label is assumed to form part of the button and not have a
// role of its own.
- EXPECT_EQ(ui::AX_ROLE_IGNORED, label_accessibility()->GetData().role);
+ EXPECT_EQ(ax::mojom::Role::kIgnored, label_accessibility()->GetData().role);
// This will happen for all potentially keyboard-focusable Views with
// non-keyboard-focusable children, so if we make the button unfocusable, the
// label will be allowed to have its own role again.
button_->SetFocusBehavior(View::FocusBehavior::NEVER);
- EXPECT_EQ(ui::AX_ROLE_STATIC_TEXT, label_accessibility()->GetData().role);
+ EXPECT_EQ(ax::mojom::Role::kStaticText,
+ label_accessibility()->GetData().role);
}
TEST_F(NativeViewAccessibilityTest, BoundsShouldMatch) {
gfx::Rect bounds =
gfx::ToEnclosingRect(button_accessibility()->GetData().location);
- gfx::Rect screen_bounds = button_accessibility()->GetScreenBoundsRect();
+ gfx::Rect screen_bounds =
+ button_accessibility()->GetUnclippedScreenBoundsRect();
EXPECT_EQ(button_->GetBoundsInScreen(), bounds);
EXPECT_EQ(screen_bounds, bounds);
@@ -111,7 +114,7 @@ TEST_F(NativeViewAccessibilityTest, LabelIsChildOfButton) {
EXPECT_EQ(1, button_accessibility()->GetChildCount());
EXPECT_EQ(button_->GetNativeViewAccessible(),
label_accessibility()->GetParent());
- EXPECT_EQ(ui::AX_ROLE_IGNORED, label_accessibility()->GetData().role);
+ EXPECT_EQ(ax::mojom::Role::kIgnored, label_accessibility()->GetData().role);
// If |button_| is no longer focusable, |label_| should show up again.
button_->SetFocusBehavior(View::FocusBehavior::NEVER);
@@ -120,21 +123,21 @@ TEST_F(NativeViewAccessibilityTest, LabelIsChildOfButton) {
button_accessibility()->ChildAtIndex(0));
EXPECT_EQ(button_->GetNativeViewAccessible(),
label_accessibility()->GetParent());
- EXPECT_NE(ui::AX_ROLE_IGNORED, label_accessibility()->GetData().role);
+ EXPECT_NE(ax::mojom::Role::kIgnored, label_accessibility()->GetData().role);
}
-// Verify Views with invisible ancestors have AX_STATE_INVISIBLE.
+// Verify Views with invisible ancestors have ax::mojom::State::kInvisible.
TEST_F(NativeViewAccessibilityTest, InvisibleViews) {
EXPECT_TRUE(widget_->IsVisible());
EXPECT_FALSE(
- button_accessibility()->GetData().HasState(ui::AX_STATE_INVISIBLE));
+ button_accessibility()->GetData().HasState(ax::mojom::State::kInvisible));
EXPECT_FALSE(
- label_accessibility()->GetData().HasState(ui::AX_STATE_INVISIBLE));
+ label_accessibility()->GetData().HasState(ax::mojom::State::kInvisible));
button_->SetVisible(false);
EXPECT_TRUE(
- button_accessibility()->GetData().HasState(ui::AX_STATE_INVISIBLE));
+ button_accessibility()->GetData().HasState(ax::mojom::State::kInvisible));
EXPECT_TRUE(
- label_accessibility()->GetData().HasState(ui::AX_STATE_INVISIBLE));
+ label_accessibility()->GetData().HasState(ax::mojom::State::kInvisible));
}
TEST_F(NativeViewAccessibilityTest, WritableFocus) {
@@ -178,7 +181,8 @@ class AxTestViewsDelegate : public TestViewsDelegate {
AxTestViewsDelegate() {}
~AxTestViewsDelegate() override {}
- void NotifyAccessibilityEvent(View* view, ui::AXEvent event_type) override {
+ void NotifyAccessibilityEvent(View* view,
+ ax::mojom::Event event_type) override {
AXAuraObjCache* ax = AXAuraObjCache::GetInstance();
std::vector<AXAuraObjWrapper*> out_children;
AXAuraObjWrapper* ax_obj = ax->GetOrCreate(view->GetWidget());
diff --git a/chromium/ui/views/accessibility/native_view_accessibility_win.cc b/chromium/ui/views/accessibility/native_view_accessibility_win.cc
index 9fe2082cc0d..bc1ef854510 100644
--- a/chromium/ui/views/accessibility/native_view_accessibility_win.cc
+++ b/chromium/ui/views/accessibility/native_view_accessibility_win.cc
@@ -15,7 +15,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/win/windows_version.h"
#include "third_party/iaccessible2/ia2_api_all.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_text_utils.h"
#include "ui/aura/window.h"
@@ -23,6 +23,7 @@
#include "ui/base/layout.h"
#include "ui/base/win/accessibility_misc_utils.h"
#include "ui/base/win/atl_module.h"
+#include "ui/display/win/screen_win.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/widget/widget.h"
@@ -101,12 +102,14 @@ NativeViewAccessibilityWin::GetTargetForNativeAccessibilityEvent() {
return HWNDForView(view());
}
-gfx::RectF NativeViewAccessibilityWin::GetBoundsInScreen() const {
- gfx::RectF bounds = gfx::RectF(view()->GetBoundsInScreen());
- gfx::NativeView native_view = view()->GetWidget()->GetNativeView();
- float device_scale = ui::GetScaleFactorForNativeView(native_view);
- bounds.Scale(device_scale);
- return bounds;
+gfx::Rect NativeViewAccessibilityWin::GetClippedScreenBoundsRect() const {
+ // We could optionally add clipping here if ever needed.
+ return GetUnclippedScreenBoundsRect();
+}
+
+gfx::Rect NativeViewAccessibilityWin::GetUnclippedScreenBoundsRect() const {
+ gfx::Rect bounds = view()->GetBoundsInScreen();
+ return display::win::ScreenWin::DIPToScreenRect(HWNDForView(view()), bounds);
}
} // namespace views
diff --git a/chromium/ui/views/accessibility/native_view_accessibility_win.h b/chromium/ui/views/accessibility/native_view_accessibility_win.h
index dde0c906e23..8f64f68877a 100644
--- a/chromium/ui/views/accessibility/native_view_accessibility_win.h
+++ b/chromium/ui/views/accessibility/native_view_accessibility_win.h
@@ -19,7 +19,8 @@ class NativeViewAccessibilityWin : public NativeViewAccessibilityBase {
// NativeViewAccessibilityBase:
gfx::NativeViewAccessible GetParent() override;
gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
- gfx::RectF GetBoundsInScreen() const override;
+ gfx::Rect GetClippedScreenBoundsRect() const override;
+ gfx::Rect GetUnclippedScreenBoundsRect() const override;
DISALLOW_COPY_AND_ASSIGN(NativeViewAccessibilityWin);
};
diff --git a/chromium/ui/views/accessibility/native_view_accessibility_win_unittest.cc b/chromium/ui/views/accessibility/native_view_accessibility_win_unittest.cc
index 9a4d5647ec1..0b1c5dc7b55 100644
--- a/chromium/ui/views/accessibility/native_view_accessibility_win_unittest.cc
+++ b/chromium/ui/views/accessibility/native_view_accessibility_win_unittest.cc
@@ -9,6 +9,8 @@
#include "base/win/scoped_variant.h"
#include "third_party/iaccessible2/ia2_api_all.h"
#include "ui/views/accessibility/native_view_accessibility_base.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/test/views_test_base.h"
@@ -101,6 +103,56 @@ TEST_F(NativeViewAccessibilityWinTest, TextfieldAccessibility) {
ASSERT_STREQ(L"New value", textfield->text().c_str());
}
+TEST_F(NativeViewAccessibilityWinTest, TextfieldAssociatedLabel) {
+ Widget widget;
+ Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
+ init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget.Init(init_params);
+
+ View* content = new View;
+ widget.SetContentsView(content);
+
+ Label* label = new Label(L"Label");
+ content->AddChildView(label);
+ Textfield* textfield = new Textfield;
+ textfield->SetAssociatedLabel(label);
+ content->AddChildView(textfield);
+
+ ComPtr<IAccessible> content_accessible(content->GetNativeViewAccessible());
+ LONG child_count = 0;
+ ASSERT_EQ(S_OK, content_accessible->get_accChildCount(&child_count));
+ ASSERT_EQ(2L, child_count);
+
+ ComPtr<IDispatch> textfield_dispatch;
+ ComPtr<IAccessible> textfield_accessible;
+ ScopedVariant child_index(2);
+ ASSERT_EQ(S_OK, content_accessible->get_accChild(
+ child_index, textfield_dispatch.GetAddressOf()));
+ ASSERT_EQ(S_OK,
+ textfield_dispatch.CopyTo(textfield_accessible.GetAddressOf()));
+
+ ScopedBstr name;
+ ScopedVariant childid_self(CHILDID_SELF);
+ ASSERT_EQ(S_OK,
+ textfield_accessible->get_accName(childid_self, name.Receive()));
+ ASSERT_STREQ(L"Label", name);
+
+ ComPtr<IAccessible2_2> textfield_ia2;
+ EXPECT_EQ(S_OK, textfield_accessible.CopyTo(textfield_ia2.GetAddressOf()));
+ ScopedBstr type(IA2_RELATION_LABELLED_BY);
+ IUnknown** targets;
+ LONG n_targets;
+ EXPECT_EQ(S_OK, textfield_ia2->get_relationTargetsOfType(type, 0, &targets,
+ &n_targets));
+ ASSERT_EQ(1, n_targets);
+ ComPtr<IUnknown> label_unknown(targets[0]);
+ ComPtr<IAccessible> label_accessible;
+ ASSERT_EQ(S_OK, label_unknown.CopyTo(label_accessible.GetAddressOf()));
+ ScopedVariant role;
+ EXPECT_EQ(S_OK, label_accessible->get_accRole(childid_self, role.Receive()));
+ EXPECT_EQ(ROLE_SYSTEM_STATICTEXT, V_I4(role.ptr()));
+}
+
// A subclass of NativeViewAccessibilityWinTest that we run twice,
// first where we create an transient child widget (child = false), the second
// time where we create a child widget (child = true).
@@ -237,8 +289,8 @@ TEST_F(NativeViewAccessibilityWinTest, DISABLED_RetrieveAllAlerts) {
ASSERT_EQ(0, n_targets);
// Fire alert events on the infobars.
- infobar->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
- infobar2->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
+ infobar->NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
+ infobar2->NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
// Now calling get_relationTargetsOfType should retrieve the alerts.
ASSERT_EQ(S_OK, root_view_accessible->get_relationTargetsOfType(
@@ -282,7 +334,7 @@ TEST_F(NativeViewAccessibilityWinTest, GetAllOwnedWidgetsCrash) {
TEST_F(NativeViewAccessibilityWinTest, WindowHasRoleApplication) {
// We expect that our internal window object does not expose
- // ROLE_SYSTEM_WINDOW, but ROLE_SYSTEM_APPLICATION instead.
+ // ROLE_SYSTEM_WINDOW, but ROLE_SYSTEM_PANE instead.
Widget widget;
Widget::InitParams init_params =
CreateParams(Widget::InitParams::TYPE_WINDOW);
@@ -294,8 +346,69 @@ TEST_F(NativeViewAccessibilityWinTest, WindowHasRoleApplication) {
ScopedVariant childid_self(CHILDID_SELF);
ScopedVariant role;
EXPECT_EQ(S_OK, accessible->get_accRole(childid_self, role.Receive()));
- EXPECT_EQ(role.type(), VT_I4);
- EXPECT_EQ(V_I4(role.ptr()), ROLE_SYSTEM_APPLICATION);
+ EXPECT_EQ(VT_I4, role.type());
+ EXPECT_EQ(ROLE_SYSTEM_PANE, V_I4(role.ptr()));
+}
+
+TEST_F(NativeViewAccessibilityWinTest, Overrides) {
+ // We expect that our internal window object does not expose
+ // ROLE_SYSTEM_WINDOW, but ROLE_SYSTEM_PANE instead.
+ Widget widget;
+ Widget::InitParams init_params = CreateParams(Widget::InitParams::TYPE_POPUP);
+ init_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget.Init(init_params);
+
+ View* contents_view = new View;
+ widget.SetContentsView(contents_view);
+
+ View* alert_view = new ScrollView;
+ alert_view->GetViewAccessibility().OverrideRole(ax::mojom::Role::kAlert);
+ alert_view->GetViewAccessibility().OverrideName(L"Name");
+ alert_view->GetViewAccessibility().OverrideDescription("Description");
+ alert_view->GetViewAccessibility().OverrideIsLeaf();
+ contents_view->AddChildView(alert_view);
+
+ // Descendant should be ignored because the parent uses OverrideIsLeaf().
+ View* ignored_descendant = new View;
+ alert_view->AddChildView(ignored_descendant);
+
+ ComPtr<IAccessible> content_accessible(
+ contents_view->GetNativeViewAccessible());
+ ScopedVariant child_index(1);
+
+ // Role.
+ ScopedVariant role;
+ EXPECT_EQ(S_OK, content_accessible->get_accRole(child_index, role.Receive()));
+ EXPECT_EQ(VT_I4, role.type());
+ EXPECT_EQ(ROLE_SYSTEM_ALERT, V_I4(role.ptr()));
+
+ // Name.
+ ScopedBstr name;
+ ASSERT_EQ(S_OK, content_accessible->get_accName(child_index, name.Receive()));
+ ASSERT_STREQ(L"Name", name);
+
+ // Description.
+ ScopedBstr description;
+ ASSERT_EQ(S_OK, content_accessible->get_accDescription(
+ child_index, description.Receive()));
+ ASSERT_STREQ(L"Description", description);
+
+ // Get the child accessible.
+ ComPtr<IDispatch> alert_dispatch;
+ ComPtr<IAccessible> alert_accessible;
+ ASSERT_EQ(S_OK, content_accessible->get_accChild(
+ child_index, alert_dispatch.GetAddressOf()));
+ ASSERT_EQ(S_OK, alert_dispatch.CopyTo(alert_accessible.GetAddressOf()));
+
+ // Child accessible is a leaf.
+ LONG child_count = 0;
+ ASSERT_EQ(S_OK, alert_accessible->get_accChildCount(&child_count));
+ ASSERT_EQ(0, child_count);
+
+ ComPtr<IDispatch> child_dispatch;
+ ASSERT_EQ(E_INVALIDARG, alert_accessible->get_accChild(
+ child_index, child_dispatch.GetAddressOf()));
+ ASSERT_EQ(child_dispatch.Get(), nullptr);
}
} // namespace test
} // namespace views
diff --git a/chromium/ui/views/accessibility/view_accessibility.cc b/chromium/ui/views/accessibility/view_accessibility.cc
index 577872cb4e7..133b4d4368d 100644
--- a/chromium/ui/views/accessibility/view_accessibility.cc
+++ b/chromium/ui/views/accessibility/view_accessibility.cc
@@ -13,16 +13,16 @@ namespace views {
namespace {
-bool IsValidRoleForViews(ui::AXRole role) {
+bool IsValidRoleForViews(ax::mojom::Role role) {
switch (role) {
// These roles all have special meaning and shouldn't ever be
// set on a View.
- case ui::AX_ROLE_DESKTOP:
- case ui::AX_ROLE_NONE:
- case ui::AX_ROLE_ROOT_WEB_AREA:
- case ui::AX_ROLE_SVG_ROOT:
- case ui::AX_ROLE_UNKNOWN:
- case ui::AX_ROLE_WEB_AREA:
+ case ax::mojom::Role::kDesktop:
+ case ax::mojom::Role::kNone:
+ case ax::mojom::Role::kRootWebArea:
+ case ax::mojom::Role::kSvgRoot:
+ case ax::mojom::Role::kUnknown:
+ case ax::mojom::Role::kWebArea:
return false;
default:
@@ -39,7 +39,8 @@ std::unique_ptr<ViewAccessibility> ViewAccessibility::Create(View* view) {
}
#endif
-ViewAccessibility::ViewAccessibility(View* view) : owner_view_(view) {}
+ViewAccessibility::ViewAccessibility(View* view)
+ : owner_view_(view), is_leaf_(false) {}
ViewAccessibility::~ViewAccessibility() {}
@@ -50,42 +51,64 @@ const ui::AXUniqueId& ViewAccessibility::GetUniqueId() const {
void ViewAccessibility::GetAccessibleNodeData(ui::AXNodeData* data) const {
// Views may misbehave if their widget is closed; return an unknown role
// rather than possibly crashing.
- if (!owner_view_->GetWidget() || owner_view_->GetWidget()->IsClosed()) {
- data->role = ui::AX_ROLE_UNKNOWN;
- data->AddIntAttribute(ui::AX_ATTR_RESTRICTION, ui::AX_RESTRICTION_DISABLED);
+ views::Widget* widget = owner_view_->GetWidget();
+ if (!widget || !widget->widget_delegate() || widget->IsClosed()) {
+ data->role = ax::mojom::Role::kUnknown;
+ data->SetRestriction(ax::mojom::Restriction::kDisabled);
return;
}
owner_view_->GetAccessibleNodeData(data);
- if (custom_data_.role != ui::AX_ROLE_UNKNOWN)
+ if (custom_data_.role != ax::mojom::Role::kUnknown)
data->role = custom_data_.role;
- if (custom_data_.HasStringAttribute(ui::AX_ATTR_NAME))
- data->SetName(custom_data_.GetStringAttribute(ui::AX_ATTR_NAME));
- data->location = gfx::RectF(owner_view_->GetBoundsInScreen());
- if (!data->HasStringAttribute(ui::AX_ATTR_DESCRIPTION)) {
- base::string16 description;
- owner_view_->GetTooltipText(gfx::Point(), &description);
- data->AddStringAttribute(ui::AX_ATTR_DESCRIPTION,
- base::UTF16ToUTF8(description));
+ if (custom_data_.HasStringAttribute(ax::mojom::StringAttribute::kName)) {
+ data->SetName(
+ custom_data_.GetStringAttribute(ax::mojom::StringAttribute::kName));
+ }
+
+ if (custom_data_.HasStringAttribute(
+ ax::mojom::StringAttribute::kDescription)) {
+ data->SetDescription(custom_data_.GetStringAttribute(
+ ax::mojom::StringAttribute::kDescription));
}
- data->AddStringAttribute(ui::AX_ATTR_CLASS_NAME, owner_view_->GetClassName());
+ if (!data->HasStringAttribute(ax::mojom::StringAttribute::kDescription)) {
+ base::string16 tooltip;
+ owner_view_->GetTooltipText(gfx::Point(), &tooltip);
+ // Some screen readers announce the accessible description right after the
+ // accessible name. Only use the tooltip as the accessible description if
+ // it's different from the name, otherwise users might be puzzled as to why
+ // their screen reader is announcing the same thing twice.
+ if (tooltip !=
+ data->GetString16Attribute(ax::mojom::StringAttribute::kName)) {
+ data->AddStringAttribute(ax::mojom::StringAttribute::kDescription,
+ base::UTF16ToUTF8(tooltip));
+ }
+ }
+
+ data->location = gfx::RectF(owner_view_->GetBoundsInScreen());
+ data->AddStringAttribute(ax::mojom::StringAttribute::kClassName,
+ owner_view_->GetClassName());
if (owner_view_->IsAccessibilityFocusable())
- data->AddState(ui::AX_STATE_FOCUSABLE);
+ data->AddState(ax::mojom::State::kFocusable);
if (!owner_view_->enabled())
- data->AddIntAttribute(ui::AX_ATTR_RESTRICTION, ui::AX_RESTRICTION_DISABLED);
+ data->SetRestriction(ax::mojom::Restriction::kDisabled);
if (!owner_view_->visible())
- data->AddState(ui::AX_STATE_INVISIBLE);
+ data->AddState(ax::mojom::State::kInvisible);
if (owner_view_->context_menu_controller())
- data->AddAction(ui::AX_ACTION_SHOW_CONTEXT_MENU);
+ data->AddAction(ax::mojom::Action::kShowContextMenu);
+}
+
+bool ViewAccessibility::IsLeaf() const {
+ return is_leaf_;
}
-void ViewAccessibility::OverrideRole(ui::AXRole role) {
+void ViewAccessibility::OverrideRole(ax::mojom::Role role) {
DCHECK(IsValidRoleForViews(role));
custom_data_.role = role;
@@ -95,6 +118,21 @@ void ViewAccessibility::OverrideName(const std::string& name) {
custom_data_.SetName(name);
}
+void ViewAccessibility::OverrideName(const base::string16& name) {
+ custom_data_.SetName(base::UTF16ToUTF8(name));
+}
+
+void ViewAccessibility::OverrideDescription(const std::string& description) {
+ DCHECK(!custom_data_.HasStringAttribute(
+ ax::mojom::StringAttribute::kDescription));
+ custom_data_.AddStringAttribute(ax::mojom::StringAttribute::kDescription,
+ description);
+}
+
+void ViewAccessibility::OverrideIsLeaf() {
+ is_leaf_ = true;
+}
+
gfx::NativeViewAccessible ViewAccessibility::GetNativeObject() {
return nullptr;
}
diff --git a/chromium/ui/views/accessibility/view_accessibility.h b/chromium/ui/views/accessibility/view_accessibility.h
index b9c02c4fe3f..8dc947bd63a 100644
--- a/chromium/ui/views/accessibility/view_accessibility.h
+++ b/chromium/ui/views/accessibility/view_accessibility.h
@@ -8,7 +8,7 @@
#include <memory>
#include "base/macros.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/platform/ax_unique_id.h"
#include "ui/gfx/native_widget_types.h"
@@ -40,18 +40,24 @@ class VIEWS_EXPORT ViewAccessibility {
virtual void GetAccessibleNodeData(ui::AXNodeData* node_data) const;
//
- // These override anything returned from View::GetAccessibleNodeData().
+ // These override accessibility information, including properties returned
+ // from View::GetAccessibleNodeData().
// Note that string attributes are only used if non-empty, so you can't
// override a string with the empty string.
//
- void OverrideRole(ui::AXRole role);
+ void OverrideRole(ax::mojom::Role role);
void OverrideName(const std::string& name);
+ void OverrideName(const base::string16& name);
+ void OverrideDescription(const std::string& description);
+ void OverrideIsLeaf(); // Force this node to be treated as a leaf node.
virtual gfx::NativeViewAccessible GetNativeObject();
- virtual void NotifyAccessibilityEvent(ui::AXEvent event_type) {}
+ virtual void NotifyAccessibilityEvent(ax::mojom::Event event_type) {}
virtual const ui::AXUniqueId& GetUniqueId() const;
+ bool IsLeaf() const;
+
protected:
explicit ViewAccessibility(View* view);
@@ -67,6 +73,8 @@ class VIEWS_EXPORT ViewAccessibility {
// anything provided by GetAccessibleNodeData().
ui::AXNodeData custom_data_;
+ bool is_leaf_;
+
DISALLOW_COPY_AND_ASSIGN(ViewAccessibility);
};
diff --git a/chromium/ui/views/accessible_pane_view.cc b/chromium/ui/views/accessible_pane_view.cc
index 2be372d5355..a22b6967a34 100644
--- a/chromium/ui/views/accessible_pane_view.cc
+++ b/chromium/ui/views/accessible_pane_view.cc
@@ -205,7 +205,7 @@ void AccessiblePaneView::SetVisible(bool flag) {
}
void AccessiblePaneView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_PANE;
+ node_data->role = ax::mojom::Role::kPane;
}
void AccessiblePaneView::RequestFocus() {
diff --git a/chromium/ui/views/animation/bounds_animator.cc b/chromium/ui/views/animation/bounds_animator.cc
index 78c22580454..13180c3f2e2 100644
--- a/chromium/ui/views/animation/bounds_animator.cc
+++ b/chromium/ui/views/animation/bounds_animator.cc
@@ -32,7 +32,7 @@ BoundsAnimator::BoundsAnimator(View* parent)
BoundsAnimator::~BoundsAnimator() {
// Reset the delegate so that we don't attempt to notify our observer from
// the destructor.
- container_->set_observer(NULL);
+ container_->set_observer(nullptr);
// Delete all the animations, but don't remove any child views. We assume the
// view owns us and is going to be deleted anyway.
@@ -49,9 +49,7 @@ void BoundsAnimator::AnimateViewTo(View* view, const gfx::Rect& target) {
if (IsAnimating(view)) {
// Don't immediatly delete the animation, that might trigger a callback from
// the animationcontainer.
- existing_data = data_[view];
-
- RemoveFromMaps(view);
+ existing_data = RemoveFromMaps(view);
}
// NOTE: we don't check if the view is already at the target location. Doing
@@ -64,11 +62,11 @@ void BoundsAnimator::AnimateViewTo(View* view, const gfx::Rect& target) {
data.target_bounds = target;
data.animation = CreateAnimation();
- animation_to_view_[data.animation] = view;
+ animation_to_view_[data.animation.get()] = view;
data.animation->Show();
- CleanupData(true, &existing_data, NULL);
+ CleanupData(true, &existing_data, nullptr);
}
void BoundsAnimator::SetTargetBounds(View* view, const gfx::Rect& target) {
@@ -86,29 +84,29 @@ gfx::Rect BoundsAnimator::GetTargetBounds(View* view) {
return data_[view].target_bounds;
}
-void BoundsAnimator::SetAnimationForView(View* view,
- SlideAnimation* animation) {
+void BoundsAnimator::SetAnimationForView(
+ View* view,
+ std::unique_ptr<SlideAnimation> animation) {
DCHECK(animation);
- std::unique_ptr<SlideAnimation> animation_wrapper(animation);
-
if (!IsAnimating(view))
return;
// We delay deleting the animation until the end so that we don't prematurely
// send out notification that we're done.
- std::unique_ptr<Animation> old_animation(ResetAnimationForView(view));
+ std::unique_ptr<Animation> old_animation = ResetAnimationForView(view);
- data_[view].animation = animation_wrapper.release();
- animation_to_view_[animation] = view;
+ SlideAnimation* animation_ptr = animation.get();
+ data_[view].animation = std::move(animation);
+ animation_to_view_[animation_ptr] = view;
- animation->set_delegate(this);
- animation->SetContainer(container_.get());
- animation->Show();
+ animation_ptr->set_delegate(this);
+ animation_ptr->SetContainer(container_.get());
+ animation_ptr->Show();
}
const SlideAnimation* BoundsAnimator::GetAnimationForView(View* view) {
- return !IsAnimating(view) ? NULL : data_[view].animation;
+ return !IsAnimating(view) ? nullptr : data_[view].animation.get();
}
void BoundsAnimator::SetAnimationDelegate(
@@ -116,7 +114,7 @@ void BoundsAnimator::SetAnimationDelegate(
std::unique_ptr<AnimationDelegate> delegate) {
DCHECK(IsAnimating(view));
- data_[view].delegate = delegate.release();
+ data_[view].delegate = std::move(delegate);
}
void BoundsAnimator::StopAnimatingView(View* view) {
@@ -157,46 +155,51 @@ void BoundsAnimator::RemoveObserver(BoundsAnimatorObserver* observer) {
observers_.RemoveObserver(observer);
}
-SlideAnimation* BoundsAnimator::CreateAnimation() {
- SlideAnimation* animation = new SlideAnimation(this);
+std::unique_ptr<gfx::SlideAnimation> BoundsAnimator::CreateAnimation() {
+ std::unique_ptr<gfx::SlideAnimation> animation =
+ std::make_unique<SlideAnimation>(this);
animation->SetContainer(container_.get());
animation->SetSlideDuration(animation_duration_ms_);
animation->SetTweenType(tween_type_);
return animation;
}
-void BoundsAnimator::RemoveFromMaps(View* view) {
+BoundsAnimator::Data::Data() = default;
+BoundsAnimator::Data::Data(Data&&) = default;
+BoundsAnimator::Data& BoundsAnimator::Data::operator=(Data&&) = default;
+BoundsAnimator::Data::~Data() = default;
+
+BoundsAnimator::Data BoundsAnimator::RemoveFromMaps(View* view) {
DCHECK(data_.count(view) > 0);
- DCHECK(animation_to_view_.count(data_[view].animation) > 0);
+ DCHECK(animation_to_view_.count(data_[view].animation.get()) > 0);
- animation_to_view_.erase(data_[view].animation);
+ Data old_data = std::move(data_[view]);
data_.erase(view);
+ animation_to_view_.erase(old_data.animation.get());
+ return old_data;
}
void BoundsAnimator::CleanupData(bool send_cancel, Data* data, View* view) {
if (send_cancel && data->delegate)
- data->delegate->AnimationCanceled(data->animation);
+ data->delegate->AnimationCanceled(data->animation.get());
- delete data->delegate;
- data->delegate = NULL;
+ data->delegate.reset();
if (data->animation) {
- data->animation->set_delegate(NULL);
- delete data->animation;
- data->animation = NULL;
+ data->animation->set_delegate(nullptr);
+ data->animation.reset();
}
}
-Animation* BoundsAnimator::ResetAnimationForView(View* view) {
+std::unique_ptr<Animation> BoundsAnimator::ResetAnimationForView(View* view) {
if (!IsAnimating(view))
- return NULL;
+ return nullptr;
- Animation* old_animation = data_[view].animation;
- animation_to_view_.erase(old_animation);
- data_[view].animation = NULL;
+ std::unique_ptr<Animation> old_animation = std::move(data_[view].animation);
+ animation_to_view_.erase(old_animation.get());
// Reset the delegate so that we don't attempt any processing when the
// animation calls us back.
- old_animation->set_delegate(NULL);
+ old_animation->set_delegate(nullptr);
return old_animation;
}
@@ -207,10 +210,8 @@ void BoundsAnimator::AnimationEndedOrCanceled(const Animation* animation,
View* view = animation_to_view_[animation];
DCHECK(view);
- // Make a copy of the data as Remove empties out the maps.
- Data data = data_[view];
-
- RemoveFromMaps(view);
+ // Save the data for later clean up.
+ Data data = RemoveFromMaps(view);
if (data.delegate) {
if (type == ANIMATION_ENDED) {
diff --git a/chromium/ui/views/animation/bounds_animator.h b/chromium/ui/views/animation/bounds_animator.h
index 7f4208985b2..5fdb04dd713 100644
--- a/chromium/ui/views/animation/bounds_animator.h
+++ b/chromium/ui/views/animation/bounds_animator.h
@@ -58,9 +58,9 @@ class VIEWS_EXPORT BoundsAnimator : public gfx::AnimationDelegate,
// animating its current bounds is returned.
gfx::Rect GetTargetBounds(View* view);
- // Sets the animation for the specified view. BoundsAnimator takes ownership
- // of the specified animation.
- void SetAnimationForView(View* view, gfx::SlideAnimation* animation);
+ // Sets the animation for the specified view.
+ void SetAnimationForView(View* view,
+ std::unique_ptr<gfx::SlideAnimation> animation);
// Returns the animation for the specified view. BoundsAnimator owns the
// returned Animation.
@@ -98,12 +98,15 @@ class VIEWS_EXPORT BoundsAnimator : public gfx::AnimationDelegate,
protected:
// Creates the animation to use for animating views.
- virtual gfx::SlideAnimation* CreateAnimation();
+ virtual std::unique_ptr<gfx::SlideAnimation> CreateAnimation();
private:
// Tracks data about the view being animated.
struct Data {
- Data() : animation(NULL), delegate(NULL) {}
+ Data();
+ Data(Data&&);
+ Data& operator=(Data&&);
+ ~Data();
// The initial bounds.
gfx::Rect start_bounds;
@@ -111,11 +114,11 @@ class VIEWS_EXPORT BoundsAnimator : public gfx::AnimationDelegate,
// Target bounds.
gfx::Rect target_bounds;
- // The animation. We own this.
- gfx::SlideAnimation* animation;
+ // The animation.
+ std::unique_ptr<gfx::SlideAnimation> animation;
- // Delegate for the animation, may be null. We own this.
- gfx::AnimationDelegate* delegate;
+ // Delegate for the animation, may be nullptr.
+ std::unique_ptr<gfx::AnimationDelegate> delegate;
};
// Used by AnimationEndedOrCanceled.
@@ -128,9 +131,9 @@ class VIEWS_EXPORT BoundsAnimator : public gfx::AnimationDelegate,
typedef std::map<const gfx::Animation*, View*> AnimationToViewMap;
- // Removes references to |view| and its animation. This does NOT delete the
- // animation or delegate.
- void RemoveFromMaps(View* view);
+ // Removes references to |view| and its animation. Returns the data for the
+ // caller to handle cleanup.
+ Data RemoveFromMaps(View* view);
// Does the necessary cleanup for |data|. If |send_cancel| is true and a
// delegate has been installed on |data| AnimationCanceled is invoked on it.
@@ -139,7 +142,7 @@ class VIEWS_EXPORT BoundsAnimator : public gfx::AnimationDelegate,
// Used when changing the animation for a view. This resets the maps for
// the animation used by view and returns the current animation. Ownership
// of the returned animation passes to the caller.
- gfx::Animation* ResetAnimationForView(View* view);
+ std::unique_ptr<gfx::Animation> ResetAnimationForView(View* view);
// Invoked from AnimationEnded and AnimationCanceled.
void AnimationEndedOrCanceled(const gfx::Animation* animation,
diff --git a/chromium/ui/views/animation/bounds_animator_unittest.cc b/chromium/ui/views/animation/bounds_animator_unittest.cc
index 000c0c3efbc..489f72392b1 100644
--- a/chromium/ui/views/animation/bounds_animator_unittest.cc
+++ b/chromium/ui/views/animation/bounds_animator_unittest.cc
@@ -19,22 +19,6 @@ using gfx::TestAnimationDelegate;
namespace views {
namespace {
-class TestBoundsAnimator : public BoundsAnimator {
- public:
- explicit TestBoundsAnimator(View* view) : BoundsAnimator(view) {
- }
-
- protected:
- SlideAnimation* CreateAnimation() override {
- SlideAnimation* animation = BoundsAnimator::CreateAnimation();
- animation->SetSlideDuration(10);
- return animation;
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TestBoundsAnimator);
-};
-
class OwnedDelegate : public gfx::AnimationDelegate {
public:
OwnedDelegate() {}
@@ -98,17 +82,18 @@ class BoundsAnimatorTest : public testing::Test {
child_(new TestView()),
animator_(&parent_) {
parent_.AddChildView(child_);
+ animator_.SetAnimationDuration(10);
}
TestView* parent() { return &parent_; }
TestView* child() { return child_; }
- TestBoundsAnimator* animator() { return &animator_; }
+ BoundsAnimator* animator() { return &animator_; }
private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
TestView parent_;
TestView* child_; // Owned by |parent_|.
- TestBoundsAnimator animator_;
+ BoundsAnimator animator_;
DISALLOW_COPY_AND_ASSIGN(BoundsAnimatorTest);
};
diff --git a/chromium/ui/views/animation/ink_drop.h b/chromium/ui/views/animation/ink_drop.h
index 0664440b4de..3569e01f261 100644
--- a/chromium/ui/views/animation/ink_drop.h
+++ b/chromium/ui/views/animation/ink_drop.h
@@ -36,11 +36,12 @@ class VIEWS_EXPORT InkDrop {
// Animates from the current InkDropState to |ink_drop_state|.
virtual void AnimateToState(InkDropState ink_drop_state) = 0;
- // Immediately snaps the InkDropState to ACTIVATED. This more specific
- // implementation of the non-existent SnapToState(InkDropState) function is
- // the only one available because it was the only InkDropState that clients
- // needed to skip animations for.
+ // Immediately snaps the InkDropState to ACTIVATED and HIDDEN specifically.
+ // These are more specific implementations of the non-existent
+ // SnapToState(InkDropState) function are the only ones available because they
+ // were the only InkDropState that clients needed to skip animations for.
virtual void SnapToActivated() = 0;
+ virtual void SnapToHidden() = 0;
// Enables or disables the hover state.
virtual void SetHovered(bool is_hovered) = 0;
diff --git a/chromium/ui/views/animation/ink_drop_host_view.cc b/chromium/ui/views/animation/ink_drop_host_view.cc
index 31f307b75e4..5a769f05902 100644
--- a/chromium/ui/views/animation/ink_drop_host_view.cc
+++ b/chromium/ui/views/animation/ink_drop_host_view.cc
@@ -221,11 +221,21 @@ void InkDropHostView::AnimateInkDrop(InkDropState state,
GetInkDrop()->AnimateToState(state);
}
+void InkDropHostView::ViewHierarchyChanged(
+ const ViewHierarchyChangedDetails& details) {
+ // If we're being removed hide the ink-drop so if we're highlighted now the
+ // highlight won't be active if we're added back again.
+ if (!details.is_add && details.child == this && ink_drop_) {
+ GetInkDrop()->SnapToHidden();
+ GetInkDrop()->SetHovered(false);
+ }
+ View::ViewHierarchyChanged(details);
+}
+
void InkDropHostView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
if (ink_drop_)
ink_drop_->HostSizeChanged(size());
- if (ink_drop_mask_)
- ink_drop_mask_->UpdateLayerSize(size());
+ UpdateInkDropMaskLayerSize(size());
}
void InkDropHostView::VisibilityChanged(View* starting_from, bool is_visible) {
@@ -300,11 +310,19 @@ void InkDropHostView::ResetInkDropMask() {
ink_drop_mask_.reset();
}
+void InkDropHostView::UpdateInkDropMaskLayerSize(const gfx::Size& new_size) {
+ if (ink_drop_mask_)
+ ink_drop_mask_->UpdateLayerSize(new_size);
+}
+
std::unique_ptr<InkDropImpl> InkDropHostView::CreateDefaultInkDropImpl() {
std::unique_ptr<InkDropImpl> ink_drop =
std::make_unique<InkDropImpl>(this, size());
- ink_drop->SetAutoHighlightMode(
- views::InkDropImpl::AutoHighlightMode::HIDE_ON_RIPPLE);
+ views::InkDropImpl::AutoHighlightMode mode =
+ PlatformStyle::kUseRipples
+ ? views::InkDropImpl::AutoHighlightMode::HIDE_ON_RIPPLE
+ : views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE;
+ ink_drop->SetAutoHighlightMode(mode);
return ink_drop;
}
diff --git a/chromium/ui/views/animation/ink_drop_host_view.h b/chromium/ui/views/animation/ink_drop_host_view.h
index 8ac475fa752..34ea050d06a 100644
--- a/chromium/ui/views/animation/ink_drop_host_view.h
+++ b/chromium/ui/views/animation/ink_drop_host_view.h
@@ -95,6 +95,8 @@ class VIEWS_EXPORT InkDropHostView : public View, public InkDropHost {
gfx::Point GetInkDropCenterBasedOnLastEvent() const;
// View:
+ void ViewHierarchyChanged(
+ const ViewHierarchyChangedDetails& details) override;
void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
void VisibilityChanged(View* starting_from, bool is_visible) override;
void OnFocus() override;
@@ -128,6 +130,10 @@ class VIEWS_EXPORT InkDropHostView : public View, public InkDropHost {
void ResetInkDropMask();
+ // Updates the ink drop mask layer size to |new_size|. It does nothing if
+ // |ink_drop_mask_| is null.
+ void UpdateInkDropMaskLayerSize(const gfx::Size& new_size);
+
// Returns an InkDropImpl configured to work well with a
// flood-fill ink drop ripple.
std::unique_ptr<InkDropImpl> CreateDefaultFloodFillInkDropImpl();
diff --git a/chromium/ui/views/animation/ink_drop_impl.cc b/chromium/ui/views/animation/ink_drop_impl.cc
index 5841c7889fe..f052e387114 100644
--- a/chromium/ui/views/animation/ink_drop_impl.cc
+++ b/chromium/ui/views/animation/ink_drop_impl.cc
@@ -343,7 +343,7 @@ void InkDropImpl::HideHighlightOnRippleHiddenState::AnimationStarted(
// TODO(bruthig): Investigate if the animation framework can address this
// issue instead. See https://crbug.com/663335.
if (GetInkDrop()->ink_drop_ripple_)
- GetInkDrop()->ink_drop_ripple_->HideImmediately();
+ GetInkDrop()->ink_drop_ripple_->SnapToHidden();
GetInkDrop()->SetHighlightState(
state_factory()->CreateVisibleState(base::TimeDelta(), false));
}
@@ -647,6 +647,13 @@ void InkDropImpl::SnapToActivated() {
ink_drop_ripple_->SnapToActivated();
}
+void InkDropImpl::SnapToHidden() {
+ DestroyHiddenTargetedAnimations();
+ if (!ink_drop_ripple_)
+ return;
+ ink_drop_ripple_->SnapToHidden();
+}
+
void InkDropImpl::SetHovered(bool is_hovered) {
is_hovered_ = is_hovered;
highlight_state_->OnHoverChanged();
diff --git a/chromium/ui/views/animation/ink_drop_impl.h b/chromium/ui/views/animation/ink_drop_impl.h
index 47dd80aa23d..98ec237e3f7 100644
--- a/chromium/ui/views/animation/ink_drop_impl.h
+++ b/chromium/ui/views/animation/ink_drop_impl.h
@@ -66,6 +66,7 @@ class VIEWS_EXPORT InkDropImpl : public InkDrop,
InkDropState GetTargetInkDropState() const override;
void AnimateToState(InkDropState ink_drop_state) override;
void SnapToActivated() override;
+ void SnapToHidden() override;
void SetHovered(bool is_hovered) override;
void SetFocused(bool is_focused) override;
bool IsHighlightFadingInOrVisible() const override;
diff --git a/chromium/ui/views/animation/ink_drop_mask.cc b/chromium/ui/views/animation/ink_drop_mask.cc
index 05bd983cf1a..a2d2adb366e 100644
--- a/chromium/ui/views/animation/ink_drop_mask.cc
+++ b/chromium/ui/views/animation/ink_drop_mask.cc
@@ -35,7 +35,7 @@ void InkDropMask::OnDeviceScaleFactorChanged(float old_device_scale_factor,
RoundRectInkDropMask::RoundRectInkDropMask(const gfx::Size& layer_size,
const gfx::InsetsF& mask_insets,
- int corner_radius)
+ float corner_radius)
: InkDropMask(layer_size),
mask_insets_(mask_insets),
corner_radius_(corner_radius) {}
@@ -52,10 +52,8 @@ void RoundRectInkDropMask::OnPaintLayer(const ui::PaintContext& context) {
gfx::RectF masking_bound(layer()->bounds());
masking_bound.Inset(mask_insets_);
- const gfx::Rect masking_bound_scaled =
- gfx::ScaleToRoundedRect(gfx::ToNearestRect(masking_bound), dsf);
- recorder.canvas()->DrawRoundRect(masking_bound_scaled, corner_radius_ * dsf,
- flags);
+ recorder.canvas()->DrawRoundRect(gfx::ScaleRect(masking_bound, dsf),
+ corner_radius_ * dsf, flags);
}
// CircleInkDropMask
diff --git a/chromium/ui/views/animation/ink_drop_mask.h b/chromium/ui/views/animation/ink_drop_mask.h
index 8899e5bf389..debfb1604e2 100644
--- a/chromium/ui/views/animation/ink_drop_mask.h
+++ b/chromium/ui/views/animation/ink_drop_mask.h
@@ -47,14 +47,14 @@ class VIEWS_EXPORT RoundRectInkDropMask : public InkDropMask {
public:
RoundRectInkDropMask(const gfx::Size& layer_size,
const gfx::InsetsF& mask_insets,
- int corner_radius);
+ float corner_radius);
private:
// Overriden from InkDropMask:
void OnPaintLayer(const ui::PaintContext& context) override;
gfx::InsetsF mask_insets_;
- int corner_radius_;
+ float corner_radius_;
DISALLOW_COPY_AND_ASSIGN(RoundRectInkDropMask);
};
diff --git a/chromium/ui/views/animation/ink_drop_ripple.cc b/chromium/ui/views/animation/ink_drop_ripple.cc
index f6360a80947..ea16770dd00 100644
--- a/chromium/ui/views/animation/ink_drop_ripple.cc
+++ b/chromium/ui/views/animation/ink_drop_ripple.cc
@@ -91,7 +91,7 @@ bool InkDropRipple::IsVisible() {
return GetRootLayer()->visible();
}
-void InkDropRipple::HideImmediately() {
+void InkDropRipple::SnapToHidden() {
AbortAllAnimations();
SetStateToHidden();
target_ink_drop_state_ = InkDropState::HIDDEN;
diff --git a/chromium/ui/views/animation/ink_drop_ripple.h b/chromium/ui/views/animation/ink_drop_ripple.h
index 6f05f7f6c0a..645abff0204 100644
--- a/chromium/ui/views/animation/ink_drop_ripple.h
+++ b/chromium/ui/views/animation/ink_drop_ripple.h
@@ -70,7 +70,7 @@ class VIEWS_EXPORT InkDropRipple {
//
// NOTE: This will NOT raise Animation(Started|Ended) events for the state
// transition to HIDDEN!
- void HideImmediately();
+ void SnapToHidden();
// Immediately snaps the ink drop to the ACTIVATED target state. All pending
// animations are aborted. Events will be raised for the pending animations
diff --git a/chromium/ui/views/animation/ink_drop_ripple_unittest.cc b/chromium/ui/views/animation/ink_drop_ripple_unittest.cc
index 2bb50772568..0184bc4c84b 100644
--- a/chromium/ui/views/animation/ink_drop_ripple_unittest.cc
+++ b/chromium/ui/views/animation/ink_drop_ripple_unittest.cc
@@ -250,7 +250,7 @@ TEST_P(InkDropRippleTest, InkDropStatesPersistWhenCallingAnimateToState) {
ink_drop_ripple_->target_ink_drop_state());
}
-TEST_P(InkDropRippleTest, HideImmediatelyWithoutActiveAnimations) {
+TEST_P(InkDropRippleTest, SnapToHiddenWithoutActiveAnimations) {
ink_drop_ripple_->AnimateToState(views::InkDropState::ACTION_PENDING);
test_api_->CompleteAnimations();
EXPECT_EQ(1, observer_.last_animation_started_ordinal());
@@ -259,7 +259,7 @@ TEST_P(InkDropRippleTest, HideImmediatelyWithoutActiveAnimations) {
EXPECT_FALSE(test_api_->HasActiveAnimations());
EXPECT_NE(InkDropState::HIDDEN, ink_drop_ripple_->target_ink_drop_state());
- ink_drop_ripple_->HideImmediately();
+ ink_drop_ripple_->SnapToHidden();
EXPECT_FALSE(test_api_->HasActiveAnimations());
EXPECT_EQ(views::InkDropState::HIDDEN,
@@ -272,8 +272,8 @@ TEST_P(InkDropRippleTest, HideImmediatelyWithoutActiveAnimations) {
}
// Verifies all active animations are aborted and the InkDropState is set to
-// HIDDEN after invoking HideImmediately().
-TEST_P(InkDropRippleTest, HideImmediatelyWithActiveAnimations) {
+// HIDDEN after invoking SnapToHidden().
+TEST_P(InkDropRippleTest, SnapToHiddenWithActiveAnimations) {
// TODO(bruthig): Re-enable! For some reason these tests fail on some win
// trunk builds. See crbug.com/731811.
if (!gfx::Animation::ShouldRenderRichAnimation())
@@ -284,7 +284,7 @@ TEST_P(InkDropRippleTest, HideImmediatelyWithActiveAnimations) {
EXPECT_NE(InkDropState::HIDDEN, ink_drop_ripple_->target_ink_drop_state());
EXPECT_EQ(1, observer_.last_animation_started_ordinal());
- ink_drop_ripple_->HideImmediately();
+ ink_drop_ripple_->SnapToHidden();
EXPECT_FALSE(test_api_->HasActiveAnimations());
EXPECT_EQ(views::InkDropState::HIDDEN,
diff --git a/chromium/ui/views/animation/ink_drop_stub.cc b/chromium/ui/views/animation/ink_drop_stub.cc
index 2883d89db82..9a8237b3c11 100644
--- a/chromium/ui/views/animation/ink_drop_stub.cc
+++ b/chromium/ui/views/animation/ink_drop_stub.cc
@@ -20,6 +20,8 @@ void InkDropStub::AnimateToState(InkDropState state) {}
void InkDropStub::SnapToActivated() {}
+void InkDropStub::SnapToHidden() {}
+
void InkDropStub::SetHovered(bool is_hovered) {}
void InkDropStub::SetFocused(bool is_hovered) {}
diff --git a/chromium/ui/views/animation/ink_drop_stub.h b/chromium/ui/views/animation/ink_drop_stub.h
index f9f6e728b56..86ed8829824 100644
--- a/chromium/ui/views/animation/ink_drop_stub.h
+++ b/chromium/ui/views/animation/ink_drop_stub.h
@@ -23,6 +23,7 @@ class VIEWS_EXPORT InkDropStub : public InkDrop {
InkDropState GetTargetInkDropState() const override;
void AnimateToState(InkDropState state) override;
void SnapToActivated() override;
+ void SnapToHidden() override;
void SetHovered(bool is_hovered) override;
void SetFocused(bool is_hovered) override;
bool IsHighlightFadingInOrVisible() const override;
diff --git a/chromium/ui/views/bubble/bubble_border.cc b/chromium/ui/views/bubble/bubble_border.cc
index 797fb98889c..e2292a8f620 100644
--- a/chromium/ui/views/bubble/bubble_border.cc
+++ b/chromium/ui/views/bubble/bubble_border.cc
@@ -8,12 +8,12 @@
#include <vector>
#include "base/logging.h"
+#include "base/no_destructor.h"
#include "cc/paint/paint_flags.h"
#include "third_party/skia/include/core/SkDrawLooper.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h"
-#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/path.h"
#include "ui/gfx/scoped_canvas.h"
@@ -65,17 +65,6 @@ namespace {
// The border is stroked at 1px, but for the purposes of reserving space we have
// to deal in dip coordinates, so round up to 1dip.
const int kBorderThicknessDip = 1;
-const int kBorderStrokeThicknessPx = 1;
-
-// Blur and offset values for the two shadows drawn around each dialog. The
-// values are all in dip.
-const int kSmallShadowVerticalOffset = 2;
-const int kSmallShadowBlur = 4;
-const SkColor kSmallShadowColor = SkColorSetA(SK_ColorBLACK, 0x33);
-
-const int kLargeShadowVerticalOffset = 2;
-const int kLargeShadowBlur = 6;
-const SkColor kLargeShadowColor = SkColorSetA(SK_ColorBLACK, 0x1A);
bool UseMaterialDesign() {
return ui::MaterialDesignController::IsSecondaryUiMaterial();
@@ -199,6 +188,14 @@ BubbleBorder::BubbleBorder(Arrow arrow, Shadow shadow, SkColor color)
BubbleBorder::~BubbleBorder() {}
+// static
+gfx::Insets BubbleBorder::GetBorderAndShadowInsets() {
+ constexpr gfx::Insets blur(kShadowBlur + kBorderThicknessDip);
+ constexpr gfx::Insets offset(-kShadowVerticalOffset, 0, kShadowVerticalOffset,
+ 0);
+ return blur + offset;
+}
+
void BubbleBorder::set_paint_arrow(ArrowPaintType value) {
if (UseMaterialDesign())
return;
@@ -368,15 +365,8 @@ void BubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) {
}
gfx::Insets BubbleBorder::GetInsets() const {
- if (UseMaterialDesign()) {
- if (shadow_ == NO_ASSETS)
- return gfx::Insets();
-
- gfx::Insets blur(kLargeShadowBlur);
- gfx::Insets offset(-kLargeShadowVerticalOffset, 0,
- kLargeShadowVerticalOffset, 0);
- return blur + offset;
- }
+ if (UseMaterialDesign())
+ return (shadow_ == NO_ASSETS) ? gfx::Insets() : GetBorderAndShadowInsets();
// The insets contain the stroke and shadow pixels outside the bubble fill.
const int inset = GetBorderThickness();
@@ -397,6 +387,33 @@ gfx::Size BubbleBorder::GetMinimumSize() const {
return GetSizeForContentsSize(gfx::Size());
}
+// static
+const cc::PaintFlags& BubbleBorder::GetBorderAndShadowFlags() {
+ // This object is always the same, so construct it once and cache.
+ static const base::NoDestructor<cc::PaintFlags> flags([] {
+ cc::PaintFlags f;
+ constexpr SkColor kBorderColor = SkColorSetA(SK_ColorBLACK, 0x26);
+ f.setColor(kBorderColor);
+ f.setAntiAlias(true);
+
+ constexpr int kSmallShadowVerticalOffset = 2;
+ constexpr int kSmallShadowBlur = 4;
+ constexpr SkColor kSmallShadowColor = SkColorSetA(SK_ColorBLACK, 0x33);
+ constexpr SkColor kLargeShadowColor = SkColorSetA(SK_ColorBLACK, 0x1A);
+ // gfx::ShadowValue counts blur pixels both inside and outside the shape,
+ // whereas these blur values only describe the outside portion, hence they
+ // must be doubled.
+ f.setLooper(gfx::CreateShadowDrawLooper({
+ {gfx::Vector2d(0, kSmallShadowVerticalOffset), 2 * kSmallShadowBlur,
+ kSmallShadowColor},
+ {gfx::Vector2d(0, kShadowVerticalOffset), 2 * kShadowBlur,
+ kLargeShadowColor},
+ }));
+ return f;
+ }());
+ return *flags;
+}
+
gfx::Size BubbleBorder::GetSizeForContentsSize(
const gfx::Size& contents_size) const {
// Enlarge the contents size by the thickness of the border images.
@@ -526,28 +543,11 @@ void BubbleBorder::PaintMd(const View& view, gfx::Canvas* canvas) {
gfx::ScopedCanvas scoped(canvas);
- cc::PaintFlags flags;
- std::vector<gfx::ShadowValue> shadows;
- // gfx::ShadowValue counts blur pixels both inside and outside the shape,
- // whereas these blur values only describe the outside portion, hence they
- // must be doubled.
- shadows.emplace_back(gfx::Vector2d(0, kSmallShadowVerticalOffset),
- 2 * kSmallShadowBlur, kSmallShadowColor);
- shadows.emplace_back(gfx::Vector2d(0, kLargeShadowVerticalOffset),
- 2 * kLargeShadowBlur, kLargeShadowColor);
- flags.setLooper(gfx::CreateShadowDrawLooper(shadows));
- flags.setColor(SkColorSetA(SK_ColorBLACK, 0x26));
- flags.setAntiAlias(true);
-
SkRRect r_rect = GetClientRect(view);
canvas->sk_canvas()->clipRRect(r_rect, SkClipOp::kDifference,
true /*doAntiAlias*/);
- // The border is drawn outside the content area.
- const SkScalar one_pixel =
- SkFloatToScalar(kBorderStrokeThicknessPx / canvas->image_scale());
- r_rect.inset(-one_pixel, -one_pixel);
- canvas->sk_canvas()->drawRRect(r_rect, flags);
+ DrawBorderAndShadow(std::move(r_rect), &cc::PaintCanvas::drawRRect, canvas);
}
void BubbleBorder::PaintNoAssets(const View& view, gfx::Canvas* canvas) {
diff --git a/chromium/ui/views/bubble/bubble_border.h b/chromium/ui/views/bubble/bubble_border.h
index fdf0c3604b8..46531ed02f6 100644
--- a/chromium/ui/views/bubble/bubble_border.h
+++ b/chromium/ui/views/bubble/bubble_border.h
@@ -11,6 +11,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "build/build_config.h"
+#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/views/background.h"
#include "ui/views/border.h"
@@ -135,6 +136,11 @@ class VIEWS_EXPORT BubbleBorder : public Border {
PAINT_NONE,
};
+ // Specific to MD bubbles: size of shadow blur (outside the bubble) and
+ // vertical offset, both in DIP.
+ static constexpr int kShadowBlur = 6;
+ static constexpr int kShadowVerticalOffset = 2;
+
BubbleBorder(Arrow arrow, Shadow shadow, SkColor color);
~BubbleBorder() override;
@@ -166,6 +172,26 @@ class VIEWS_EXPORT BubbleBorder : public Border {
a : static_cast<Arrow>(a ^ BOTTOM);
}
+ // Returns the insets required by a border and shadow. This is only used for
+ // MD bubbles.
+ static gfx::Insets GetBorderAndShadowInsets();
+
+ // Draws a border and shadow outside the |rect| on |canvas|, using |draw| as
+ // the draw function. Templated so as to accept either SkRect or SkRRect.
+ template <typename T>
+ static void DrawBorderAndShadow(
+ T rect,
+ void (cc::PaintCanvas::*draw)(const T&, const cc::PaintFlags&),
+ gfx::Canvas* canvas) {
+ // Provide a 1 px border outside the bounds.
+ const int kBorderStrokeThicknessPx = 1;
+ const SkScalar one_pixel =
+ SkFloatToScalar(kBorderStrokeThicknessPx / canvas->image_scale());
+ rect.outset(one_pixel, one_pixel);
+
+ (canvas->sk_canvas()->*draw)(rect, GetBorderAndShadowFlags());
+ }
+
// Get or set the arrow type.
void set_arrow(Arrow arrow) { arrow_ = arrow; }
Arrow arrow() const { return arrow_; }
@@ -233,6 +259,10 @@ class VIEWS_EXPORT BubbleBorder : public Border {
FRIEND_TEST_ALL_PREFIXES(BubbleBorderTest, GetBoundsOriginTest);
FRIEND_TEST_ALL_PREFIXES(BubbleBorderTest, ShadowTypes);
+ // Returns the paint flags to use for painting the border and shadow. This is
+ // only used for MD bubbles.
+ static const cc::PaintFlags& GetBorderAndShadowFlags();
+
// The border and arrow stroke size used in image assets, in pixels.
static const int kStroke;
diff --git a/chromium/ui/views/bubble/bubble_dialog_delegate.cc b/chromium/ui/views/bubble/bubble_dialog_delegate.cc
index aa98ca418f7..9f766e72100 100644
--- a/chromium/ui/views/bubble/bubble_dialog_delegate.cc
+++ b/chromium/ui/views/bubble/bubble_dialog_delegate.cc
@@ -320,13 +320,14 @@ void BubbleDialogDelegateView::HandleVisibilityChanged(Widget* widget,
anchor_widget()->GetTopLevelWidget()->SetAlwaysRenderAsActive(visible);
}
- // Fire AX_EVENT_ALERT for bubbles marked as AX_ROLE_ALERT_DIALOG; this
- // instructs accessibility tools to read the bubble in its entirety rather
- // than just its title and initially focused view. See
- // http://crbug.com/474622 for details.
+ // Fire ax::mojom::Event::kAlert for bubbles marked as
+ // ax::mojom::Role::kAlertDialog; this instructs accessibility tools to read
+ // the bubble in its entirety rather than just its title and initially focused
+ // view. See http://crbug.com/474622 for details.
if (widget == GetWidget() && visible) {
- if (GetAccessibleWindowRole() == ui::AX_ROLE_ALERT_DIALOG)
- widget->GetRootView()->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
+ if (GetAccessibleWindowRole() == ax::mojom::Role::kAlertDialog)
+ widget->GetRootView()->NotifyAccessibilityEvent(ax::mojom::Event::kAlert,
+ true);
}
}
diff --git a/chromium/ui/views/bubble/tooltip_icon.cc b/chromium/ui/views/bubble/tooltip_icon.cc
index b3a5ca6e8f7..de30b6dcc62 100644
--- a/chromium/ui/views/bubble/tooltip_icon.cc
+++ b/chromium/ui/views/bubble/tooltip_icon.cc
@@ -55,7 +55,7 @@ void TooltipIcon::OnGestureEvent(ui::GestureEvent* event) {
}
void TooltipIcon::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_TOOLTIP;
+ node_data->role = ax::mojom::Role::kTooltip;
node_data->SetName(tooltip_);
}
diff --git a/chromium/ui/views/bubble/tray_bubble_view.cc b/chromium/ui/views/bubble/tray_bubble_view.cc
index 392cbd14a30..fe4ba9727f6 100644
--- a/chromium/ui/views/bubble/tray_bubble_view.cc
+++ b/chromium/ui/views/bubble/tray_bubble_view.cc
@@ -322,7 +322,7 @@ void TrayBubbleView::OnBeforeBubbleWidgetInit(Widget::InitParams* params,
Widget* bubble_widget) const {
// Apply a WM-provided shadow (see ui/wm/core/).
params->shadow_type = Widget::InitParams::SHADOW_TYPE_DROP;
- params->shadow_elevation = wm::ShadowElevation::LARGE;
+ params->shadow_elevation = wm::kShadowElevationActiveWindow;
}
void TrayBubbleView::OnWidgetClosing(Widget* widget) {
@@ -332,7 +332,8 @@ void TrayBubbleView::OnWidgetClosing(Widget* widget) {
BubbleDialogDelegateView::OnWidgetClosing(widget);
--g_current_tray_bubble_showing_count_;
- DCHECK_GE(g_current_tray_bubble_showing_count_, 0);
+ DCHECK_GE(g_current_tray_bubble_showing_count_, 0)
+ << "Closing " << widget->GetName();
}
void TrayBubbleView::OnWidgetActivationChanged(Widget* widget, bool active) {
@@ -360,7 +361,10 @@ void TrayBubbleView::GetWidgetHitTestMask(gfx::Path* mask) const {
}
base::string16 TrayBubbleView::GetAccessibleWindowTitle() const {
- return delegate_->GetAccessibleNameForBubble();
+ if (delegate_)
+ return delegate_->GetAccessibleNameForBubble();
+ else
+ return base::string16();
}
gfx::Size TrayBubbleView::CalculatePreferredSize() const {
@@ -421,7 +425,7 @@ void TrayBubbleView::OnMouseExited(const ui::MouseEvent& event) {
void TrayBubbleView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
if (delegate_ && CanActivate()) {
- node_data->role = ui::AX_ROLE_WINDOW;
+ node_data->role = ax::mojom::Role::kWindow;
node_data->SetName(delegate_->GetAccessibleNameForBubble());
}
}
@@ -438,7 +442,8 @@ void TrayBubbleView::MouseMovedOutOfHost() {
// The mouse was accidentally over the bubble when it opened and the AutoClose
// logic was not activated. Now that the user did move the mouse we tell the
// delegate to disable AutoClose.
- delegate_->OnMouseEnteredView();
+ if (delegate_)
+ delegate_->OnMouseEnteredView();
mouse_actively_entered_ = true;
mouse_watcher_->Stop();
}
diff --git a/chromium/ui/views/cocoa/bridged_native_widget.h b/chromium/ui/views/cocoa/bridged_native_widget.h
index 67a0d56ee63..64be7882515 100644
--- a/chromium/ui/views/cocoa/bridged_native_widget.h
+++ b/chromium/ui/views/cocoa/bridged_native_widget.h
@@ -12,6 +12,7 @@
#import "base/mac/scoped_nsobject.h"
#include "base/macros.h"
+#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
#import "ui/accelerated_widget_mac/accelerated_widget_mac.h"
#include "ui/base/ime/input_method_delegate.h"
#include "ui/compositor/layer_owner.h"
@@ -138,7 +139,7 @@ class VIEWS_EXPORT BridgedNativeWidget
// Transition the window into or out of fullscreen. This will immediately
// invert the value of target_fullscreen_state().
- void ToggleDesiredFullscreenState();
+ void ToggleDesiredFullscreenState(bool async = false);
// Called by the NSWindowDelegate when the size of the window changes.
void OnSizeChanged();
@@ -324,6 +325,7 @@ class VIEWS_EXPORT BridgedNativeWidget
base::scoped_nsobject<NSView> compositor_superview_;
std::unique_ptr<ui::AcceleratedWidgetMac> compositor_widget_;
std::unique_ptr<ui::Compositor> compositor_;
+ viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_;
// Tracks the bounds when the window last started entering fullscreen. Used to
// provide an answer for GetRestoredBounds(), but not ever sent to Cocoa (it
diff --git a/chromium/ui/views/cocoa/bridged_native_widget.mm b/chromium/ui/views/cocoa/bridged_native_widget.mm
index 7c5c25f2ce0..3c6e9903d7d 100644
--- a/chromium/ui/views/cocoa/bridged_native_widget.mm
+++ b/chromium/ui/views/cocoa/bridged_native_widget.mm
@@ -836,21 +836,15 @@ void BridgedNativeWidget::OnFullscreenTransitionComplete(
return;
}
+ // The transition completed, but into the wrong state. This can happen when
+ // there are calls to change the fullscreen state whilst mid-transition.
// First update to reflect reality so that OnTargetFullscreenStateChanged()
// expects the change.
target_fullscreen_state_ = actual_fullscreen_state;
- ToggleDesiredFullscreenState();
-
- // Usually ToggleDesiredFullscreenState() sets |in_fullscreen_transition_| via
- // OnFullscreenTransitionStart(). When it does not, it means Cocoa ignored the
- // toggleFullScreen: request. This can occur when the fullscreen transition
- // fails and Cocoa is *about* to send windowDidFailToEnterFullScreen:.
- // Annoyingly, for this case, Cocoa first sends windowDidExitFullScreen:.
- if (in_fullscreen_transition_)
- DCHECK_NE(target_fullscreen_state_, actual_fullscreen_state);
+ ToggleDesiredFullscreenState(true /* async */);
}
-void BridgedNativeWidget::ToggleDesiredFullscreenState() {
+void BridgedNativeWidget::ToggleDesiredFullscreenState(bool async) {
// If there is currently an animation into or out of fullscreen, then AppKit
// emits the string "not in fullscreen state" to stdio and does nothing. For
// this case, schedule a transition back into the desired state when the
@@ -878,7 +872,18 @@ void BridgedNativeWidget::ToggleDesiredFullscreenState() {
// This will be reset when a transition out of fullscreen completes.
gfx::SetNSWindowCanFullscreen(window_, true);
- [window_ toggleFullScreen:nil];
+ // Until 10.13, AppKit would obey a call to -toggleFullScreen: made inside
+ // OnFullscreenTransitionComplete(). Starting in 10.13, it behaves as though
+ // the transition is still in progress and just emits "not in a fullscreen
+ // state" when trying to exit fullscreen in the same runloop that entered it.
+ // To handle this case, invoke -toggleFullScreen: asynchronously.
+ if (async) {
+ [window_ performSelector:@selector(toggleFullScreen:)
+ withObject:nil
+ afterDelay:0];
+ } else {
+ [window_ toggleFullScreen:nil];
+ }
}
void BridgedNativeWidget::OnSizeChanged() {
@@ -1414,11 +1419,9 @@ void BridgedNativeWidget::InitCompositor() {
DCHECK(layer());
float scale_factor = GetDeviceScaleFactorFromView(compositor_superview_);
gfx::Size size_in_dip = GetClientAreaSize();
- // TODO(fsamuel): A valid viz::LocalSurfaceId() likely needs to be plumbed
- // here to properly enable surface synchronization.
compositor_->SetScaleAndSize(scale_factor,
ConvertSizeToPixel(scale_factor, size_in_dip),
- viz::LocalSurfaceId());
+ parent_local_surface_id_allocator_.GenerateId());
compositor_->SetRootLayer(layer());
}
@@ -1491,15 +1494,18 @@ void BridgedNativeWidget::AddCompositorSuperview() {
void BridgedNativeWidget::UpdateLayerProperties() {
DCHECK(layer());
DCHECK(compositor_superview_);
+ float scale_factor = GetDeviceScaleFactorFromView(compositor_superview_);
gfx::Size size_in_dip = GetClientAreaSize();
+ gfx::Size size_in_pixel = ConvertSizeToPixel(scale_factor, size_in_dip);
+
layer()->SetBounds(gfx::Rect(size_in_dip));
- float scale_factor = GetDeviceScaleFactorFromView(compositor_superview_);
- // TODO(fsamuel): A valid viz::LocalSurfaceId() likely needs to be plumbed
- // here to properly enable surface synchronization.
- compositor_->SetScaleAndSize(scale_factor,
- ConvertSizeToPixel(scale_factor, size_in_dip),
- viz::LocalSurfaceId());
+ if (compositor_->size() != size_in_pixel ||
+ compositor_->device_scale_factor() != scale_factor) {
+ compositor_->SetScaleAndSize(
+ scale_factor, size_in_pixel,
+ parent_local_surface_id_allocator_.GenerateId());
+ }
// For a translucent window, the shadow calculation needs to be carried out
// after the frame from the compositor arrives.
diff --git a/chromium/ui/views/cocoa/bridged_native_widget_unittest.mm b/chromium/ui/views/cocoa/bridged_native_widget_unittest.mm
index 4a7157d0bd6..282a17b231e 100644
--- a/chromium/ui/views/cocoa/bridged_native_widget_unittest.mm
+++ b/chromium/ui/views/cocoa/bridged_native_widget_unittest.mm
@@ -214,6 +214,18 @@ bool IsRTLSelectBuggy(SEL sel) {
@synthesize ignoredToggleFullScreenCount = ignoredToggleFullScreenCount_;
+- (void)performSelector:(SEL)aSelector
+ withObject:(id)anArgument
+ afterDelay:(NSTimeInterval)delay {
+ // This is used in simulations without a message loop. Don't start a message
+ // loop since that would expose the tests to system notifications and
+ // potential flakes. Instead, just pretend the message loop is flushed here.
+ if (aSelector == @selector(toggleFullScreen:))
+ [self toggleFullScreen:anArgument];
+ else
+ [super performSelector:aSelector withObject:anArgument afterDelay:delay];
+}
+
- (void)toggleFullScreen:(id)sender {
++ignoredToggleFullScreenCount_;
}
diff --git a/chromium/ui/views/controls/button/button.cc b/chromium/ui/views/controls/button/button.cc
index e8b9a13207d..77c453f79d0 100644
--- a/chromium/ui/views/controls/button/button.cc
+++ b/chromium/ui/views/controls/button/button.cc
@@ -6,8 +6,6 @@
#include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/ax_node_data.h"
-
-#include "ui/accessibility/ax_node_data.h"
#include "ui/base/class_property.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
@@ -97,7 +95,7 @@ void Button::SetTooltipText(const base::string16& tooltip_text) {
void Button::SetAccessibleName(const base::string16& name) {
accessible_name_ = name;
- NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kTextChanged, true);
}
void Button::SetState(ButtonState state) {
@@ -152,7 +150,7 @@ void Button::SetHotTracked(bool is_hot_tracked) {
SetState(is_hot_tracked ? STATE_HOVERED : STATE_NORMAL);
if (is_hot_tracked)
- NotifyAccessibilityEvent(ui::AX_EVENT_HOVER, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kHover, true);
}
bool Button::IsHotTracked() const {
@@ -385,34 +383,28 @@ void Button::OnPaint(gfx::Canvas* canvas) {
}
void Button::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_BUTTON;
+ node_data->role = ax::mojom::Role::kButton;
node_data->SetName(accessible_name_);
- if (!enabled()) {
- node_data->AddIntAttribute(ui::AX_ATTR_RESTRICTION,
- ui::AX_RESTRICTION_DISABLED);
- }
+ if (!enabled())
+ node_data->SetRestriction(ax::mojom::Restriction::kDisabled);
switch (state_) {
case STATE_HOVERED:
- node_data->AddState(ui::AX_STATE_HOVERED);
+ node_data->AddState(ax::mojom::State::kHovered);
break;
case STATE_PRESSED:
- node_data->AddIntAttribute(ui::AX_ATTR_CHECKED_STATE,
- ui::AX_CHECKED_STATE_TRUE);
+ node_data->SetCheckedState(ax::mojom::CheckedState::kTrue);
break;
case STATE_DISABLED:
- node_data->AddIntAttribute(ui::AX_ATTR_RESTRICTION,
- ui::AX_RESTRICTION_DISABLED);
+ node_data->SetRestriction(ax::mojom::Restriction::kDisabled);
break;
case STATE_NORMAL:
case STATE_COUNT:
// No additional accessibility node_data set for this button node_data.
break;
}
- if (enabled()) {
- node_data->AddIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB,
- ui::AX_DEFAULT_ACTION_VERB_PRESS);
- }
+ if (enabled())
+ node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kPress);
}
void Button::VisibilityChanged(View* starting_from, bool visible) {
@@ -425,6 +417,7 @@ void Button::VisibilityChanged(View* starting_from, bool visible) {
void Button::ViewHierarchyChanged(const ViewHierarchyChangedDetails& details) {
if (!details.is_add && state_ != STATE_DISABLED && details.child == this)
SetState(STATE_NORMAL);
+ InkDropHostView::ViewHierarchyChanged(details);
}
void Button::OnFocus() {
diff --git a/chromium/ui/views/controls/button/button_unittest.cc b/chromium/ui/views/controls/button/button_unittest.cc
index 20f610f96a6..067653b4945 100644
--- a/chromium/ui/views/controls/button/button_unittest.cc
+++ b/chromium/ui/views/controls/button/button_unittest.cc
@@ -510,6 +510,58 @@ TEST_F(ButtonTest, InkDropAfterTryingToShowContextMenu) {
EXPECT_EQ(InkDropState::ACTION_PENDING, ink_drop->GetTargetInkDropState());
}
+TEST_F(ButtonTest, HideInkDropHighlightWhenRemoved) {
+ views::View test_container;
+ test_container.set_owned_by_client();
+ TestInkDrop* ink_drop = new TestInkDrop();
+ CreateButtonWithInkDrop(base::WrapUnique(ink_drop), false);
+ // Mark the button as owned by client so we can remove it from widget()
+ // without it being deleted.
+ button()->set_owned_by_client();
+
+ // Make sure that the button ink drop is hidden after the button gets removed.
+ widget()->SetContentsView(&test_container);
+ test_container.AddChildView(button());
+ ui::test::EventGenerator generator(widget()->GetNativeWindow());
+ generator.MoveMouseToInHost(2, 2);
+ EXPECT_TRUE(ink_drop->is_hovered());
+ // Set ink-drop state to ACTIVATED to make sure that removing the container
+ // sets it back to HIDDEN.
+ ink_drop->AnimateToState(InkDropState::ACTIVATED);
+ test_container.RemoveAllChildViews(false);
+ EXPECT_FALSE(ink_drop->is_hovered());
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop->GetTargetInkDropState());
+
+ // Make sure hiding the ink drop happens even if the button is indirectly
+ // being removed.
+ views::View parent_test_container;
+ parent_test_container.set_owned_by_client();
+ parent_test_container.AddChildView(&test_container);
+ test_container.AddChildView(button());
+ widget()->SetContentsView(&parent_test_container);
+
+ // Trigger hovering and then remove from the indirect parent. This should
+ // propagate down to Button which should remove the highlight effect.
+ EXPECT_FALSE(ink_drop->is_hovered());
+ generator.MoveMouseToInHost(10, 10);
+ EXPECT_TRUE(ink_drop->is_hovered());
+ // Set ink-drop state to ACTIVATED to make sure that removing the container
+ // sets it back to HIDDEN.
+ ink_drop->AnimateToState(InkDropState::ACTIVATED);
+ parent_test_container.RemoveAllChildViews(false);
+ EXPECT_EQ(InkDropState::HIDDEN, ink_drop->GetTargetInkDropState());
+ EXPECT_FALSE(ink_drop->is_hovered());
+
+ // Remove references to and delete button() which cannot be removed by owned
+ // containers as it's permanently set as owned by client.
+ test_container.RemoveAllChildViews(false);
+ delete button();
+
+ // Set the widget contents view to a new View so widget() doesn't contain a
+ // stale reference to the test containers that are about to go out of scope.
+ widget()->SetContentsView(new View());
+}
+
// Tests that when button is set to notify on release, dragging mouse out and
// back transitions ink drop states correctly.
TEST_F(ButtonTest, InkDropShowHideOnMouseDraggedNotifyOnRelease) {
diff --git a/chromium/ui/views/controls/button/checkbox.cc b/chromium/ui/views/controls/button/checkbox.cc
index 968aaf469eb..8468460448f 100644
--- a/chromium/ui/views/controls/button/checkbox.cc
+++ b/chromium/ui/views/controls/button/checkbox.cc
@@ -12,6 +12,7 @@
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
+#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/native_theme/native_theme.h"
@@ -163,17 +164,16 @@ const char* Checkbox::GetClassName() const {
void Checkbox::GetAccessibleNodeData(ui::AXNodeData* node_data) {
LabelButton::GetAccessibleNodeData(node_data);
- node_data->role = ui::AX_ROLE_CHECK_BOX;
- const ui::AXCheckedState checked_state =
- checked() ? ui::AX_CHECKED_STATE_TRUE : ui::AX_CHECKED_STATE_FALSE;
- node_data->AddIntAttribute(ui::AX_ATTR_CHECKED_STATE, checked_state);
+ node_data->role = ax::mojom::Role::kCheckBox;
+ const ax::mojom::CheckedState checked_state =
+ checked() ? ax::mojom::CheckedState::kTrue
+ : ax::mojom::CheckedState::kFalse;
+ node_data->SetCheckedState(checked_state);
if (enabled()) {
if (checked()) {
- node_data->AddIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB,
- ui::AX_DEFAULT_ACTION_VERB_UNCHECK);
+ node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kUncheck);
} else {
- node_data->AddIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB,
- ui::AX_DEFAULT_ACTION_VERB_CHECK);
+ node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kCheck);
}
}
}
@@ -216,14 +216,16 @@ std::unique_ptr<InkDropRipple> Checkbox::CreateInkDropRipple() const {
SkColor Checkbox::GetInkDropBaseColor() const {
// Usually ink drop ripples match the text color. Checkboxes use the color of
- // the unchecked icon.
- return GetIconImageColor(false);
+ // the unchecked, enabled icon.
+ return GetIconImageColor(IconState::ENABLED);
}
gfx::ImageSkia Checkbox::GetImage(ButtonState for_state) const {
if (UseMd()) {
+ const int checked = checked_ ? IconState::CHECKED : 0;
+ const int enabled = for_state != STATE_DISABLED ? IconState::ENABLED : 0;
return gfx::CreateVectorIcon(GetVectorIcon(), 16,
- GetIconImageColor(checked_));
+ GetIconImageColor(checked | enabled));
}
const size_t checked_index = checked_ ? 1 : 0;
@@ -264,14 +266,19 @@ const gfx::VectorIcon& Checkbox::GetVectorIcon() const {
return checked() ? kCheckboxActiveIcon : kCheckboxNormalIcon;
}
-SkColor Checkbox::GetIconImageColor(bool checked) const {
+SkColor Checkbox::GetIconImageColor(int icon_state) const {
DCHECK(UseMd());
- return checked
- ? GetNativeTheme()->GetSystemColor(
- ui::NativeTheme::kColorId_FocusedBorderColor)
- // When unchecked, the icon color matches push button text color.
- : style::GetColor(*this, style::CONTEXT_BUTTON_MD,
- style::STYLE_PRIMARY);
+ const SkColor active_color =
+ (icon_state & IconState::CHECKED)
+ ? GetNativeTheme()->GetSystemColor(
+ ui::NativeTheme::kColorId_FocusedBorderColor)
+ // When unchecked, the icon color matches push button text color.
+ : style::GetColor(*this, style::CONTEXT_BUTTON_MD,
+ style::STYLE_PRIMARY);
+ return (icon_state & IconState::ENABLED)
+ ? active_color
+ : color_utils::BlendTowardOppositeLuma(active_color,
+ gfx::kDisabledControlAlpha);
}
void Checkbox::NotifyClick(const ui::Event& event) {
diff --git a/chromium/ui/views/controls/button/checkbox.h b/chromium/ui/views/controls/button/checkbox.h
index 7fc27353a01..f6605e8dd4c 100644
--- a/chromium/ui/views/controls/button/checkbox.h
+++ b/chromium/ui/views/controls/button/checkbox.h
@@ -74,7 +74,11 @@ class VIEWS_EXPORT Checkbox : public LabelButton {
private:
friend class IconFocusRing;
- SkColor GetIconImageColor(bool checked) const;
+ // Bitmask constants for GetIconImageColor.
+ enum IconState { CHECKED = 0b1, ENABLED = 0b10 };
+
+ // |icon_state| is a bitmask using the IconState enum.
+ SkColor GetIconImageColor(int icon_state) const;
// Button:
void NotifyClick(const ui::Event& event) override;
diff --git a/chromium/ui/views/controls/button/image_button.cc b/chromium/ui/views/controls/button/image_button.cc
index 86da89c1729..6d945e4579c 100644
--- a/chromium/ui/views/controls/button/image_button.cc
+++ b/chromium/ui/views/controls/button/image_button.cc
@@ -217,7 +217,7 @@ void ToggleImageButton::SetToggled(bool toggled) {
toggled_ = toggled;
SchedulePaint();
- NotifyAccessibilityEvent(ui::AX_EVENT_ARIA_ATTRIBUTE_CHANGED, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kAriaAttributeChanged, true);
}
void ToggleImageButton::SetToggledImage(ButtonState image_state,
@@ -279,10 +279,9 @@ void ToggleImageButton::GetAccessibleNodeData(ui::AXNodeData* node_data) {
// accessible toggle button.
if ((toggled_ && !images_[ButtonState::STATE_NORMAL].isNull()) ||
(!toggled_ && !alternate_images_[ButtonState::STATE_NORMAL].isNull())) {
- node_data->role = ui::AX_ROLE_TOGGLE_BUTTON;
- node_data->AddIntAttribute(
- ui::AX_ATTR_CHECKED_STATE,
- toggled_ ? ui::AX_CHECKED_STATE_TRUE : ui::AX_CHECKED_STATE_FALSE);
+ node_data->role = ax::mojom::Role::kToggleButton;
+ node_data->SetCheckedState(toggled_ ? ax::mojom::CheckedState::kTrue
+ : ax::mojom::CheckedState::kFalse);
}
}
diff --git a/chromium/ui/views/controls/button/image_button.h b/chromium/ui/views/controls/button/image_button.h
index 61c0ca338c1..fb73e6c1e06 100644
--- a/chromium/ui/views/controls/button/image_button.h
+++ b/chromium/ui/views/controls/button/image_button.h
@@ -23,12 +23,14 @@ class VIEWS_EXPORT ImageButton : public Button {
public:
static const char kViewClassName[];
+ // An enum describing the horizontal alignment of images on Buttons.
enum HorizontalAlignment {
ALIGN_LEFT = 0,
ALIGN_CENTER,
ALIGN_RIGHT
};
+ // An enum describing the vertical alignment of images on Buttons.
enum VerticalAlignment {
ALIGN_TOP = 0,
ALIGN_MIDDLE,
diff --git a/chromium/ui/views/controls/button/label_button.cc b/chromium/ui/views/controls/button/label_button.cc
index 6fc12bbc6f9..7cf98686b71 100644
--- a/chromium/ui/views/controls/button/label_button.cc
+++ b/chromium/ui/views/controls/button/label_button.cc
@@ -273,7 +273,15 @@ void LabelButton::Layout() {
label_area.height());
gfx::Point image_origin(child_area.origin());
- image_origin.Offset(0, (child_area.height() - image_size.height()) / 2);
+ if (label_->multi_line()) {
+ // Right now this code currently only works for CheckBox and RadioButton
+ // descendants that have multi-line enabled for their label.
+ image_origin.Offset(
+ 0, std::max(
+ 0, (label_->font_list().GetHeight() - image_size.height()) / 2));
+ } else {
+ image_origin.Offset(0, (child_area.height() - image_size.height()) / 2);
+ }
if (horizontal_alignment_ == gfx::ALIGN_CENTER) {
const int spacing = (image_size.width() > 0 && label_size.width() > 0) ?
image_label_spacing_ : 0;
diff --git a/chromium/ui/views/controls/button/label_button_unittest.cc b/chromium/ui/views/controls/button/label_button_unittest.cc
index 466b9ccc543..4a1ac7683d6 100644
--- a/chromium/ui/views/controls/button/label_button_unittest.cc
+++ b/chromium/ui/views/controls/button/label_button_unittest.cc
@@ -24,6 +24,7 @@
#include "ui/native_theme/native_theme.h"
#include "ui/views/animation/test/ink_drop_host_view_test_api.h"
#include "ui/views/animation/test/test_ink_drop.h"
+#include "ui/views/layout/layout_provider.h"
#include "ui/views/style/platform_style.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/test/widget_test.h"
@@ -134,8 +135,9 @@ TEST_F(LabelButtonTest, Init) {
ui::AXNodeData accessible_node_data;
button.GetAccessibleNodeData(&accessible_node_data);
- EXPECT_EQ(ui::AX_ROLE_BUTTON, accessible_node_data.role);
- EXPECT_EQ(text, accessible_node_data.GetString16Attribute(ui::AX_ATTR_NAME));
+ EXPECT_EQ(ax::mojom::Role::kButton, accessible_node_data.role);
+ EXPECT_EQ(text, accessible_node_data.GetString16Attribute(
+ ax::mojom::StringAttribute::kName));
EXPECT_FALSE(button.is_default());
EXPECT_EQ(button.style(), Button::STYLE_TEXTBUTTON);
@@ -184,25 +186,25 @@ TEST_F(LabelButtonTest, AccessibleState) {
ui::AXNodeData accessible_node_data;
button_->GetAccessibleNodeData(&accessible_node_data);
- EXPECT_EQ(ui::AX_ROLE_BUTTON, accessible_node_data.role);
- EXPECT_EQ(base::string16(),
- accessible_node_data.GetString16Attribute(ui::AX_ATTR_NAME));
+ EXPECT_EQ(ax::mojom::Role::kButton, accessible_node_data.role);
+ EXPECT_EQ(base::string16(), accessible_node_data.GetString16Attribute(
+ ax::mojom::StringAttribute::kName));
// Without a label (e.g. image-only), the accessible name should automatically
// be set from the tooltip.
const base::string16 tooltip_text = ASCIIToUTF16("abc");
button_->SetTooltipText(tooltip_text);
button_->GetAccessibleNodeData(&accessible_node_data);
- EXPECT_EQ(tooltip_text,
- accessible_node_data.GetString16Attribute(ui::AX_ATTR_NAME));
+ EXPECT_EQ(tooltip_text, accessible_node_data.GetString16Attribute(
+ ax::mojom::StringAttribute::kName));
EXPECT_EQ(base::string16(), button_->GetText());
// Setting a label overrides the tooltip text.
const base::string16 label_text = ASCIIToUTF16("def");
button_->SetText(label_text);
button_->GetAccessibleNodeData(&accessible_node_data);
- EXPECT_EQ(label_text,
- accessible_node_data.GetString16Attribute(ui::AX_ATTR_NAME));
+ EXPECT_EQ(label_text, accessible_node_data.GetString16Attribute(
+ ax::mojom::StringAttribute::kName));
EXPECT_EQ(label_text, button_->GetText());
base::string16 tooltip;
@@ -304,6 +306,42 @@ TEST_F(LabelButtonTest, LabelAndImage) {
EXPECT_EQ(button_->GetPreferredSize(), gfx::Size(1, 1));
}
+TEST_F(LabelButtonTest, LabelWrapAndImageAlignment) {
+ LayoutProvider* provider = LayoutProvider::Get();
+ const gfx::FontList font_list = button_->label()->font_list();
+ const base::string16 text(ASCIIToUTF16("abcdefghijklm abcdefghijklm"));
+ const int text_wrap_width = gfx::GetStringWidth(text, font_list) / 2;
+ const int image_spacing =
+ provider->GetDistanceMetric(DISTANCE_RELATED_LABEL_HORIZONTAL);
+
+ button_->SetText(text);
+ button_->label()->SetMultiLine(true);
+
+ const int image_size = font_list.GetHeight();
+ const gfx::ImageSkia image = CreateTestImage(image_size, image_size);
+ ASSERT_EQ(font_list.GetHeight(), image.width());
+
+ button_->SetImage(Button::STATE_NORMAL, image);
+ button_->SetMaxSize(
+ gfx::Size(image.width() + image_spacing + text_wrap_width, 0));
+
+ gfx::Insets button_insets = button_->GetInsets();
+ gfx::Size preferred_size = button_->GetPreferredSize();
+ preferred_size.set_height(button_->GetHeightForWidth(preferred_size.width()));
+ button_->SetSize(preferred_size);
+ button_->Layout();
+
+ EXPECT_EQ(preferred_size.width(),
+ image.width() + image_spacing + text_wrap_width);
+ EXPECT_EQ(preferred_size.height(),
+ font_list.GetHeight() * 2 + button_insets.height());
+
+ // The image should be centered on the first line of the multi-line label.
+ EXPECT_EQ(button_->image()->y(),
+ (font_list.GetHeight() - button_->image()->height()) / 2 +
+ button_insets.top());
+}
+
// This test was added because GetHeightForWidth and GetPreferredSize were
// inconsistent. GetPreferredSize would account for image size + insets whereas
// GetHeightForWidth wouldn't. As of writing they share a large chunk of
diff --git a/chromium/ui/views/controls/button/md_text_button.h b/chromium/ui/views/controls/button/md_text_button.h
index 8d0d6e35b73..27ba3c0cb97 100644
--- a/chromium/ui/views/controls/button/md_text_button.h
+++ b/chromium/ui/views/controls/button/md_text_button.h
@@ -51,9 +51,10 @@ class VIEWS_EXPORT MdTextButton : public LabelButton {
void UpdateStyleToIndicateDefaultStatus() override;
void StateChanged(ButtonState old_state) override;
- private:
+ protected:
MdTextButton(ButtonListener* listener, int button_context);
+ private:
void UpdatePadding();
void UpdateColors();
diff --git a/chromium/ui/views/controls/button/menu_button.cc b/chromium/ui/views/controls/button/menu_button.cc
index 536fd0159e2..b6996aab742 100644
--- a/chromium/ui/views/controls/button/menu_button.cc
+++ b/chromium/ui/views/controls/button/menu_button.cc
@@ -259,6 +259,7 @@ bool MenuButton::OnKeyPressed(const ui::KeyEvent& event) {
// Alt-space on windows should show the window menu.
if (event.IsAltDown())
break;
+ FALLTHROUGH;
case ui::VKEY_RETURN:
case ui::VKEY_UP:
case ui::VKEY_DOWN: {
@@ -285,12 +286,10 @@ bool MenuButton::OnKeyReleased(const ui::KeyEvent& event) {
void MenuButton::GetAccessibleNodeData(ui::AXNodeData* node_data) {
Button::GetAccessibleNodeData(node_data);
- node_data->role = ui::AX_ROLE_POP_UP_BUTTON;
- node_data->AddState(ui::AX_STATE_HASPOPUP);
- if (enabled()) {
- node_data->AddIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB,
- ui::AX_DEFAULT_ACTION_VERB_OPEN);
- }
+ node_data->role = ax::mojom::Role::kPopUpButton;
+ node_data->AddState(ax::mojom::State::kHaspopup);
+ if (enabled())
+ node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kOpen);
}
void MenuButton::PaintMenuMarker(gfx::Canvas* canvas) {
diff --git a/chromium/ui/views/controls/button/radio_button.cc b/chromium/ui/views/controls/button/radio_button.cc
index bfe433636f3..e8499db3311 100644
--- a/chromium/ui/views/controls/button/radio_button.cc
+++ b/chromium/ui/views/controls/button/radio_button.cc
@@ -75,7 +75,7 @@ const char* RadioButton::GetClassName() const {
void RadioButton::GetAccessibleNodeData(ui::AXNodeData* node_data) {
Checkbox::GetAccessibleNodeData(node_data);
- node_data->role = ui::AX_ROLE_RADIO_BUTTON;
+ node_data->role = ax::mojom::Role::kRadioButton;
}
View* RadioButton::GetSelectedViewForGroup(int group) {
diff --git a/chromium/ui/views/controls/button/toggle_button.cc b/chromium/ui/views/controls/button/toggle_button.cc
index b62c2de33e0..650d85b8c34 100644
--- a/chromium/ui/views/controls/button/toggle_button.cc
+++ b/chromium/ui/views/controls/button/toggle_button.cc
@@ -23,13 +23,13 @@ namespace views {
namespace {
// Constants are measured in dip.
-const int kTrackHeight = 12;
-const int kTrackWidth = 28;
+constexpr int kTrackHeight = 12;
+constexpr int kTrackWidth = 28;
// Margins from edge of track to edge of view.
-const int kTrackVerticalMargin = 5;
-const int kTrackHorizontalMargin = 6;
+constexpr int kTrackVerticalMargin = 5;
+constexpr int kTrackHorizontalMargin = 6;
// Inset from the rounded edge of the thumb to the rounded edge of the track.
-const int kThumbInset = 2;
+constexpr int kThumbInset = 2;
} // namespace
@@ -60,9 +60,9 @@ class ToggleButton::ThumbView : public InkDropHostView {
}
private:
- static const int kShadowOffsetX = 0;
- static const int kShadowOffsetY = 1;
- static const int kShadowBlur = 2;
+ static constexpr int kShadowOffsetX = 0;
+ static constexpr int kShadowOffsetY = 1;
+ static constexpr int kShadowBlur = 2;
// views::View:
const char* GetClassName() const override {
@@ -197,10 +197,9 @@ void ToggleButton::OnNativeThemeChanged(const ui::NativeTheme* theme) {
void ToggleButton::GetAccessibleNodeData(ui::AXNodeData* node_data) {
Button::GetAccessibleNodeData(node_data);
- node_data->role = ui::AX_ROLE_SWITCH;
- const ui::AXCheckedState checked_state =
- is_on_ ? ui::AX_CHECKED_STATE_TRUE : ui::AX_CHECKED_STATE_FALSE;
- node_data->AddIntAttribute(ui::AX_ATTR_CHECKED_STATE, checked_state);
+ node_data->role = ax::mojom::Role::kSwitch;
+ node_data->SetCheckedState(is_on_ ? ax::mojom::CheckedState::kTrue
+ : ax::mojom::CheckedState::kFalse);
}
void ToggleButton::OnFocus() {
diff --git a/chromium/ui/views/controls/combobox/combobox.cc b/chromium/ui/views/controls/combobox/combobox.cc
index 295fbbaf5ed..67f9af2eaee 100644
--- a/chromium/ui/views/controls/combobox/combobox.cc
+++ b/chromium/ui/views/controls/combobox/combobox.cc
@@ -766,29 +766,31 @@ void Combobox::OnBlur() {
}
void Combobox::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- // AX_ROLE_COMBO_BOX is for UI elements with a dropdown and an editable text
- // field, which views::Combobox does not have. Use AX_ROLE_POP_UP_BUTTON to
- // match an HTML <select> element.
- node_data->role = ui::AX_ROLE_POP_UP_BUTTON;
+ // ax::mojom::Role::kComboBox is for UI elements with a dropdown and
+ // an editable text field, which views::Combobox does not have. Use
+ // ax::mojom::Role::kPopUpButton to match an HTML <select> element.
+ node_data->role = ax::mojom::Role::kPopUpButton;
node_data->SetName(accessible_name_);
node_data->SetValue(model_->GetItemAt(selected_index_));
if (enabled()) {
- node_data->AddIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB,
- ui::AX_DEFAULT_ACTION_VERB_OPEN);
+ node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kOpen);
}
- node_data->AddIntAttribute(ui::AX_ATTR_POS_IN_SET, selected_index_);
- node_data->AddIntAttribute(ui::AX_ATTR_SET_SIZE, model_->GetItemCount());
+ node_data->AddIntAttribute(ax::mojom::IntAttribute::kPosInSet,
+ selected_index_);
+ node_data->AddIntAttribute(ax::mojom::IntAttribute::kSetSize,
+ model_->GetItemCount());
}
bool Combobox::HandleAccessibleAction(const ui::AXActionData& action_data) {
// The action handling in View would generate a mouse event and send it to
// |this|. However, mouse events for Combobox are handled by |arrow_button_|,
// which is hidden from the a11y tree (so can't expose actions). Rather than
- // forwarding AX_ACTION_DO_DEFAULT to View and then forwarding the mouse event
- // it generates to |arrow_button_| to have it forward back to |this| (as its
- // ButtonListener), just handle the action explicitly here and bypass View.
- if (enabled() && action_data.action == ui::AX_ACTION_DO_DEFAULT) {
+ // forwarding ax::mojom::Action::kDoDefault to View and then forwarding the
+ // mouse event it generates to |arrow_button_| to have it forward back to
+ // |this| (as its ButtonListener), just handle the action explicitly here and
+ // bypass View.
+ if (enabled() && action_data.action == ax::mojom::Action::kDoDefault) {
ShowDropDownMenu(ui::MENU_SOURCE_KEYBOARD);
return true;
}
@@ -996,7 +998,7 @@ void Combobox::OnMenuClosed(Button::ButtonState original_button_state) {
}
void Combobox::OnPerformAction() {
- NotifyAccessibilityEvent(ui::AX_EVENT_VALUE_CHANGED, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kValueChanged, true);
SchedulePaint();
// This combobox may be deleted by the listener.
diff --git a/chromium/ui/views/controls/combobox/combobox_unittest.cc b/chromium/ui/views/controls/combobox/combobox_unittest.cc
index 4134a21e34b..5c32debbaf9 100644
--- a/chromium/ui/views/controls/combobox/combobox_unittest.cc
+++ b/chromium/ui/views/controls/combobox/combobox_unittest.cc
@@ -648,19 +648,19 @@ TEST_F(ComboboxTest, ShowViaAccessibleAction) {
InitCombobox(nullptr, Combobox::STYLE_NORMAL);
ui::AXActionData data;
- data.action = ui::AX_ACTION_DO_DEFAULT;
+ data.action = ax::mojom::Action::kDoDefault;
EXPECT_EQ(0, menu_show_count_);
combobox_->HandleAccessibleAction(data);
EXPECT_EQ(1, menu_show_count_);
- // AX_ACTION_SHOW_CONTEXT_MENU is specifically for a context menu (e.g. right-
- // click). Combobox should ignore it.
- data.action = ui::AX_ACTION_SHOW_CONTEXT_MENU;
+ // ax::mojom::Action::kShowContextMenu is specifically for a context menu
+ // (e.g. right- click). Combobox should ignore it.
+ data.action = ax::mojom::Action::kShowContextMenu;
combobox_->HandleAccessibleAction(data);
EXPECT_EQ(1, menu_show_count_); // No change.
- data.action = ui::AX_ACTION_BLUR;
+ data.action = ax::mojom::Action::kBlur;
combobox_->HandleAccessibleAction(data);
EXPECT_EQ(1, menu_show_count_); // No change.
@@ -668,7 +668,7 @@ TEST_F(ComboboxTest, ShowViaAccessibleAction) {
combobox_->HandleAccessibleAction(data);
EXPECT_EQ(1, menu_show_count_); // No change.
- data.action = ui::AX_ACTION_SHOW_CONTEXT_MENU;
+ data.action = ax::mojom::Action::kShowContextMenu;
combobox_->HandleAccessibleAction(data);
EXPECT_EQ(1, menu_show_count_); // No change.
}
diff --git a/chromium/ui/views/controls/image_view.cc b/chromium/ui/views/controls/image_view.cc
index bc748e3552d..badae559e96 100644
--- a/chromium/ui/views/controls/image_view.cc
+++ b/chromium/ui/views/controls/image_view.cc
@@ -106,7 +106,9 @@ gfx::Point ImageView::ComputeImageOrigin(const gfx::Size& image_size) const {
switch (actual_horiz_alignment) {
case LEADING: x = insets.left(); break;
case TRAILING: x = width() - insets.right() - image_size.width(); break;
- case CENTER: x = (width() - image_size.width()) / 2; break;
+ case CENTER:
+ x = (width() - insets.width() - image_size.width()) / 2 + insets.left();
+ break;
default: NOTREACHED(); x = 0; break;
}
@@ -114,7 +116,9 @@ gfx::Point ImageView::ComputeImageOrigin(const gfx::Size& image_size) const {
switch (vert_alignment_) {
case LEADING: y = insets.top(); break;
case TRAILING: y = height() - insets.bottom() - image_size.height(); break;
- case CENTER: y = (height() - image_size.height()) / 2; break;
+ case CENTER:
+ y = (height() - insets.height() - image_size.height()) / 2 + insets.top();
+ break;
default: NOTREACHED(); y = 0; break;
}
@@ -127,7 +131,7 @@ void ImageView::OnPaint(gfx::Canvas* canvas) {
}
void ImageView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_IMAGE;
+ node_data->role = ax::mojom::Role::kImage;
node_data->SetName(tooltip_text_);
}
diff --git a/chromium/ui/views/controls/image_view.h b/chromium/ui/views/controls/image_view.h
index e850c033cb2..751bee97277 100644
--- a/chromium/ui/views/controls/image_view.h
+++ b/chromium/ui/views/controls/image_view.h
@@ -82,6 +82,8 @@ class VIEWS_EXPORT ImageView : public View {
views::PaintInfo::ScaleType GetPaintScaleType() const override;
private:
+ friend class ImageViewTest;
+
void OnPaintImage(gfx::Canvas* canvas);
// Returns true if |img| is the same as the last image we painted. This is
diff --git a/chromium/ui/views/controls/image_view_unittest.cc b/chromium/ui/views/controls/image_view_unittest.cc
new file mode 100644
index 00000000000..417d342d445
--- /dev/null
+++ b/chromium/ui/views/controls/image_view_unittest.cc
@@ -0,0 +1,134 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/controls/image_view.h"
+
+#include "base/i18n/rtl.h"
+#include "base/memory/ptr_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkColor.h"
+#include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/size.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/views/border.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/test/views_test_base.h"
+#include "ui/views/widget/widget.h"
+
+namespace {
+
+enum class Axis {
+ kHorizontal,
+ kVertical,
+};
+
+// A test utility function to set the application default text direction.
+void SetRTL(bool rtl) {
+ // Override the current locale/direction.
+ base::i18n::SetICUDefaultLocale(rtl ? "he" : "en");
+ EXPECT_EQ(rtl, base::i18n::IsRTL());
+}
+
+} // namespace
+
+namespace views {
+
+class ImageViewTest : public ViewsTestBase,
+ public ::testing::WithParamInterface<Axis> {
+ public:
+ ImageViewTest() {}
+
+ // ViewsTestBase:
+ void SetUp() override {
+ ViewsTestBase::SetUp();
+
+ Widget::InitParams params =
+ CreateParams(Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+ params.bounds = gfx::Rect(200, 200);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget_.Init(params);
+ View* container = new View();
+ // Make sure children can take up exactly as much space as they require.
+ BoxLayout::Orientation orientation = GetParam() == Axis::kHorizontal
+ ? BoxLayout::kHorizontal
+ : BoxLayout::kVertical;
+ container->SetLayoutManager(std::make_unique<BoxLayout>(orientation));
+ widget_.SetContentsView(container);
+
+ image_view_ = new ImageView();
+ container->AddChildView(image_view_);
+
+ widget_.Show();
+ }
+
+ void TearDown() override {
+ widget_.Close();
+ ViewsTestBase::TearDown();
+ }
+
+ int CurrentImageOriginForParam() {
+ gfx::Point origin =
+ image_view()->ComputeImageOrigin(image_view()->GetImageSize());
+ return GetParam() == Axis::kHorizontal ? origin.x() : origin.y();
+ }
+
+ protected:
+ ImageView* image_view() { return image_view_; }
+ Widget* widget() { return &widget_; }
+
+ private:
+ ImageView* image_view_ = nullptr;
+ Widget widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageViewTest);
+};
+
+// Test the image origin of the internal ImageSkia is correct when it is
+// center-aligned (both horizontally and vertically).
+TEST_P(ImageViewTest, CenterAlignment) {
+ image_view()->SetHorizontalAlignment(ImageView::CENTER);
+
+ constexpr int kImageSkiaSize = 4;
+ SkBitmap bitmap;
+ bitmap.allocN32Pixels(kImageSkiaSize, kImageSkiaSize);
+ gfx::ImageSkia image_skia = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
+ image_view()->SetImage(image_skia);
+ widget()->GetContentsView()->Layout();
+ EXPECT_NE(gfx::Size(), image_skia.size());
+
+ // With no changes to the size / padding of |image_view|, the origin of
+ // |image_skia| is the same as the origin of |image_view|.
+ EXPECT_EQ(0, CurrentImageOriginForParam());
+
+ // Test insets are always respected in LTR and RTL.
+ constexpr int kInset = 5;
+ image_view()->SetBorder(CreateEmptyBorder(gfx::Insets(kInset)));
+ widget()->GetContentsView()->Layout();
+ EXPECT_EQ(kInset, CurrentImageOriginForParam());
+
+ SetRTL(true);
+ widget()->GetContentsView()->Layout();
+ EXPECT_EQ(kInset, CurrentImageOriginForParam());
+
+ // Check this still holds true when the insets are asymmetrical.
+ constexpr int kLeadingInset = 4;
+ constexpr int kTrailingInset = 6;
+ image_view()->SetBorder(CreateEmptyBorder(
+ gfx::Insets(/*top=*/kLeadingInset, /*left=*/kLeadingInset,
+ /*bottom=*/kTrailingInset, /*right=*/kTrailingInset)));
+ widget()->GetContentsView()->Layout();
+ EXPECT_EQ(kLeadingInset, CurrentImageOriginForParam());
+
+ SetRTL(false);
+ widget()->GetContentsView()->Layout();
+ EXPECT_EQ(kLeadingInset, CurrentImageOriginForParam());
+}
+
+INSTANTIATE_TEST_CASE_P(,
+ ImageViewTest,
+ ::testing::Values(Axis::kHorizontal, Axis::kVertical));
+
+} // namespace views
diff --git a/chromium/ui/views/controls/label.cc b/chromium/ui/views/controls/label.cc
index 5fb2a8667c8..6b6d5f02b8a 100644
--- a/chromium/ui/views/controls/label.cc
+++ b/chromium/ui/views/controls/label.cc
@@ -25,6 +25,7 @@
#include "ui/gfx/color_utils.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/text_elider.h"
+#include "ui/gfx/text_utils.h"
#include "ui/native_theme/native_theme.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/background.h"
@@ -75,7 +76,6 @@ const gfx::FontList& Label::GetDefaultFontList() {
}
void Label::SetFontList(const gfx::FontList& font_list) {
- is_first_paint_text_ = true;
full_text_->SetFontList(font_list);
ResetLayout();
}
@@ -83,7 +83,6 @@ void Label::SetFontList(const gfx::FontList& font_list) {
void Label::SetText(const base::string16& new_text) {
if (new_text == text())
return;
- is_first_paint_text_ = true;
full_text_->SetText(new_text);
ResetLayout();
stored_selection_range_ = gfx::Range::InvalidRange();
@@ -92,7 +91,6 @@ void Label::SetText(const base::string16& new_text) {
void Label::SetAutoColorReadabilityEnabled(bool enabled) {
if (auto_color_readability_ == enabled)
return;
- is_first_paint_text_ = true;
auto_color_readability_ = enabled;
RecalculateColors();
}
@@ -100,7 +98,6 @@ void Label::SetAutoColorReadabilityEnabled(bool enabled) {
void Label::SetEnabledColor(SkColor color) {
if (enabled_color_set_ && requested_enabled_color_ == color)
return;
- is_first_paint_text_ = true;
requested_enabled_color_ = color;
enabled_color_set_ = true;
RecalculateColors();
@@ -109,7 +106,6 @@ void Label::SetEnabledColor(SkColor color) {
void Label::SetBackgroundColor(SkColor color) {
if (background_color_set_ && background_color_ == color)
return;
- is_first_paint_text_ = true;
background_color_ = color;
background_color_set_ = true;
RecalculateColors();
@@ -118,7 +114,6 @@ void Label::SetBackgroundColor(SkColor color) {
void Label::SetSelectionTextColor(SkColor color) {
if (selection_text_color_set_ && requested_selection_text_color_ == color)
return;
- is_first_paint_text_ = true;
requested_selection_text_color_ = color;
selection_text_color_set_ = true;
RecalculateColors();
@@ -127,7 +122,6 @@ void Label::SetSelectionTextColor(SkColor color) {
void Label::SetSelectionBackgroundColor(SkColor color) {
if (selection_background_color_set_ && selection_background_color_ == color)
return;
- is_first_paint_text_ = true;
selection_background_color_ = color;
selection_background_color_set_ = true;
RecalculateColors();
@@ -136,7 +130,6 @@ void Label::SetSelectionBackgroundColor(SkColor color) {
void Label::SetShadows(const gfx::ShadowValues& shadows) {
if (full_text_->shadows() == shadows)
return;
- is_first_paint_text_ = true;
full_text_->set_shadows(shadows);
ResetLayout();
}
@@ -144,21 +137,14 @@ void Label::SetShadows(const gfx::ShadowValues& shadows) {
void Label::SetSubpixelRenderingEnabled(bool subpixel_rendering_enabled) {
if (subpixel_rendering_enabled_ == subpixel_rendering_enabled)
return;
- is_first_paint_text_ = true;
subpixel_rendering_enabled_ = subpixel_rendering_enabled;
RecalculateColors();
}
void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
- // If the UI layout is right-to-left, flip the alignment direction.
- if (base::i18n::IsRTL() &&
- (alignment == gfx::ALIGN_LEFT || alignment == gfx::ALIGN_RIGHT)) {
- alignment = (alignment == gfx::ALIGN_LEFT) ?
- gfx::ALIGN_RIGHT : gfx::ALIGN_LEFT;
- }
+ alignment = gfx::MaybeFlipForRTL(alignment);
if (horizontal_alignment() == alignment)
return;
- is_first_paint_text_ = true;
full_text_->SetHorizontalAlignment(alignment);
ResetLayout();
}
@@ -166,7 +152,6 @@ void Label::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
void Label::SetLineHeight(int height) {
if (line_height() == height)
return;
- is_first_paint_text_ = true;
full_text_->SetMinLineHeight(height);
ResetLayout();
}
@@ -176,7 +161,6 @@ void Label::SetMultiLine(bool multi_line) {
elide_behavior_ == gfx::NO_ELIDE));
if (this->multi_line() == multi_line)
return;
- is_first_paint_text_ = true;
multi_line_ = multi_line;
full_text_->SetMultiline(multi_line);
full_text_->SetReplaceNewlineCharsWithSymbols(!multi_line);
@@ -186,7 +170,6 @@ void Label::SetMultiLine(bool multi_line) {
void Label::SetMaxLines(int max_lines) {
if (max_lines_ == max_lines)
return;
- is_first_paint_text_ = true;
max_lines_ = max_lines;
ResetLayout();
}
@@ -194,7 +177,6 @@ void Label::SetMaxLines(int max_lines) {
void Label::SetObscured(bool obscured) {
if (this->obscured() == obscured)
return;
- is_first_paint_text_ = true;
full_text_->SetObscured(obscured);
if (obscured)
SetSelectable(false);
@@ -208,7 +190,6 @@ void Label::SetAllowCharacterBreak(bool allow_character_break) {
return;
full_text_->SetWordWrapBehavior(behavior);
if (multi_line()) {
- is_first_paint_text_ = true;
ResetLayout();
}
}
@@ -218,7 +199,6 @@ void Label::SetElideBehavior(gfx::ElideBehavior elide_behavior) {
elide_behavior_ == gfx::NO_ELIDE));
if (elide_behavior_ == elide_behavior)
return;
- is_first_paint_text_ = true;
elide_behavior_ = elide_behavior;
ResetLayout();
}
@@ -396,9 +376,9 @@ const char* Label::GetClassName() const {
View* Label::GetTooltipHandlerForPoint(const gfx::Point& point) {
if (!handles_tooltips_ ||
(tooltip_text_.empty() && !ShouldShowDefaultTooltip()))
- return NULL;
+ return nullptr;
- return HitTestPoint(point) ? this : NULL;
+ return HitTestPoint(point) ? this : nullptr;
}
bool Label::CanProcessEventsWithinSubtree() const {
@@ -410,7 +390,11 @@ WordLookupClient* Label::GetWordLookupClient() {
}
void Label::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_STATIC_TEXT;
+ if (text_context_ == style::CONTEXT_DIALOG_TITLE)
+ node_data->role = ax::mojom::Role::kTitleBar;
+ else
+ node_data->role = ax::mojom::Role::kStaticText;
+
node_data->SetName(full_text_->GetDisplayText());
}
@@ -516,13 +500,7 @@ void Label::OnBoundsChanged(const gfx::Rect& previous_bounds) {
void Label::OnPaint(gfx::Canvas* canvas) {
View::OnPaint(canvas);
- if (is_first_paint_text_) {
- is_first_paint_text_ = false;
- PaintText(canvas);
- } else {
- PaintText(canvas);
- }
-
+ PaintText(canvas);
if (HasFocus())
PaintFocusRing(canvas);
}
@@ -836,7 +814,6 @@ void Label::Init(const base::string16& text, const gfx::FontList& font_list) {
collapse_when_hidden_ = false;
fixed_width_ = 0;
max_width_ = 0;
- is_first_paint_text_ = true;
SetText(text);
// Only selectable labels will get requests to show the context menu, due to
diff --git a/chromium/ui/views/controls/label.h b/chromium/ui/views/controls/label.h
index 1cee7279272..635025a8250 100644
--- a/chromium/ui/views/controls/label.h
+++ b/chromium/ui/views/controls/label.h
@@ -5,6 +5,8 @@
#ifndef UI_VIEWS_CONTROLS_LABEL_H_
#define UI_VIEWS_CONTROLS_LABEL_H_
+#include <memory>
+
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -366,10 +368,6 @@ class VIEWS_EXPORT Label : public View,
int fixed_width_;
int max_width_;
- // TODO(ckocagil): Remove is_first_paint_text_ before crbug.com/441028 is
- // closed.
- bool is_first_paint_text_;
-
std::unique_ptr<SelectionController> selection_controller_;
// Context menu related members.
diff --git a/chromium/ui/views/controls/label_unittest.cc b/chromium/ui/views/controls/label_unittest.cc
index 7e70ba3be24..54654acf866 100644
--- a/chromium/ui/views/controls/label_unittest.cc
+++ b/chromium/ui/views/controls/label_unittest.cc
@@ -227,7 +227,7 @@ class LabelSelectionTest : public LabelTest {
label()->GetRenderTextForSelectionController();
const gfx::Range range(index, index + 1);
const std::vector<gfx::Rect> bounds =
- render_text->GetSubstringBoundsForTesting(range);
+ render_text->GetSubstringBounds(range);
DCHECK_EQ(1u, bounds.size());
const int mid_y = bounds[0].y() + bounds[0].height() / 2;
@@ -567,9 +567,11 @@ TEST_F(LabelTest, Accessibility) {
ui::AXNodeData node_data;
label()->GetAccessibleNodeData(&node_data);
- EXPECT_EQ(ui::AX_ROLE_STATIC_TEXT, node_data.role);
- EXPECT_EQ(label()->text(), node_data.GetString16Attribute(ui::AX_ATTR_NAME));
- EXPECT_FALSE(node_data.HasIntAttribute(ui::AX_ATTR_RESTRICTION));
+ EXPECT_EQ(ax::mojom::Role::kStaticText, node_data.role);
+ EXPECT_EQ(label()->text(),
+ node_data.GetString16Attribute(ax::mojom::StringAttribute::kName));
+ EXPECT_FALSE(
+ node_data.HasIntAttribute(ax::mojom::IntAttribute::kRestriction));
}
TEST_F(LabelTest, TextChangeWithoutLayout) {
diff --git a/chromium/ui/views/controls/link.cc b/chromium/ui/views/controls/link.cc
index 1cc2e1faf5e..f4e605aaedb 100644
--- a/chromium/ui/views/controls/link.cc
+++ b/chromium/ui/views/controls/link.cc
@@ -163,7 +163,7 @@ bool Link::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
void Link::GetAccessibleNodeData(ui::AXNodeData* node_data) {
Label::GetAccessibleNodeData(node_data);
- node_data->role = ui::AX_ROLE_LINK;
+ node_data->role = ax::mojom::Role::kLink;
}
void Link::OnEnabledChanged() {
diff --git a/chromium/ui/views/controls/menu/menu_config_win.cc b/chromium/ui/views/controls/menu/menu_config_win.cc
index 34d29d7bef1..6048ee062fd 100644
--- a/chromium/ui/views/controls/menu/menu_config_win.cc
+++ b/chromium/ui/views/controls/menu/menu_config_win.cc
@@ -10,7 +10,7 @@
#include "base/logging.h"
#include "base/win/scoped_gdi_object.h"
-#include "base/win/win_util.h"
+#include "base/win/win_client_metrics.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/gfx/color_utils.h"
#include "ui/native_theme/native_theme_win.h"
diff --git a/chromium/ui/views/controls/menu/menu_controller.cc b/chromium/ui/views/controls/menu/menu_controller.cc
index 9389f25f034..4feb2cd4b2e 100644
--- a/chromium/ui/views/controls/menu/menu_controller.cc
+++ b/chromium/ui/views/controls/menu/menu_controller.cc
@@ -1200,8 +1200,7 @@ void MenuController::SetSelection(MenuItemView* menu_item,
if (menu_item &&
(MenuDepth(menu_item) != 1 ||
menu_item->GetType() != MenuItemView::SUBMENU)) {
- menu_item->NotifyAccessibilityEvent(
- ui::AX_EVENT_SELECTION, true);
+ menu_item->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true);
}
}
@@ -1328,7 +1327,8 @@ void MenuController::OnKeyDown(ui::KeyboardCode key_code) {
case ui::VKEY_F4:
if (!is_combobox_)
break;
- // Fallthrough to accept or dismiss combobox menus on F4, like windows.
+ // Fallthrough to accept or dismiss combobox menus on F4, like windows.
+ FALLTHROUGH;
case ui::VKEY_RETURN:
#if defined(OS_MACOSX)
case ui::VKEY_SPACE:
@@ -2697,7 +2697,7 @@ void MenuController::SetHotTrackedButton(Button* hot_button) {
// Hot-tracked state may change outside of the MenuController. Correct it.
if (hot_button && !hot_button->IsHotTracked()) {
hot_button->SetHotTracked(true);
- hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true);
+ hot_button->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true);
}
return;
}
@@ -2706,7 +2706,7 @@ void MenuController::SetHotTrackedButton(Button* hot_button) {
hot_button_ = hot_button;
if (hot_button) {
hot_button->SetHotTracked(true);
- hot_button->NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true);
+ hot_button->NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true);
}
}
diff --git a/chromium/ui/views/controls/menu/menu_item_view.cc b/chromium/ui/views/controls/menu/menu_item_view.cc
index d90a8ec45fc..4cf7d61f7ef 100644
--- a/chromium/ui/views/controls/menu/menu_item_view.cc
+++ b/chromium/ui/views/controls/menu/menu_item_view.cc
@@ -17,6 +17,7 @@
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/image/image.h"
+#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/text_utils.h"
#include "ui/native_theme/common_theme.h"
#include "ui/strings/grit/ui_strings.h"
@@ -152,7 +153,7 @@ bool MenuItemView::GetTooltipText(const gfx::Point& p,
}
void MenuItemView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_MENU_ITEM;
+ node_data->role = ax::mojom::Role::kMenuItem;
base::string16 item_text;
if (IsContainer()) {
@@ -161,7 +162,8 @@ void MenuItemView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
View* child = child_at(0);
ui::AXNodeData node_data;
child->GetAccessibleNodeData(&node_data);
- item_text = node_data.GetString16Attribute(ui::AX_ATTR_NAME);
+ item_text =
+ node_data.GetString16Attribute(ax::mojom::StringAttribute::kName);
} else {
item_text = title_;
}
@@ -169,14 +171,13 @@ void MenuItemView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
switch (GetType()) {
case SUBMENU:
- node_data->AddState(ui::AX_STATE_HASPOPUP);
+ node_data->AddState(ax::mojom::State::kHaspopup);
break;
case CHECKBOX:
case RADIO: {
const bool is_checked = GetDelegate()->IsItemChecked(GetCommand());
- const ui::AXCheckedState checked_state =
- is_checked ? ui::AX_CHECKED_STATE_TRUE : ui::AX_CHECKED_STATE_FALSE;
- node_data->AddIntAttribute(ui::AX_ATTR_CHECKED_STATE, checked_state);
+ node_data->SetCheckedState(is_checked ? ax::mojom::CheckedState::kTrue
+ : ax::mojom::CheckedState::kFalse);
} break;
case NORMAL:
case SEPARATOR:
@@ -188,7 +189,7 @@ void MenuItemView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
base::char16 mnemonic = GetMnemonic();
if (mnemonic != '\0') {
node_data->AddStringAttribute(
- ui::AX_ATTR_KEY_SHORTCUTS,
+ ax::mojom::StringAttribute::kKeyShortcuts,
base::UTF16ToUTF8(base::string16(1, mnemonic)));
}
}
@@ -241,6 +242,7 @@ MenuItemView* MenuItemView::AddMenuItemAt(
const base::string16& label,
const base::string16& sublabel,
const base::string16& minor_text,
+ const gfx::VectorIcon* minor_icon,
const gfx::ImageSkia& icon,
Type type,
ui::MenuSeparatorType separator_style) {
@@ -260,6 +262,7 @@ MenuItemView* MenuItemView::AddMenuItemAt(
item->SetTitle(label);
item->SetSubtitle(sublabel);
item->SetMinorText(minor_text);
+ item->SetMinorIcon(minor_icon);
if (!icon.isNull())
item->SetIcon(icon);
if (type == SUBMENU)
@@ -289,20 +292,22 @@ MenuItemView* MenuItemView::AppendMenuItem(int item_id,
const base::string16& label,
Type type) {
return AppendMenuItemImpl(item_id, label, base::string16(), base::string16(),
- gfx::ImageSkia(), type, ui::NORMAL_SEPARATOR);
+ nullptr, gfx::ImageSkia(), type,
+ ui::NORMAL_SEPARATOR);
}
MenuItemView* MenuItemView::AppendSubMenu(int item_id,
const base::string16& label) {
return AppendMenuItemImpl(item_id, label, base::string16(), base::string16(),
- gfx::ImageSkia(), SUBMENU, ui::NORMAL_SEPARATOR);
+ nullptr, gfx::ImageSkia(), SUBMENU,
+ ui::NORMAL_SEPARATOR);
}
MenuItemView* MenuItemView::AppendSubMenuWithIcon(int item_id,
const base::string16& label,
const gfx::ImageSkia& icon) {
return AppendMenuItemImpl(item_id, label, base::string16(), base::string16(),
- icon, SUBMENU, ui::NORMAL_SEPARATOR);
+ nullptr, icon, SUBMENU, ui::NORMAL_SEPARATOR);
}
MenuItemView* MenuItemView::AppendMenuItemWithLabel(
@@ -317,14 +322,15 @@ MenuItemView* MenuItemView::AppendDelegateMenuItem(int item_id) {
void MenuItemView::AppendSeparator() {
AppendMenuItemImpl(0, base::string16(), base::string16(), base::string16(),
- gfx::ImageSkia(), SEPARATOR, ui::NORMAL_SEPARATOR);
+ nullptr, gfx::ImageSkia(), SEPARATOR,
+ ui::NORMAL_SEPARATOR);
}
MenuItemView* MenuItemView::AppendMenuItemWithIcon(int item_id,
const base::string16& label,
const gfx::ImageSkia& icon) {
return AppendMenuItemImpl(item_id, label, base::string16(), base::string16(),
- icon, NORMAL, ui::NORMAL_SEPARATOR);
+ nullptr, icon, NORMAL, ui::NORMAL_SEPARATOR);
}
MenuItemView* MenuItemView::AppendMenuItemImpl(
@@ -332,12 +338,13 @@ MenuItemView* MenuItemView::AppendMenuItemImpl(
const base::string16& label,
const base::string16& sublabel,
const base::string16& minor_text,
+ const gfx::VectorIcon* minor_icon,
const gfx::ImageSkia& icon,
Type type,
ui::MenuSeparatorType separator_style) {
const int index = submenu_ ? submenu_->child_count() : 0;
- return AddMenuItemAt(index, item_id, label, sublabel, minor_text, icon, type,
- separator_style);
+ return AddMenuItemAt(index, item_id, label, sublabel, minor_text, minor_icon,
+ icon, type, separator_style);
}
SubmenuView* MenuItemView::CreateSubmenu() {
@@ -379,6 +386,11 @@ void MenuItemView::SetMinorText(const base::string16& minor_text) {
invalidate_dimensions(); // Triggers preferred size recalculation.
}
+void MenuItemView::SetMinorIcon(const gfx::VectorIcon* minor_icon) {
+ minor_icon_ = minor_icon;
+ invalidate_dimensions(); // Triggers preferred size recalculation.
+}
+
void MenuItemView::SetSelected(bool selected) {
selected_ = selected;
SchedulePaint();
@@ -866,35 +878,56 @@ void MenuItemView::PaintButton(gfx::Canvas* canvas, PaintButtonMode mode) {
flags);
}
- PaintMinorText(canvas, GetTextColor(true, render_selection, emphasized));
+ PaintMinorIconAndText(canvas,
+ GetTextColor(true, render_selection, emphasized));
// Set the submenu indicator (arrow) image and color.
if (HasSubmenu())
submenu_arrow_image_view_->SetImage(GetSubmenuArrowImage(icon_color));
}
-void MenuItemView::PaintMinorText(gfx::Canvas* canvas, SkColor color) {
+void MenuItemView::PaintMinorIconAndText(gfx::Canvas* canvas, SkColor color) {
base::string16 minor_text = GetMinorText();
- if (minor_text.empty())
+ const gfx::VectorIcon* minor_icon = GetMinorIcon();
+ if (minor_text.empty() && !minor_icon)
return;
int available_height = height() - GetTopMargin() - GetBottomMargin();
- int max_accel_width =
+ int max_minor_text_width =
parent_menu_item_->GetSubmenu()->max_minor_text_width();
const MenuConfig& config = MenuConfig::instance();
- int accel_right_margin = config.align_arrow_and_shortcut ?
- config.arrow_to_edge_padding : item_right_margin_;
- gfx::Rect accel_bounds(width() - accel_right_margin - max_accel_width,
- GetTopMargin(), max_accel_width, available_height);
- accel_bounds.set_x(GetMirroredXForRect(accel_bounds));
- int flags = GetDrawStringFlags();
- flags &= ~(gfx::Canvas::TEXT_ALIGN_RIGHT | gfx::Canvas::TEXT_ALIGN_LEFT);
- if (base::i18n::IsRTL())
- flags |= gfx::Canvas::TEXT_ALIGN_LEFT;
- else
- flags |= gfx::Canvas::TEXT_ALIGN_RIGHT;
- canvas->DrawStringRectWithFlags(minor_text, GetFontList(), color,
- accel_bounds, flags);
+ int minor_text_right_margin = config.align_arrow_and_shortcut
+ ? config.arrow_to_edge_padding
+ : item_right_margin_;
+ gfx::Rect minor_text_bounds(
+ width() - minor_text_right_margin - max_minor_text_width, GetTopMargin(),
+ max_minor_text_width, available_height);
+ minor_text_bounds.set_x(GetMirroredXForRect(minor_text_bounds));
+
+ auto render_text = gfx::RenderText::CreateHarfBuzzInstance();
+ if (!minor_text.empty()) {
+ render_text->SetText(minor_text);
+ render_text->SetFontList(GetFontList());
+ render_text->SetColor(color);
+ render_text->SetDisplayRect(minor_text_bounds);
+ render_text->SetHorizontalAlignment(base::i18n::IsRTL() ? gfx::ALIGN_LEFT
+ : gfx::ALIGN_RIGHT);
+ render_text->Draw(canvas);
+ }
+
+ if (minor_icon) {
+ gfx::ImageSkia image = CreateVectorIcon(*minor_icon, color);
+
+ int image_x = GetMirroredRect(minor_text_bounds).right() -
+ render_text->GetContentWidth() -
+ (minor_text.empty() ? 0 : config.icon_to_label_padding) -
+ image.width();
+ int minor_text_center_y =
+ minor_text_bounds.y() + minor_text_bounds.height() / 2;
+ int image_y = minor_text_center_y - image.height() / 2;
+ canvas->DrawImageInt(
+ image, GetMirroredXWithWidthInView(image_x, image.width()), image_y);
+ }
}
SkColor MenuItemView::GetTextColor(bool minor,
@@ -1057,6 +1090,10 @@ base::string16 MenuItemView::GetMinorText() const {
return minor_text_;
}
+const gfx::VectorIcon* MenuItemView::GetMinorIcon() const {
+ return minor_icon_;
+}
+
bool MenuItemView::IsContainer() const {
// Let the first child take over |this| when we only have one child and no
// title.
diff --git a/chromium/ui/views/controls/menu/menu_item_view.h b/chromium/ui/views/controls/menu/menu_item_view.h
index f474f6f9dac..ab487377b9e 100644
--- a/chromium/ui/views/controls/menu/menu_item_view.h
+++ b/chromium/ui/views/controls/menu/menu_item_view.h
@@ -29,6 +29,7 @@
namespace gfx {
class FontList;
+struct VectorIcon;
}
namespace views {
@@ -154,6 +155,7 @@ class VIEWS_EXPORT MenuItemView : public View {
const base::string16& label,
const base::string16& sublabel,
const base::string16& minor_text,
+ const gfx::VectorIcon* minor_icon,
const gfx::ImageSkia& icon,
Type type,
ui::MenuSeparatorType separator_style);
@@ -209,6 +211,7 @@ class VIEWS_EXPORT MenuItemView : public View {
const base::string16& label,
const base::string16& sublabel,
const base::string16& minor_text,
+ const gfx::VectorIcon* minor_icon,
const gfx::ImageSkia& icon,
Type type,
ui::MenuSeparatorType separator_style);
@@ -240,6 +243,9 @@ class VIEWS_EXPORT MenuItemView : public View {
// Sets the minor text.
void SetMinorText(const base::string16& minor_text);
+ // Sets the minor icon.
+ void SetMinorIcon(const gfx::VectorIcon* minor_icon);
+
// Returns the type of this menu.
const Type& GetType() const { return type_; }
@@ -395,8 +401,8 @@ class VIEWS_EXPORT MenuItemView : public View {
// are not rendered.
void PaintButton(gfx::Canvas* canvas, PaintButtonMode mode);
- // Paints the right-side text.
- void PaintMinorText(gfx::Canvas* canvas, SkColor color);
+ // Paints the right-side icon and text.
+ void PaintMinorIconAndText(gfx::Canvas* canvas, SkColor color);
// Destroys the window used to display this menu and recursively destroys
// the windows used to display all descendants.
@@ -406,6 +412,9 @@ class VIEWS_EXPORT MenuItemView : public View {
// item. This will be the accelerator (if one exists), otherwise |subtitle_|.
base::string16 GetMinorText() const;
+ // Returns the icon that should be displayed to the left of the minor text.
+ const gfx::VectorIcon* GetMinorIcon() const;
+
// Returns the text color for the current state. |minor| specifies if the
// minor text or the normal text is desired.
SkColor GetTextColor(bool minor,
@@ -484,6 +493,9 @@ class VIEWS_EXPORT MenuItemView : public View {
// Minor text.
base::string16 minor_text_;
+ // Minor icon.
+ const gfx::VectorIcon* minor_icon_ = nullptr;
+
// Does the title have a mnemonic? Only useful on the root menu item.
bool has_mnemonics_;
diff --git a/chromium/ui/views/controls/menu/menu_item_view_unittest.cc b/chromium/ui/views/controls/menu/menu_item_view_unittest.cc
index ab5f10ec455..bdc22a6b784 100644
--- a/chromium/ui/views/controls/menu/menu_item_view_unittest.cc
+++ b/chromium/ui/views/controls/menu/menu_item_view_unittest.cc
@@ -8,8 +8,12 @@
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/compositor/canvas_painter.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/controls/menu/submenu_view.h"
+#include "ui/views/test/menu_test_utils.h"
+#include "ui/views/test/views_test_base.h"
+#include "ui/views/vector_icons.h"
namespace views {
@@ -143,4 +147,69 @@ TEST(MenuItemViewUnitTest, TestEmptySubmenuWhenAllChildItemsAreHidden) {
empty_item->title());
}
+class MenuItemViewPaintUnitTest : public ViewsTestBase {
+ public:
+ MenuItemViewPaintUnitTest() {}
+ ~MenuItemViewPaintUnitTest() override {}
+
+ MenuItemView* menu_item_view() { return menu_item_view_; }
+ MenuRunner* menu_runner() { return menu_runner_.get(); }
+ Widget* widget() { return widget_.get(); }
+
+ // ViewsTestBase implementation.
+ void SetUp() override {
+ ViewsTestBase::SetUp();
+ menu_delegate_.reset(new test::TestMenuDelegate);
+ menu_item_view_ = new MenuItemView(menu_delegate_.get());
+
+ widget_.reset(new Widget);
+ Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
+ params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ widget_->Init(params);
+ widget_->Show();
+
+ menu_runner_.reset(new MenuRunner(menu_item_view_, 0));
+ }
+
+ void TearDown() override {
+ widget_->CloseNow();
+ ViewsTestBase::TearDown();
+ }
+
+ private:
+ // Owned by MenuRunner.
+ MenuItemView* menu_item_view_;
+
+ std::unique_ptr<test::TestMenuDelegate> menu_delegate_;
+ std::unique_ptr<MenuRunner> menu_runner_;
+ std::unique_ptr<Widget> widget_;
+
+ DISALLOW_COPY_AND_ASSIGN(MenuItemViewPaintUnitTest);
+};
+
+// Provides assertion coverage for painting minor text and icons.
+TEST_F(MenuItemViewPaintUnitTest, MinorTextAndIconAssertionCoverage) {
+ auto AddItem = [this](auto label, auto minor_label, auto minor_icon) {
+ menu_item_view()->AddMenuItemAt(
+ 0, 1000, base::ASCIIToUTF16(label), base::string16(), minor_label,
+ minor_icon, gfx::ImageSkia(), views::MenuItemView::NORMAL,
+ ui::NORMAL_SEPARATOR);
+ };
+ AddItem("No minor content", base::string16(), nullptr);
+ AddItem("Minor text only", base::ASCIIToUTF16("minor text"), nullptr);
+ AddItem("Minor icon only", base::string16(), &views::kMenuCheckIcon);
+ AddItem("Minor text and icon", base::ASCIIToUTF16("minor text"),
+ &views::kMenuCheckIcon);
+
+ menu_runner()->RunMenuAt(widget(), nullptr, gfx::Rect(), MENU_ANCHOR_TOPLEFT,
+ ui::MENU_SOURCE_KEYBOARD);
+
+ SkBitmap bitmap;
+ gfx::Size size = menu_item_view()->GetMirroredBounds().size();
+ ui::CanvasPainter canvas_painter(&bitmap, size, 1.f, SK_ColorTRANSPARENT,
+ false);
+ menu_item_view()->GetSubmenu()->Paint(
+ PaintInfo::CreateRootPaintInfo(canvas_painter.context(), size));
+}
+
} // namespace views
diff --git a/chromium/ui/views/controls/menu/menu_model_adapter.cc b/chromium/ui/views/controls/menu/menu_model_adapter.cc
index 06a9d3cfda9..2a540157090 100644
--- a/chromium/ui/views/controls/menu/menu_model_adapter.cc
+++ b/chromium/ui/views/controls/menu/menu_model_adapter.cc
@@ -64,6 +64,7 @@ MenuItemView* MenuModelAdapter::AddMenuItemFromModelAt(ui::MenuModel* model,
gfx::Image icon;
model->GetIconAt(model_index, &icon);
base::string16 label, sublabel, minor_text;
+ const gfx::VectorIcon* minor_icon = nullptr;
ui::MenuSeparatorType separator_style = ui::NORMAL_SEPARATOR;
MenuItemView::Type type;
ui::MenuModel::ItemType menu_type = model->GetTypeAt(model_index);
@@ -75,18 +76,21 @@ MenuItemView* MenuModelAdapter::AddMenuItemFromModelAt(ui::MenuModel* model,
label = model->GetLabelAt(model_index);
sublabel = model->GetSublabelAt(model_index);
minor_text = model->GetMinorTextAt(model_index);
+ minor_icon = model->GetMinorIconAt(model_index);
break;
case ui::MenuModel::TYPE_CHECK:
type = MenuItemView::CHECKBOX;
label = model->GetLabelAt(model_index);
sublabel = model->GetSublabelAt(model_index);
minor_text = model->GetMinorTextAt(model_index);
+ minor_icon = model->GetMinorIconAt(model_index);
break;
case ui::MenuModel::TYPE_RADIO:
type = MenuItemView::RADIO;
label = model->GetLabelAt(model_index);
sublabel = model->GetSublabelAt(model_index);
minor_text = model->GetMinorTextAt(model_index);
+ minor_icon = model->GetMinorIconAt(model_index);
break;
case ui::MenuModel::TYPE_SEPARATOR:
icon = gfx::Image();
@@ -98,6 +102,7 @@ MenuItemView* MenuModelAdapter::AddMenuItemFromModelAt(ui::MenuModel* model,
label = model->GetLabelAt(model_index);
sublabel = model->GetSublabelAt(model_index);
minor_text = model->GetMinorTextAt(model_index);
+ minor_icon = model->GetMinorIconAt(model_index);
break;
default:
NOTREACHED();
@@ -106,13 +111,8 @@ MenuItemView* MenuModelAdapter::AddMenuItemFromModelAt(ui::MenuModel* model,
}
return menu->AddMenuItemAt(
- menu_index,
- item_id,
- label,
- sublabel,
- minor_text,
- icon.IsEmpty() ? gfx::ImageSkia() : *icon.ToImageSkia(),
- type,
+ menu_index, item_id, label, sublabel, minor_text, minor_icon,
+ icon.IsEmpty() ? gfx::ImageSkia() : *icon.ToImageSkia(), type,
separator_style);
}
diff --git a/chromium/ui/views/controls/menu/menu_scroll_view_container.cc b/chromium/ui/views/controls/menu/menu_scroll_view_container.cc
index fc9e3426f7c..01069fe8680 100644
--- a/chromium/ui/views/controls/menu/menu_scroll_view_container.cc
+++ b/chromium/ui/views/controls/menu/menu_scroll_view_container.cc
@@ -259,7 +259,7 @@ void MenuScrollViewContainer::OnPaintBackground(gfx::Canvas* canvas) {
void MenuScrollViewContainer::GetAccessibleNodeData(ui::AXNodeData* node_data) {
// Get the name from the submenu view.
content_view_->GetAccessibleNodeData(node_data);
- node_data->role = ui::AX_ROLE_MENU_BAR;
+ node_data->role = ax::mojom::Role::kMenuBar;
}
void MenuScrollViewContainer::OnBoundsChanged(
diff --git a/chromium/ui/views/controls/menu/submenu_view.cc b/chromium/ui/views/controls/menu/submenu_view.cc
index f7a75314ec4..b8926dedbdc 100644
--- a/chromium/ui/views/controls/menu/submenu_view.cc
+++ b/chromium/ui/views/controls/menu/submenu_view.cc
@@ -194,9 +194,9 @@ void SubmenuView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
// the orientation.
if (GetMenuItem())
GetMenuItem()->GetAccessibleNodeData(node_data);
- node_data->role = ui::AX_ROLE_MENU_LIST_POPUP;
+ node_data->role = ax::mojom::Role::kMenuListPopup;
// Menus in Chrome are always traversed in a vertical direction.
- node_data->AddState(ui::AX_STATE_VERTICAL);
+ node_data->AddState(ax::mojom::State::kVertical);
}
void SubmenuView::PaintChildren(const PaintInfo& paint_info) {
@@ -389,11 +389,8 @@ void SubmenuView::ShowAt(Widget* parent,
}
GetScrollViewContainer()->NotifyAccessibilityEvent(
- ui::AX_EVENT_MENU_START,
- true);
- NotifyAccessibilityEvent(
- ui::AX_EVENT_MENU_POPUP_START,
- true);
+ ax::mojom::Event::kMenuStart, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kMenuPopupStart, true);
}
void SubmenuView::Reposition(const gfx::Rect& bounds) {
@@ -403,9 +400,9 @@ void SubmenuView::Reposition(const gfx::Rect& bounds) {
void SubmenuView::Close() {
if (host_) {
- NotifyAccessibilityEvent(ui::AX_EVENT_MENU_POPUP_END, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kMenuPopupEnd, true);
GetScrollViewContainer()->NotifyAccessibilityEvent(
- ui::AX_EVENT_MENU_END, true);
+ ax::mojom::Event::kMenuEnd, true);
host_->DestroyMenuHost();
host_ = NULL;
diff --git a/chromium/ui/views/controls/message_box_view.cc b/chromium/ui/views/controls/message_box_view.cc
index 087c94001c5..27dc783cf4f 100644
--- a/chromium/ui/views/controls/message_box_view.cc
+++ b/chromium/ui/views/controls/message_box_view.cc
@@ -136,7 +136,7 @@ void MessageBoxView::SetLink(const base::string16& text,
}
void MessageBoxView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_ALERT;
+ node_data->role = ax::mojom::Role::kAlert;
}
///////////////////////////////////////////////////////////////////////////////
@@ -148,7 +148,7 @@ void MessageBoxView::ViewHierarchyChanged(
if (prompt_field_)
prompt_field_->SelectAll(true);
- NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
}
}
@@ -207,8 +207,9 @@ void MessageBoxView::Init(const InitParams& params) {
message_labels_[0]->SetSelectable(true);
if (params.options & HAS_PROMPT_FIELD) {
- prompt_field_ = new Textfield;
+ prompt_field_ = new Textfield();
prompt_field_->SetText(params.default_prompt);
+ prompt_field_->SetAccessibleName(params.message);
}
inter_row_vertical_spacing_ = params.inter_row_vertical_spacing;
diff --git a/chromium/ui/views/controls/native/native_view_host.cc b/chromium/ui/views/controls/native/native_view_host.cc
index 2c5016d5d5d..df116d35b8a 100644
--- a/chromium/ui/views/controls/native/native_view_host.cc
+++ b/chromium/ui/views/controls/native/native_view_host.cc
@@ -185,7 +185,7 @@ const char* NativeViewHost::GetClassName() const {
void NativeViewHost::OnFocus() {
if (native_view_)
native_wrapper_->SetFocus();
- NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true);
}
gfx::NativeViewAccessible NativeViewHost::GetNativeViewAccessible() {
diff --git a/chromium/ui/views/controls/progress_bar.cc b/chromium/ui/views/controls/progress_bar.cc
index f0b0ade79da..2a5bbfd9a64 100644
--- a/chromium/ui/views/controls/progress_bar.cc
+++ b/chromium/ui/views/controls/progress_bar.cc
@@ -54,7 +54,7 @@ ProgressBar::~ProgressBar() {
}
void ProgressBar::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_PROGRESS_INDICATOR;
+ node_data->role = ax::mojom::Role::kProgressIndicator;
}
gfx::Size ProgressBar::CalculatePreferredSize() const {
diff --git a/chromium/ui/views/controls/progress_bar_unittest.cc b/chromium/ui/views/controls/progress_bar_unittest.cc
index 2fe8ba943b2..6eddafe318b 100644
--- a/chromium/ui/views/controls/progress_bar_unittest.cc
+++ b/chromium/ui/views/controls/progress_bar_unittest.cc
@@ -18,9 +18,11 @@ TEST(ProgressBarTest, Accessibility) {
ui::AXNodeData node_data;
bar.GetAccessibleNodeData(&node_data);
- EXPECT_EQ(ui::AX_ROLE_PROGRESS_INDICATOR, node_data.role);
- EXPECT_EQ(base::string16(), node_data.GetString16Attribute(ui::AX_ATTR_NAME));
- EXPECT_FALSE(node_data.HasIntAttribute(ui::AX_ATTR_RESTRICTION));
+ EXPECT_EQ(ax::mojom::Role::kProgressIndicator, node_data.role);
+ EXPECT_EQ(base::string16(),
+ node_data.GetString16Attribute(ax::mojom::StringAttribute::kName));
+ EXPECT_FALSE(
+ node_data.HasIntAttribute(ax::mojom::IntAttribute::kRestriction));
}
// Test that default colors can be overridden. Used by Chromecast.
diff --git a/chromium/ui/views/controls/resize_area.cc b/chromium/ui/views/controls/resize_area.cc
index 06c0325fea3..6601ad28224 100644
--- a/chromium/ui/views/controls/resize_area.cc
+++ b/chromium/ui/views/controls/resize_area.cc
@@ -70,7 +70,7 @@ void ResizeArea::OnMouseCaptureLost() {
}
void ResizeArea::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_SPLITTER;
+ node_data->role = ax::mojom::Role::kSplitter;
}
void ResizeArea::ReportResizeAmount(int resize_amount, bool last_update) {
diff --git a/chromium/ui/views/controls/scrollbar/base_scroll_bar.cc b/chromium/ui/views/controls/scrollbar/base_scroll_bar.cc
index 12eeb9af696..9add6bb5776 100644
--- a/chromium/ui/views/controls/scrollbar/base_scroll_bar.cc
+++ b/chromium/ui/views/controls/scrollbar/base_scroll_bar.cc
@@ -268,20 +268,37 @@ void BaseScrollBar::ShowContextMenuForView(View* source,
View::ConvertPointFromWidget(this, &temp_pt);
context_menu_mouse_position_ = IsHorizontal() ? temp_pt.x() : temp_pt.y();
- views::MenuItemView* menu = new views::MenuItemView(this);
- // MenuRunner takes ownership of |menu|.
- menu_runner_.reset(new MenuRunner(
- menu, MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU));
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollHere);
- menu->AppendSeparator();
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollStart);
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollEnd);
- menu->AppendSeparator();
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageUp);
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPageDown);
- menu->AppendSeparator();
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollPrev);
- menu->AppendDelegateMenuItem(ScrollBarContextMenuCommand_ScrollNext);
+ if (!menu_model_) {
+ menu_model_ = std::make_unique<ui::SimpleMenuModel>(this);
+ menu_model_->AddItemWithStringId(ScrollBarContextMenuCommand_ScrollHere,
+ IDS_APP_SCROLLBAR_CXMENU_SCROLLHERE);
+ menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
+ menu_model_->AddItemWithStringId(
+ ScrollBarContextMenuCommand_ScrollStart,
+ IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFTEDGE
+ : IDS_APP_SCROLLBAR_CXMENU_SCROLLHOME);
+ menu_model_->AddItemWithStringId(
+ ScrollBarContextMenuCommand_ScrollEnd,
+ IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHTEDGE
+ : IDS_APP_SCROLLBAR_CXMENU_SCROLLEND);
+ menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
+ menu_model_->AddItemWithStringId(ScrollBarContextMenuCommand_ScrollPageUp,
+ IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEUP);
+ menu_model_->AddItemWithStringId(ScrollBarContextMenuCommand_ScrollPageDown,
+ IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEDOWN);
+ menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
+ menu_model_->AddItemWithStringId(ScrollBarContextMenuCommand_ScrollPrev,
+ IsHorizontal()
+ ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFT
+ : IDS_APP_SCROLLBAR_CXMENU_SCROLLUP);
+ menu_model_->AddItemWithStringId(ScrollBarContextMenuCommand_ScrollNext,
+ IsHorizontal()
+ ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHT
+ : IDS_APP_SCROLLBAR_CXMENU_SCROLLDOWN);
+ }
+ menu_runner_ = std::make_unique<MenuRunner>(
+ menu_model_.get(),
+ MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU);
menu_runner_->RunMenuAt(GetWidget(), nullptr, gfx::Rect(p, gfx::Size()),
MENU_ANCHOR_TOPLEFT, source_type);
}
@@ -289,42 +306,7 @@ void BaseScrollBar::ShowContextMenuForView(View* source,
///////////////////////////////////////////////////////////////////////////////
// BaseScrollBar, Menu::Delegate implementation:
-base::string16 BaseScrollBar::GetLabel(int id) const {
- int ids_value = 0;
- switch (id) {
- case ScrollBarContextMenuCommand_ScrollHere:
- ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLHERE;
- break;
- case ScrollBarContextMenuCommand_ScrollStart:
- ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFTEDGE
- : IDS_APP_SCROLLBAR_CXMENU_SCROLLHOME;
- break;
- case ScrollBarContextMenuCommand_ScrollEnd:
- ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHTEDGE
- : IDS_APP_SCROLLBAR_CXMENU_SCROLLEND;
- break;
- case ScrollBarContextMenuCommand_ScrollPageUp:
- ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEUP;
- break;
- case ScrollBarContextMenuCommand_ScrollPageDown:
- ids_value = IDS_APP_SCROLLBAR_CXMENU_SCROLLPAGEDOWN;
- break;
- case ScrollBarContextMenuCommand_ScrollPrev:
- ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLLEFT
- : IDS_APP_SCROLLBAR_CXMENU_SCROLLUP;
- break;
- case ScrollBarContextMenuCommand_ScrollNext:
- ids_value = IsHorizontal() ? IDS_APP_SCROLLBAR_CXMENU_SCROLLRIGHT
- : IDS_APP_SCROLLBAR_CXMENU_SCROLLDOWN;
- break;
- default:
- NOTREACHED() << "Invalid BaseScrollBar Context Menu command!";
- }
-
- return ids_value ? l10n_util::GetStringUTF16(ids_value) : base::string16();
-}
-
-bool BaseScrollBar::IsCommandEnabled(int id) const {
+bool BaseScrollBar::IsCommandIdEnabled(int id) const {
switch (id) {
case ScrollBarContextMenuCommand_ScrollPageUp:
case ScrollBarContextMenuCommand_ScrollPageDown:
@@ -333,7 +315,11 @@ bool BaseScrollBar::IsCommandEnabled(int id) const {
return true;
}
-void BaseScrollBar::ExecuteCommand(int id) {
+bool BaseScrollBar::IsCommandIdChecked(int id) const {
+ return false;
+}
+
+void BaseScrollBar::ExecuteCommand(int id, int event_flags) {
switch (id) {
case ScrollBarContextMenuCommand_ScrollHere:
ScrollToThumbPosition(context_menu_mouse_position_, true);
diff --git a/chromium/ui/views/controls/scrollbar/base_scroll_bar.h b/chromium/ui/views/controls/scrollbar/base_scroll_bar.h
index 7c89c6f2580..07ae5b04111 100644
--- a/chromium/ui/views/controls/scrollbar/base_scroll_bar.h
+++ b/chromium/ui/views/controls/scrollbar/base_scroll_bar.h
@@ -7,10 +7,10 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
+#include "ui/base/models/simple_menu_model.h"
#include "ui/views/animation/scroll_animator.h"
#include "ui/views/context_menu_controller.h"
#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/menu/menu_delegate.h"
#include "ui/views/controls/scrollbar/scroll_bar.h"
#include "ui/views/repeat_controller.h"
@@ -30,7 +30,7 @@ class MenuRunner;
class VIEWS_EXPORT BaseScrollBar : public ScrollBar,
public ScrollDelegate,
public ContextMenuController,
- public MenuDelegate {
+ public ui::SimpleMenuModel::Delegate {
public:
explicit BaseScrollBar(bool horizontal);
~BaseScrollBar() override;
@@ -90,10 +90,10 @@ class VIEWS_EXPORT BaseScrollBar : public ScrollBar,
const gfx::Point& point,
ui::MenuSourceType source_type) override;
- // Menu::Delegate overrides:
- base::string16 GetLabel(int id) const override;
- bool IsCommandEnabled(int id) const override;
- void ExecuteCommand(int id) override;
+ // ui::SimpleMenuModel::Delegate overrides:
+ bool IsCommandIdChecked(int id) const override;
+ bool IsCommandIdEnabled(int id) const override;
+ void ExecuteCommand(int id, int event_flags) override;
protected:
BaseScrollBarThumb* GetThumb() const;
@@ -166,6 +166,7 @@ class VIEWS_EXPORT BaseScrollBar : public ScrollBar,
// was invoked.
int context_menu_mouse_position_;
+ std::unique_ptr<ui::SimpleMenuModel> menu_model_;
std::unique_ptr<MenuRunner> menu_runner_;
std::unique_ptr<ScrollAnimator> scroll_animator_;
diff --git a/chromium/ui/views/controls/scrollbar/scroll_bar.cc b/chromium/ui/views/controls/scrollbar/scroll_bar.cc
index 67146933197..be7c83eec68 100644
--- a/chromium/ui/views/controls/scrollbar/scroll_bar.cc
+++ b/chromium/ui/views/controls/scrollbar/scroll_bar.cc
@@ -12,7 +12,7 @@ ScrollBar::~ScrollBar() {
}
void ScrollBar::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_SCROLL_BAR;
+ node_data->role = ax::mojom::Role::kScrollBar;
}
bool ScrollBar::IsHorizontal() const {
diff --git a/chromium/ui/views/controls/separator.cc b/chromium/ui/views/controls/separator.cc
index 82a6cabbd71..8be91e790d2 100644
--- a/chromium/ui/views/controls/separator.cc
+++ b/chromium/ui/views/controls/separator.cc
@@ -41,7 +41,7 @@ gfx::Size Separator::CalculatePreferredSize() const {
}
void Separator::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_SPLITTER;
+ node_data->role = ax::mojom::Role::kSplitter;
}
void Separator::OnPaint(gfx::Canvas* canvas) {
diff --git a/chromium/ui/views/controls/slider.cc b/chromium/ui/views/controls/slider.cc
index c52218fa2a6..015c695e102 100644
--- a/chromium/ui/views/controls/slider.cc
+++ b/chromium/ui/views/controls/slider.cc
@@ -87,10 +87,6 @@ void Slider::SetValue(float value) {
SetValueInternal(value, VALUE_CHANGED_BY_API);
}
-void Slider::SetAccessibleName(const base::string16& name) {
- accessible_name_ = name;
-}
-
void Slider::UpdateState(bool control_on) {
is_active_ = control_on;
SchedulePaint();
@@ -158,7 +154,7 @@ void Slider::SetValueInternal(float value, SliderChangeReason reason) {
if (accessibility_events_enabled_) {
if (GetWidget() && GetWidget()->IsVisible()) {
DCHECK(!pending_accessibility_value_change_);
- NotifyAccessibilityEvent(ui::AX_EVENT_VALUE_CHANGED, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kValueChanged, true);
} else {
pending_accessibility_value_change_ = true;
}
@@ -258,8 +254,7 @@ bool Slider::OnKeyPressed(const ui::KeyEvent& event) {
}
void Slider::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_SLIDER;
- node_data->SetName(accessible_name_);
+ node_data->role = ax::mojom::Role::kSlider;
node_data->SetValue(base::UTF8ToUTF16(
base::StringPrintf("%d%%", static_cast<int>(value_ * 100 + 0.5))));
}
@@ -341,7 +336,7 @@ void Slider::NotifyPendingAccessibilityValueChanged() {
if (!pending_accessibility_value_change_)
return;
- NotifyAccessibilityEvent(ui::AX_EVENT_VALUE_CHANGED, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kValueChanged, true);
pending_accessibility_value_change_ = false;
}
@@ -352,7 +347,7 @@ void Slider::OnGestureEvent(ui::GestureEvent* event) {
case ui::ET_GESTURE_TAP_DOWN:
OnSliderDragStarted();
PrepareForMove(event->location().x());
- // Intentional fall through to next case.
+ FALLTHROUGH;
case ui::ET_GESTURE_SCROLL_BEGIN:
case ui::ET_GESTURE_SCROLL_UPDATE:
MoveButtonTo(event->location());
diff --git a/chromium/ui/views/controls/slider.h b/chromium/ui/views/controls/slider.h
index db8d7e1ea77..66121a2ffb9 100644
--- a/chromium/ui/views/controls/slider.h
+++ b/chromium/ui/views/controls/slider.h
@@ -53,8 +53,6 @@ class VIEWS_EXPORT Slider : public View, public gfx::AnimationDelegate {
float value() const { return value_; }
void SetValue(float value);
- void SetAccessibleName(const base::string16& name);
-
void set_enable_accessibility_events(bool enabled) {
accessibility_events_enabled_ = enabled;
}
@@ -124,7 +122,6 @@ class VIEWS_EXPORT Slider : public View, public gfx::AnimationDelegate {
float keyboard_increment_ = 0.1f;
float initial_animating_value_ = 0.f;
bool value_is_valid_ = false;
- base::string16 accessible_name_;
bool accessibility_events_enabled_ = true;
// Relative position of the mouse cursor (or the touch point) on the slider's
diff --git a/chromium/ui/views/controls/slider_unittest.cc b/chromium/ui/views/controls/slider_unittest.cc
index 46ee5fd2aca..5ce176bd113 100644
--- a/chromium/ui/views/controls/slider_unittest.cc
+++ b/chromium/ui/views/controls/slider_unittest.cc
@@ -129,8 +129,9 @@ class SliderTest : public views::ViewsTestBase {
bool has_value_changed() { return has_value_changed_; }
private:
- void NotifyAccessibilityEvent(View* view, ui::AXEvent event_type) override {
- if (event_type == ui::AX_EVENT_VALUE_CHANGED)
+ void NotifyAccessibilityEvent(View* view,
+ ax::mojom::Event event_type) override {
+ if (event_type == ax::mojom::Event::kValueChanged)
has_value_changed_ = true;
}
diff --git a/chromium/ui/views/controls/styled_label.cc b/chromium/ui/views/controls/styled_label.cc
index 95b60d61197..1515c68c296 100644
--- a/chromium/ui/views/controls/styled_label.cc
+++ b/chromium/ui/views/controls/styled_label.cc
@@ -6,12 +6,16 @@
#include <stddef.h>
+#include <algorithm>
#include <limits>
+#include <memory>
#include <vector>
+#include "base/i18n/rtl.h"
#include "base/strings/string_util.h"
#include "ui/gfx/font_list.h"
#include "ui/gfx/text_elider.h"
+#include "ui/gfx/text_utils.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/link.h"
@@ -65,6 +69,16 @@ std::unique_ptr<Label> CreateLabelRange(
return result;
}
+// Returns the horizontal offset to align views in a line.
+int HorizontalAdjustment(int used_width,
+ int width,
+ gfx::HorizontalAlignment alignment) {
+ const int space = width - used_width;
+ return alignment == gfx::ALIGN_LEFT
+ ? 0
+ : alignment == gfx::ALIGN_CENTER ? space / 2 : space;
+}
+
} // namespace
// StyledLabel::RangeStyleInfo ------------------------------------------------
@@ -108,7 +122,9 @@ StyledLabel::StyledLabel(const base::string16& text,
width_at_last_layout_(0),
displayed_on_background_color_(SkColorSetRGB(0xFF, 0xFF, 0xFF)),
displayed_on_background_color_set_(false),
- auto_color_readability_enabled_(true) {
+ auto_color_readability_enabled_(true),
+ horizontal_alignment_(base::i18n::IsRTL() ? gfx::ALIGN_RIGHT
+ : gfx::ALIGN_LEFT) {
base::TrimWhitespace(text, base::TRIM_TRAILING, &text_);
}
@@ -139,6 +155,11 @@ void StyledLabel::AddStyleRange(const gfx::Range& range,
PreferredSizeChanged();
}
+void StyledLabel::AddCustomView(std::unique_ptr<View> custom_view) {
+ DCHECK(custom_view->owned_by_client());
+ custom_views_.insert(std::move(custom_view));
+}
+
void StyledLabel::SetTextContext(int text_context) {
if (text_context_ == text_context)
return;
@@ -232,6 +253,22 @@ void StyledLabel::LinkClicked(Link* source, int event_flags) {
listener_->StyledLabelLinkClicked(this, link_targets_[source], event_flags);
}
+// TODO(wutao): support gfx::ALIGN_TO_HEAD alignment.
+void StyledLabel::SetHorizontalAlignment(gfx::HorizontalAlignment alignment) {
+ DCHECK_NE(gfx::ALIGN_TO_HEAD, alignment);
+ alignment = gfx::MaybeFlipForRTL(alignment);
+
+ if (horizontal_alignment_ == alignment)
+ return;
+ horizontal_alignment_ = alignment;
+ SchedulePaint();
+}
+
+void StyledLabel::ClearStyleRanges() {
+ style_ranges_.clear();
+ PreferredSizeChanged();
+}
+
int StyledLabel::GetDefaultLineHeight() const {
return specified_line_height_ > 0
? specified_line_height_
@@ -271,13 +308,13 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
if (width <= 0 || text_.empty())
return gfx::Size();
- const int line_height = GetDefaultLineHeight();
+ const int default_line_height = GetDefaultLineHeight();
// The index of the line we're on.
int line = 0;
- // The x position (in pixels) of the line we're on, relative to content
- // bounds.
- int x = 0;
+ const gfx::Insets insets = GetInsets();
+ // The current child view's position, relative to content bounds, in pixels.
+ gfx::Point offset(0, insets.top());
int total_height = 0;
// The width that was actually used. Guaranteed to be no larger than |width|.
int used_width = 0;
@@ -290,10 +327,16 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
bool first_loop_iteration = true;
+ // Max height of the views in a line.
+ int max_line_height = default_line_height;
+
+ // Temporary references to the views in a line, used for alignment.
+ std::vector<View*> views_in_a_line;
+
// Iterate over the text, creating a bunch of labels and links and laying them
// out in the appropriate positions.
while (!remaining_string.empty()) {
- if (x == 0 && !first_loop_iteration) {
+ if (offset.x() == 0 && !first_loop_iteration) {
if (remaining_string.front() == L'\n') {
// Wrapped to the next line on \n, remove it. Other whitespace,
// eg, spaces to indent next line, are preserved.
@@ -312,75 +355,104 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
range = current_range->range;
const size_t position = text_.size() - remaining_string.size();
-
- const gfx::Rect chunk_bounds(x, 0, width - x, 2 * line_height);
std::vector<base::string16> substrings;
- // If the start of the remaining text is inside a styled range, the font
- // style may differ from the base font. The font specified by the range
- // should be used when eliding text.
- gfx::FontList text_font_list = position >= range.start()
- ? GetFontListForRange(current_range)
- : GetDefaultFontList();
- int elide_result = gfx::ElideRectangleText(
- remaining_string, text_font_list, chunk_bounds.width(),
- chunk_bounds.height(), gfx::WRAP_LONG_WORDS, &substrings);
-
- if (substrings.empty()) {
- // There is no room for anything; abort. Since wrapping is enabled, this
- // should only occur if there is insufficient vertical space remaining.
- // ElideRectangleText always adds a single character, even if there is no
- // room horizontally.
- DCHECK_NE(0, elide_result & gfx::INSUFFICIENT_SPACE_VERTICAL);
- break;
- }
+ // If the current range is not a custom_view, then we use ElideRectangleText
+ // to determine the line wrapping. Note: if it is a custom_view, then the
+ // |position| should equal |range.start()| because the custom_view is
+ // treated as one unit.
+ if (position != range.start() || (current_range != style_ranges_.end() &&
+ !current_range->style_info.custom_view)) {
+ const gfx::Rect chunk_bounds(offset.x(), 0, width - offset.x(),
+ default_line_height);
+ // If the start of the remaining text is inside a styled range, the font
+ // style may differ from the base font. The font specified by the range
+ // should be used when eliding text.
+ gfx::FontList text_font_list = position >= range.start()
+ ? GetFontListForRange(current_range)
+ : GetDefaultFontList();
+ int elide_result = gfx::ElideRectangleText(
+ remaining_string, text_font_list, chunk_bounds.width(),
+ chunk_bounds.height(), gfx::WRAP_LONG_WORDS, &substrings);
+
+ if (substrings.empty()) {
+ // There is no room for anything; abort. Since wrapping is enabled, this
+ // should only occur if there is insufficient vertical space remaining.
+ // ElideRectangleText always adds a single character, even if there is
+ // no room horizontally.
+ DCHECK_NE(0, elide_result & gfx::INSUFFICIENT_SPACE_VERTICAL);
+ break;
+ }
- // Views are aligned to integer coordinates, but typesetting is not. This
- // means that it's possible for an ElideRectangleText on a prior iteration
- // to fit a word on the current line, which does not fit after that word is
- // wrapped in a View for its chunk at the end of the line. In most cases,
- // this will just wrap more words on to the next line. However, if the
- // remaining chunk width is insufficient for the very _first_ word, that
- // word will be incorrectly split. In this case, start a new line instead.
- bool truncated_chunk =
- x != 0 && (elide_result & gfx::INSUFFICIENT_SPACE_FOR_FIRST_WORD) != 0;
- if (substrings[0].empty() || truncated_chunk) {
- // The entire line is \n, or nothing fits on this line. Start a new line.
- // As for the first line, don't advance line number so that it will be
- // handled again at the beginning of the loop.
- if (x != 0 || line > 0) {
- ++line;
+ // Views are aligned to integer coordinates, but typesetting is not. This
+ // means that it's possible for an ElideRectangleText on a prior iteration
+ // to fit a word on the current line, which does not fit after that word
+ // is wrapped in a View for its chunk at the end of the line. In most
+ // cases, this will just wrap more words on to the next line. However, if
+ // the remaining chunk width is insufficient for the very _first_ word,
+ // that word will be incorrectly split. In this case, start a new line
+ // instead.
+ bool truncated_chunk =
+ offset.x() != 0 &&
+ (elide_result & gfx::INSUFFICIENT_SPACE_FOR_FIRST_WORD) != 0;
+ if (substrings[0].empty() || truncated_chunk) {
+ // The entire line is \n, or nothing fits on this line. Start a new
+ // line. As for the first line, don't advance line number so that it
+ // will be handled again at the beginning of the loop.
+ AdvanceOneLine(&line, &offset, &max_line_height, width,
+ &views_in_a_line,
+ offset.x() != 0 || line > 0 /* new_line */);
+ continue;
}
- x = 0;
- continue;
}
- base::string16 chunk = substrings[0];
-
+ base::string16 chunk;
+ View* custom_view = nullptr;
std::unique_ptr<Label> label;
if (position >= range.start()) {
const RangeStyleInfo& style_info = current_range->style_info;
- if (style_info.disable_line_wrapping && chunk.size() < range.length() &&
- position == range.start() && x != 0) {
+ if (style_info.custom_view) {
+ custom_view = style_info.custom_view;
+ // Ownership of the custom view must be passed to StyledLabel.
+ DCHECK(
+ std::find_if(custom_views_.cbegin(), custom_views_.cend(),
+ [custom_view](const std::unique_ptr<View>& view_ptr) {
+ return view_ptr.get() == custom_view;
+ }) != custom_views_.cend());
+ // Do not allow wrap in custom view.
+ DCHECK_EQ(position, range.start());
+ chunk = remaining_string.substr(0, range.end() - position);
+ } else {
+ chunk = substrings[0];
+ }
+
+ if (((custom_view &&
+ offset.x() + custom_view->GetPreferredSize().width() > width) ||
+ (style_info.disable_line_wrapping &&
+ chunk.size() < range.length())) &&
+ position == range.start() && offset.x() != 0) {
// If the chunk should not be wrapped, try to fit it entirely on the
// next line.
- x = 0;
- ++line;
+ AdvanceOneLine(&line, &offset, &max_line_height, width,
+ &views_in_a_line);
continue;
}
if (chunk.size() > range.end() - position)
chunk = chunk.substr(0, range.end() - position);
- label = CreateLabelRange(chunk, text_context_, default_text_style_,
- style_info, this);
-
- if (style_info.IsLink() && !dry_run)
- link_targets_[label.get()] = range;
+ if (!custom_view) {
+ label = CreateLabelRange(chunk, text_context_, default_text_style_,
+ style_info, this);
+ if (style_info.IsLink() && !dry_run)
+ link_targets_[label.get()] = range;
+ }
if (position + chunk.size() >= range.end())
++current_range;
} else {
+ chunk = substrings[0];
+
// This chunk is normal text.
if (position + chunk.size() > range.start())
chunk = chunk.substr(0, range.start() - position);
@@ -388,53 +460,86 @@ gfx::Size StyledLabel::CalculateAndDoLayout(int width, bool dry_run) {
default_style, this);
}
- if (displayed_on_background_color_set_)
- label->SetBackgroundColor(displayed_on_background_color_);
- label->SetAutoColorReadabilityEnabled(auto_color_readability_enabled_);
+ if (label) {
+ if (displayed_on_background_color_set_)
+ label->SetBackgroundColor(displayed_on_background_color_);
+ label->SetAutoColorReadabilityEnabled(auto_color_readability_enabled_);
+ }
- const gfx::Size view_size = label->GetPreferredSize();
- const gfx::Insets insets = GetInsets();
- gfx::Point view_origin(insets.left() + x,
- insets.top() + line * line_height);
- if (Link::GetDefaultFocusStyle() == Link::FocusStyle::RING) {
+ View* child_view = custom_view ? custom_view : label.get();
+ gfx::Size view_size = child_view->GetPreferredSize();
+ // |offset.y()| already contains |insets.top()|.
+ gfx::Point view_origin(insets.left() + offset.x(), offset.y());
+ gfx::Insets focus_border_insets;
+ if (Link::GetDefaultFocusStyle() == Link::FocusStyle::RING && label) {
// Calculate the size of the optional focus border, and overlap by that
// amount. Otherwise, "<a>link</a>," will render as "link ,".
- const gfx::Insets focus_border_insets = FocusBorderInsets(*label);
- view_origin.Offset(-focus_border_insets.left(),
- -focus_border_insets.top());
- label->SetBoundsRect(gfx::Rect(view_origin, view_size));
- x += view_size.width() - focus_border_insets.width();
- used_width = std::max(used_width, x);
- total_height =
- std::max(total_height, label->bounds().bottom() + insets.bottom() -
- focus_border_insets.bottom());
- } else {
- label->SetBoundsRect(gfx::Rect(view_origin, view_size));
- x += view_size.width();
- total_height =
- std::max(total_height, label->bounds().bottom() + insets.bottom());
+ focus_border_insets = FocusBorderInsets(*label);
+ }
+ view_origin.Offset(-focus_border_insets.left(), -focus_border_insets.top());
+ // The custom view could be wider than the available width; clamp as needed.
+ if (custom_view) {
+ view_size.set_width(std::min(
+ view_size.width(), width - offset.x() + focus_border_insets.width()));
+ }
+ child_view->SetBoundsRect(gfx::Rect(view_origin, view_size));
+ offset.set_x(offset.x() + view_size.width() - focus_border_insets.width());
+ total_height =
+ std::max(total_height, child_view->bounds().bottom() + insets.bottom() -
+ focus_border_insets.bottom());
+ used_width = std::max(used_width, offset.x());
+ max_line_height = std::max(
+ max_line_height, view_size.height() - focus_border_insets.height());
+
+ if (!dry_run) {
+ views_in_a_line.push_back(child_view);
+ if (label)
+ AddChildView(label.release());
+ else
+ AddChildView(child_view);
}
- used_width = std::max(used_width, x);
-
- if (!dry_run)
- AddChildView(label.release());
// If |gfx::ElideRectangleText| returned more than one substring, that
// means the whole text did not fit into remaining line width, with text
// after |susbtring[0]| spilling into next line. If whole |substring[0]|
// was added to the current line (this may not be the case if part of the
// substring has different style), proceed to the next line.
- if (substrings.size() > 1 && chunk.size() == substrings[0].size()) {
- x = 0;
- ++line;
+ if (!custom_view && substrings.size() > 1 &&
+ chunk.size() == substrings[0].size()) {
+ AdvanceOneLine(&line, &offset, &max_line_height, width, &views_in_a_line);
}
remaining_string = remaining_string.substr(chunk.size());
}
-
+ AdvanceOneLine(&line, &offset, &max_line_height, width, &views_in_a_line,
+ false);
DCHECK_LE(used_width, width);
calculated_size_ = gfx::Size(used_width + GetInsets().width(), total_height);
return calculated_size_;
}
+void StyledLabel::AdvanceOneLine(int* line_number,
+ gfx::Point* offset,
+ int* max_line_height,
+ int width,
+ std::vector<View*>* views_in_a_line,
+ bool new_line) {
+ const int x_delta =
+ HorizontalAdjustment(offset->x(), width, horizontal_alignment_);
+ for (auto* view : *views_in_a_line) {
+ gfx::Rect bounds = view->bounds();
+ bounds.set_x(bounds.x() + x_delta);
+ bounds.set_y(offset->y() + (*max_line_height - bounds.height()) / 2.0f);
+ view->SetBoundsRect(bounds);
+ }
+ views_in_a_line->clear();
+
+ if (new_line) {
+ ++(*line_number);
+ offset->set_y(offset->y() + *max_line_height);
+ *max_line_height = GetDefaultLineHeight();
+ }
+ offset->set_x(0);
+}
+
} // namespace views
diff --git a/chromium/ui/views/controls/styled_label.h b/chromium/ui/views/controls/styled_label.h
index 5b25f40ba21..6dc8e734bdc 100644
--- a/chromium/ui/views/controls/styled_label.h
+++ b/chromium/ui/views/controls/styled_label.h
@@ -7,6 +7,8 @@
#include <list>
#include <map>
+#include <memory>
+#include <set>
#include "base/macros.h"
#include "base/optional.h"
@@ -15,6 +17,7 @@
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/range/range.h"
+#include "ui/gfx/text_constants.h"
#include "ui/views/controls/link_listener.h"
#include "ui/views/style/typography.h"
#include "ui/views/view.h"
@@ -62,6 +65,10 @@ class VIEWS_EXPORT StyledLabel : public View, public LinkListener {
// If set, the whole range will be put on a single line.
bool disable_line_wrapping = false;
+
+ // A custom view shown instead of the underlying text. Ownership of custom
+ // views must be passed to StyledLabel via AddCustomView().
+ View* custom_view = nullptr;
};
// Note that any trailing whitespace in |text| will be trimmed.
@@ -81,6 +88,9 @@ class VIEWS_EXPORT StyledLabel : public View, public LinkListener {
// |range| must be contained in |text_|.
void AddStyleRange(const gfx::Range& range, const RangeStyleInfo& style_info);
+ // Passes ownership of a custom view for use by RangeStyleInfo structs.
+ void AddCustomView(std::unique_ptr<View> custom_view);
+
// Set the context of this text. All ranges have the same context.
// |text_context| must be a value from views::style::TextContext.
void SetTextContext(int text_context);
@@ -125,6 +135,12 @@ class VIEWS_EXPORT StyledLabel : public View, public LinkListener {
// LinkListener implementation:
void LinkClicked(Link* source, int event_flags) override;
+ // Sets the horizontal alignment; the argument value is mirrored in RTL UI.
+ void SetHorizontalAlignment(gfx::HorizontalAlignment alignment);
+
+ // Clears all the styles applied to the label.
+ void ClearStyleRanges();
+
private:
struct StyleRange {
StyleRange(const gfx::Range& range,
@@ -155,6 +171,15 @@ class VIEWS_EXPORT StyledLabel : public View, public LinkListener {
// |width_at_last_size_calculation_|. Returns the needed size.
gfx::Size CalculateAndDoLayout(int width, bool dry_run);
+ // Adjusts the offsets of the views in a line for alignment and other line
+ // parameters.
+ void AdvanceOneLine(int* line_number,
+ gfx::Point* offset,
+ int* max_line_height,
+ int width,
+ std::vector<View*>* views_in_a_line,
+ bool new_line = true);
+
// The text to display.
base::string16 text_;
@@ -174,6 +199,9 @@ class VIEWS_EXPORT StyledLabel : public View, public LinkListener {
// that correspond to ranges with is_link style set will be added to the map.
std::map<View*, gfx::Range> link_targets_;
+ // Owns the custom views used to replace ranges of text with icons, etc.
+ std::set<std::unique_ptr<View>> custom_views_;
+
// This variable saves the result of the last GetHeightForWidth call in order
// to avoid repeated calculation.
mutable gfx::Size calculated_size_;
@@ -188,6 +216,10 @@ class VIEWS_EXPORT StyledLabel : public View, public LinkListener {
// background.
bool auto_color_readability_enabled_;
+ // The horizontal alignment. This value is flipped for RTL. The default
+ // behavior is to align left in LTR UI and right in RTL UI.
+ gfx::HorizontalAlignment horizontal_alignment_;
+
DISALLOW_COPY_AND_ASSIGN(StyledLabel);
};
diff --git a/chromium/ui/views/controls/styled_label_unittest.cc b/chromium/ui/views/controls/styled_label_unittest.cc
index e7226092de1..7aa780d2c8f 100644
--- a/chromium/ui/views/controls/styled_label_unittest.cc
+++ b/chromium/ui/views/controls/styled_label_unittest.cc
@@ -22,6 +22,7 @@
#include "ui/views/controls/styled_label_listener.h"
#include "ui/views/style/typography.h"
#include "ui/views/test/test_layout_provider.h"
+#include "ui/views/test/test_views.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
@@ -282,8 +283,7 @@ TEST_P(MDStyledLabelTest, DontBreakLinks) {
const std::string link_text("and this should be a link");
InitStyledLabel(text + link_text);
styled()->AddStyleRange(
- gfx::Range(static_cast<uint32_t>(text.size()),
- static_cast<uint32_t>(text.size() + link_text.size())),
+ gfx::Range(text.size(), text.size() + link_text.size()),
StyledLabel::RangeStyleInfo::CreateForLink());
Label label(ASCIIToUTF16(text + link_text.substr(0, link_text.size() / 2)));
@@ -316,8 +316,7 @@ TEST_F(StyledLabelTest, StyledRangeWithDisabledLineWrapping) {
StyledLabel::RangeStyleInfo style_info;
style_info.disable_line_wrapping = true;
styled()->AddStyleRange(
- gfx::Range(static_cast<uint32_t>(text.size()),
- static_cast<uint32_t>(text.size() + unbreakable_text.size())),
+ gfx::Range(text.size(), text.size() + unbreakable_text.size()),
style_info);
Label label(ASCIIToUTF16(
@@ -343,8 +342,7 @@ TEST_F(StyledLabelTest, StyledRangeCustomFontUnderlined) {
style_info.custom_font =
styled()->GetDefaultFontList().DeriveWithStyle(gfx::Font::UNDERLINE);
styled()->AddStyleRange(
- gfx::Range(static_cast<uint32_t>(text.size()),
- static_cast<uint32_t>(text.size() + underlined_text.size())),
+ gfx::Range(text.size(), text.size() + underlined_text.size()),
style_info);
styled()->SetBounds(0, 0, 1000, 1000);
@@ -372,8 +370,7 @@ TEST_F(StyledLabelTest, StyledRangeTextStyleBold) {
StyledLabel::RangeStyleInfo style_info;
style_info.text_style = style::STYLE_DISABLED;
- styled()->AddStyleRange(
- gfx::Range(0u, static_cast<uint32_t>(bold_text.size())), style_info);
+ styled()->AddStyleRange(gfx::Range(0u, bold_text.size()), style_info);
// Calculate the bold text width if it were a pure label view, both with bold
// and normal style.
@@ -434,14 +431,12 @@ TEST_F(StyledLabelTest, Color) {
StyledLabel::RangeStyleInfo style_info_red;
style_info_red.override_color = SK_ColorRED;
- styled()->AddStyleRange(
- gfx::Range(0u, static_cast<uint32_t>(text_red.size())), style_info_red);
+ styled()->AddStyleRange(gfx::Range(0u, text_red.size()), style_info_red);
StyledLabel::RangeStyleInfo style_info_link =
StyledLabel::RangeStyleInfo::CreateForLink();
styled()->AddStyleRange(
- gfx::Range(static_cast<uint32_t>(text_red.size()),
- static_cast<uint32_t>(text_red.size() + text_link.size())),
+ gfx::Range(text_red.size(), text_red.size() + text_link.size()),
style_info_link);
styled()->SetBounds(0, 0, 1000, 1000);
@@ -498,13 +493,10 @@ TEST_P(MDStyledLabelTest, StyledRangeWithTooltip) {
StyledLabel::RangeStyleInfo tooltip_style;
tooltip_style.tooltip = ASCIIToUTF16("tooltip");
styled()->AddStyleRange(
- gfx::Range(static_cast<uint32_t>(tooltip_start),
- static_cast<uint32_t>(tooltip_start + tooltip_text.size())),
+ gfx::Range(tooltip_start, tooltip_start + tooltip_text.size()),
tooltip_style);
- styled()->AddStyleRange(
- gfx::Range(static_cast<uint32_t>(link_start),
- static_cast<uint32_t>(link_start + link_text.size())),
- StyledLabel::RangeStyleInfo::CreateForLink());
+ styled()->AddStyleRange(gfx::Range(link_start, link_start + link_text.size()),
+ StyledLabel::RangeStyleInfo::CreateForLink());
// Break line inside the range with the tooltip.
Label label(ASCIIToUTF16(
@@ -652,6 +644,147 @@ TEST_F(StyledLabelTest, Border) {
styled()->GetPreferredSize().width());
}
+TEST_F(StyledLabelTest, LineHeightWithShorterCustomView) {
+ const std::string text("one ");
+ InitStyledLabel(text);
+ int default_height = styled()->GetHeightForWidth(1000);
+
+ const std::string custom_view_text("with custom view");
+ const int less_height = 10;
+ std::unique_ptr<View> custom_view = std::make_unique<StaticSizedView>(
+ gfx::Size(20, default_height - less_height));
+ custom_view->set_owned_by_client();
+ StyledLabel::RangeStyleInfo style_info;
+ style_info.custom_view = custom_view.get();
+ InitStyledLabel(text + custom_view_text);
+ styled()->AddStyleRange(
+ gfx::Range(text.size(), text.size() + custom_view_text.size()),
+ style_info);
+ styled()->AddCustomView(std::move(custom_view));
+ EXPECT_EQ(default_height, styled()->GetHeightForWidth(100));
+}
+
+TEST_F(StyledLabelTest, LineHeightWithTallerCustomView) {
+ const std::string text("one ");
+ InitStyledLabel(text);
+ int default_height = styled()->GetHeightForWidth(100);
+
+ const std::string custom_view_text("with custom view");
+ const int more_height = 10;
+ std::unique_ptr<View> custom_view = std::make_unique<StaticSizedView>(
+ gfx::Size(20, default_height + more_height));
+ custom_view->set_owned_by_client();
+ StyledLabel::RangeStyleInfo style_info;
+ style_info.custom_view = custom_view.get();
+ InitStyledLabel(text + custom_view_text);
+ styled()->AddStyleRange(
+ gfx::Range(text.size(), text.size() + custom_view_text.size()),
+ style_info);
+ styled()->AddCustomView(std::move(custom_view));
+ EXPECT_EQ(default_height + more_height, styled()->GetHeightForWidth(100));
+}
+
+TEST_F(StyledLabelTest, LineWrapperWithCustomView) {
+ const std::string text_before("one ");
+ InitStyledLabel(text_before);
+ int default_height = styled()->GetHeightForWidth(100);
+ const std::string custom_view_text("two with custom view ");
+ const std::string text_after("three");
+
+ int custom_view_height = 25;
+ std::unique_ptr<View> custom_view =
+ std::make_unique<StaticSizedView>(gfx::Size(200, custom_view_height));
+ custom_view->set_owned_by_client();
+ StyledLabel::RangeStyleInfo style_info;
+ style_info.custom_view = custom_view.get();
+ InitStyledLabel(text_before + custom_view_text + text_after);
+ styled()->AddStyleRange(
+ gfx::Range(text_before.size(),
+ text_before.size() + custom_view_text.size()),
+ style_info);
+ styled()->AddCustomView(std::move(custom_view));
+ EXPECT_EQ(default_height * 2 + custom_view_height,
+ styled()->GetHeightForWidth(100));
+}
+
+TEST_F(StyledLabelTest, LeftAlignment) {
+ const std::string multiline_text("one\ntwo\nthree");
+ InitStyledLabel(multiline_text);
+ styled()->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ styled()->SetBounds(0, 0, 1000, 1000);
+ styled()->Layout();
+ ASSERT_EQ(3, styled()->child_count());
+ EXPECT_EQ(0, styled()->child_at(0)->bounds().x());
+ EXPECT_EQ(0, styled()->child_at(1)->bounds().x());
+ EXPECT_EQ(0, styled()->child_at(2)->bounds().x());
+}
+
+TEST_F(StyledLabelTest, RightAlignment) {
+ const std::string multiline_text("one\ntwo\nthree");
+ InitStyledLabel(multiline_text);
+ styled()->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
+ styled()->SetBounds(0, 0, 1000, 1000);
+ styled()->Layout();
+ ASSERT_EQ(3, styled()->child_count());
+ EXPECT_EQ(1000, styled()->child_at(0)->bounds().right());
+ EXPECT_EQ(1000, styled()->child_at(1)->bounds().right());
+ EXPECT_EQ(1000, styled()->child_at(2)->bounds().right());
+}
+
+TEST_F(StyledLabelTest, CenterAlignment) {
+ const std::string multiline_text("one\ntwo\nthree");
+ InitStyledLabel(multiline_text);
+ styled()->SetHorizontalAlignment(gfx::ALIGN_CENTER);
+ styled()->SetBounds(0, 0, 1000, 1000);
+ styled()->Layout();
+
+ Label label_one(ASCIIToUTF16("one"));
+ Label label_two(ASCIIToUTF16("two"));
+ Label label_three(ASCIIToUTF16("three"));
+
+ ASSERT_EQ(3, styled()->child_count());
+ EXPECT_EQ((1000 - label_one.GetPreferredSize().width()) / 2,
+ styled()->child_at(0)->bounds().x());
+ EXPECT_EQ((1000 - label_two.GetPreferredSize().width()) / 2,
+ styled()->child_at(1)->bounds().x());
+ EXPECT_EQ((1000 - label_three.GetPreferredSize().width()) / 2,
+ styled()->child_at(2)->bounds().x());
+}
+
+TEST_P(MDStyledLabelTest, ViewsCenteredWithLinkAndCustomView) {
+ const std::string text("This is a test block of text, ");
+ const std::string link_text("and this should be a link");
+ const std::string custom_view_text("And this is a custom view");
+ InitStyledLabel(text + link_text + custom_view_text);
+ styled()->AddStyleRange(
+ gfx::Range(text.size(), text.size() + link_text.size()),
+ StyledLabel::RangeStyleInfo::CreateForLink());
+
+ int custom_view_height = 25;
+ std::unique_ptr<View> custom_view =
+ std::make_unique<StaticSizedView>(gfx::Size(20, custom_view_height));
+ custom_view->set_owned_by_client();
+ StyledLabel::RangeStyleInfo style_info;
+ style_info.custom_view = custom_view.get();
+ styled()->AddStyleRange(
+ gfx::Range(text.size() + link_text.size(),
+ text.size() + link_text.size() + custom_view_text.size()),
+ style_info);
+ styled()->AddCustomView(std::move(custom_view));
+
+ styled()->SetBounds(0, 0, 1000, 500);
+ styled()->Layout();
+ int height = styled()->GetPreferredSize().height();
+
+ ASSERT_EQ(3, styled()->child_count());
+ EXPECT_EQ((height - styled()->child_at(0)->bounds().height()) / 2,
+ styled()->child_at(0)->bounds().y());
+ EXPECT_EQ((height - styled()->child_at(1)->bounds().height()) / 2,
+ styled()->child_at(1)->bounds().y());
+ EXPECT_EQ((height - styled()->child_at(2)->bounds().height()) / 2,
+ styled()->child_at(2)->bounds().y());
+}
+
INSTANTIATE_TEST_CASE_P(,
MDStyledLabelTest,
::testing::Values(SecondaryUiMode::MD,
diff --git a/chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc b/chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc
index bff1a9c4807..7c44a024a40 100644
--- a/chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc
+++ b/chromium/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -21,6 +21,7 @@
#include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/native_theme/native_theme.h"
+#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/border.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h"
@@ -34,35 +35,32 @@ namespace views {
namespace {
// TODO(markusheintz|msw): Use NativeTheme colors.
-const SkColor kTabTitleColor_Inactive = SkColorSetRGB(0x64, 0x64, 0x64);
-const SkColor kTabTitleColor_Active = SK_ColorBLACK;
+constexpr SkColor kTabTitleColor_InactiveBorder =
+ SkColorSetARGBMacro(0xFF, 0x64, 0x64, 0x64);
+constexpr SkColor kTabTitleColor_InactiveHighlight =
+ SkColorSetARGBMacro(0xFF, 0x80, 0x86, 0x8B);
+constexpr SkColor kTabTitleColor_ActiveBorder = SK_ColorBLACK;
+constexpr SkColor kTabTitleColor_ActiveHighlight =
+ SkColorSetARGBMacro(0xFF, 0x42, 0x85, 0xF4);
const SkColor kTabTitleColor_Hovered = SK_ColorBLACK;
const SkColor kTabBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8);
const SkScalar kTabBorderThickness = 1.0f;
-
-const gfx::Font::Weight kHoverWeight = gfx::Font::Weight::NORMAL;
+constexpr SkColor kTabHighlightBackgroundColor =
+ SkColorSetARGBMacro(0xFF, 0xE8, 0xF0, 0xFE);
+constexpr int kTabHighlightBorderRadius = 32;
+constexpr int kTabHighlightPreferredHeight = 32;
+constexpr int kTabHighlightPreferredWidth = 208;
+
+const gfx::Font::Weight kHoverWeightBorder = gfx::Font::Weight::NORMAL;
+const gfx::Font::Weight kHoverWeightHighlight = gfx::Font::Weight::MEDIUM;
const gfx::Font::Weight kActiveWeight = gfx::Font::Weight::BOLD;
-const gfx::Font::Weight kInactiveWeight = gfx::Font::Weight::NORMAL;
+const gfx::Font::Weight kInactiveWeightBorder = gfx::Font::Weight::NORMAL;
+const gfx::Font::Weight kInactiveWeightHighlight = gfx::Font::Weight::MEDIUM;
-const int kHarmonyTabStripTabHeight = 32;
+constexpr int kLabelFontSizeDeltaHighlight = 1;
-// The View containing the text for each tab in the tab strip.
-class TabLabel : public Label {
- public:
- explicit TabLabel(const base::string16& tab_title)
- : Label(tab_title, style::CONTEXT_LABEL, style::STYLE_TAB_ACTIVE) {}
-
- // Label:
- void GetAccessibleNodeData(ui::AXNodeData* data) override {
- // views::Tab shouldn't expose any of its children in the a11y tree.
- // Instead, it should provide the a11y information itself. Normally,
- // non-keyboard-focusable children of keyboard-focusable parents are
- // ignored, but Tabs only mark the currently selected tab as
- // keyboard-focusable. This means all unselected Tabs expose their children
- // to the a11y tree. To fix, manually ignore the children.
- data->role = ui::AX_ROLE_IGNORED;
- }
-};
+const int kHarmonyTabStripTabHeight = 32;
+constexpr int kBorderThickness = 2;
} // namespace
@@ -91,7 +89,8 @@ class MdTab : public Tab {
// class uses a BoxLayout to position tabs.
class MdTabStrip : public TabStrip, public gfx::AnimationDelegate {
public:
- MdTabStrip();
+ MdTabStrip(TabbedPane::Orientation orientation,
+ TabbedPane::TabStripStyle style);
~MdTabStrip() override;
// Overridden from TabStrip:
@@ -125,21 +124,41 @@ const char Tab::kViewClassName[] = "Tab";
Tab::Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents)
: tabbed_pane_(tabbed_pane),
- title_(new TabLabel(title)),
+ title_(new Label(title, style::CONTEXT_LABEL, style::STYLE_TAB_ACTIVE)),
tab_state_(TAB_ACTIVE),
contents_(contents) {
- // Calculate this now while the font list is guaranteed to be bold.
+ // Calculate the size while the font list is bold.
preferred_title_size_ = title_->GetPreferredSize();
+ const bool is_vertical =
+ tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kVertical;
+ const bool is_highlight_style =
+ tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight;
+
+ if (is_vertical) {
+ title_->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
+ title_->SetElideBehavior(gfx::ElideBehavior::NO_ELIDE);
+ }
- const int kTabVerticalPadding = 5;
- const int kTabHorizontalPadding = 10;
-
- SetBorder(CreateEmptyBorder(
- gfx::Insets(kTabVerticalPadding, kTabHorizontalPadding)));
+ if (is_highlight_style && is_vertical) {
+ const int kTabVerticalPadding = 8;
+ const int kTabHorizontalPadding = 32;
+ SetBorder(CreateEmptyBorder(gfx::Insets(
+ kTabVerticalPadding, kTabHorizontalPadding, kTabVerticalPadding, 0)));
+ } else {
+ const int kTabVerticalPadding = 5;
+ const int kTabHorizontalPadding = 10;
+ SetBorder(CreateEmptyBorder(
+ gfx::Insets(kTabVerticalPadding, kTabHorizontalPadding)));
+ }
SetLayoutManager(std::make_unique<FillLayout>());
-
SetState(TAB_INACTIVE);
+ // Calculate the size while the font list is normal and set the max size.
+ preferred_title_size_.SetToMax(title_->GetPreferredSize());
AddChildView(title_);
+
+ // Use leaf so that name is spoken by screen reader without exposing the
+ // children.
+ GetViewAccessibility().OverrideIsLeaf();
}
Tab::~Tab() {}
@@ -157,28 +176,41 @@ void Tab::SetSelected(bool selected) {
void Tab::OnStateChanged() {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
+ const bool is_highlight_mode =
+ tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight;
+ const int font_size_delta = is_highlight_mode ? kLabelFontSizeDeltaHighlight
+ : ui::kLabelFontSizeDelta;
switch (tab_state_) {
case TAB_INACTIVE:
- title_->SetEnabledColor(kTabTitleColor_Inactive);
- title_->SetFontList(rb.GetFontListWithDelta(
- ui::kLabelFontSizeDelta, gfx::Font::NORMAL, kInactiveWeight));
+ // Notify assistive tools to update this tab's selected status.
+ // The way Chrome OS accessibility is implemented right now, firing almost
+ // any event will work, we just need to trigger its state to be refreshed.
+ NotifyAccessibilityEvent(ax::mojom::Event::kCheckedStateChanged, true);
+ title_->SetEnabledColor(is_highlight_mode
+ ? kTabTitleColor_InactiveHighlight
+ : kTabTitleColor_InactiveBorder);
+ title_->SetFontList(
+ rb.GetFontListWithDelta(font_size_delta, gfx::Font::NORMAL,
+ is_highlight_mode ? kInactiveWeightHighlight
+ : kInactiveWeightBorder));
break;
case TAB_ACTIVE:
- title_->SetEnabledColor(kTabTitleColor_Active);
+ title_->SetEnabledColor(is_highlight_mode ? kTabTitleColor_ActiveHighlight
+ : kTabTitleColor_ActiveBorder);
title_->SetFontList(rb.GetFontListWithDelta(
- ui::kLabelFontSizeDelta, gfx::Font::NORMAL, kActiveWeight));
+ font_size_delta, gfx::Font::NORMAL, kActiveWeight));
break;
case TAB_HOVERED:
title_->SetEnabledColor(kTabTitleColor_Hovered);
title_->SetFontList(rb.GetFontListWithDelta(
- ui::kLabelFontSizeDelta, gfx::Font::NORMAL, kHoverWeight));
+ font_size_delta, gfx::Font::NORMAL,
+ is_highlight_mode ? kHoverWeightHighlight : kHoverWeightBorder));
break;
}
}
bool Tab::OnMousePressed(const ui::MouseEvent& event) {
- if (event.IsOnlyLeftMouseButton() &&
- GetLocalBounds().Contains(event.location()))
+ if (enabled() && event.IsOnlyLeftMouseButton())
tabbed_pane_->SelectTab(this);
return true;
}
@@ -211,6 +243,11 @@ void Tab::OnGestureEvent(ui::GestureEvent* event) {
gfx::Size Tab::CalculatePreferredSize() const {
gfx::Size size(preferred_title_size_);
size.Enlarge(GetInsets().width(), GetInsets().height());
+ if (tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight &&
+ tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kVertical) {
+ size.SetToMax(
+ gfx::Size(kTabHighlightPreferredWidth, kTabHighlightPreferredHeight));
+ }
return size;
}
@@ -226,32 +263,51 @@ void Tab::SetState(TabState tab_state) {
SchedulePaint();
}
+void Tab::OnPaint(gfx::Canvas* canvas) {
+ View::OnPaint(canvas);
+ if (!selected())
+ return;
+ if (tabbed_pane_->GetOrientation() != TabbedPane::Orientation::kVertical ||
+ tabbed_pane_->GetStyle() != TabbedPane::TabStripStyle::kHighlight) {
+ return;
+ }
+
+ SkScalar radius = SkIntToScalar(kTabHighlightBorderRadius);
+ const SkScalar kRadius[8] = {0, 0, radius, radius, radius, radius, 0, 0};
+ SkPath path;
+ gfx::Rect bounds(size());
+ path.addRoundRect(gfx::RectToSkRect(bounds), kRadius);
+ cc::PaintFlags fill_flags;
+ fill_flags.setAntiAlias(true);
+ fill_flags.setColor(kTabHighlightBackgroundColor);
+ canvas->DrawPath(path, fill_flags);
+}
+
void Tab::GetAccessibleNodeData(ui::AXNodeData* data) {
- data->role = ui::AX_ROLE_TAB;
+ data->role = ax::mojom::Role::kTab;
data->SetName(title()->text());
- data->AddState(ui::AX_STATE_SELECTABLE);
+ data->AddState(ax::mojom::State::kSelectable);
if (selected())
- data->AddState(ui::AX_STATE_SELECTED);
+ data->AddState(ax::mojom::State::kSelected);
}
bool Tab::HandleAccessibleAction(const ui::AXActionData& action_data) {
- if (action_data.action != ui::AX_ACTION_SET_SELECTION || !enabled())
- return false;
-
- // It's not clear what should happen if a tab is 'deselected', so the
- // AX_ACTION_SET_SELECTION action will always select the tab.
- tabbed_pane_->SelectTab(this);
- return true;
+ // If the assistive tool sends kSetSelection, handle it like kDoDefault.
+ // These generate a click event handled in Tab::OnMousePressed.
+ ui::AXActionData action_data_copy(action_data);
+ if (action_data.action == ax::mojom::Action::kSetSelection)
+ action_data_copy.action = ax::mojom::Action::kDoDefault;
+ return View::HandleAccessibleAction(action_data_copy);
}
void Tab::OnFocus() {
OnStateChanged();
// When the tab gains focus, send an accessibility event indicating that the
// contents are focused. When the tab loses focus, whichever new View ends up
- // with focus will send an AX_EVENT_FOCUS of its own, so there's no need to
- // send one in OnBlur().
+ // with focus will send an ax::mojom::Event::kFocus of its own, so there's no
+ // need to send one in OnBlur().
if (contents())
- contents()->NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
+ contents()->NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true);
SchedulePaint();
}
@@ -262,17 +318,25 @@ void Tab::OnBlur() {
bool Tab::OnKeyPressed(const ui::KeyEvent& event) {
ui::KeyboardCode key = event.key_code();
- if (key != ui::VKEY_LEFT && key != ui::VKEY_RIGHT)
- return false;
- return tabbed_pane_->MoveSelectionBy(key == ui::VKEY_RIGHT ? 1 : -1);
+ const bool is_horizontal =
+ tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kHorizontal;
+ // Use left and right arrows to navigate tabs in horizontal orientation.
+ if (is_horizontal) {
+ return (key == ui::VKEY_LEFT || key == ui::VKEY_RIGHT) &&
+ tabbed_pane_->MoveSelectionBy(key == ui::VKEY_RIGHT ? 1 : -1);
+ }
+ // Use up and down arrows to navigate tabs in vertical orientation.
+ return (key == ui::VKEY_UP || key == ui::VKEY_DOWN) &&
+ tabbed_pane_->MoveSelectionBy(key == ui::VKEY_DOWN ? 1 : -1);
}
MdTab::MdTab(TabbedPane* tabbed_pane,
const base::string16& title,
View* contents)
: Tab(tabbed_pane, title, contents) {
- const int kBorderThickness = 2;
- SetBorder(CreateEmptyBorder(gfx::Insets(kBorderThickness)));
+ if (tabbed_pane->GetOrientation() == TabbedPane::Orientation::kHorizontal) {
+ SetBorder(CreateEmptyBorder(gfx::Insets(kBorderThickness)));
+ }
OnStateChanged();
}
@@ -321,12 +385,24 @@ void MdTab::OnBlur() {
// static
const char TabStrip::kViewClassName[] = "TabStrip";
-TabStrip::TabStrip() {
- const int kTabStripLeadingEdgePadding = 9;
- auto layout = std::make_unique<BoxLayout>(
- BoxLayout::kHorizontal, gfx::Insets(0, kTabStripLeadingEdgePadding));
+TabStrip::TabStrip(TabbedPane::Orientation orientation,
+ TabbedPane::TabStripStyle style)
+ : orientation_(orientation), style_(style) {
+ std::unique_ptr<BoxLayout> layout;
+ if (orientation == TabbedPane::Orientation::kHorizontal) {
+ const int kTabStripLeadingEdgePadding = 9;
+ layout = std::make_unique<BoxLayout>(
+ BoxLayout::kHorizontal, gfx::Insets(0, kTabStripLeadingEdgePadding));
+ layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_END);
+ } else {
+ const int kTabStripEdgePadding = 8;
+ const int kTabSpacing = 16;
+ layout = std::make_unique<BoxLayout>(
+ BoxLayout::kVertical, gfx::Insets(kTabStripEdgePadding, 0, 0, 0),
+ kTabSpacing);
+ layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_START);
+ }
layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_START);
- layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_END);
layout->SetDefaultFlex(0);
SetLayoutManager(std::move(layout));
}
@@ -340,34 +416,69 @@ const char* TabStrip::GetClassName() const {
}
void TabStrip::OnPaintBorder(gfx::Canvas* canvas) {
+ // Do not draw border line in kHighlight mode.
+ if (style_ == TabbedPane::TabStripStyle::kHighlight)
+ return;
+
cc::PaintFlags fill_flags;
fill_flags.setColor(kTabBorderColor);
fill_flags.setStrokeWidth(kTabBorderThickness);
- SkScalar line_y = SkIntToScalar(height()) - (kTabBorderThickness / 2);
- SkScalar line_end = SkIntToScalar(width());
+ SkScalar line_center_cross_axis;
+ SkScalar line_end_main_axis;
+
+ const bool is_horizontal =
+ orientation_ == TabbedPane::Orientation::kHorizontal;
+ if (is_horizontal) {
+ line_center_cross_axis =
+ SkIntToScalar(height()) - (kTabBorderThickness / 2);
+ line_end_main_axis = SkIntToScalar(width());
+ } else {
+ line_center_cross_axis = SkIntToScalar(width()) - (kTabBorderThickness / 2);
+ line_end_main_axis = SkIntToScalar(height());
+ }
+
int selected_tab_index = GetSelectedTabIndex();
if (selected_tab_index >= 0) {
Tab* selected_tab = GetTabAtIndex(selected_tab_index);
SkPath path;
SkScalar tab_height =
SkIntToScalar(selected_tab->height()) - kTabBorderThickness;
- SkScalar tab_width =
- SkIntToScalar(selected_tab->width()) - kTabBorderThickness;
- SkScalar tab_start = SkIntToScalar(selected_tab->GetMirroredX());
- path.moveTo(0, line_y);
- path.rLineTo(tab_start, 0);
- path.rLineTo(0, -tab_height);
- path.rLineTo(tab_width, 0);
- path.rLineTo(0, tab_height);
- path.lineTo(line_end, line_y);
-
- cc::PaintFlags fill_flags;
+ SkScalar tab_width;
+
+ SkScalar tab_start_x = SkIntToScalar(selected_tab->GetMirroredX());
+ SkScalar tab_start_y = SkIntToScalar(selected_tab->bounds().y());
+ if (is_horizontal) {
+ tab_width = SkIntToScalar(selected_tab->width()) - kTabBorderThickness;
+ path.moveTo(0, line_center_cross_axis);
+ path.rLineTo(tab_start_x, 0);
+ path.rLineTo(0, -tab_height);
+ path.rLineTo(tab_width, 0);
+ path.rLineTo(0, tab_height);
+ path.lineTo(line_end_main_axis, line_center_cross_axis);
+ } else {
+ tab_width =
+ SkIntToScalar(width() - selected_tab->GetInsets().left() / 2) -
+ kTabBorderThickness;
+ path.moveTo(line_center_cross_axis, 0);
+ path.rLineTo(0, tab_start_y);
+ path.rLineTo(-tab_width, 0);
+ path.rLineTo(0, tab_height);
+ path.rLineTo(tab_width, 0);
+ path.lineTo(line_center_cross_axis, line_end_main_axis);
+ }
+
fill_flags.setStyle(cc::PaintFlags::kStroke_Style);
- fill_flags.setColor(kTabBorderColor);
- fill_flags.setStrokeWidth(kTabBorderThickness);
canvas->DrawPath(path, fill_flags);
} else {
- canvas->sk_canvas()->drawLine(0, line_y, line_end, line_y, fill_flags);
+ if (is_horizontal) {
+ canvas->sk_canvas()->drawLine(0, line_center_cross_axis,
+ line_end_main_axis, line_center_cross_axis,
+ fill_flags);
+ } else {
+ canvas->sk_canvas()->drawLine(line_center_cross_axis, 0,
+ line_center_cross_axis, line_end_main_axis,
+ fill_flags);
+ }
}
}
@@ -394,12 +505,16 @@ Tab* TabStrip::GetTabAtDeltaFromSelected(int delta) const {
return GetTabAtIndex(index);
}
-MdTabStrip::MdTabStrip() {
- auto layout = std::make_unique<BoxLayout>(BoxLayout::kHorizontal);
- layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
- layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
- layout->SetDefaultFlex(1);
- SetLayoutManager(std::move(layout));
+MdTabStrip::MdTabStrip(TabbedPane::Orientation orientation,
+ TabbedPane::TabStripStyle style)
+ : TabStrip(orientation, style) {
+ if (orientation == TabbedPane::Orientation::kHorizontal) {
+ auto layout = std::make_unique<BoxLayout>(BoxLayout::kHorizontal);
+ layout->set_main_axis_alignment(BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
+ layout->set_cross_axis_alignment(BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
+ layout->SetDefaultFlex(1);
+ SetLayoutManager(std::move(layout));
+ }
// These durations are taken from the Paper Tabs source:
// https://github.com/PolymerElements/paper-tabs/blob/master/paper-tabs.html
@@ -417,29 +532,52 @@ void MdTabStrip::OnSelectedTabChanged(Tab* from_tab, Tab* to_tab) {
DCHECK(!from_tab->selected());
DCHECK(to_tab->selected());
- animating_from_ = gfx::Range(from_tab->GetMirroredX(),
- from_tab->GetMirroredX() + from_tab->width());
- animating_to_ = gfx::Range(to_tab->GetMirroredX(),
- to_tab->GetMirroredX() + to_tab->width());
+ if (orientation() == TabbedPane::Orientation::kHorizontal) {
+ animating_from_ = gfx::Range(from_tab->GetMirroredX(),
+ from_tab->GetMirroredX() + from_tab->width());
+ animating_to_ = gfx::Range(to_tab->GetMirroredX(),
+ to_tab->GetMirroredX() + to_tab->width());
+ } else {
+ animating_from_ = gfx::Range(from_tab->bounds().y(),
+ from_tab->bounds().y() + from_tab->height());
+ animating_to_ = gfx::Range(to_tab->bounds().y(),
+ to_tab->bounds().y() + to_tab->height());
+ }
contract_animation_->Stop();
expand_animation_->Start();
}
void MdTabStrip::OnPaintBorder(gfx::Canvas* canvas) {
- int max_y = child_at(0)->y() + child_at(0)->height();
+ // Do not draw border line in kHighlight mode.
+ if (style() == TabbedPane::TabStripStyle::kHighlight)
+ return;
+
const int kUnselectedBorderThickness = 1;
const int kSelectedBorderThickness = 2;
+ const bool is_horizontal =
+ orientation() == TabbedPane::Orientation::kHorizontal;
+
+ int max_cross_axis;
+
+ // First, draw the unselected border across the TabStrip's entire width or
+ // height, depending on the orientation of the tab alignment. The area
+ // underneath or on the right of the selected tab will be overdrawn later.
+ gfx::Rect rect;
+ if (is_horizontal) {
+ max_cross_axis = child_at(0)->y() + child_at(0)->height();
+ rect = gfx::Rect(0, max_cross_axis - kUnselectedBorderThickness, width(),
+ kUnselectedBorderThickness);
+ } else {
+ max_cross_axis = width();
+ rect = gfx::Rect(max_cross_axis - kUnselectedBorderThickness, 0,
+ kUnselectedBorderThickness, height());
+ }
+ canvas->FillRect(rect, GetNativeTheme()->GetSystemColor(
+ ui::NativeTheme::kColorId_TabBottomBorder));
- // First, draw the unselected border across the TabStrip's entire width. The
- // area underneath the selected tab will be overdrawn later.
- canvas->FillRect(gfx::Rect(0, max_y - kUnselectedBorderThickness, width(),
- kUnselectedBorderThickness),
- GetNativeTheme()->GetSystemColor(
- ui::NativeTheme::kColorId_TabBottomBorder));
-
- int min_x = 0;
- int max_x = 0;
+ int min_main_axis = 0;
+ int max_main_axis = 0;
// Now, figure out the range to draw the selection marker underneath. There
// are three states here:
@@ -454,43 +592,53 @@ void MdTabStrip::OnPaintBorder(gfx::Canvas* canvas) {
if (!tab)
return;
if (expand_animation_->is_animating()) {
- bool animating_left = animating_to_.start() < animating_from_.start();
+ bool animating_leading = animating_to_.start() < animating_from_.start();
double anim_value = gfx::Tween::CalculateValue(
gfx::Tween::FAST_OUT_LINEAR_IN, expand_animation_->GetCurrentValue());
- if (animating_left) {
- min_x = gfx::Tween::IntValueBetween(anim_value, animating_from_.start(),
- animating_to_.start());
- max_x = animating_from_.end();
+ if (animating_leading) {
+ min_main_axis = gfx::Tween::IntValueBetween(
+ anim_value, animating_from_.start(), animating_to_.start());
+ max_main_axis = animating_from_.end();
} else {
- min_x = animating_from_.start();
- max_x = gfx::Tween::IntValueBetween(anim_value, animating_from_.end(),
- animating_to_.end());
+ min_main_axis = animating_from_.start();
+ max_main_axis = gfx::Tween::IntValueBetween(
+ anim_value, animating_from_.end(), animating_to_.end());
}
} else if (contract_animation_->is_animating()) {
- bool animating_left = animating_to_.start() < animating_from_.start();
+ bool animating_leading = animating_to_.start() < animating_from_.start();
double anim_value = gfx::Tween::CalculateValue(
gfx::Tween::LINEAR_OUT_SLOW_IN, contract_animation_->GetCurrentValue());
- if (animating_left) {
- min_x = animating_to_.start();
- max_x = gfx::Tween::IntValueBetween(anim_value, animating_from_.end(),
- animating_to_.end());
+ if (animating_leading) {
+ min_main_axis = animating_to_.start();
+ max_main_axis = gfx::Tween::IntValueBetween(
+ anim_value, animating_from_.end(), animating_to_.end());
} else {
- min_x = gfx::Tween::IntValueBetween(anim_value, animating_from_.start(),
- animating_to_.start());
- max_x = animating_to_.end();
+ min_main_axis = gfx::Tween::IntValueBetween(
+ anim_value, animating_from_.start(), animating_to_.start());
+ max_main_axis = animating_to_.end();
}
} else if (tab) {
- min_x = tab->GetMirroredX();
- max_x = tab->GetMirroredX() + tab->width();
+ if (is_horizontal) {
+ min_main_axis = tab->GetMirroredX();
+ max_main_axis = tab->GetMirroredX() + tab->width();
+ } else {
+ min_main_axis = tab->bounds().y();
+ max_main_axis = tab->bounds().y() + tab->height();
+ }
}
- DCHECK(min_x != max_x);
+ DCHECK(min_main_axis != max_main_axis);
// Draw over the unselected border from above.
- canvas->FillRect(gfx::Rect(min_x, max_y - kSelectedBorderThickness,
- max_x - min_x, kSelectedBorderThickness),
- GetNativeTheme()->GetSystemColor(
- ui::NativeTheme::kColorId_FocusedBorderColor));
+ if (is_horizontal) {
+ rect = gfx::Rect(min_main_axis, max_cross_axis - kSelectedBorderThickness,
+ max_main_axis - min_main_axis, kSelectedBorderThickness);
+ } else {
+ rect = gfx::Rect(max_cross_axis - kSelectedBorderThickness, min_main_axis,
+ kSelectedBorderThickness, max_main_axis - min_main_axis);
+ }
+ canvas->FillRect(rect, GetNativeTheme()->GetSystemColor(
+ ui::NativeTheme::kColorId_FocusedBorderColor));
}
void MdTabStrip::AnimationProgressed(const gfx::Animation* animation) {
@@ -502,12 +650,14 @@ void MdTabStrip::AnimationEnded(const gfx::Animation* animation) {
contract_animation_->Start();
}
-TabbedPane::TabbedPane()
- : listener_(NULL),
- tab_strip_(ui::MaterialDesignController::IsSecondaryUiMaterial()
- ? new MdTabStrip
- : new TabStrip),
- contents_(new View()) {
+TabbedPane::TabbedPane(TabbedPane::Orientation orientation,
+ TabbedPane::TabStripStyle style)
+ : listener_(NULL), contents_(new View()) {
+ DCHECK(orientation != TabbedPane::Orientation::kHorizontal ||
+ style != TabbedPane::TabStripStyle::kHighlight);
+ tab_strip_ = ui::MaterialDesignController::IsSecondaryUiMaterial()
+ ? new MdTabStrip(orientation, style)
+ : new TabStrip(orientation, style);
AddChildView(tab_strip_);
AddChildView(contents_);
}
@@ -581,14 +731,29 @@ gfx::Size TabbedPane::CalculatePreferredSize() const {
gfx::Size size;
for (int i = 0; i < contents_->child_count(); ++i)
size.SetToMax(contents_->child_at(i)->GetPreferredSize());
- size.Enlarge(0, tab_strip_->GetPreferredSize().height());
+ if (GetOrientation() == Orientation::kHorizontal)
+ size.Enlarge(0, tab_strip_->GetPreferredSize().height());
+ else
+ size.Enlarge(tab_strip_->GetPreferredSize().width(), 0);
return size;
}
+TabbedPane::Orientation TabbedPane::GetOrientation() const {
+ return tab_strip_->orientation();
+}
+
+TabbedPane::TabStripStyle TabbedPane::GetStyle() const {
+ return tab_strip_->style();
+}
+
Tab* TabbedPane::GetSelectedTab() {
return tab_strip_->GetSelectedTab();
}
+View* TabbedPane::GetSelectedTabContentView() {
+ return GetSelectedTab() ? GetSelectedTab()->contents() : nullptr;
+}
+
bool TabbedPane::MoveSelectionBy(int delta) {
if (contents_->child_count() <= 1)
return false;
@@ -598,9 +763,15 @@ bool TabbedPane::MoveSelectionBy(int delta) {
void TabbedPane::Layout() {
const gfx::Size size = tab_strip_->GetPreferredSize();
- tab_strip_->SetBounds(0, 0, width(), size.height());
- contents_->SetBounds(0, tab_strip_->bounds().bottom(), width(),
- std::max(0, height() - size.height()));
+ if (GetOrientation() == Orientation::kHorizontal) {
+ tab_strip_->SetBounds(0, 0, width(), size.height());
+ contents_->SetBounds(0, tab_strip_->bounds().bottom(), width(),
+ std::max(0, height() - size.height()));
+ } else {
+ tab_strip_->SetBounds(0, 0, size.width(), height());
+ contents_->SetBounds(tab_strip_->bounds().width(), 0,
+ std::max(0, width() - size.width()), height());
+ }
for (int i = 0; i < contents_->child_count(); ++i)
contents_->child_at(i)->SetSize(contents_->size());
}
@@ -625,12 +796,8 @@ const char* TabbedPane::GetClassName() const {
return kViewClassName;
}
-View* TabbedPane::GetSelectedTabContentView() {
- return GetSelectedTab() ? GetSelectedTab()->contents() : nullptr;
-}
-
void TabbedPane::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_TAB_LIST;
+ node_data->role = ax::mojom::Role::kTabList;
}
} // namespace views
diff --git a/chromium/ui/views/controls/tabbed_pane/tabbed_pane.h b/chromium/ui/views/controls/tabbed_pane/tabbed_pane.h
index 2397828d847..0d3cec8d493 100644
--- a/chromium/ui/views/controls/tabbed_pane/tabbed_pane.h
+++ b/chromium/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -24,12 +24,27 @@ class TabbedPaneTest;
// TabbedPane is a view that shows tabs. When the user clicks on a tab, the
// associated view is displayed.
+// Support for horizontal-highlight and vertical-border modes is limited and
+// may require additional polish.
class VIEWS_EXPORT TabbedPane : public View {
public:
// Internal class name.
static const char kViewClassName[];
- TabbedPane();
+ // The orientation of the tab alignment.
+ enum class Orientation {
+ kHorizontal,
+ kVertical,
+ };
+
+ // The style of the tab strip.
+ enum class TabStripStyle {
+ kBorder, // Draw border around the selected tab.
+ kHighlight, // Highlight background and text of the selected tab.
+ };
+
+ TabbedPane(Orientation orientation = Orientation::kHorizontal,
+ TabStripStyle style = TabStripStyle::kBorder);
~TabbedPane() override;
TabbedPaneListener* listener() const { return listener_; }
@@ -62,6 +77,12 @@ class VIEWS_EXPORT TabbedPane : public View {
gfx::Size CalculatePreferredSize() const override;
const char* GetClassName() const override;
+ // Gets the orientation of the tab alignment.
+ Orientation GetOrientation() const;
+
+ // Gets the style of the tab strip.
+ TabStripStyle GetStyle() const;
+
private:
friend class FocusTraversalTest;
friend class Tab;
@@ -144,6 +165,9 @@ class Tab : public View {
void SetState(TabState tab_state);
+ // views::View:
+ void OnPaint(gfx::Canvas* canvas) override;
+
TabbedPane* tabbed_pane_;
Label* title_;
gfx::Size preferred_title_size_;
@@ -154,13 +178,14 @@ class Tab : public View {
DISALLOW_COPY_AND_ASSIGN(Tab);
};
-// The tab strip shown above the tab contents.
+// The tab strip shown above/left of the tab contents.
class TabStrip : public View {
public:
// Internal class name.
static const char kViewClassName[];
- TabStrip();
+ TabStrip(TabbedPane::Orientation orientation,
+ TabbedPane::TabStripStyle style);
~TabStrip() override;
// Called by TabStrip when the selected tab changes. This function is only
@@ -177,7 +202,17 @@ class TabStrip : public View {
Tab* GetTabAtIndex(int index) const;
int GetSelectedTabIndex() const;
+ TabbedPane::Orientation orientation() const { return orientation_; }
+
+ TabbedPane::TabStripStyle style() const { return style_; }
+
private:
+ // The orientation of the tab alignment.
+ const TabbedPane::Orientation orientation_;
+
+ // The style of the tab strip.
+ const TabbedPane::TabStripStyle style_;
+
DISALLOW_COPY_AND_ASSIGN(TabStrip);
};
diff --git a/chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
index c6b243d1965..02bb3cf82c8 100644
--- a/chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
+++ b/chromium/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
@@ -11,7 +11,7 @@
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/events/keycodes/keyboard_code_conversion.h"
#include "ui/views/test/test_views.h"
@@ -38,6 +38,12 @@ class TabbedPaneTest : public ViewsTestBase {
}
protected:
+ void MakeTabbedPane(TabbedPane::Orientation orientation,
+ TabbedPane::TabStripStyle style) {
+ tabbed_pane_ = std::make_unique<TabbedPane>(orientation, style);
+ tabbed_pane_->set_owned_by_client();
+ }
+
Tab* GetTabAt(int index) {
return static_cast<Tab*>(tabbed_pane_->tab_strip_->child_at(index));
}
@@ -58,36 +64,92 @@ class TabbedPaneTest : public ViewsTestBase {
DISALLOW_COPY_AND_ASSIGN(TabbedPaneTest);
};
-// Tests TabbedPane::GetPreferredSize() and TabbedPane::Layout().
+// Tests tab orientation.
+TEST_F(TabbedPaneTest, HorizontalOrientation) {
+ EXPECT_EQ(tabbed_pane_->GetOrientation(),
+ TabbedPane::Orientation::kHorizontal);
+}
+
+// Tests tab orientation.
+TEST_F(TabbedPaneTest, VerticalOrientation) {
+ MakeTabbedPane(TabbedPane::Orientation::kVertical,
+ TabbedPane::TabStripStyle::kBorder);
+ EXPECT_EQ(tabbed_pane_->GetOrientation(), TabbedPane::Orientation::kVertical);
+}
+
+// Tests tab strip style.
+TEST_F(TabbedPaneTest, TabStripBorderStyle) {
+ EXPECT_EQ(tabbed_pane_->GetStyle(), TabbedPane::TabStripStyle::kBorder);
+}
+
+// Tests tab strip style.
+TEST_F(TabbedPaneTest, TabStripHighlightStyle) {
+ MakeTabbedPane(TabbedPane::Orientation::kVertical,
+ TabbedPane::TabStripStyle::kHighlight);
+ EXPECT_EQ(tabbed_pane_->GetStyle(), TabbedPane::TabStripStyle::kHighlight);
+}
+
+// Tests the preferred size and layout when tabs are aligned horizontally.
+// TabbedPane requests a size that fits its largest tab, and disregards the
+// width of horizontal tab strips for preferred size calculations. Tab titles
+// are elided to fit the actual width.
TEST_F(TabbedPaneTest, SizeAndLayout) {
View* child1 = new StaticSizedView(gfx::Size(20, 10));
+ tabbed_pane_->AddTab(ASCIIToUTF16("tab1 with very long text"), child1);
+ View* child2 = new StaticSizedView(gfx::Size(5, 5));
+ tabbed_pane_->AddTab(ASCIIToUTF16("tab2 with very long text"), child2);
+ tabbed_pane_->SelectTabAt(0);
+
+ // |tabbed_pane_| width should match the largest child in horizontal mode.
+ EXPECT_EQ(tabbed_pane_->GetPreferredSize().width(), 20);
+ // |tabbed_pane_| reserves extra height for the tab strip in horizontal mode.
+ EXPECT_GT(tabbed_pane_->GetPreferredSize().height(), 10);
+
+ // The child views should resize to fit in larger tabbed panes.
+ tabbed_pane_->SetBounds(0, 0, 100, 200);
+ RunPendingMessages();
+ // |tabbed_pane_| has no border. Therefore the children should be as wide as
+ // the |tabbed_pane_|.
+ EXPECT_EQ(child1->bounds().width(), 100);
+ EXPECT_GT(child1->bounds().height(), 0);
+ // |tabbed_pane_| reserves extra height for the tab strip. Therefore the
+ // children's height should be smaller than the |tabbed_pane_|'s height.
+ EXPECT_LT(child1->bounds().height(), 200);
+
+ // If we switch to the other tab, it should get assigned the same bounds.
+ tabbed_pane_->SelectTabAt(1);
+ EXPECT_EQ(child1->bounds(), child2->bounds());
+}
+
+// Tests the preferred size and layout when tabs are aligned vertically..
+TEST_F(TabbedPaneTest, SizeAndLayoutInVerticalOrientation) {
+ MakeTabbedPane(TabbedPane::Orientation::kVertical,
+ TabbedPane::TabStripStyle::kBorder);
+ View* child1 = new StaticSizedView(gfx::Size(20, 10));
tabbed_pane_->AddTab(ASCIIToUTF16("tab1"), child1);
View* child2 = new StaticSizedView(gfx::Size(5, 5));
tabbed_pane_->AddTab(ASCIIToUTF16("tab2"), child2);
tabbed_pane_->SelectTabAt(0);
- // The |tabbed_pane_| implementation of Views has no border by default.
- // Therefore it should be as wide as the widest tab. The native Windows
- // tabbed pane has a border that used up extra space. Therefore the preferred
- // width is larger than the largest child.
- gfx::Size pref(tabbed_pane_->GetPreferredSize());
- EXPECT_GE(pref.width(), 20);
- EXPECT_GT(pref.height(), 10);
+ // |tabbed_pane_| reserves extra width for the tab strip in vertical mode.
+ EXPECT_GT(tabbed_pane_->GetPreferredSize().width(), 20);
+ // |tabbed_pane_| height should match the largest child in vertical mode.
+ EXPECT_EQ(tabbed_pane_->GetPreferredSize().height(), 10);
- // The bounds of our children should be smaller than the tabbed pane's bounds.
+ // The child views should resize to fit in larger tabbed panes.
tabbed_pane_->SetBounds(0, 0, 100, 200);
RunPendingMessages();
- gfx::Rect bounds(child1->bounds());
- EXPECT_GT(bounds.width(), 0);
- // The |tabbed_pane_| has no border. Therefore the children should be as wide
- // as the |tabbed_pane_|.
- EXPECT_LE(bounds.width(), 100);
- EXPECT_GT(bounds.height(), 0);
- EXPECT_LT(bounds.height(), 200);
+ EXPECT_GT(child1->bounds().width(), 0);
+ // |tabbed_pane_| reserves extra width for the tab strip. Therefore the
+ // children's width should be smaller than the |tabbed_pane_|'s width.
+ EXPECT_LT(child1->bounds().width(), 100);
+ // |tabbed_pane_| has no border. Therefore the children should be as high as
+ // the |tabbed_pane_|.
+ EXPECT_EQ(child1->bounds().height(), 200);
// If we switch to the other tab, it should get assigned the same bounds.
tabbed_pane_->SelectTabAt(1);
- EXPECT_EQ(bounds, child2->bounds());
+ EXPECT_EQ(child1->bounds(), child2->bounds());
}
TEST_F(TabbedPaneTest, AddAndSelect) {
@@ -161,14 +223,15 @@ TEST_F(TabbedPaneTest, SelectTabWithAccessibleAction) {
ui::AXNodeData data;
GetTabAt(i)->GetAccessibleNodeData(&data);
SCOPED_TRACE(testing::Message() << "Tab at index: " << i);
- EXPECT_EQ(ui::AX_ROLE_TAB, data.role);
- EXPECT_EQ(DefaultTabTitle(), data.GetString16Attribute(ui::AX_ATTR_NAME));
- EXPECT_TRUE(data.HasState(ui::AX_STATE_SELECTABLE));
- EXPECT_EQ(i == 0, data.HasState(ui::AX_STATE_SELECTED));
+ EXPECT_EQ(ax::mojom::Role::kTab, data.role);
+ EXPECT_EQ(DefaultTabTitle(),
+ data.GetString16Attribute(ax::mojom::StringAttribute::kName));
+ EXPECT_TRUE(data.HasState(ax::mojom::State::kSelectable));
+ EXPECT_EQ(i == 0, data.HasState(ax::mojom::State::kSelected));
}
ui::AXActionData action;
- action.action = ui::AX_ACTION_SET_SELECTION;
+ action.action = ax::mojom::Action::kSetSelection;
// Select the first tab.
GetTabAt(0)->HandleAccessibleAction(action);
diff --git a/chromium/ui/views/controls/table/table_view.cc b/chromium/ui/views/controls/table/table_view.cc
index e2082961b4f..a6c8234c5cb 100644
--- a/chromium/ui/views/controls/table/table_view.cc
+++ b/chromium/ui/views/controls/table/table_view.cc
@@ -447,21 +447,22 @@ bool TableView::GetTooltipTextOrigin(const gfx::Point& p,
}
void TableView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_TABLE;
- node_data->AddIntAttribute(ui::AX_ATTR_RESTRICTION,
- ui::AX_RESTRICTION_READ_ONLY);
- node_data->AddIntAttribute(ui::AX_ATTR_SET_SIZE, RowCount());
+ // TODO(aleventhal) Needs work, see https://crbug.com/811277.
+ node_data->role = ax::mojom::Role::kTable;
+ node_data->SetRestriction(ax::mojom::Restriction::kReadOnly);
+ node_data->AddIntAttribute(ax::mojom::IntAttribute::kSetSize, RowCount());
if (selection_model_.active() != ui::ListSelectionModel::kUnselectedIndex) {
// Get information about the active item, this is not the same as the set
// of selected items (of which there could be more than one).
- node_data->role = ui::AX_ROLE_ROW;
- node_data->AddIntAttribute(ui::AX_ATTR_POS_IN_SET,
+ node_data->role = ax::mojom::Role::kRow;
+ node_data->AddIntAttribute(ax::mojom::IntAttribute::kPosInSet,
selection_model_.active());
if (selection_model_.IsSelected(selection_model_.active())) {
- node_data->AddState(ui::AX_STATE_SELECTED);
+ node_data->AddState(ax::mojom::State::kSelected);
}
+ // Generate accessible name from column headers and selected cell text.
std::vector<base::string16> name_parts;
for (const VisibleColumn& visible_column : visible_columns_) {
base::string16 value = model_->GetText(
@@ -472,6 +473,9 @@ void TableView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
}
}
node_data->SetName(base::JoinString(name_parts, base::ASCIIToUTF16(", ")));
+ } else {
+ // Name requires a selection.
+ node_data->SetNameExplicitlyEmpty();
}
}
@@ -648,7 +652,7 @@ void TableView::OnFocus() {
scroll_view->SetHasFocusIndicator(true);
SchedulePaintForSelection();
- NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true);
}
void TableView::OnBlur() {
@@ -873,7 +877,7 @@ void TableView::SetSelectionModel(ui::ListSelectionModel new_selection) {
if (observer_)
observer_->OnSelectionChanged();
- NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true);
}
void TableView::AdvanceSelection(AdvanceDirection direction) {
diff --git a/chromium/ui/views/controls/textfield/textfield.cc b/chromium/ui/views/controls/textfield/textfield.cc
index 7be7cbfa1a6..d02b648714c 100644
--- a/chromium/ui/views/controls/textfield/textfield.cc
+++ b/chromium/ui/views/controls/textfield/textfield.cc
@@ -38,6 +38,7 @@
#include "ui/gfx/selection_bound.h"
#include "ui/native_theme/native_theme.h"
#include "ui/strings/grit/ui_strings.h"
+#include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/background.h"
#include "ui/views/controls/focus_ring.h"
#include "ui/views/controls/focusable_border.h"
@@ -45,6 +46,7 @@
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/native/native_view_host.h"
#include "ui/views/controls/textfield/textfield_controller.h"
+#include "ui/views/controls/views_text_services_context_menu.h"
#include "ui/views/drag_utils.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/native_cursor.h"
@@ -268,9 +270,9 @@ Textfield::Textfield()
background_color_(SK_ColorWHITE),
selection_text_color_(SK_ColorWHITE),
selection_background_color_(SK_ColorBLUE),
- placeholder_text_color_(kDefaultPlaceholderTextColor),
placeholder_text_draw_flags_(gfx::Canvas::DefaultCanvasTextAlignment()),
invalid_(false),
+ label_ax_id_(0),
text_input_type_(ui::TEXT_INPUT_TYPE_TEXT),
text_input_flags_(0),
performing_user_action_(false),
@@ -317,6 +319,11 @@ Textfield::~Textfield() {
}
}
+void Textfield::SetAssociatedLabel(Label* label) {
+ label_ax_id_ = label->GetViewAccessibility().GetUniqueId().Get();
+ accessible_name_ = label->text();
+}
+
void Textfield::SetReadOnly(bool read_only) {
// Update read-only without changing the focusable state (or active, etc.).
read_only_ = read_only;
@@ -345,7 +352,7 @@ void Textfield::SetText(const base::string16& new_text) {
UpdateCursorViewPosition();
UpdateCursorVisibility();
SchedulePaint();
- NotifyAccessibilityEvent(ui::AX_EVENT_VALUE_CHANGED, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kValueChanged, true);
}
void Textfield::AppendText(const base::string16& new_text) {
@@ -354,7 +361,7 @@ void Textfield::AppendText(const base::string16& new_text) {
model_->Append(new_text);
OnCaretBoundsChanged();
SchedulePaint();
- NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kTextChanged, true);
}
void Textfield::InsertOrReplaceText(const base::string16& new_text) {
@@ -614,9 +621,11 @@ void Textfield::SetBorder(std::unique_ptr<Border> b) {
}
gfx::NativeCursor Textfield::GetCursor(const ui::MouseEvent& event) {
+ bool platform_arrow = PlatformStyle::kTextfieldUsesDragCursorWhenDraggable;
bool in_selection = GetRenderText()->IsPointInSelection(event.location());
bool drag_event = event.type() == ui::ET_MOUSE_DRAGGED;
- bool text_cursor = !initiating_drag_ && (drag_event || !in_selection);
+ bool text_cursor =
+ !initiating_drag_ && (drag_event || !in_selection || !platform_arrow);
return text_cursor ? GetNativeIBeamCursor() : gfx::kNullCursor;
}
@@ -935,37 +944,40 @@ void Textfield::OnDragDone() {
}
void Textfield::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_TEXT_FIELD;
+ node_data->role = ax::mojom::Role::kTextField;
+ if (label_ax_id_) {
+ node_data->AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds,
+ {label_ax_id_});
+ }
+
node_data->SetName(accessible_name_);
// Editable state indicates support of editable interface, and is always set
// for a textfield, even if disabled or readonly.
- node_data->AddState(ui::AX_STATE_EDITABLE);
+ node_data->AddState(ax::mojom::State::kEditable);
if (enabled()) {
- node_data->AddIntAttribute(ui::AX_ATTR_DEFAULT_ACTION_VERB,
- ui::AX_DEFAULT_ACTION_VERB_ACTIVATE);
+ node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kActivate);
// Only readonly if enabled. Don't overwrite the disabled restriction.
- if (read_only()) {
- node_data->AddIntAttribute(ui::AX_ATTR_RESTRICTION,
- ui::AX_RESTRICTION_READ_ONLY);
- }
+ if (read_only())
+ node_data->SetRestriction(ax::mojom::Restriction::kReadOnly);
}
if (text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD) {
- node_data->AddState(ui::AX_STATE_PROTECTED);
+ node_data->AddState(ax::mojom::State::kProtected);
node_data->SetValue(base::string16(
text().size(), gfx::RenderText::kPasswordReplacementChar));
} else {
node_data->SetValue(text());
}
- node_data->AddStringAttribute(ui::AX_ATTR_PLACEHOLDER,
+ node_data->AddStringAttribute(ax::mojom::StringAttribute::kPlaceholder,
base::UTF16ToUTF8(GetPlaceholderText()));
const gfx::Range range = GetSelectedRange();
- node_data->AddIntAttribute(ui::AX_ATTR_TEXT_SEL_START, range.start());
- node_data->AddIntAttribute(ui::AX_ATTR_TEXT_SEL_END, range.end());
+ node_data->AddIntAttribute(ax::mojom::IntAttribute::kTextSelStart,
+ range.start());
+ node_data->AddIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, range.end());
}
bool Textfield::HandleAccessibleAction(const ui::AXActionData& action_data) {
- if (action_data.action == ui::AX_ACTION_SET_SELECTION) {
+ if (action_data.action == ax::mojom::Action::kSetSelection) {
if (action_data.anchor_node_id != action_data.focus_node_id)
return false;
// TODO(nektar): Check that the focus_node_id matches the ID of this node.
@@ -977,11 +989,11 @@ bool Textfield::HandleAccessibleAction(const ui::AXActionData& action_data) {
if (read_only())
return View::HandleAccessibleAction(action_data);
- if (action_data.action == ui::AX_ACTION_SET_VALUE) {
+ if (action_data.action == ax::mojom::Action::kSetValue) {
SetText(action_data.value);
ClearSelection();
return true;
- } else if (action_data.action == ui::AX_ACTION_REPLACE_SELECTED_TEXT) {
+ } else if (action_data.action == ax::mojom::Action::kReplaceSelectedText) {
InsertOrReplaceText(action_data.value);
ClearSelection();
return true;
@@ -1688,7 +1700,7 @@ void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) {
case ui::TextEditCommand::DELETE_TO_END_OF_LINE:
case ui::TextEditCommand::DELETE_TO_END_OF_PARAGRAPH:
add_to_kill_buffer = text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD;
- // Fall through.
+ FALLTHROUGH;
case ui::TextEditCommand::DELETE_WORD_BACKWARD:
case ui::TextEditCommand::DELETE_WORD_FORWARD:
if (HasSelection())
@@ -1872,6 +1884,10 @@ void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) {
OnAfterUserAction();
}
+void Textfield::OffsetDoubleClickWord(int offset) {
+ selection_controller_.OffsetDoubleClickWord(offset);
+}
+
////////////////////////////////////////////////////////////////////////////////
// Textfield, private:
@@ -1984,7 +2000,7 @@ void Textfield::UpdateAfterChange(bool text_changed, bool cursor_changed) {
if (text_changed) {
if (controller_)
controller_->ContentsChanged(this, text());
- NotifyAccessibilityEvent(ui::AX_EVENT_VALUE_CHANGED, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kValueChanged, true);
}
if (cursor_changed) {
UpdateCursorViewPosition();
@@ -2036,9 +2052,10 @@ void Textfield::PaintTextAndCursor(gfx::Canvas* canvas) {
GetPlaceholderText(),
placeholder_font_list_.has_value() ? placeholder_font_list_.value()
: GetFontList(),
- ui::MaterialDesignController::IsSecondaryUiMaterial()
- ? SkColorSetA(GetTextColor(), 0x83)
- : placeholder_text_color_,
+ placeholder_text_color_.value_or(
+ ui::MaterialDesignController::IsSecondaryUiMaterial()
+ ? SkColorSetA(GetTextColor(), 0x83)
+ : kDefaultPlaceholderTextColor),
render_text->display_rect(), placeholder_text_draw_flags);
}
@@ -2063,7 +2080,7 @@ void Textfield::OnCaretBoundsChanged() {
GetInputMethod()->OnCaretBoundsChanged(this);
if (touch_selection_controller_)
touch_selection_controller_->SelectionChanged();
- NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_SELECTION_CHANGED, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kTextSelectionChanged, true);
}
void Textfield::OnBeforeUserAction() {
@@ -2125,7 +2142,11 @@ void Textfield::UpdateContextMenu() {
// IsCommandIdEnabled() as appropriate, for the commands added.
if (controller_)
controller_->UpdateContextMenu(context_menu_contents_.get());
+
+ text_services_context_menu_ = ViewsTextServicesContextMenu::Create(
+ context_menu_contents_.get(), this);
}
+
context_menu_runner_.reset(
new MenuRunner(context_menu_contents_.get(),
MenuRunner::HAS_MNEMONICS | MenuRunner::CONTEXT_MENU));
diff --git a/chromium/ui/views/controls/textfield/textfield.h b/chromium/ui/views/controls/textfield/textfield.h
index 1c36080fcf6..db30abdd006 100644
--- a/chromium/ui/views/controls/textfield/textfield.h
+++ b/chromium/ui/views/controls/textfield/textfield.h
@@ -40,8 +40,10 @@ class TimeDelta;
namespace views {
+class Label;
class MenuRunner;
class TextfieldController;
+class ViewsTextServicesContextMenu;
// A views/skia textfield implementation. No platform-specific code is used.
class VIEWS_EXPORT Textfield : public View,
@@ -218,9 +220,15 @@ class VIEWS_EXPORT Textfield : public View,
// Clears Edit history.
void ClearEditHistory();
- // Set the accessible name of the text field.
+ // Set the accessible name of the text field. If the textfield has a visible
+ // label, use SetAssociatedLabel() instead.
void SetAccessibleName(const base::string16& name);
+ // If the accessible name should be the same as the label text, use this. It
+ // will set both the accessible label relationship and the accessible name
+ // from the contents of the label.
+ void SetAssociatedLabel(Label* label);
+
// Set extra spacing placed between glyphs; used for obscured text styling.
void SetGlyphSpacing(int spacing);
@@ -352,6 +360,11 @@ class VIEWS_EXPORT Textfield : public View,
// Executes the given |command|.
virtual void ExecuteTextEditCommand(ui::TextEditCommand command);
+ // Offsets the double-clicked word's range. This is only used in the unusual
+ // case where the text changes on the second mousedown of a double-click.
+ // This is harmless if there is not a currently double-clicked word.
+ void OffsetDoubleClickWord(int offset);
+
private:
friend class TextfieldTestApi;
@@ -488,8 +501,10 @@ class VIEWS_EXPORT Textfield : public View,
base::string16 placeholder_text_;
// Placeholder text color.
- // TODO(estade): remove this when Harmony/MD is default.
- SkColor placeholder_text_color_;
+ // TODO(newcomer): Use NativeTheme to define different default placeholder
+ // text colors for chrome/CrOS when harmony is enabled by default
+ // (https://crbug.com/803279).
+ base::Optional<SkColor> placeholder_text_color_;
// The draw flags specified for |placeholder_text_|.
int placeholder_text_draw_flags_;
@@ -502,6 +517,9 @@ class VIEWS_EXPORT Textfield : public View,
// such.
bool invalid_;
+ // The unique id for the associated label's accessible object.
+ int32_t label_ax_id_;
+
// The accessible name of the text field.
base::string16 accessible_name_;
@@ -551,6 +569,7 @@ class VIEWS_EXPORT Textfield : public View,
// Context menu related members.
std::unique_ptr<ui::SimpleMenuModel> context_menu_contents_;
+ std::unique_ptr<ViewsTextServicesContextMenu> text_services_context_menu_;
std::unique_ptr<views::MenuRunner> context_menu_runner_;
// View containing the text cursor.
diff --git a/chromium/ui/views/controls/textfield/textfield_test_api.cc b/chromium/ui/views/controls/textfield/textfield_test_api.cc
index bef918aea45..3f756dfaad7 100644
--- a/chromium/ui/views/controls/textfield/textfield_test_api.cc
+++ b/chromium/ui/views/controls/textfield/textfield_test_api.cc
@@ -5,6 +5,7 @@
#include "ui/views/controls/textfield/textfield_test_api.h"
#include "ui/gfx/geometry/rect.h"
+#include "ui/views/controls/views_text_services_context_menu.h"
namespace views {
@@ -33,4 +34,10 @@ void TextfieldTestApi::SetCursorViewRect(gfx::Rect bounds) {
textfield_->cursor_view_.SetBoundsRect(bounds);
}
+bool TextfieldTestApi::IsTextDirectionCheckedInContextMenu(
+ base::i18n::TextDirection direction) const {
+ return ViewsTextServicesContextMenu::IsTextDirectionCheckedForTesting(
+ textfield_->text_services_context_menu_.get(), direction);
+}
+
} // namespace views
diff --git a/chromium/ui/views/controls/textfield/textfield_test_api.h b/chromium/ui/views/controls/textfield/textfield_test_api.h
index 8b898715afd..c111175ea47 100644
--- a/chromium/ui/views/controls/textfield/textfield_test_api.h
+++ b/chromium/ui/views/controls/textfield/textfield_test_api.h
@@ -5,6 +5,7 @@
#ifndef UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_TEST_API_H_
#define UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_TEST_API_H_
+#include "base/i18n/rtl.h"
#include "base/macros.h"
#include "ui/views/controls/textfield/textfield.h"
@@ -50,6 +51,9 @@ class TextfieldTestApi {
bool IsCursorVisible() const { return textfield_->cursor_view_.visible(); }
+ bool IsTextDirectionCheckedInContextMenu(
+ base::i18n::TextDirection direction) const;
+
private:
Textfield* textfield_;
diff --git a/chromium/ui/views/controls/textfield/textfield_unittest.cc b/chromium/ui/views/controls/textfield/textfield_unittest.cc
index 4ee16e76284..5cfb980672f 100644
--- a/chromium/ui/views/controls/textfield/textfield_unittest.cc
+++ b/chromium/ui/views/controls/textfield/textfield_unittest.cc
@@ -890,9 +890,11 @@ TEST_F(TextfieldTest, ControlAndSelectTest) {
// Test word select.
SendWordEvent(ui::VKEY_RIGHT, true);
-#if defined(OS_WIN) // Select word right includes space/punctuation.
+#if defined(OS_WIN) // Windows breaks on word starts and includes spaces.
+ EXPECT_STR_EQ("one ", textfield_->GetSelectedText());
+ SendWordEvent(ui::VKEY_RIGHT, true);
EXPECT_STR_EQ("one two ", textfield_->GetSelectedText());
-#else // Non-Windows: select word right does NOT include space/punctuation.
+#else // Non-Windows breaks on word ends and does NOT include spaces.
EXPECT_STR_EQ("one two", textfield_->GetSelectedText());
#endif
SendWordEvent(ui::VKEY_RIGHT, true);
@@ -1441,6 +1443,9 @@ TEST_F(TextfieldTest, CursorMovement) {
// Ctrl+Right, then Ctrl+Left should move the cursor to the beginning of the
// first word.
SendWordEvent(ui::VKEY_RIGHT, shift);
+#if defined(OS_WIN) // Windows breaks on word start, move further to pass "ne".
+ SendWordEvent(ui::VKEY_RIGHT, shift);
+#endif
SendWordEvent(ui::VKEY_LEFT, shift);
SendKeyEvent(ui::VKEY_O);
EXPECT_STR_EQ(" one two", textfield_->text());
@@ -3214,18 +3219,18 @@ TEST_F(TextfieldTest, AccessiblePasswordTest) {
ui::AXNodeData node_data_regular;
textfield_->GetAccessibleNodeData(&node_data_regular);
- EXPECT_EQ(ui::AX_ROLE_TEXT_FIELD, node_data_regular.role);
- EXPECT_EQ(ASCIIToUTF16("password"),
- node_data_regular.GetString16Attribute(ui::AX_ATTR_VALUE));
- EXPECT_FALSE(node_data_regular.HasState(ui::AX_STATE_PROTECTED));
+ EXPECT_EQ(ax::mojom::Role::kTextField, node_data_regular.role);
+ EXPECT_EQ(ASCIIToUTF16("password"), node_data_regular.GetString16Attribute(
+ ax::mojom::StringAttribute::kValue));
+ EXPECT_FALSE(node_data_regular.HasState(ax::mojom::State::kProtected));
textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
ui::AXNodeData node_data_protected;
textfield_->GetAccessibleNodeData(&node_data_protected);
- EXPECT_EQ(ui::AX_ROLE_TEXT_FIELD, node_data_protected.role);
- EXPECT_EQ(UTF8ToUTF16("••••••••"),
- node_data_protected.GetString16Attribute(ui::AX_ATTR_VALUE));
- EXPECT_TRUE(node_data_protected.HasState(ui::AX_STATE_PROTECTED));
+ EXPECT_EQ(ax::mojom::Role::kTextField, node_data_protected.role);
+ EXPECT_EQ(UTF8ToUTF16("••••••••"), node_data_protected.GetString16Attribute(
+ ax::mojom::StringAttribute::kValue));
+ EXPECT_TRUE(node_data_protected.HasState(ax::mojom::State::kProtected));
}
// Verify that cursor visibility is controlled by SetCursorEnabled.
@@ -3400,4 +3405,37 @@ TEST_F(TextfieldTest, SendingDeletePreservesShiftFlag) {
EXPECT_EQ(ui::EF_SHIFT_DOWN, textfield_->event_flags());
}
+#if defined(OS_MACOSX)
+// Tests to see if the BiDi submenu items are updated correctly when the
+// textfield's text direction is changed.
+TEST_F(TextfieldTest, TextServicesContextMenuTextDirectionTest) {
+ InitTextfield();
+ EXPECT_TRUE(textfield_->context_menu_controller());
+
+ EXPECT_TRUE(GetContextMenuModel());
+
+ textfield_->ChangeTextDirectionAndLayoutAlignment(
+ base::i18n::TextDirection::LEFT_TO_RIGHT);
+ test_api_->UpdateContextMenu();
+
+ EXPECT_FALSE(test_api_->IsTextDirectionCheckedInContextMenu(
+ base::i18n::TextDirection::UNKNOWN_DIRECTION));
+ EXPECT_TRUE(test_api_->IsTextDirectionCheckedInContextMenu(
+ base::i18n::TextDirection::LEFT_TO_RIGHT));
+ EXPECT_FALSE(test_api_->IsTextDirectionCheckedInContextMenu(
+ base::i18n::TextDirection::RIGHT_TO_LEFT));
+
+ textfield_->ChangeTextDirectionAndLayoutAlignment(
+ base::i18n::TextDirection::RIGHT_TO_LEFT);
+ test_api_->UpdateContextMenu();
+
+ EXPECT_FALSE(test_api_->IsTextDirectionCheckedInContextMenu(
+ base::i18n::TextDirection::UNKNOWN_DIRECTION));
+ EXPECT_FALSE(test_api_->IsTextDirectionCheckedInContextMenu(
+ base::i18n::TextDirection::LEFT_TO_RIGHT));
+ EXPECT_TRUE(test_api_->IsTextDirectionCheckedInContextMenu(
+ base::i18n::TextDirection::RIGHT_TO_LEFT));
+}
+#endif // defined(OS_MACOSX)
+
} // namespace views
diff --git a/chromium/ui/views/controls/tree/tree_view.cc b/chromium/ui/views/controls/tree/tree_view.cc
index d8382aa975f..f5709270c99 100644
--- a/chromium/ui/views/controls/tree/tree_view.cc
+++ b/chromium/ui/views/controls/tree/tree_view.cc
@@ -272,8 +272,8 @@ void TreeView::SetSelectedNode(TreeModelNode* model_node) {
controller_->OnTreeViewSelectionChanged(this);
if (changed) {
- NotifyAccessibilityEvent(ui::AX_EVENT_TEXT_CHANGED, true);
- NotifyAccessibilityEvent(ui::AX_EVENT_SELECTION, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kTextChanged, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kSelection, true);
}
}
@@ -425,14 +425,13 @@ void TreeView::ShowContextMenu(const gfx::Point& p,
}
void TreeView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_TREE;
- node_data->AddIntAttribute(ui::AX_ATTR_RESTRICTION,
- ui::AX_RESTRICTION_READ_ONLY);
+ node_data->role = ax::mojom::Role::kTree;
+ node_data->SetRestriction(ax::mojom::Restriction::kReadOnly);
if (!selected_node_)
return;
// Get selected item info.
- node_data->role = ui::AX_ROLE_TREE_ITEM;
+ node_data->role = ax::mojom::Role::kTreeItem;
node_data->SetName(selected_node_->model_node()->GetTitle());
}
diff --git a/chromium/ui/views/controls/views_text_services_context_menu.cc b/chromium/ui/views/controls/views_text_services_context_menu.cc
new file mode 100644
index 00000000000..ec5975312cc
--- /dev/null
+++ b/chromium/ui/views/controls/views_text_services_context_menu.cc
@@ -0,0 +1,25 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/controls/views_text_services_context_menu.h"
+
+#include "base/logging.h"
+
+namespace views {
+
+// static
+std::unique_ptr<ViewsTextServicesContextMenu>
+ViewsTextServicesContextMenu::Create(ui::SimpleMenuModel* menu,
+ Textfield* client) {
+ return nullptr;
+}
+
+bool ViewsTextServicesContextMenu::IsTextDirectionCheckedForTesting(
+ ViewsTextServicesContextMenu* menu,
+ base::i18n::TextDirection direction) {
+ NOTREACHED();
+ return false;
+}
+
+} // namespace views \ No newline at end of file
diff --git a/chromium/ui/views/controls/views_text_services_context_menu.h b/chromium/ui/views/controls/views_text_services_context_menu.h
new file mode 100644
index 00000000000..2388b27653b
--- /dev/null
+++ b/chromium/ui/views/controls/views_text_services_context_menu.h
@@ -0,0 +1,41 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef UI_VIEWS_CONTROLS_TEXTFIELD_VIEWS_TEXT_SERVICES_CONTEXT_MENU_H_
+#define UI_VIEWS_CONTROLS_TEXTFIELD_VIEWS_TEXT_SERVICES_CONTEXT_MENU_H_
+
+#include <memory>
+
+#include "base/i18n/rtl.h"
+#include "ui/views/views_export.h"
+
+namespace ui {
+class SimpleMenuModel;
+}
+
+namespace views {
+
+class Textfield;
+
+// This class is used to add and handle text service items in the text context
+// menu.
+class ViewsTextServicesContextMenu {
+ public:
+ virtual ~ViewsTextServicesContextMenu() {}
+
+ // Creates a platform-specific ViewsTextServicesContextMenu object.
+ static std::unique_ptr<ViewsTextServicesContextMenu> Create(
+ ui::SimpleMenuModel* menu,
+ Textfield* textfield);
+
+ // Method for testing. Returns true if the text direction BiDi submenu item
+ // in |menu| should be checked.
+ VIEWS_EXPORT static bool IsTextDirectionCheckedForTesting(
+ ViewsTextServicesContextMenu* menu,
+ base::i18n::TextDirection direction);
+};
+
+} // namespace views
+
+#endif // UI_VIEWS_CONTROLS_TEXTFIELD_VIEWS_TEXT_SERVICES_CONTEXT_MENU_H_
diff --git a/chromium/ui/views/controls/views_text_services_context_menu_mac.mm b/chromium/ui/views/controls/views_text_services_context_menu_mac.mm
new file mode 100644
index 00000000000..be96d8ac4ee
--- /dev/null
+++ b/chromium/ui/views/controls/views_text_services_context_menu_mac.mm
@@ -0,0 +1,83 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/views/controls/views_text_services_context_menu.h"
+
+#include "base/memory/ptr_util.h"
+#include "ui/base/cocoa/text_services_context_menu.h"
+#include "ui/base/models/simple_menu_model.h"
+#include "ui/views/controls/textfield/textfield.h"
+
+namespace views {
+
+namespace {
+
+// This class serves as a bridge to TextServicesContextMenu to add and handle
+// text service items in the context menu. The items include Speech, Look Up
+// and BiDi.
+// TODO (spqchan): Add Look Up and BiDi.
+class ViewsTextServicesContextMenuMac
+ : public ViewsTextServicesContextMenu,
+ public ui::TextServicesContextMenu::Delegate {
+ public:
+ ViewsTextServicesContextMenuMac(ui::SimpleMenuModel* menu, Textfield* client)
+ : text_services_menu_(this), client_(client) {
+ text_services_menu_.AppendToContextMenu(menu);
+ text_services_menu_.AppendEditableItems(menu);
+ }
+
+ ~ViewsTextServicesContextMenuMac() override {}
+
+ // TextServicesContextMenu::Delegate:
+ base::string16 GetSelectedText() const override {
+ return client_->GetSelectedText();
+ }
+
+ bool IsTextDirectionEnabled(
+ base::i18n::TextDirection direction) const override {
+ return direction != base::i18n::UNKNOWN_DIRECTION;
+ }
+
+ bool IsTextDirectionChecked(
+ base::i18n::TextDirection direction) const override {
+ return direction != base::i18n::UNKNOWN_DIRECTION &&
+ client_->GetTextDirection() == direction;
+ }
+
+ void UpdateTextDirection(base::i18n::TextDirection direction) override {
+ DCHECK_NE(direction, base::i18n::UNKNOWN_DIRECTION);
+
+ base::i18n::TextDirection text_direction =
+ direction == base::i18n::LEFT_TO_RIGHT ? base::i18n::LEFT_TO_RIGHT
+ : base::i18n::RIGHT_TO_LEFT;
+ client_->ChangeTextDirectionAndLayoutAlignment(text_direction);
+ }
+
+ private:
+ // Appends and handles the text service menu.
+ ui::TextServicesContextMenu text_services_menu_;
+
+ // The view associated with the menu. Weak. Owns |this|.
+ Textfield* client_;
+
+ DISALLOW_COPY_AND_ASSIGN(ViewsTextServicesContextMenuMac);
+};
+
+} // namespace
+
+// static
+std::unique_ptr<ViewsTextServicesContextMenu>
+ViewsTextServicesContextMenu::Create(ui::SimpleMenuModel* menu,
+ Textfield* client) {
+ return std::make_unique<ViewsTextServicesContextMenuMac>(menu, client);
+}
+
+// static
+bool ViewsTextServicesContextMenu::IsTextDirectionCheckedForTesting(
+ ViewsTextServicesContextMenu* menu,
+ base::i18n::TextDirection direction) {
+ return static_cast<views::ViewsTextServicesContextMenuMac*>(menu)
+ ->IsTextDirectionChecked(direction);
+}
+} // namespace views \ No newline at end of file
diff --git a/chromium/ui/views/controls/webview/webview.cc b/chromium/ui/views/controls/webview/webview.cc
index b65a9e4cbbe..5144b14e415 100644
--- a/chromium/ui/views/controls/webview/webview.cc
+++ b/chromium/ui/views/controls/webview/webview.cc
@@ -14,7 +14,7 @@
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/events/event.h"
#include "ui/views/controls/native/native_view_host.h"
@@ -54,11 +54,11 @@ content::WebContents* WebView::GetWebContents() {
void WebView::SetWebContents(content::WebContents* replacement) {
if (replacement == web_contents())
return;
+ SetCrashedOverlayView(nullptr);
DetachWebContents();
WebContentsObserver::Observe(replacement);
// web_contents() now returns |replacement| from here onwards.
- SetFocusBehavior(web_contents() ? FocusBehavior::ALWAYS
- : FocusBehavior::NEVER);
+ UpdateCrashedOverlayView();
if (wc_owner_.get() != replacement)
wc_owner_.reset();
if (embed_fullscreen_widget_mode_enabled_) {
@@ -91,6 +91,25 @@ void WebView::SetResizeBackgroundColor(SkColor resize_background_color) {
holder_->set_resize_background_color(resize_background_color);
}
+void WebView::SetCrashedOverlayView(View* crashed_overlay_view) {
+ if (crashed_overlay_view_ == crashed_overlay_view)
+ return;
+
+ if (crashed_overlay_view_) {
+ RemoveChildView(crashed_overlay_view_);
+ if (!crashed_overlay_view_->owned_by_client())
+ delete crashed_overlay_view_;
+ }
+
+ crashed_overlay_view_ = crashed_overlay_view;
+ if (crashed_overlay_view_) {
+ AddChildView(crashed_overlay_view_);
+ crashed_overlay_view_->SetBoundsRect(gfx::Rect(size()));
+ }
+
+ UpdateCrashedOverlayView();
+}
+
////////////////////////////////////////////////////////////////////////////////
// WebView, View overrides:
@@ -111,6 +130,9 @@ std::unique_ptr<content::WebContents> WebView::SwapWebContents(
}
void WebView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
+ if (crashed_overlay_view_)
+ crashed_overlay_view_->SetBoundsRect(gfx::Rect(size()));
+
// In most cases, the holder is simply sized to fill this WebView's bounds.
// Only WebContentses that are in fullscreen mode and being screen-captured
// will engage the special layout/sizing behavior.
@@ -181,21 +203,25 @@ bool WebView::OnMousePressed(const ui::MouseEvent& event) {
}
void WebView::OnFocus() {
- if (web_contents())
+ if (web_contents() && !web_contents()->IsCrashed())
web_contents()->Focus();
}
void WebView::AboutToRequestFocusFromTabTraversal(bool reverse) {
- if (web_contents())
+ if (web_contents() && !web_contents()->IsCrashed())
web_contents()->FocusThroughTabTraversal(reverse);
}
void WebView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_WEB_VIEW;
+ node_data->role = ax::mojom::Role::kWebView;
+ // A webview does not need an accessible name as the document title is
+ // provided via other means. Providing it here would be redundant.
+ // Mark the name as explicitly empty so that accessibility_checks pass.
+ node_data->SetNameExplicitlyEmpty();
}
gfx::NativeViewAccessible WebView::GetNativeViewAccessible() {
- if (web_contents()) {
+ if (web_contents() && !web_contents()->IsCrashed()) {
content::RenderWidgetHostView* host_view =
web_contents()->GetRenderWidgetHostView();
if (host_view)
@@ -216,10 +242,12 @@ bool WebView::EmbedsFullscreenWidget() const {
// WebView, content::WebContentsObserver implementation:
void WebView::RenderViewReady() {
+ UpdateCrashedOverlayView();
NotifyAccessibilityWebContentsChanged();
}
void WebView::RenderViewDeleted(content::RenderViewHost* render_view_host) {
+ UpdateCrashedOverlayView();
NotifyAccessibilityWebContentsChanged();
}
@@ -264,6 +292,7 @@ void WebView::OnWebContentsFocused(
}
void WebView::RenderProcessGone(base::TerminationStatus status) {
+ UpdateCrashedOverlayView();
NotifyAccessibilityWebContentsChanged();
}
@@ -317,9 +346,32 @@ void WebView::ReattachForFullscreenChange(bool enter_fullscreen) {
NotifyAccessibilityWebContentsChanged();
}
+void WebView::UpdateCrashedOverlayView() {
+ // TODO(dmazzoni): Fix WebContents::IsCrashed() so we can call that
+ // instead of checking termination status codes.
+ if (web_contents() &&
+ web_contents()->GetCrashedStatus() !=
+ base::TERMINATION_STATUS_NORMAL_TERMINATION &&
+ web_contents()->GetCrashedStatus() !=
+ base::TERMINATION_STATUS_STILL_RUNNING &&
+ crashed_overlay_view_) {
+ SetFocusBehavior(FocusBehavior::NEVER);
+ holder_->SetVisible(false);
+ crashed_overlay_view_->SetVisible(true);
+ return;
+ }
+
+ SetFocusBehavior(web_contents() ? FocusBehavior::ALWAYS
+ : FocusBehavior::NEVER);
+
+ if (crashed_overlay_view_)
+ crashed_overlay_view_->SetVisible(false);
+ holder_->SetVisible(true);
+}
+
void WebView::NotifyAccessibilityWebContentsChanged() {
if (web_contents())
- NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, false);
+ NotifyAccessibilityEvent(ax::mojom::Event::kChildrenChanged, false);
}
content::WebContents* WebView::CreateWebContents(
diff --git a/chromium/ui/views/controls/webview/webview.h b/chromium/ui/views/controls/webview/webview.h
index 73ad929c699..afdd0a03938 100644
--- a/chromium/ui/views/controls/webview/webview.h
+++ b/chromium/ui/views/controls/webview/webview.h
@@ -79,6 +79,11 @@ class WEBVIEW_EXPORT WebView : public View,
// by default.
void SetResizeBackgroundColor(SkColor resize_background_color);
+ // If provided, this View will be shown in place of the web contents
+ // when the web contents is in a crashed state. This is cleared automatically
+ // if the web contents is changed.
+ void SetCrashedOverlayView(View* crashed_overlay_view);
+
// When used to host UI, we need to explicitly allow accelerators to be
// processed. Default is false.
void set_allow_accelerators(bool allow_accelerators) {
@@ -140,6 +145,7 @@ class WEBVIEW_EXPORT WebView : public View,
void AttachWebContents();
void DetachWebContents();
void ReattachForFullscreenChange(bool enter_fullscreen);
+ void UpdateCrashedOverlayView();
void NotifyAccessibilityWebContentsChanged();
// Create a regular or test web contents (based on whether we're running
@@ -158,6 +164,7 @@ class WEBVIEW_EXPORT WebView : public View,
bool is_embedding_fullscreen_widget_;
content::BrowserContext* browser_context_;
bool allow_accelerators_;
+ View* crashed_overlay_view_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(WebView);
};
diff --git a/chromium/ui/views/controls/webview/webview_unittest.cc b/chromium/ui/views/controls/webview/webview_unittest.cc
index 2ca7683f8d8..b3c86732c50 100644
--- a/chromium/ui/views/controls/webview/webview_unittest.cc
+++ b/chromium/ui/views/controls/webview/webview_unittest.cc
@@ -48,8 +48,8 @@ class WebViewTestViewsDelegate : public views::TestViewsDelegate {
DISALLOW_COPY_AND_ASSIGN(WebViewTestViewsDelegate);
};
-// Provides functionality to observe events on a WebContents like WasShown/
-// WasHidden/WebContentsDestroyed.
+// Provides functionality to observe events on a WebContents like
+// OnVisibilityChanged/WebContentsDestroyed.
class WebViewTestWebContentsObserver : public content::WebContentsObserver {
public:
WebViewTestWebContentsObserver(content::WebContents* web_contents)
@@ -72,18 +72,27 @@ class WebViewTestWebContentsObserver : public content::WebContentsObserver {
web_contents_ = NULL;
}
- void WasShown() override {
+ void OnVisibilityChanged(content::Visibility visibility) override {
+ switch (visibility) {
+ case content::Visibility::VISIBLE: {
#if defined(USE_AURA)
- valid_root_while_shown_ =
- web_contents()->GetNativeView()->GetRootWindow() != NULL;
+ valid_root_while_shown_ =
+ web_contents()->GetNativeView()->GetRootWindow() != NULL;
#endif
- was_shown_ = true;
- ++shown_count_;
- }
-
- void WasHidden() override {
- was_shown_ = false;
- ++hidden_count_;
+ was_shown_ = true;
+ ++shown_count_;
+ break;
+ }
+ case content::Visibility::HIDDEN: {
+ was_shown_ = false;
+ ++hidden_count_;
+ break;
+ }
+ default: {
+ ADD_FAILURE() << "Unexpected call to OnVisibilityChanged.";
+ break;
+ }
+ }
}
bool was_shown() const { return was_shown_; }
@@ -485,4 +494,58 @@ TEST_F(WebViewUnitTest, DetachedWebViewDestructor) {
webview.reset();
}
+// Test that the specified crashed overlay view is shown when a WebContents
+// is in a crashed state.
+TEST_F(WebViewUnitTest, CrashedOverlayView) {
+ const std::unique_ptr<content::WebContents> web_contents(CreateWebContents());
+ std::unique_ptr<WebView> web_view(
+ new WebView(web_contents->GetBrowserContext()));
+ View* contents_view = top_level_widget()->GetContentsView();
+ contents_view->AddChildView(web_view.get());
+ web_view->SetWebContents(web_contents.get());
+
+ View* crashed_overlay_view = new View();
+ web_view->SetCrashedOverlayView(crashed_overlay_view);
+ EXPECT_FALSE(crashed_overlay_view->IsDrawn());
+
+ // Normally when a renderer crashes, the WebView will learn about it
+ // automatically via WebContentsObserver. Since this is a test
+ // WebContents, simulate that by calling SetIsCrashed and then
+ // explicitly calling RenderViewDeleted on the WebView to trigger it
+ // to swap in the crashed overlay view.
+ web_contents->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
+ EXPECT_TRUE(web_contents->IsCrashed());
+ static_cast<content::WebContentsObserver*>(web_view.get())
+ ->RenderViewDeleted(nullptr);
+ EXPECT_TRUE(crashed_overlay_view->IsDrawn());
+}
+
+// Test that a crashed overlay view isn't deleted if it's owned by client.
+TEST_F(WebViewUnitTest, CrashedOverlayViewOwnedbyClient) {
+ const std::unique_ptr<content::WebContents> web_contents(CreateWebContents());
+ std::unique_ptr<WebView> web_view(
+ new WebView(web_contents->GetBrowserContext()));
+ View* contents_view = top_level_widget()->GetContentsView();
+ contents_view->AddChildView(web_view.get());
+ web_view->SetWebContents(web_contents.get());
+
+ View* crashed_overlay_view = new View();
+ crashed_overlay_view->set_owned_by_client();
+ web_view->SetCrashedOverlayView(crashed_overlay_view);
+ EXPECT_FALSE(crashed_overlay_view->IsDrawn());
+
+ // Simulate a renderer crash (see above).
+ web_contents->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
+ EXPECT_TRUE(web_contents->IsCrashed());
+ static_cast<content::WebContentsObserver*>(web_view.get())
+ ->RenderViewDeleted(nullptr);
+ EXPECT_TRUE(crashed_overlay_view->IsDrawn());
+
+ web_view->SetCrashedOverlayView(nullptr);
+ web_view.reset();
+
+ // This shouldn't crash, we still own this.
+ delete crashed_overlay_view;
+}
+
} // namespace views
diff --git a/chromium/ui/views/examples/label_example.cc b/chromium/ui/views/examples/label_example.cc
index 05e30aa2e12..4af92326d72 100644
--- a/chromium/ui/views/examples/label_example.cc
+++ b/chromium/ui/views/examples/label_example.cc
@@ -101,7 +101,7 @@ void LabelExample::CreateExampleView(View* container) {
label->SetFontList(gfx::FontList("Courier, 18px"));
gfx::ShadowValues shadows(1,
gfx::ShadowValue(gfx::Vector2d(), 1, SK_ColorRED));
- gfx::ShadowValue shadow(gfx::Vector2d(2, 2), 0, SK_ColorGRAY);
+ constexpr gfx::ShadowValue shadow(gfx::Vector2d(2, 2), 0, SK_ColorGRAY);
shadows.push_back(shadow);
label->SetShadows(shadows);
container->AddChildView(label);
diff --git a/chromium/ui/views/mus/BUILD.gn b/chromium/ui/views/mus/BUILD.gn
index dc46a047be4..a8e4c997153 100644
--- a/chromium/ui/views/mus/BUILD.gn
+++ b/chromium/ui/views/mus/BUILD.gn
@@ -53,9 +53,9 @@ jumbo_component("mus") {
"//mojo/public/cpp/bindings",
"//net",
"//services/catalog/public/cpp",
- "//services/catalog/public/interfaces:constants",
+ "//services/catalog/public/mojom:constants",
"//services/service_manager/public/cpp",
- "//services/service_manager/public/interfaces",
+ "//services/service_manager/public/mojom",
"//services/ui/public/cpp",
"//services/ui/public/interfaces",
"//skia",
@@ -250,6 +250,7 @@ test("views_mus_interactive_ui_tests") {
"//ui/aura",
"//ui/aura:test_support",
"//ui/base",
+ "//ui/base:test_support",
"//ui/base/ime",
"//ui/events:events_base",
"//ui/events:test_support",
diff --git a/chromium/ui/views/mus/aura_init.cc b/chromium/ui/views/mus/aura_init.cc
index 60773f241f9..7631ab57b0e 100644
--- a/chromium/ui/views/mus/aura_init.cc
+++ b/chromium/ui/views/mus/aura_init.cc
@@ -12,7 +12,7 @@
#include "base/path_service.h"
#include "build/build_config.h"
#include "services/catalog/public/cpp/resource_loader.h"
-#include "services/catalog/public/interfaces/constants.mojom.h"
+#include "services/catalog/public/mojom/constants.mojom.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/aura/env.h"
#include "ui/base/ime/input_method_initializer.h"
@@ -133,7 +133,7 @@ bool AuraInit::InitializeResources(service_manager::Connector* connector,
const std::string& resource_file,
const std::string& resource_file_200,
bool register_path_provider) {
- // Resources may have already been initialized (e.g. when 'chrome --mash' is
+ // Resources may have already been initialized (e.g. when chrome with mash is
// used to launch the current app).
if (ui::ResourceBundle::HasSharedInstance())
return true;
diff --git a/chromium/ui/views/mus/desktop_window_tree_host_mus_unittest.cc b/chromium/ui/views/mus/desktop_window_tree_host_mus_unittest.cc
index 683a0520ade..34a105de7de 100644
--- a/chromium/ui/views/mus/desktop_window_tree_host_mus_unittest.cc
+++ b/chromium/ui/views/mus/desktop_window_tree_host_mus_unittest.cc
@@ -328,10 +328,10 @@ TEST_F(DesktopWindowTreeHostMusTest, ShadowDefaults) {
widget.Init(params);
// |DesktopNativeWidgetAura::content_window_| should have no shadow; the wm
// should provide it if it so desires.
- EXPECT_EQ(wm::ShadowElevation::NONE,
+ EXPECT_EQ(wm::kShadowElevationNone,
widget.GetNativeView()->GetProperty(wm::kShadowElevationKey));
// The wm honors the shadow property from the WindowTreeHost's window.
- EXPECT_EQ(wm::ShadowElevation::DEFAULT,
+ EXPECT_EQ(wm::kShadowElevationDefault,
widget.GetNativeView()->GetHost()->window()->GetProperty(
wm::kShadowElevationKey));
}
@@ -342,9 +342,9 @@ TEST_F(DesktopWindowTreeHostMusTest, NoShadow) {
params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
params.shadow_type = Widget::InitParams::SHADOW_TYPE_NONE;
widget.Init(params);
- EXPECT_EQ(wm::ShadowElevation::NONE,
+ EXPECT_EQ(wm::kShadowElevationNone,
widget.GetNativeView()->GetProperty(wm::kShadowElevationKey));
- EXPECT_EQ(wm::ShadowElevation::NONE,
+ EXPECT_EQ(wm::kShadowElevationNone,
widget.GetNativeView()->GetHost()->window()->GetProperty(
wm::kShadowElevationKey));
}
diff --git a/chromium/ui/views/mus/mus_client.cc b/chromium/ui/views/mus/mus_client.cc
index 30a7651135d..9399f8228d7 100644
--- a/chromium/ui/views/mus/mus_client.cc
+++ b/chromium/ui/views/mus/mus_client.cc
@@ -95,9 +95,9 @@ MusClient::MusClient(service_manager::Connector* connector,
// TODO(msw): Avoid this... use some default value? Allow clients to extend?
property_converter_ = std::make_unique<aura::PropertyConverter>();
property_converter_->RegisterPrimitiveProperty(
- wm::kShadowElevationKey,
+ ::wm::kShadowElevationKey,
ui::mojom::WindowManager::kShadowElevation_Property,
- base::Bind(&wm::IsValidShadowElevation));
+ aura::PropertyConverter::CreateAcceptAnyValueCallback());
if (create_wm_state)
wm_state_ = std::make_unique<wm::WMState>();
@@ -195,6 +195,12 @@ MusClient::ConfigurePropertiesFromParams(
properties[WindowManager::kRemoveStandardFrame_InitProperty] =
mojo::ConvertTo<TransportType>(init_params.remove_standard_frame);
+ if (init_params.corner_radius) {
+ properties[WindowManager::kWindowCornerRadius_Property] =
+ mojo::ConvertTo<TransportType>(
+ static_cast<PrimitiveType>(*init_params.corner_radius));
+ }
+
if (!Widget::RequiresNonClientView(init_params.type))
return properties;
diff --git a/chromium/ui/views/mus/views_mus_test_suite.cc b/chromium/ui/views/mus/views_mus_test_suite.cc
index 202bd8c986c..0008b8eeaf4 100644
--- a/chromium/ui/views/mus/views_mus_test_suite.cc
+++ b/chromium/ui/views/mus/views_mus_test_suite.cc
@@ -7,6 +7,7 @@
#include <memory>
#include <string>
+#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
@@ -28,6 +29,7 @@
#include "ui/aura/mus/window_tree_host_mus.h"
#include "ui/aura/test/mus/input_method_mus_test_api.h"
#include "ui/aura/window.h"
+#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/compositor/test/fake_context_factory.h"
#include "ui/gl/gl_switches.h"
@@ -240,12 +242,15 @@ void ViewsMusTestSuite::Initialize() {
EnsureCommandLineSwitch(ui::switches::kUseTestConfig);
EnsureCommandLineSwitch(switches::kOverrideUseSoftwareGLForTests);
- base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kMus);
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kMusHostingViz);
ViewsTestSuite::Initialize();
+ // NOTE: this has to be after ViewsTestSuite::Initialize() as
+ // TestSuite::Initialize() resets kEnableFeatures and the command line.
+ feature_list_.InitAndEnableFeature(features::kMash);
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kEnableFeatures, features::kMash.name);
+
PlatformTestHelper::set_factory(base::Bind(&CreatePlatformTestHelper));
}
diff --git a/chromium/ui/views/mus/views_mus_test_suite.h b/chromium/ui/views/mus/views_mus_test_suite.h
index d8184d0ee6e..4dc9d09dc07 100644
--- a/chromium/ui/views/mus/views_mus_test_suite.h
+++ b/chromium/ui/views/mus/views_mus_test_suite.h
@@ -8,6 +8,7 @@
#include <memory>
#include "base/macros.h"
+#include "base/test/scoped_feature_list.h"
#include "ui/views/views_test_suite.h"
namespace views {
@@ -23,6 +24,8 @@ class ViewsMusTestSuite : public ViewsTestSuite {
void InitializeEnv() override;
void DestroyEnv() override;
+ base::test::ScopedFeatureList feature_list_;
+
std::unique_ptr<aura::Env> env_;
DISALLOW_COPY_AND_ASSIGN(ViewsMusTestSuite);
diff --git a/chromium/ui/views/selection_controller.cc b/chromium/ui/views/selection_controller.cc
index 1169936be56..aa400d8bf22 100644
--- a/chromium/ui/views/selection_controller.cc
+++ b/chromium/ui/views/selection_controller.cc
@@ -154,6 +154,11 @@ void SelectionController::OnMouseCaptureLost() {
delegate_->UpdateSelectionClipboard();
}
+void SelectionController::OffsetDoubleClickWord(int offset) {
+ double_click_word_.set_start(double_click_word_.start() + offset);
+ double_click_word_.set_end(double_click_word_.end() + offset);
+}
+
void SelectionController::TrackMouseClicks(const ui::MouseEvent& event) {
if (event.IsOnlyLeftMouseButton()) {
base::TimeDelta time_delta = event.time_stamp() - last_click_time_;
diff --git a/chromium/ui/views/selection_controller.h b/chromium/ui/views/selection_controller.h
index 3a2279bef55..cb929fdd621 100644
--- a/chromium/ui/views/selection_controller.h
+++ b/chromium/ui/views/selection_controller.h
@@ -58,6 +58,11 @@ class VIEWS_EXPORT SelectionController {
handles_selection_clipboard_ = value;
}
+ // Offsets the double-clicked word's range. This is only used in the unusual
+ // case where the text changes on the second mousedown of a double-click.
+ // This is harmless if there is not a currently double-clicked word.
+ void OffsetDoubleClickWord(int offset);
+
private:
// Tracks the mouse clicks for single/double/triple clicks.
void TrackMouseClicks(const ui::MouseEvent& event);
diff --git a/chromium/ui/views/style/platform_style.cc b/chromium/ui/views/style/platform_style.cc
index 42b006117aa..b12430178e9 100644
--- a/chromium/ui/views/style/platform_style.cc
+++ b/chromium/ui/views/style/platform_style.cc
@@ -33,6 +33,12 @@ const SkColor kStyleButtonShadowColor = SK_ColorWHITE;
} // namespace
+#if defined(OS_WIN) || defined(OS_CHROMEOS)
+const bool PlatformStyle::kIsOkButtonLeading = true;
+#else
+const bool PlatformStyle::kIsOkButtonLeading = false;
+#endif
+
#if !defined(OS_MACOSX)
const int PlatformStyle::kMinLabelButtonWidth = 70;
@@ -48,6 +54,7 @@ const bool PlatformStyle::kReturnClicksFocusedControl = true;
const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = false;
const bool PlatformStyle::kUseRipples = true;
const bool PlatformStyle::kTextfieldScrollsToStartOnFocusChange = false;
+const bool PlatformStyle::kTextfieldUsesDragCursorWhenDraggable = true;
// static
std::unique_ptr<ScrollBar> PlatformStyle::CreateScrollBar(bool is_horizontal) {
diff --git a/chromium/ui/views/style/platform_style.h b/chromium/ui/views/style/platform_style.h
index 246293d97c0..d5b7e3bf951 100644
--- a/chromium/ui/views/style/platform_style.h
+++ b/chromium/ui/views/style/platform_style.h
@@ -24,6 +24,10 @@ class VIEWS_EXPORT PlatformStyle {
// Type used by LabelButton to map button states to text colors.
using ButtonColorByState = SkColor[Button::STATE_COUNT];
+ // Whether the ok button is in the leading position (left in LTR) in a
+ // typical Cancel/OK button group.
+ static const bool kIsOkButtonLeading;
+
// Minimum size for platform-styled buttons (Button::STYLE_BUTTON).
static const int kMinLabelButtonWidth;
static const int kMinLabelButtonHeight;
@@ -58,6 +62,10 @@ class VIEWS_EXPORT PlatformStyle {
// focus.
static const bool kTextfieldScrollsToStartOnFocusChange;
+ // Whether text fields should use a "drag" cursor when not actually
+ // dragging but available to do so.
+ static const bool kTextfieldUsesDragCursorWhenDraggable;
+
// Creates the default scrollbar for the given orientation.
static std::unique_ptr<ScrollBar> CreateScrollBar(bool is_horizontal);
diff --git a/chromium/ui/views/style/platform_style_mac.mm b/chromium/ui/views/style/platform_style_mac.mm
index 3a4a52537e6..5d14515be15 100644
--- a/chromium/ui/views/style/platform_style_mac.mm
+++ b/chromium/ui/views/style/platform_style_mac.mm
@@ -20,6 +20,7 @@ const bool PlatformStyle::kDialogDefaultButtonCanBeCancel = false;
const bool PlatformStyle::kSelectWordOnRightClick = true;
const bool PlatformStyle::kSelectAllOnRightClickWhenUnfocused = true;
const bool PlatformStyle::kTextfieldScrollsToStartOnFocusChange = true;
+const bool PlatformStyle::kTextfieldUsesDragCursorWhenDraggable = false;
const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = true;
const bool PlatformStyle::kUseRipples = false;
diff --git a/chromium/ui/views/touchui/touch_selection_menu_runner_views.cc b/chromium/ui/views/touchui/touch_selection_menu_runner_views.cc
index 75ab64c985b..3b283a149a9 100644
--- a/chromium/ui/views/touchui/touch_selection_menu_runner_views.cc
+++ b/chromium/ui/views/touchui/touch_selection_menu_runner_views.cc
@@ -10,6 +10,8 @@
#include "base/strings/utf_string_conversions.h"
#include "ui/aura/window.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/rect.h"
@@ -120,7 +122,16 @@ TouchSelectionMenuRunnerViews::Menu::Menu(TouchSelectionMenuRunnerViews* owner,
SetAnchorRect(adjusted_anchor_rect);
BubbleDialogDelegateView::CreateBubble(this);
- GetWidget()->Show();
+ Widget* widget = GetWidget();
+ gfx::Rect bounds = widget->GetWindowBoundsInScreen();
+ gfx::Rect work_area = display::Screen::GetScreen()
+ ->GetDisplayNearestPoint(bounds.origin())
+ .work_area();
+ if (!work_area.IsEmpty()) {
+ bounds.AdjustToFit(work_area);
+ widget->SetBounds(bounds);
+ }
+ widget->Show();
}
bool TouchSelectionMenuRunnerViews::Menu::IsMenuAvailable(
diff --git a/chromium/ui/views/vector_icons/OWNERS b/chromium/ui/views/vector_icons/OWNERS
new file mode 100644
index 00000000000..d7ec991d34a
--- /dev/null
+++ b/chromium/ui/views/vector_icons/OWNERS
@@ -0,0 +1 @@
+file://components/vector_icons/OWNERS
diff --git a/chromium/ui/views/vector_icons/vector_icons.cc.template b/chromium/ui/views/vector_icons/vector_icons.cc.template
index 9411587ff5b..c0e98199d90 100644
--- a/chromium/ui/views/vector_icons/vector_icons.cc.template
+++ b/chromium/ui/views/vector_icons/vector_icons.cc.template
@@ -10,11 +10,7 @@
#include "base/logging.h"
#include "ui/gfx/vector_icon_types.h"
-#define PATH_ELEMENT_TEMPLATE(path_name, ...) \
-static constexpr gfx::PathElement path_name[] = {__VA_ARGS__};
-
-#define VECTOR_ICON_TEMPLATE(icon_name, path_name, path_name_1x) \
-const gfx::VectorIcon icon_name = { path_name , path_name_1x };
+#include "components/vector_icons/cc_macros.h"
namespace views {
diff --git a/chromium/ui/views/view.cc b/chromium/ui/views/view.cc
index e114a6f37be..8568fae0fc1 100644
--- a/chromium/ui/views/view.cc
+++ b/chromium/ui/views/view.cc
@@ -21,7 +21,7 @@
#include "build/build_config.h"
#include "third_party/skia/include/core/SkRect.h"
#include "ui/accessibility/ax_action_data.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/ime/input_method.h"
@@ -96,21 +96,22 @@ const View* GetHierarchyRoot(const View* view) {
namespace internal {
#if DCHECK_IS_ON()
- class ScopedChildrenLock {
- public:
- explicit ScopedChildrenLock(const View* view)
- : reset_(&view->iterating_, true) {}
- ~ScopedChildrenLock() {}
- private:
- base::AutoReset<bool> reset_;
- DISALLOW_COPY_AND_ASSIGN(ScopedChildrenLock);
- };
+class ScopedChildrenLock {
+ public:
+ explicit ScopedChildrenLock(const View* view)
+ : reset_(&view->iterating_, true) {}
+ ~ScopedChildrenLock() {}
+
+ private:
+ base::AutoReset<bool> reset_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedChildrenLock);
+};
#else
- class ScopedChildrenLock {
- public:
- explicit ScopedChildrenLock(const View* view) {}
- ~ScopedChildrenLock() {}
- };
+class ScopedChildrenLock {
+ public:
+ explicit ScopedChildrenLock(const View* view) {}
+ ~ScopedChildrenLock() {}
+};
#endif
} // namespace internal
@@ -127,7 +128,7 @@ View::View()
: owned_by_client_(false),
id_(0),
group_(-1),
- parent_(NULL),
+ parent_(nullptr),
#if DCHECK_IS_ON()
iterating_(false),
#endif
@@ -140,13 +141,13 @@ View::View()
snap_layer_to_pixel_boundary_(false),
flip_canvas_on_paint_for_rtl_ui_(false),
paint_to_layer_(false),
- accelerator_focus_manager_(NULL),
+ accelerator_focus_manager_(nullptr),
registered_accelerator_count_(0),
- next_focusable_view_(NULL),
- previous_focusable_view_(NULL),
+ next_focusable_view_(nullptr),
+ previous_focusable_view_(nullptr),
focus_behavior_(FocusBehavior::NEVER),
- context_menu_controller_(NULL),
- drag_controller_(NULL) {
+ context_menu_controller_(nullptr),
+ drag_controller_(nullptr) {
SetTargetHandler(this);
}
@@ -157,7 +158,7 @@ View::~View() {
{
internal::ScopedChildrenLock lock(this);
for (auto* child : children_) {
- child->parent_ = NULL;
+ child->parent_ = nullptr;
if (!child->owned_by_client_)
delete child;
}
@@ -171,7 +172,7 @@ View::~View() {
const Widget* View::GetWidget() const {
// The root view holds a reference to this view hierarchy's Widget.
- return parent_ ? parent_->GetWidget() : NULL;
+ return parent_ ? parent_->GetWidget() : nullptr;
}
Widget* View::GetWidget() {
@@ -292,12 +293,13 @@ void View::ReorderChildView(View* view, int index) {
}
void View::RemoveChildView(View* view) {
- DoRemoveChildView(view, true, true, false, NULL);
+ DoRemoveChildView(view, true, true, false, nullptr);
}
void View::RemoveAllChildViews(bool delete_children) {
while (!children_.empty())
- DoRemoveChildView(children_.front(), false, false, delete_children, NULL);
+ DoRemoveChildView(children_.front(), false, false, delete_children,
+ nullptr);
UpdateTooltip();
}
@@ -383,7 +385,7 @@ gfx::Rect View::GetVisibleBounds() const {
const View* view = this;
gfx::Transform transform;
- while (view != NULL && !vis_bounds.IsEmpty()) {
+ while (view != nullptr && !vis_bounds.IsEmpty()) {
transform.ConcatTransform(view->GetTransform());
gfx::Transform translation;
translation.Translate(static_cast<float>(view->GetMirroredX()),
@@ -392,7 +394,7 @@ gfx::Rect View::GetVisibleBounds() const {
vis_bounds = view->ConvertRectToParent(vis_bounds);
const View* ancestor = view->parent_;
- if (ancestor != NULL) {
+ if (ancestor != nullptr) {
ancestor_bounds.SetRect(0, 0, ancestor->width(), ancestor->height());
vis_bounds.Intersect(ancestor_bounds);
} else if (!view->GetWidget()) {
@@ -435,9 +437,9 @@ void View::SetPreferredSize(const gfx::Size& size) {
}
void View::SizeToPreferredSize() {
- gfx::Size prefsize = GetPreferredSize();
- if ((prefsize.width() != width()) || (prefsize.height() != height()))
- SetBounds(x(), y(), prefsize.width(), prefsize.height());
+ gfx::Size pref_size = GetPreferredSize();
+ if ((pref_size.width() != width()) || (pref_size.height() != height()))
+ SetBounds(x(), y(), pref_size.width(), pref_size.height());
}
gfx::Size View::GetMinimumSize() const {
@@ -467,7 +469,8 @@ void View::SetVisible(bool visible) {
// Notify the parent.
if (parent_) {
parent_->ChildVisibilityChanged(this);
- parent_->NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, false);
+ parent_->NotifyAccessibilityEvent(ax::mojom::Event::kChildrenChanged,
+ false);
}
for (ViewObserver& observer : observers_)
@@ -646,7 +649,7 @@ const View* View::GetAncestorWithClassName(const std::string& name) const {
if (!strcmp(view->GetClassName(), name.c_str()))
return view;
}
- return NULL;
+ return nullptr;
}
View* View::GetAncestorWithClassName(const std::string& name) {
@@ -664,7 +667,7 @@ const View* View::GetViewByID(int id) const {
if (view)
return view;
}
- return NULL;
+ return nullptr;
}
View* View::GetViewByID(int id) {
@@ -697,7 +700,7 @@ void View::GetViewsInGroup(int group, Views* views) {
View* View::GetSelectedViewForGroup(int group) {
Views views;
GetWidget()->GetRootView()->GetViewsInGroup(group, &views);
- return views.empty() ? NULL : views[0];
+ return views.empty() ? nullptr : views[0];
}
// Coordinate conversion -------------------------------------------------------
@@ -745,7 +748,7 @@ void View::ConvertPointToWidget(const View* src, gfx::Point* p) {
DCHECK(src);
DCHECK(p);
- src->ConvertPointForAncestor(NULL, p);
+ src->ConvertPointForAncestor(nullptr, p);
}
// static
@@ -753,7 +756,7 @@ void View::ConvertPointFromWidget(const View* dest, gfx::Point* p) {
DCHECK(dest);
DCHECK(p);
- dest->ConvertPointFromAncestor(NULL, p);
+ dest->ConvertPointFromAncestor(nullptr, p);
}
// static
@@ -898,7 +901,7 @@ void View::Paint(const PaintInfo& parent_paint_info) {
}
ui::TransformRecorder transform_recorder(context);
- SetupTransformRecorderForPainting(paint_info.offset_from_parent(),
+ SetUpTransformRecorderForPainting(paint_info.offset_from_parent(),
&transform_recorder);
// Note that the cache is not aware of the offset of the view
@@ -979,7 +982,7 @@ bool View::CanProcessEventsWithinSubtree() const {
View* View::GetTooltipHandlerForPoint(const gfx::Point& point) {
// TODO(tdanderson): Move this implementation into ViewTargetDelegate.
if (!HitTestPoint(point) || !CanProcessEventsWithinSubtree())
- return NULL;
+ return nullptr;
// Walk the child Views recursively looking for the View that most
// tightly encloses the specified point.
@@ -1002,7 +1005,7 @@ gfx::NativeCursor View::GetCursor(const ui::MouseEvent& event) {
#if defined(OS_WIN)
static ui::Cursor arrow;
if (!arrow.platform())
- arrow.SetPlatformCursor(LoadCursor(NULL, IDC_ARROW));
+ arrow.SetPlatformCursor(LoadCursor(nullptr, IDC_ARROW));
return arrow;
#else
return gfx::kNullCursor;
@@ -1057,7 +1060,7 @@ void View::OnMouseExited(const ui::MouseEvent& event) {
}
void View::SetMouseHandler(View* new_mouse_handler) {
- // |new_mouse_handler| may be NULL.
+ // |new_mouse_handler| may be nullptr.
if (parent_)
parent_->SetMouseHandler(new_mouse_handler);
}
@@ -1095,7 +1098,7 @@ void View::OnMouseEvent(ui::MouseEvent* event) {
OnMouseMoved(*event);
return;
}
- // FALL-THROUGH
+ FALLTHROUGH;
case ui::ET_MOUSE_DRAGGED:
if (ProcessMouseDragged(*event))
event->SetHandled();
@@ -1112,7 +1115,7 @@ void View::OnMouseEvent(ui::MouseEvent* event) {
case ui::ET_MOUSE_ENTERED:
if (event->flags() & ui::EF_TOUCH_ACCESSIBILITY)
- NotifyAccessibilityEvent(ui::AX_EVENT_HOVER, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kHover, true);
OnMouseEntered(*event);
break;
@@ -1295,12 +1298,12 @@ bool View::IsAccessibilityFocusable() const {
FocusManager* View::GetFocusManager() {
Widget* widget = GetWidget();
- return widget ? widget->GetFocusManager() : NULL;
+ return widget ? widget->GetFocusManager() : nullptr;
}
const FocusManager* View::GetFocusManager() const {
const Widget* widget = GetWidget();
- return widget ? widget->GetFocusManager() : NULL;
+ return widget ? widget->GetFocusManager() : nullptr;
}
void View::RequestFocus() {
@@ -1319,11 +1322,11 @@ bool View::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
}
FocusTraversable* View::GetFocusTraversable() {
- return NULL;
+ return nullptr;
}
FocusTraversable* View::GetPaneFocusTraversable() {
- return NULL;
+ return nullptr;
}
// Tooltips --------------------------------------------------------------------
@@ -1408,13 +1411,13 @@ ViewAccessibility& View::GetViewAccessibility() {
bool View::HandleAccessibleAction(const ui::AXActionData& action_data) {
switch (action_data.action) {
- case ui::AX_ACTION_BLUR:
+ case ax::mojom::Action::kBlur:
if (HasFocus()) {
GetFocusManager()->ClearFocus();
return true;
}
break;
- case ui::AX_ACTION_DO_DEFAULT: {
+ case ax::mojom::Action::kDoDefault: {
const gfx::Point center = GetLocalBounds().CenterPoint();
OnMousePressed(ui::MouseEvent(
ui::ET_MOUSE_PRESSED, center, center, ui::EventTimeForNow(),
@@ -1424,16 +1427,16 @@ bool View::HandleAccessibleAction(const ui::AXActionData& action_data) {
ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON));
return true;
}
- case ui::AX_ACTION_FOCUS:
+ case ax::mojom::Action::kFocus:
if (IsAccessibilityFocusable()) {
RequestFocus();
return true;
}
break;
- case ui::AX_ACTION_SCROLL_TO_MAKE_VISIBLE:
+ case ax::mojom::Action::kScrollToMakeVisible:
ScrollRectToVisible(GetLocalBounds());
return true;
- case ui::AX_ACTION_SHOW_CONTEXT_MENU:
+ case ax::mojom::Action::kShowContextMenu:
ShowContextMenu(GetBoundsInScreen().CenterPoint(),
ui::MENU_SOURCE_KEYBOARD);
return true;
@@ -1449,9 +1452,8 @@ gfx::NativeViewAccessible View::GetNativeViewAccessible() {
return GetViewAccessibility().GetNativeObject();
}
-void View::NotifyAccessibilityEvent(
- ui::AXEvent event_type,
- bool send_native_event) {
+void View::NotifyAccessibilityEvent(ax::mojom::Event event_type,
+ bool send_native_event) {
if (ViewsDelegate::GetInstance())
ViewsDelegate::GetInstance()->NotifyAccessibilityEvent(this, event_type);
@@ -1461,7 +1463,7 @@ void View::NotifyAccessibilityEvent(
OnAccessibilityEvent(event_type);
}
-void View::OnAccessibilityEvent(ui::AXEvent event_type) {}
+void View::OnAccessibilityEvent(ax::mojom::Event event_type) {}
// Scrolling -------------------------------------------------------------------
@@ -1602,7 +1604,7 @@ void View::UpdateParentLayer() {
if (!layer())
return;
- ui::Layer* parent_layer = NULL;
+ ui::Layer* parent_layer = nullptr;
gfx::Vector2d offset(GetMirroredX(), y());
if (parent_) {
@@ -1668,7 +1670,7 @@ void View::DestroyLayerImpl(LayerChangeNotifyBehavior notify_parents) {
if (new_parent)
ReorderLayers();
- UpdateChildLayerBounds(CalculateOffsetToAncestorWithLayer(NULL));
+ UpdateChildLayerBounds(CalculateOffsetToAncestorWithLayer(nullptr));
SchedulePaint();
@@ -1747,7 +1749,7 @@ void View::ReorderLayers() {
if (widget) {
// Reorder the widget's child NativeViews in case a child NativeView is
- // associated with a view (eg via a NativeViewHost). Always do the
+ // associated with a view (e.g. via a NativeViewHost). Always do the
// reordering because the associated NativeView's layer (if it has one)
// is parented to the widget's layer regardless of whether the host view has
// an ancestor with a layer.
@@ -1775,7 +1777,7 @@ void View::OnChildLayerChanged(View* child) {}
// Input -----------------------------------------------------------------------
View::DragInfo* View::GetDragInfo() {
- return parent_ ? parent_->GetDragInfo() : NULL;
+ return parent_ ? parent_->GetDragInfo() : nullptr;
}
// Focus -----------------------------------------------------------------------
@@ -1792,7 +1794,7 @@ void View::OnFocus() {
// TODO(beng): Investigate whether it's possible for us to move this to
// Focus().
// Notify assistive technologies of the focus change.
- NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true);
}
void View::OnBlur() {
@@ -2002,7 +2004,7 @@ bool View::ShouldPaint() const {
return visible_ && !size().IsEmpty();
}
-void View::SetupTransformRecorderForPainting(
+void View::SetUpTransformRecorderForPainting(
const gfx::Vector2d& offset_from_parent,
ui::TransformRecorder* recorder) const {
// If the view is backed by a layer, it should paint with itself as the origin
@@ -2051,7 +2053,7 @@ void View::PaintDebugRects(const PaintInfo& parent_paint_info) {
const ui::PaintContext& context = paint_info.context();
ui::TransformRecorder transform_recorder(context);
- SetupTransformRecorderForPainting(paint_info.offset_from_parent(),
+ SetUpTransformRecorderForPainting(paint_info.offset_from_parent(),
&transform_recorder);
RecursivePaintHelper(&View::PaintDebugRects, paint_info);
@@ -2276,12 +2278,12 @@ void View::BoundsChanged(const gfx::Rect& previous_bounds) {
} else {
// If our bounds have changed, then any descendant layer bounds may have
// changed. Update them accordingly.
- UpdateChildLayerBounds(CalculateOffsetToAncestorWithLayer(NULL));
+ UpdateChildLayerBounds(CalculateOffsetToAncestorWithLayer(nullptr));
}
OnBoundsChanged(previous_bounds);
if (bounds_ != previous_bounds)
- NotifyAccessibilityEvent(ui::AX_EVENT_LOCATION_CHANGED, false);
+ NotifyAccessibilityEvent(ax::mojom::Event::kLocationChanged, false);
if (needs_layout_ || previous_bounds.size() != size()) {
needs_layout_ = false;
@@ -2356,7 +2358,7 @@ void View::SetLayoutManagerImpl(std::unique_ptr<LayoutManager> layout_manager) {
// Some code keeps a bare pointer to the layout manager for calling
// derived-class-specific-functions. It's an easy mistake to create a new
// unique_ptr and re-set the layout manager with a new unique_ptr, which
- // will cause a crash. Re-setting to null is OK.
+ // will cause a crash. Re-setting to nullptr is OK.
CHECK(!layout_manager.get() || layout_manager_.get() != layout_manager.get());
layout_manager_ = std::move(layout_manager);
@@ -2562,7 +2564,7 @@ bool View::ProcessMouseDragged(const ui::MouseEvent& event) {
// Fall through to return value based on context menu controller.
}
// WARNING: we may have been deleted.
- return (context_menu_controller != NULL) || possible_drag;
+ return (context_menu_controller != nullptr) || possible_drag;
}
void View::ProcessMouseReleased(const ui::MouseEvent& event) {
@@ -2620,7 +2622,7 @@ void View::UnregisterAccelerators(bool leave_data_intact) {
if (GetWidget()) {
if (accelerator_focus_manager_) {
accelerator_focus_manager_->UnregisterAccelerators(this);
- accelerator_focus_manager_ = NULL;
+ accelerator_focus_manager_ = nullptr;
}
if (!leave_data_intact) {
accelerators_->clear();
@@ -2636,14 +2638,14 @@ void View::InitFocusSiblings(View* v, int index) {
int count = child_count();
if (count == 0) {
- v->next_focusable_view_ = NULL;
- v->previous_focusable_view_ = NULL;
+ v->next_focusable_view_ = nullptr;
+ v->previous_focusable_view_ = nullptr;
} else {
if (index == count) {
// We are inserting at the end, but the end of the child list may not be
// the last focusable element. Let's try to find an element with no next
// focusable element to link to.
- View* last_focusable_view = NULL;
+ View* last_focusable_view = nullptr;
{
internal::ScopedChildrenLock lock(this);
for (auto* child : children_) {
@@ -2653,7 +2655,7 @@ void View::InitFocusSiblings(View* v, int index) {
}
}
}
- if (last_focusable_view == NULL) {
+ if (last_focusable_view == nullptr) {
// Hum... there is a cycle in the focus list. Let's just insert ourself
// after the last child.
View* prev = children_[index - 1];
@@ -2663,7 +2665,7 @@ void View::InitFocusSiblings(View* v, int index) {
prev->next_focusable_view_ = v;
} else {
last_focusable_view->next_focusable_view_ = v;
- v->next_focusable_view_ = NULL;
+ v->next_focusable_view_ = nullptr;
v->previous_focusable_view_ = last_focusable_view;
}
} else {
@@ -2680,7 +2682,7 @@ void View::InitFocusSiblings(View* v, int index) {
void View::AdvanceFocusIfNecessary() {
// Focus should only be advanced if this is the focused view and has become
// unfocusable. If the view is still focusable or is not focused, we can
- // return early avoiding furthur unnecessary checks. Focusability check is
+ // return early avoiding further unnecessary checks. Focusability check is
// performed first as it tends to be faster.
if (IsAccessibilityFocusable() || !HasFocus())
return;
@@ -2722,7 +2724,7 @@ void View::PropagateDeviceScaleFactorChanged(float old_device_scale_factor,
void View::UpdateTooltip() {
Widget* widget = GetWidget();
- // TODO(beng): The TooltipManager NULL check can be removed when we
+ // TODO(beng): The TooltipManager nullptr check can be removed when we
// consolidate Init() methods and make views_unittests Init() all
// Widgets that it uses.
if (widget && widget->GetTooltipManager())
diff --git a/chromium/ui/views/view.h b/chromium/ui/views/view.h
index f3075731dd6..8b874876b89 100644
--- a/chromium/ui/views/view.h
+++ b/chromium/ui/views/view.h
@@ -12,6 +12,7 @@
#include <memory>
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include "base/compiler_specific.h"
@@ -19,7 +20,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "build/build_config.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/class_property.h"
#include "ui/base/dragdrop/drag_drop_types.h"
@@ -52,7 +53,7 @@ class Canvas;
class Insets;
class Path;
class Transform;
-}
+} // namespace gfx
namespace ui {
struct AXActionData;
@@ -64,7 +65,7 @@ class NativeTheme;
class PaintContext;
class ThemeProvider;
class TransformRecorder;
-}
+} // namespace ui
namespace views {
@@ -86,7 +87,7 @@ class PreEventDispatchHandler;
class PostEventDispatchHandler;
class RootView;
class ScopedChildrenLock;
-}
+} // namespace internal
/////////////////////////////////////////////////////////////////////////////
//
@@ -263,6 +264,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// By default a View is owned by its parent unless specified otherwise here.
void set_owned_by_client() { owned_by_client_ = true; }
+ bool owned_by_client() const { return owned_by_client_; }
// Tree operations -----------------------------------------------------------
@@ -318,7 +320,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// position accessors.
// Transformations are not applied on the size/position. For example, if
// bounds is (0, 0, 100, 100) and it is scaled by 0.5 along the X axis, the
- // width will still be 100 (although when painted, it will be 50x50, painted
+ // width will still be 100 (although when painted, it will be 50x100, painted
// at location (0, 0)).
void SetBounds(int x, int y, int width, int height);
@@ -539,7 +541,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Return the receiving view's class name. A view class is a string which
// uniquely identifies the view class. It is intended to be used as a way to
- // find out during run time if a view can be safely casted to a specific view
+ // find out during run time if a view can be safely cast to a specific view
// subclass. The default implementation returns kViewClassName.
virtual const char* GetClassName() const;
@@ -750,7 +752,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// The provided event is in the receiver's coordinate system.
//
// Return true if you processed the event and want to receive subsequent
- // MouseDraggged and MouseReleased events. This also stops the event from
+ // MouseDragged and MouseReleased events. This also stops the event from
// bubbling. If you return false, the event will bubble through parent
// views.
//
@@ -825,7 +827,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
virtual void SetMouseHandler(View* new_mouse_handler);
// Invoked when a key is pressed or released.
- // Subclasser should return true if the event has been processed and false
+ // Subclasses should return true if the event has been processed and false
// otherwise. If the event has not been processed, the parent will be given a
// chance.
virtual bool OnKeyPressed(const ui::KeyEvent& event);
@@ -1004,7 +1006,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// Provides default implementation for context menu handling. The default
// implementation calls the ShowContextMenu of the current
// ContextMenuController (if it is not NULL). Overridden in subclassed views
- // to provide right-click menu display triggerd by the keyboard (i.e. for the
+ // to provide right-click menu display triggered by the keyboard (i.e. for the
// Chrome toolbar Back and Forward buttons). No source needs to be specified,
// as it is always equal to the current View.
virtual void ShowContextMenu(const gfx::Point& p,
@@ -1115,12 +1117,12 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// cases where the view is a native control that's already sending a
// native accessibility event and the duplicate event would cause
// problems.
- void NotifyAccessibilityEvent(ui::AXEvent event_type,
+ void NotifyAccessibilityEvent(ax::mojom::Event event_type,
bool send_native_event);
// Views may override this function to know when an accessibility
// event is fired. This will be called by NotifyAccessibilityEvent.
- virtual void OnAccessibilityEvent(ui::AXEvent event_type);
+ virtual void OnAccessibilityEvent(ax::mojom::Event event_type);
// Scrolling -----------------------------------------------------------------
// TODO(beng): Figure out if this can live somewhere other than View, i.e.
@@ -1138,7 +1140,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
// The following methods are used by ScrollView to determine the amount
// to scroll relative to the visible bounds of the view. For example, a
- // return value of 10 indicates the scrollview should scroll 10 pixels in
+ // return value of 10 indicates the scroll_view should scroll 10 pixels in
// the appropriate direction.
//
// Each method takes the following parameters:
@@ -1442,7 +1444,7 @@ class VIEWS_EXPORT View : public ui::LayerDelegate,
bool ShouldPaint() const;
// Adjusts the transform of |recorder| in advance of painting.
- void SetupTransformRecorderForPainting(
+ void SetUpTransformRecorderForPainting(
const gfx::Vector2d& offset_from_parent,
ui::TransformRecorder* recorder) const;
diff --git a/chromium/ui/views/view_unittest.cc b/chromium/ui/views/view_unittest.cc
index 38a0c05b4cf..82631bbd6ce 100644
--- a/chromium/ui/views/view_unittest.cc
+++ b/chromium/ui/views/view_unittest.cc
@@ -12,7 +12,6 @@
#include "base/command_line.h"
#include "base/i18n/rtl.h"
#include "base/macros.h"
-#include "base/memory/ptr_util.h"
#include "base/rand_util.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
@@ -262,7 +261,7 @@ class TestView : public View {
void OnNativeThemeChanged(const ui::NativeTheme* native_theme) override;
- void OnAccessibilityEvent(ui::AXEvent event_type) override;
+ void OnAccessibilityEvent(ax::mojom::Event event_type) override;
// OnBoundsChanged.
bool did_change_bounds_;
@@ -292,7 +291,7 @@ class TestView : public View {
bool can_process_events_within_subtree_;
// Accessibility events
- ui::AXEvent last_a11y_event_;
+ ax::mojom::Event last_a11y_event_;
};
////////////////////////////////////////////////////////////////////////////////
@@ -328,7 +327,7 @@ TEST_F(ViewTest, LayoutCalledInvalidateAndOriginChanges) {
// OnBoundsChanged
////////////////////////////////////////////////////////////////////////////////
-void TestView::OnAccessibilityEvent(ui::AXEvent event_type) {
+void TestView::OnAccessibilityEvent(ax::mojom::Event event_type) {
last_a11y_event_ = event_type;
}
@@ -340,17 +339,17 @@ TEST_F(ViewTest, OnBoundsChangedFiresA11yEvent) {
gfx::Rect scaled(0, 0, 250, 250);
gfx::Rect moved(100, 100, 250, 250);
- v.last_a11y_event_ = ui::AX_EVENT_NONE;
+ v.last_a11y_event_ = ax::mojom::Event::kNone;
v.SetBoundsRect(initial);
- EXPECT_EQ(v.last_a11y_event_, ui::AX_EVENT_LOCATION_CHANGED);
+ EXPECT_EQ(v.last_a11y_event_, ax::mojom::Event::kLocationChanged);
- v.last_a11y_event_ = ui::AX_EVENT_NONE;
+ v.last_a11y_event_ = ax::mojom::Event::kNone;
v.SetBoundsRect(scaled);
- EXPECT_EQ(v.last_a11y_event_, ui::AX_EVENT_LOCATION_CHANGED);
+ EXPECT_EQ(v.last_a11y_event_, ax::mojom::Event::kLocationChanged);
- v.last_a11y_event_ = ui::AX_EVENT_NONE;
+ v.last_a11y_event_ = ax::mojom::Event::kNone;
v.SetBoundsRect(moved);
- EXPECT_EQ(v.last_a11y_event_, ui::AX_EVENT_LOCATION_CHANGED);
+ EXPECT_EQ(v.last_a11y_event_, ax::mojom::Event::kLocationChanged);
}
void TestView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
@@ -4516,7 +4515,7 @@ class PaintLayerView : public View {
PaintLayerView() = default;
void PaintChildren(const PaintInfo& info) override {
- last_paint_info_ = base::MakeUnique<PaintInfo>(info);
+ last_paint_info_ = std::make_unique<PaintInfo>(info);
View::PaintChildren(info);
}
diff --git a/chromium/ui/views/views_delegate.cc b/chromium/ui/views/views_delegate.cc
index 1f7068795ff..964f1390be0 100644
--- a/chromium/ui/views/views_delegate.cc
+++ b/chromium/ui/views/views_delegate.cc
@@ -61,8 +61,7 @@ bool ViewsDelegate::GetSavedWindowPlacement(
}
void ViewsDelegate::NotifyAccessibilityEvent(View* view,
- ui::AXEvent event_type) {
-}
+ ax::mojom::Event event_type) {}
void ViewsDelegate::NotifyMenuItemFocused(const base::string16& menu_name,
const base::string16& menu_item_name,
diff --git a/chromium/ui/views/views_delegate.h b/chromium/ui/views/views_delegate.h
index aed6c6eeff0..cfaf7b0dd8a 100644
--- a/chromium/ui/views/views_delegate.h
+++ b/chromium/ui/views/views_delegate.h
@@ -17,7 +17,7 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "build/build_config.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/base/ui_base_types.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/views/views_export.h"
@@ -135,7 +135,8 @@ class VIEWS_EXPORT ViewsDelegate {
gfx::Rect* bounds,
ui::WindowShowState* show_state) const;
- virtual void NotifyAccessibilityEvent(View* view, ui::AXEvent event_type);
+ virtual void NotifyAccessibilityEvent(View* view,
+ ax::mojom::Event event_type);
// For accessibility, notify the delegate that a menu item was focused
// so that alternate feedback (speech / magnified text) can be provided.
diff --git a/chromium/ui/views/views_perftests.cc b/chromium/ui/views/views_perftests.cc
index c7ace58ab5c..65a61183415 100644
--- a/chromium/ui/views/views_perftests.cc
+++ b/chromium/ui/views/views_perftests.cc
@@ -3,10 +3,12 @@
// found in the LICENSE file.
#include "base/test/launcher/unit_test_launcher.h"
+#include "mojo/edk/embedder/embedder.h"
#include "ui/views/views_test_suite.h"
int main(int argc, char** argv) {
views::ViewsTestSuite test_suite(argc, argv);
+ mojo::edk::Init();
return base::LaunchUnitTestsSerially(
argc, argv,
base::Bind(&views::ViewsTestSuite::Run, base::Unretained(&test_suite)));
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
index da27f6dd704..cde45a41be5 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc
@@ -362,7 +362,7 @@ void DesktopNativeWidgetAura::HandleActivationChanged(bool active) {
View* view_for_activation = focus_manager->GetFocusedView()
? focus_manager->GetFocusedView()
: focus_manager->GetStoredFocusView();
- if (!view_for_activation) {
+ if (!view_for_activation || !view_for_activation->GetWidget()) {
view_for_activation = GetWidget()->GetRootView();
} else if (view_for_activation == focus_manager->GetStoredFocusView()) {
// When desktop native widget has modal transient child, we don't
@@ -413,7 +413,7 @@ void DesktopNativeWidgetAura::InitNativeWidget(
NativeWidgetAura::RegisterNativeWidgetForWindow(this, content_window_);
content_window_->SetType(GetAuraWindowTypeForWidgetType(params.type));
content_window_->Init(params.layer_type);
- wm::SetShadowElevation(content_window_, wm::ShadowElevation::NONE);
+ wm::SetShadowElevation(content_window_, wm::kShadowElevationNone);
if (!desktop_window_tree_host_) {
if (params.desktop_window_tree_host) {
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
index 1bf5a5e2ca5..19f103c0385 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
@@ -4,6 +4,7 @@
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
+#include "base/containers/flat_set.h"
#include "base/memory/ptr_util.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkRegion.h"
@@ -18,6 +19,7 @@
#include "ui/compositor/paint_context.h"
#include "ui/display/win/dpi.h"
#include "ui/display/win/screen_win.h"
+#include "ui/events/keyboard_hook.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/geometry/vector2d.h"
#include "ui/gfx/native_widget_types.h"
@@ -558,6 +560,23 @@ void DesktopWindowTreeHostWin::ReleaseCapture() {
message_handler_->ReleaseCapture();
}
+bool DesktopWindowTreeHostWin::CaptureSystemKeyEventsImpl(
+ base::Optional<base::flat_set<int>> key_codes) {
+ // Only one KeyboardHook should be active at a time, otherwise there will be
+ // problems with event routing (i.e. which Hook takes precedence) and
+ // destruction ordering.
+ DCHECK(!keyboard_hook_);
+ keyboard_hook_ = ui::KeyboardHook::Create(
+ std::move(key_codes),
+ base::BindRepeating(&DesktopWindowTreeHostWin::HandleKeyEvent,
+ base::Unretained(this)));
+ return keyboard_hook_ != nullptr;
+}
+
+void DesktopWindowTreeHostWin::ReleaseSystemKeyEventCapture() {
+ keyboard_hook_.reset();
+}
+
void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) {
ui::CursorLoaderWin cursor_loader;
cursor_loader.SetPlatformCursor(&cursor);
@@ -718,10 +737,6 @@ gfx::NativeViewAccessible DesktopWindowTreeHostWin::GetNativeViewAccessible() {
: nullptr;
}
-bool DesktopWindowTreeHostWin::ShouldHandleSystemCommands() const {
- return GetWidget()->widget_delegate()->ShouldHandleSystemCommands();
-}
-
void DesktopWindowTreeHostWin::HandleAppDeactivated() {
native_widget_delegate_->SetAlwaysRenderAsActive(false);
}
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
index db66147f0e9..732f492c102 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_win.h
@@ -5,6 +5,9 @@
#ifndef UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_WIN_H_
#define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_WIN_H_
+#include <memory>
+#include <string>
+
#include "base/macros.h"
#include "ui/aura/window_tree_host.h"
#include "ui/views/views_export.h"
@@ -21,6 +24,7 @@ class FocusClient;
namespace ui {
class InputMethod;
+class KeyboardHook;
} // namespace ui
namespace wm {
@@ -127,6 +131,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
gfx::Point GetLocationOnScreenInPixels() const override;
void SetCapture() override;
void ReleaseCapture() override;
+ bool CaptureSystemKeyEventsImpl(
+ base::Optional<base::flat_set<int>> keys_codes) override;
+ void ReleaseSystemKeyEventCapture() override;
void SetCursorNative(gfx::NativeCursor cursor) override;
void OnCursorVisibilityChangedNative(bool show) override;
void MoveCursorToScreenLocationInPixels(
@@ -163,7 +170,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
gfx::Size DIPToScreenSize(const gfx::Size& dip_size) const override;
void ResetWindowControls() override;
gfx::NativeViewAccessible GetNativeViewAccessible() override;
- bool ShouldHandleSystemCommands() const override;
void HandleAppDeactivated() override;
void HandleActivationChanged(bool active) override;
bool HandleAppCommand(short command) override;
@@ -281,6 +287,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
// whenever the cursor visibility state changes.
static bool is_cursor_visible_;
+ // Captures system key events when keyboard lock is requested.
+ std::unique_ptr<ui::KeyboardHook> keyboard_hook_;
+
std::unique_ptr<wm::ScopedTooltipDisabler> tooltip_disabler_;
// Indicates if current window will receive mouse events when should not
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index deaf9cbc13c..f8550833ee6 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -7,6 +7,7 @@
#include <utility>
#include "base/command_line.h"
+#include "base/containers/flat_set.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
@@ -35,6 +36,7 @@
#include "ui/events/devices/x11/device_list_cache_x11.h"
#include "ui/events/devices/x11/touch_factory_x11.h"
#include "ui/events/event_utils.h"
+#include "ui/events/keyboard_hook.h"
#include "ui/events/null_event_targeter.h"
#include "ui/events/platform/platform_event_source.h"
#include "ui/events/platform/x11/x11_event_source.h"
@@ -337,6 +339,7 @@ void DesktopWindowTreeHostX11::OnFocusEvent(bool focus_in,
// (FocusOut with NotifyNonlinearVirtual)
// |has_pointer_focus_| should be false before and after this event.
has_pointer_focus_ = false;
+ break;
default:
break;
}
@@ -1290,6 +1293,23 @@ void DesktopWindowTreeHostX11::ReleaseCapture() {
}
}
+bool DesktopWindowTreeHostX11::CaptureSystemKeyEventsImpl(
+ base::Optional<base::flat_set<int>> key_codes) {
+ // Only one KeyboardHook should be active at a time, otherwise there will be
+ // problems with event routing (i.e. which Hook takes precedence) and
+ // destruction ordering.
+ DCHECK(!keyboard_hook_);
+ keyboard_hook_ = ui::KeyboardHook::Create(
+ std::move(key_codes),
+ base::BindRepeating(&DesktopWindowTreeHostX11::DispatchKeyEvent,
+ base::Unretained(this)));
+ return keyboard_hook_ != nullptr;
+}
+
+void DesktopWindowTreeHostX11::ReleaseSystemKeyEventCapture() {
+ keyboard_hook_.reset();
+}
+
void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) {
XDefineCursor(xdisplay_, xwindow_, cursor.platform());
}
@@ -1758,7 +1778,11 @@ void DesktopWindowTreeHostX11::DispatchMouseEvent(ui::MouseEvent* event) {
} else {
// Another DesktopWindowTreeHostX11 has installed itself as
// capture. Translate the event's location and dispatch to the other.
- ConvertEventToDifferentHost(event, g_current_capture);
+ DCHECK_EQ(ui::GetScaleFactorForNativeView(window()),
+ ui::GetScaleFactorForNativeView(g_current_capture->window()));
+ ConvertEventLocationToTargetWindowLocation(
+ g_current_capture->GetLocationOnScreenInPixels(),
+ GetLocationOnScreenInPixels(), event->AsLocatedEvent());
g_current_capture->SendEventToSink(event);
}
}
@@ -1766,7 +1790,11 @@ void DesktopWindowTreeHostX11::DispatchMouseEvent(ui::MouseEvent* event) {
void DesktopWindowTreeHostX11::DispatchTouchEvent(ui::TouchEvent* event) {
if (g_current_capture && g_current_capture != this &&
event->type() == ui::ET_TOUCH_PRESSED) {
- ConvertEventToDifferentHost(event, g_current_capture);
+ DCHECK_EQ(ui::GetScaleFactorForNativeView(window()),
+ ui::GetScaleFactorForNativeView(g_current_capture->window()));
+ ConvertEventLocationToTargetWindowLocation(
+ g_current_capture->GetLocationOnScreenInPixels(),
+ GetLocationOnScreenInPixels(), event->AsLocatedEvent());
g_current_capture->SendEventToSink(event);
} else {
SendEventToSink(event);
@@ -1778,20 +1806,6 @@ void DesktopWindowTreeHostX11::DispatchKeyEvent(ui::KeyEvent* event) {
SendEventToSink(event);
}
-void DesktopWindowTreeHostX11::ConvertEventToDifferentHost(
- ui::LocatedEvent* located_event,
- DesktopWindowTreeHostX11* host) {
- DCHECK_NE(this, host);
- DCHECK_EQ(ui::GetScaleFactorForNativeView(window()),
- ui::GetScaleFactorForNativeView(host->window()));
- gfx::Vector2d offset =
- GetLocationOnScreenInPixels() - host->GetLocationOnScreenInPixels();
- gfx::PointF location_in_pixel_in_host =
- located_event->location_f() + gfx::Vector2dF(offset);
- located_event->set_location_f(location_in_pixel_in_host);
- located_event->set_root_location_f(location_in_pixel_in_host);
-}
-
void DesktopWindowTreeHostX11::ResetWindowRegion() {
// If a custom window shape was supplied then apply it.
if (custom_window_shape_) {
@@ -2006,9 +2020,9 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
}
break;
}
- case FocusIn:
- case FocusOut:
- OnFocusEvent(xev->type == FocusIn, event->xfocus.mode,
+ case x11::FocusIn:
+ case x11::FocusOut:
+ OnFocusEvent(xev->type == x11::FocusIn, event->xfocus.mode,
event->xfocus.detail);
break;
case ConfigureNotify: {
@@ -2071,7 +2085,7 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
num_coalesced = ui::CoalescePendingMotionEvents(xev, &last_event);
if (num_coalesced > 0)
xev = &last_event;
- // fallthrough
+ FALLTHROUGH;
case ui::ET_TOUCH_PRESSED:
case ui::ET_TOUCH_RELEASED: {
ui::TouchEvent touchev(xev);
@@ -2092,7 +2106,15 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
xev = &last_event;
}
ui::MouseEvent mouseev(xev);
- DispatchMouseEvent(&mouseev);
+ // If after CoalescePendingMotionEvents the type of xev is resolved to
+ // UNKNOWN, don't dispatch the event.
+ // TODO(804418): investigate why ColescePendingMotionEvents can
+ // include mouse wheel events as well. Investigation showed that
+ // events on Linux are checked with cmt-device path, and can include
+ // DT_CMT_SCROLL_ data. See more discussion in
+ // https://crrev.com/c/853953
+ if (mouseev.type() != ui::ET_UNKNOWN)
+ DispatchMouseEvent(&mouseev);
break;
}
case ui::ET_MOUSEWHEEL: {
diff --git a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index 674951e1c90..021a1d9ad2b 100644
--- a/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/chromium/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -31,6 +31,7 @@ class ImageSkiaRep;
namespace ui {
class EventHandler;
+class KeyboardHook;
class XScopedEventSelector;
}
@@ -163,6 +164,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
gfx::Point GetLocationOnScreenInPixels() const override;
void SetCapture() override;
void ReleaseCapture() override;
+ bool CaptureSystemKeyEventsImpl(
+ base::Optional<base::flat_set<int>> keys_codes) override;
+ void ReleaseSystemKeyEventCapture() override;
void SetCursorNative(gfx::NativeCursor cursor) override;
void MoveCursorToScreenLocationInPixels(
const gfx::Point& location_in_pixels) override;
@@ -242,11 +246,6 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
// Dispatches a key event.
void DispatchKeyEvent(ui::KeyEvent* event);
- // Updates the location of |located_event| to be in |host|'s coordinate system
- // so that it can be dispatched to |host|.
- void ConvertEventToDifferentHost(ui::LocatedEvent* located_event,
- DesktopWindowTreeHostX11* host);
-
// Resets the window region for the current widget bounds if necessary.
void ResetWindowRegion();
@@ -423,6 +422,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
bool had_pointer_grab_;
bool had_window_focus_;
+ // Captures system key events when keyboard lock is requested.
+ std::unique_ptr<ui::KeyboardHook> keyboard_hook_;
+
base::CancelableCallback<void()> delayed_resize_task_;
std::unique_ptr<aura::ScopedWindowTargeter> targeter_for_modal_;
diff --git a/chromium/ui/views/widget/desktop_aura/window_event_filter.cc b/chromium/ui/views/widget/desktop_aura/window_event_filter.cc
index 05ab5af4eaf..2d3170ca5cd 100644
--- a/chromium/ui/views/widget/desktop_aura/window_event_filter.cc
+++ b/chromium/ui/views/widget/desktop_aura/window_event_filter.cc
@@ -89,28 +89,31 @@ void WindowEventFilter::OnClickedCaption(ui::MouseEvent* event,
break;
case LinuxUI::WINDOW_FRAME_ACTION_LOWER:
LowerWindow();
+ event->SetHandled();
break;
case LinuxUI::WINDOW_FRAME_ACTION_MINIMIZE:
window_tree_host_->Minimize();
+ event->SetHandled();
break;
case LinuxUI::WINDOW_FRAME_ACTION_TOGGLE_MAXIMIZE:
if (target->GetProperty(aura::client::kResizeBehaviorKey) &
ui::mojom::kResizeBehaviorCanMaximize)
ToggleMaximizedState();
+ event->SetHandled();
break;
case LinuxUI::WINDOW_FRAME_ACTION_MENU:
views::Widget* widget = views::Widget::GetWidgetForNativeView(target);
if (!widget)
break;
views::View* view = widget->GetContentsView();
- if (!view)
+ if (!view || !view->context_menu_controller())
break;
gfx::Point location(event->location());
views::View::ConvertPointToScreen(view, &location);
view->ShowContextMenu(location, ui::MENU_SOURCE_MOUSE);
+ event->SetHandled();
break;
}
- event->SetHandled();
}
void WindowEventFilter::OnClickedMaximizeButton(ui::MouseEvent* event) {
diff --git a/chromium/ui/views/widget/native_widget_aura.cc b/chromium/ui/views/widget/native_widget_aura.cc
index 8797bf889fb..a9be3abbd01 100644
--- a/chromium/ui/views/widget/native_widget_aura.cc
+++ b/chromium/ui/views/widget/native_widget_aura.cc
@@ -57,7 +57,7 @@
#if defined(OS_WIN)
#include "base/win/scoped_gdi_object.h"
-#include "base/win/win_util.h"
+#include "base/win/win_client_metrics.h"
#include "ui/base/l10n/l10n_util_win.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
#endif
@@ -136,10 +136,10 @@ void NativeWidgetAura::SetShadowElevationFromInitParams(
aura::Window* window,
const Widget::InitParams& params) {
if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_NONE) {
- SetShadowElevation(window, wm::ShadowElevation::NONE);
+ wm::SetShadowElevation(window, wm::kShadowElevationNone);
} else if (params.shadow_type == Widget::InitParams::SHADOW_TYPE_DROP &&
params.shadow_elevation) {
- SetShadowElevation(window, *params.shadow_elevation);
+ wm::SetShadowElevation(window, *params.shadow_elevation);
}
}
@@ -157,15 +157,23 @@ void NativeWidgetAura::InitNativeWidget(const Widget::InitParams& params) {
// MusClient has assertions that ui::mojom::WindowType matches
// views::Widget::InitParams::Type.
aura::SetWindowType(window_, static_cast<ui::mojom::WindowType>(params.type));
+ if (params.corner_radius) {
+ window_->SetProperty(aura::client::kWindowCornerRadiusKey,
+ *params.corner_radius);
+ }
window_->SetProperty(aura::client::kShowStateKey, params.show_state);
if (params.type == Widget::InitParams::TYPE_BUBBLE)
wm::SetHideOnDeactivate(window_, true);
window_->SetTransparent(
params.opacity == Widget::InitParams::TRANSLUCENT_WINDOW);
+
+ // Check for SHADOW_TYPE_NONE before aura::Window::Init() to ensure observers
+ // do not add useless shadow layers by deriving one from the window type.
+ SetShadowElevationFromInitParams(window_, params);
+
window_->Init(params.layer_type);
// Set name after layer init so it propagates to layer.
window_->SetName(params.name);
- SetShadowElevationFromInitParams(window_, params);
if (params.type == Widget::InitParams::TYPE_CONTROL)
window_->Show();
diff --git a/chromium/ui/views/widget/native_widget_mac.mm b/chromium/ui/views/widget/native_widget_mac.mm
index 28040b162fa..f5db821551e 100644
--- a/chromium/ui/views/widget/native_widget_mac.mm
+++ b/chromium/ui/views/widget/native_widget_mac.mm
@@ -13,6 +13,7 @@
#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "components/crash/core/common/crash_key.h"
#import "ui/base/cocoa/constrained_window/constrained_window_animation.h"
#import "ui/base/cocoa/window_size_constants.h"
#include "ui/gfx/font_list.h"
@@ -635,11 +636,25 @@ NativeWidgetMacNSWindow* NativeWidgetMac::CreateNSWindow(
// static
void Widget::CloseAllSecondaryWidgets() {
- // Create a copy of [NSApp windows] to increase every window's retain count.
- // -[NSWindow dealloc] won't be invoked on any windows until this array goes
- // out of scope.
- base::scoped_nsobject<NSArray> starting_windows([[NSApp windows] copy]);
- for (NSWindow* window in starting_windows.get()) {
+ NSArray* starting_windows = [NSApp windows]; // Creates an autoreleased copy.
+ for (NSWindow* window in starting_windows) {
+ // Ignore any windows that couldn't have been created by NativeWidgetMac or
+ // a subclass. GetNativeWidgetForNativeWindow() will later interrogate the
+ // NSWindow delegate, but we can't trust that delegate to be a valid object.
+ if (![window isKindOfClass:[NativeWidgetMacNSWindow class]])
+ continue;
+
+ // Record a crash key to detect when client code may destroy a
+ // WidgetObserver without removing it (possibly leaking the Widget).
+ // A crash can occur in generic Widget teardown paths when trying to notify.
+ // See http://crbug.com/808318.
+ static crash_reporter::CrashKeyString<256> window_info_key("windowInfo");
+ std::string value = base::SysNSStringToUTF8(
+ [NSString stringWithFormat:@"Closing %@ (%@)", [window title],
+ [window className]]);
+ crash_reporter::ScopedCrashKeyString scopedWindowKey(&window_info_key,
+ value);
+
Widget* widget = GetWidgetForNativeWindow(window);
if (widget && widget->is_secondary_widget())
[window close];
diff --git a/chromium/ui/views/widget/native_widget_mac_accessibility_unittest.mm b/chromium/ui/views/widget/native_widget_mac_accessibility_unittest.mm
index 23ab9fb0eb2..a6baee39626 100644
--- a/chromium/ui/views/widget/native_widget_mac_accessibility_unittest.mm
+++ b/chromium/ui/views/widget/native_widget_mac_accessibility_unittest.mm
@@ -12,7 +12,7 @@
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#import "testing/gtest_mac.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h"
#import "ui/accessibility/platform/ax_platform_node_mac.h"
#include "ui/base/ime/text_input_type.h"
@@ -36,8 +36,8 @@ NSString* const kTestTitle = @"Test textfield";
class FlexibleRoleTestView : public View {
public:
- explicit FlexibleRoleTestView(ui::AXRole role) : role_(role) {}
- void set_role(ui::AXRole role) { role_ = role; }
+ explicit FlexibleRoleTestView(ax::mojom::Role role) : role_(role) {}
+ void set_role(ax::mojom::Role role) { role_ = role; }
// Add a child view and resize to fit the child.
void FitBoundsToNewChild(View* view) {
@@ -60,7 +60,7 @@ class FlexibleRoleTestView : public View {
}
private:
- ui::AXRole role_;
+ ax::mojom::Role role_;
bool mouse_was_pressed_ = false;
DISALLOW_COPY_AND_ASSIGN(FlexibleRoleTestView);
@@ -133,7 +133,7 @@ class NativeWidgetMacAccessibilityTest : public test::WidgetTest {
}
// Shorthand helpers to get a11y properties from A11yElementAtMidpoint().
- NSString* AXRole() {
+ NSString* AXRoleString() {
return AttributeValueAtMidpoint(NSAccessibilityRoleAttribute);
}
id AXParent() {
@@ -292,7 +292,7 @@ TEST_F(NativeWidgetMacAccessibilityTest, FocusableElementsAreLeafNodes) {
TestLabelButton* button = new TestLabelButton();
button->SetSize(widget()->GetContentsView()->size());
widget()->GetContentsView()->AddChildView(button);
- EXPECT_NSEQ(NSAccessibilityButtonRole, AXRole());
+ EXPECT_NSEQ(NSAccessibilityButtonRole, AXRoleString());
EXPECT_EQ(
0u,
[[button->GetNativeViewAccessible()
@@ -339,7 +339,7 @@ TEST_F(NativeWidgetMacAccessibilityTest, ChildrenAttribute) {
// Check ignored children don't show up in the accessibility tree.
widget()->GetContentsView()->AddChildView(
- new FlexibleRoleTestView(ui::AX_ROLE_IGNORED));
+ new FlexibleRoleTestView(ax::mojom::Role::kIgnored));
EXPECT_EQ(kNumChildren,
[AttributeValueAtMidpoint(NSAccessibilityChildrenAttribute) count]);
}
@@ -356,7 +356,8 @@ TEST_F(NativeWidgetMacAccessibilityTest, ParentAttribute) {
// Views with non-Widget parents will have the role of the parent view.
widget()->GetContentsView()->RemoveChildView(child);
- FlexibleRoleTestView* parent = new FlexibleRoleTestView(ui::AX_ROLE_GROUP);
+ FlexibleRoleTestView* parent =
+ new FlexibleRoleTestView(ax::mojom::Role::kGroup);
parent->FitBoundsToNewChild(child);
widget()->GetContentsView()->AddChildView(parent);
EXPECT_NSEQ(
@@ -364,7 +365,7 @@ TEST_F(NativeWidgetMacAccessibilityTest, ParentAttribute) {
[AXParent() accessibilityAttributeValue:NSAccessibilityRoleAttribute]);
// Test an ignored role parent is skipped in favor of the grandparent.
- parent->set_role(ui::AX_ROLE_IGNORED);
+ parent->set_role(ax::mojom::Role::kIgnored);
EXPECT_NSEQ(
NSAccessibilityWindowRole,
[AXParent() accessibilityAttributeValue:NSAccessibilityRoleAttribute]);
@@ -390,7 +391,7 @@ TEST_F(NativeWidgetMacAccessibilityTest, PositionAttribute) {
// Test for NSAccessibilityHelpAttribute.
TEST_F(NativeWidgetMacAccessibilityTest, HelpAttribute) {
- Label* label = new Label(base::SysNSStringToUTF16(kTestPlaceholderText));
+ Label* label = new Label(base::SysNSStringToUTF16(kTestStringValue));
label->SetSize(GetWidgetBounds().size());
EXPECT_NSEQ(@"", AttributeValueAtMidpoint(NSAccessibilityHelpAttribute));
label->SetTooltipText(base::SysNSStringToUTF16(kTestPlaceholderText));
@@ -402,11 +403,12 @@ TEST_F(NativeWidgetMacAccessibilityTest, HelpAttribute) {
// Test view properties that should report the native NSWindow, and test
// specific properties on that NSWindow.
TEST_F(NativeWidgetMacAccessibilityTest, NativeWindowProperties) {
- FlexibleRoleTestView* view = new FlexibleRoleTestView(ui::AX_ROLE_GROUP);
+ FlexibleRoleTestView* view =
+ new FlexibleRoleTestView(ax::mojom::Role::kGroup);
view->SetSize(GetWidgetBounds().size());
widget()->GetContentsView()->AddChildView(view);
// Make sure it's |view| in the hit test by checking its accessibility role.
- EXPECT_EQ(NSAccessibilityGroupRole, AXRole());
+ EXPECT_EQ(NSAccessibilityGroupRole, AXRoleString());
NSWindow* window = widget()->GetNativeWindow();
EXPECT_NSEQ(window, AttributeValueAtMidpoint(NSAccessibilityWindowAttribute));
@@ -439,7 +441,7 @@ TEST_F(NativeWidgetMacAccessibilityTest, TextfieldGenericAttributes) {
boolValue]);
// NSAccessibilityTitleAttribute.
- EXPECT_NSEQ(NSAccessibilityTextFieldRole, AXRole());
+ EXPECT_NSEQ(NSAccessibilityTextFieldRole, AXRoleString());
EXPECT_NSEQ(kTestTitle, AXTitle());
EXPECT_NSEQ(kTestStringValue, AXValue());
@@ -538,14 +540,15 @@ TEST_F(NativeWidgetMacAccessibilityTest, TextfieldEditableAttributes) {
// Test writing accessibility attributes via an accessibility client for normal
// Views.
TEST_F(NativeWidgetMacAccessibilityTest, ViewWritableAttributes) {
- FlexibleRoleTestView* view = new FlexibleRoleTestView(ui::AX_ROLE_GROUP);
+ FlexibleRoleTestView* view =
+ new FlexibleRoleTestView(ax::mojom::Role::kGroup);
view->SetSize(GetWidgetBounds().size());
widget()->GetContentsView()->AddChildView(view);
// Make sure the accessibility object tested is the correct one.
id ax_node = A11yElementAtMidpoint();
EXPECT_TRUE(ax_node);
- EXPECT_NSEQ(NSAccessibilityGroupRole, AXRole());
+ EXPECT_NSEQ(NSAccessibilityGroupRole, AXRoleString());
// Make sure |view| is focusable, then focus/unfocus it.
view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
@@ -721,12 +724,13 @@ TEST_F(NativeWidgetMacAccessibilityTest, TextParameterizedAttributes) {
// Test performing a 'click' on Views with clickable roles work.
TEST_F(NativeWidgetMacAccessibilityTest, PressAction) {
- FlexibleRoleTestView* view = new FlexibleRoleTestView(ui::AX_ROLE_BUTTON);
+ FlexibleRoleTestView* view =
+ new FlexibleRoleTestView(ax::mojom::Role::kButton);
widget()->GetContentsView()->AddChildView(view);
view->SetSize(GetWidgetBounds().size());
id ax_node = A11yElementAtMidpoint();
- EXPECT_NSEQ(NSAccessibilityButtonRole, AXRole());
+ EXPECT_NSEQ(NSAccessibilityButtonRole, AXRoleString());
EXPECT_TRUE([[ax_node accessibilityActionNames]
containsObject:NSAccessibilityPressAction]);
@@ -789,7 +793,7 @@ TEST_F(NativeWidgetMacAccessibilityTest, ProtectedTextfields) {
// Explicit checks done without comparing to NSTextField.
EXPECT_TRUE(
[ax_node accessibilityIsAttributeSettable:NSAccessibilityValueAttribute]);
- EXPECT_NSEQ(NSAccessibilityTextFieldRole, AXRole());
+ EXPECT_NSEQ(NSAccessibilityTextFieldRole, AXRoleString());
NSString* kShownValue = @"•"
@"••••••••••••••••";
@@ -831,7 +835,7 @@ TEST_F(NativeWidgetMacAccessibilityTest, Label) {
id ax_node = A11yElementAtMidpoint();
EXPECT_TRUE(ax_node);
- EXPECT_NSEQ(NSAccessibilityStaticTextRole, AXRole());
+ EXPECT_NSEQ(NSAccessibilityStaticTextRole, AXRoleString());
EXPECT_NSEQ(kTestStringValue, AXValue());
// Title and description for StaticTextRole should always be empty.
@@ -867,6 +871,21 @@ TEST_F(NativeWidgetMacAccessibilityTest, Label) {
// TODO(tapted): Add a test for multiline Labels (currently not supported).
}
+// Labels used as title bars should be exposed as normal static text on Mac.
+TEST_F(NativeWidgetMacAccessibilityTest, LabelUsedAsTitleBar) {
+ Label* label = new Label(base::SysNSStringToUTF16(kTestStringValue),
+ style::CONTEXT_DIALOG_TITLE, style::STYLE_PRIMARY);
+ label->SetSize(GetWidgetBounds().size());
+ widget()->GetContentsView()->AddChildView(label);
+
+ // Get the Label's accessibility object.
+ id ax_node = A11yElementAtMidpoint();
+ EXPECT_TRUE(ax_node);
+
+ EXPECT_NSEQ(NSAccessibilityStaticTextRole, AXRoleString());
+ EXPECT_NSEQ(kTestStringValue, AXValue());
+}
+
class TestComboboxModel : public ui::ComboboxModel {
public:
TestComboboxModel() = default;
@@ -891,7 +910,7 @@ TEST_F(NativeWidgetMacAccessibilityTest, Combobox) {
id ax_node = A11yElementAtMidpoint();
EXPECT_TRUE(ax_node);
- EXPECT_NSEQ(NSAccessibilityPopUpButtonRole, AXRole());
+ EXPECT_NSEQ(NSAccessibilityPopUpButtonRole, AXRoleString());
// The initial value should be the first item in the menu.
EXPECT_NSEQ(kTestStringValue, AXValue());
diff --git a/chromium/ui/views/widget/native_widget_mac_unittest.mm b/chromium/ui/views/widget/native_widget_mac_unittest.mm
index b8e66d1533e..6555f7ddd0f 100644
--- a/chromium/ui/views/widget/native_widget_mac_unittest.mm
+++ b/chromium/ui/views/widget/native_widget_mac_unittest.mm
@@ -760,6 +760,76 @@ TEST_F(NativeWidgetMacTest, NonWidgetParent) {
EXPECT_EQ(0u, [[native_parent childWindows] count]);
}
+// Tests that CloseAllSecondaryWidgets behaves in various configurations.
+TEST_F(NativeWidgetMacTest, CloseAllSecondaryWidgetsValidState) {
+ NSWindow* last_window = nil;
+ {
+ // First verify the behavior of CloseAllSecondaryWidgets in the normal case,
+ // and how [NSApp windows] changes in response to Widget closure.
+ base::mac::ScopedNSAutoreleasePool pool;
+ Widget* widget = CreateTopLevelPlatformWidget();
+ widget->Show();
+ TestWidgetObserver observer(widget);
+ last_window = widget->GetNativeWindow();
+ EXPECT_TRUE([[NSApp windows] containsObject:last_window]);
+ Widget::CloseAllSecondaryWidgets();
+ EXPECT_TRUE(observer.widget_closed());
+ }
+
+ {
+ // Calls to [NSApp windows] do autorelease, so ensure the pool empties.
+ base::mac::ScopedNSAutoreleasePool pool;
+
+ // [NSApp windows] updates inside dealloc, so the window should be gone.
+ EXPECT_FALSE([[NSApp windows] containsObject:last_window]);
+ }
+
+ {
+ // Repeat, but now retain a reference and close the window before
+ // CloseAllSecondaryWidgets().
+ base::mac::ScopedNSAutoreleasePool pool;
+ Widget* widget = CreateTopLevelPlatformWidget();
+ widget->Show();
+ TestWidgetObserver observer(widget);
+ last_window = [widget->GetNativeWindow() retain];
+ EXPECT_TRUE([[NSApp windows] containsObject:last_window]);
+ widget->CloseNow();
+ EXPECT_TRUE(observer.widget_closed());
+ }
+ {
+ base::mac::ScopedNSAutoreleasePool pool;
+ // Reference retained, so the window should still be present.
+ EXPECT_TRUE([[NSApp windows] containsObject:last_window]);
+ }
+
+ {
+ base::mac::ScopedNSAutoreleasePool pool;
+ Widget::CloseAllSecondaryWidgets();
+ [last_window release];
+ }
+ {
+ base::mac::ScopedNSAutoreleasePool pool;
+ EXPECT_FALSE([[NSApp windows] containsObject:last_window]);
+ }
+
+ // Repeat, with two Widgets. We can't control the order of window closure.
+ // If the parent is closed first, it should tear down the child while
+ // iterating over the windows. -[NSWindow close] will be sent to the child
+ // twice, but that should be fine.
+ Widget* parent = CreateTopLevelPlatformWidget();
+ Widget* child = CreateChildPlatformWidget(parent->GetNativeView());
+ parent->Show();
+ child->Show();
+ TestWidgetObserver parent_observer(parent);
+ TestWidgetObserver child_observer(child);
+
+ EXPECT_TRUE([[NSApp windows] containsObject:parent->GetNativeWindow()]);
+ EXPECT_TRUE([[NSApp windows] containsObject:child->GetNativeWindow()]);
+ Widget::CloseAllSecondaryWidgets();
+ EXPECT_TRUE(parent_observer.widget_closed());
+ EXPECT_TRUE(child_observer.widget_closed());
+}
+
// Tests closing the last remaining NSWindow reference via -windowWillClose:.
// This is a regression test for http://crbug.com/616701.
TEST_F(NativeWidgetMacTest, NonWidgetParentLastReference) {
diff --git a/chromium/ui/views/widget/widget.cc b/chromium/ui/views/widget/widget.cc
index d685bf4f40e..926519dfa33 100644
--- a/chromium/ui/views/widget/widget.cc
+++ b/chromium/ui/views/widget/widget.cc
@@ -525,6 +525,8 @@ void Widget::SetBoundsConstrained(const gfx::Rect& bounds) {
if (work_area.IsEmpty()) {
SetBounds(bounds);
} else {
+ // TODO(https://crbug.com/806936): The following code doesn't actually do
+ // what the comment describing this function says it should.
// Inset the work area slightly.
work_area.Inset(10, 10, 10, 10);
work_area.AdjustToFit(bounds);
diff --git a/chromium/ui/views/widget/widget.h b/chromium/ui/views/widget/widget.h
index 242c9496b29..6c0c60807a2 100644
--- a/chromium/ui/views/widget/widget.h
+++ b/chromium/ui/views/widget/widget.h
@@ -59,10 +59,6 @@ class OSExchangeData;
class ThemeProvider;
} // namespace ui
-namespace wm {
-enum class ShadowElevation;
-}
-
namespace views {
class DesktopWindowTreeHost;
@@ -243,7 +239,9 @@ class VIEWS_EXPORT Widget : public internal::NativeWidgetDelegate,
ShadowType shadow_type;
// A hint about the size of the shadow if the type is SHADOW_TYPE_DROP. May
// be ignored on some platforms. No value indicates no preference.
- base::Optional<wm::ShadowElevation> shadow_elevation;
+ base::Optional<int> shadow_elevation;
+ // The window corner radius. May be ignored on some platforms.
+ base::Optional<int> corner_radius;
// Specifies that the system default caption and icon should not be
// rendered, and that the client area should be equivalent to the window
// area. Only used on some platforms (Windows and Linux).
diff --git a/chromium/ui/views/widget/widget_delegate.cc b/chromium/ui/views/widget/widget_delegate.cc
index a7696103df3..294113b8996 100644
--- a/chromium/ui/views/widget/widget_delegate.cc
+++ b/chromium/ui/views/widget/widget_delegate.cc
@@ -74,8 +74,8 @@ ui::ModalType WidgetDelegate::GetModalType() const {
return ui::MODAL_TYPE_NONE;
}
-ui::AXRole WidgetDelegate::GetAccessibleWindowRole() const {
- return ui::AX_ROLE_WINDOW;
+ax::mojom::Role WidgetDelegate::GetAccessibleWindowRole() const {
+ return ax::mojom::Role::kWindow;
}
base::string16 WidgetDelegate::GetAccessibleWindowTitle() const {
@@ -94,14 +94,6 @@ bool WidgetDelegate::ShouldShowCloseButton() const {
return true;
}
-bool WidgetDelegate::ShouldHandleSystemCommands() const {
- const Widget* widget = GetWidget();
- if (!widget)
- return false;
-
- return widget->non_client_view() != NULL;
-}
-
gfx::ImageSkia WidgetDelegate::GetWindowAppIcon() {
// Use the window icon as app icon by default.
return GetWindowIcon();
diff --git a/chromium/ui/views/widget/widget_delegate.h b/chromium/ui/views/widget/widget_delegate.h
index bd4d8a7a1de..8ae82197483 100644
--- a/chromium/ui/views/widget/widget_delegate.h
+++ b/chromium/ui/views/widget/widget_delegate.h
@@ -9,7 +9,7 @@
#include <vector>
#include "base/macros.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/base/ui_base_types.h"
#include "ui/views/view.h"
@@ -72,7 +72,7 @@ class VIEWS_EXPORT WidgetDelegate {
// ui::MODAL_TYPE_NONE (not modal).
virtual ui::ModalType GetModalType() const;
- virtual ui::AXRole GetAccessibleWindowRole() const;
+ virtual ax::mojom::Role GetAccessibleWindowRole() const;
// Returns the title to be read with screen readers.
virtual base::string16 GetAccessibleWindowTitle() const;
@@ -86,10 +86,6 @@ class VIEWS_EXPORT WidgetDelegate {
// Returns true if the window should show a close button in the title bar.
virtual bool ShouldShowCloseButton() const;
- // Returns true if the window should handle standard system commands, such as
- // close, minimize, maximize.
- virtual bool ShouldHandleSystemCommands() const;
-
// Returns the app icon for the window. On Windows, this is the ICON_BIG used
// in Alt-Tab list and Win7's taskbar.
virtual gfx::ImageSkia GetWindowAppIcon();
diff --git a/chromium/ui/views/widget/widget_hwnd_utils.cc b/chromium/ui/views/widget/widget_hwnd_utils.cc
index 163e4b54b03..c7296fed234 100644
--- a/chromium/ui/views/widget/widget_hwnd_utils.cc
+++ b/chromium/ui/views/widget/widget_hwnd_utils.cc
@@ -60,7 +60,7 @@ void CalculateWindowStylesFromInitParams(
*style |= WS_POPUP;
break;
}
- // Else, no break. Fall through to TYPE_WINDOW.
+ FALLTHROUGH;
case Widget::InitParams::TYPE_WINDOW: {
// WS_OVERLAPPEDWINDOW is equivalent to:
// WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
diff --git a/chromium/ui/views/widget/widget_interactive_uitest.cc b/chromium/ui/views/widget/widget_interactive_uitest.cc
index 7bc23806118..1cad461f7dd 100644
--- a/chromium/ui/views/widget/widget_interactive_uitest.cc
+++ b/chromium/ui/views/widget/widget_interactive_uitest.cc
@@ -14,11 +14,13 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/win/windows_version.h"
#include "build/build_config.h"
#include "mojo/edk/embedder/embedder.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/text_input_client.h"
#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/test/ui_controls.h"
#include "ui/base/ui_base_paths.h"
#include "ui/base/ui_base_switches.h"
#include "ui/events/event_processor.h"
@@ -362,6 +364,75 @@ TEST_F(WidgetTestInteractive, DesktopNativeWidgetAuraActivationAndFocusTest) {
widget2->CloseNow();
widget1->CloseNow();
}
+
+class TouchEventHandler : public ui::EventHandler {
+ public:
+ TouchEventHandler(Widget* widget) : widget_(widget) {
+ widget_->GetNativeWindow()->GetHost()->window()->AddPreTargetHandler(this);
+ }
+
+ ~TouchEventHandler() override {
+ widget_->GetNativeWindow()->GetHost()->window()->RemovePreTargetHandler(
+ this);
+ }
+
+ void WaitForEvents() {
+ base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
+ base::MessageLoopForUI::ScopedNestableTaskAllower allow_nested(loop);
+ base::RunLoop run_loop;
+ quit_closure_ = run_loop.QuitClosure();
+ run_loop.Run();
+ }
+
+ static void __stdcall AsyncActivateMouse(HWND hwnd,
+ UINT msg,
+ ULONG_PTR data,
+ LRESULT result) {
+ EXPECT_EQ(MA_NOACTIVATE, result);
+ std::move(reinterpret_cast<TouchEventHandler*>(data)->quit_closure_).Run();
+ }
+
+ void ActivateViaMouse() {
+ SendMessageCallback(
+ widget_->GetNativeWindow()->GetHost()->GetAcceleratedWidget(),
+ WM_MOUSEACTIVATE, 0, 0, AsyncActivateMouse,
+ reinterpret_cast<ULONG_PTR>(this));
+ }
+
+ private:
+ // ui::EventHandler:
+ void OnTouchEvent(ui::TouchEvent* event) override {
+ if (event->type() == ui::ET_TOUCH_PRESSED)
+ ActivateViaMouse();
+ }
+
+ Widget* widget_;
+ base::OnceClosure quit_closure_;
+ DISALLOW_COPY_AND_ASSIGN(TouchEventHandler);
+};
+
+// TODO(dtapuska): Disabled due to it being flaky crbug.com/817531
+TEST_F(WidgetTestInteractive, DISABLED_TouchNoActivateWindow) {
+ // ui_controls::SendTouchEvents which uses InjectTouchInput API only works
+ // on Windows 8 and up.
+ if (base::win::GetVersion() <= base::win::VERSION_WIN7)
+ return;
+
+ View* focusable_view = new View;
+ focusable_view->SetFocusBehavior(View::FocusBehavior::ALWAYS);
+ Widget* widget = CreateWidget();
+ widget->GetContentsView()->AddChildView(focusable_view);
+ widget->Show();
+
+ {
+ TouchEventHandler touch_event_handler(widget);
+ ASSERT_TRUE(ui_controls::SendTouchEvents(ui_controls::PRESS, 1, 100, 100));
+ touch_event_handler.WaitForEvents();
+ }
+
+ widget->CloseNow();
+}
+
#endif // defined(OS_WIN)
TEST_F(WidgetTestInteractive, CaptureAutoReset) {
@@ -641,6 +712,82 @@ TEST_F(WidgetTestInteractive, ViewFocusOnWidgetActivationChanges) {
widget2->CloseNow();
}
+// Test z-order of child widgets relative to their parent.
+TEST_F(WidgetTestInteractive, ChildStackedRelativeToParent) {
+ WidgetAutoclosePtr parent(CreateTopLevelPlatformWidget());
+ Widget* child = CreateChildPlatformWidget(parent->GetNativeView());
+
+ parent->SetBounds(gfx::Rect(160, 100, 320, 200));
+ child->SetBounds(gfx::Rect(50, 50, 30, 20));
+
+ // Child shown first. Initially not visible, but on top of parent when shown.
+ // Use ShowInactive whenever showing the child, otherwise the usual activation
+ // logic will just put it on top anyway. Here, we want to ensure it is on top
+ // of its parent regardless.
+ child->ShowInactive();
+ EXPECT_FALSE(child->IsVisible());
+
+ ShowSync(parent.get());
+ EXPECT_TRUE(child->IsVisible());
+ EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
+ EXPECT_FALSE(IsWindowStackedAbove(parent.get(), child)); // Sanity check.
+
+ WidgetAutoclosePtr popover(CreateTopLevelPlatformWidget());
+ popover->SetBounds(gfx::Rect(150, 90, 340, 240));
+ ShowSync(popover.get());
+
+ // NOTE: for aura-mus-client stacking of top-levels is not maintained in the
+ // client, so z-order of top-levels can't be determined.
+ const bool check_toplevel_z_order = !IsMus();
+ if (check_toplevel_z_order)
+ EXPECT_TRUE(IsWindowStackedAbove(popover.get(), child));
+ EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
+
+ // Showing the parent again should raise it and its child above the popover.
+ ShowSync(parent.get());
+ EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
+ if (check_toplevel_z_order)
+ EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
+
+ // Test grandchildren.
+ Widget* grandchild = CreateChildPlatformWidget(child->GetNativeView());
+ grandchild->SetBounds(gfx::Rect(5, 5, 15, 10));
+ grandchild->ShowInactive();
+ EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
+ EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
+ if (check_toplevel_z_order)
+ EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
+
+ ShowSync(popover.get());
+ if (check_toplevel_z_order)
+ EXPECT_TRUE(IsWindowStackedAbove(popover.get(), grandchild));
+ EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
+
+ ShowSync(parent.get());
+ EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
+ if (check_toplevel_z_order)
+ EXPECT_TRUE(IsWindowStackedAbove(child, popover.get()));
+
+ // Test hiding and reshowing.
+ parent->Hide();
+ EXPECT_FALSE(grandchild->IsVisible());
+ ShowSync(parent.get());
+
+ EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
+ EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
+ if (check_toplevel_z_order)
+ EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
+
+ grandchild->Hide();
+ EXPECT_FALSE(grandchild->IsVisible());
+ grandchild->ShowInactive();
+
+ EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
+ EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
+ if (check_toplevel_z_order)
+ EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
+}
+
#if defined(OS_WIN)
// Test view focus retention when a widget's HWND is disabled and re-enabled.
diff --git a/chromium/ui/views/widget/widget_unittest.cc b/chromium/ui/views/widget/widget_unittest.cc
index 9bee0337d55..76a9b283676 100644
--- a/chromium/ui/views/widget/widget_unittest.cc
+++ b/chromium/ui/views/widget/widget_unittest.cc
@@ -47,6 +47,12 @@
#include "base/mac/mac_util.h"
#endif
+#if defined(OS_CHROMEOS)
+#include "ui/wm/core/base_focus_rules.h"
+#include "ui/wm/core/focus_controller.h"
+#include "ui/wm/core/shadow_controller.h"
+#endif
+
namespace views {
namespace test {
@@ -61,12 +67,6 @@ gfx::Point ConvertPointFromWidgetToView(View* view, const gfx::Point& p) {
return tmp;
}
-// This class can be used as a deleter for std::unique_ptr<Widget>
-// to call function Widget::CloseNow automatically.
-struct WidgetCloser {
- inline void operator()(Widget* widget) const { widget->CloseNow(); }
-};
-
class TestBubbleDialogDelegateView : public BubbleDialogDelegateView {
public:
TestBubbleDialogDelegateView(View* anchor)
@@ -82,8 +82,6 @@ class TestBubbleDialogDelegateView : public BubbleDialogDelegateView {
mutable bool reset_controls_called_;
};
-using WidgetAutoclosePtr = std::unique_ptr<Widget, WidgetCloser>;
-
} // namespace
// A view that keeps track of the events it receives, and consumes all scroll
@@ -286,82 +284,6 @@ TEST_F(WidgetTest, ChildBoundsRelativeToParent) {
EXPECT_EQ(toplevel_bounds, child->GetWindowBoundsInScreen());
}
-// Test z-order of child widgets relative to their parent.
-TEST_F(WidgetTest, ChildStackedRelativeToParent) {
- WidgetAutoclosePtr parent(CreateTopLevelPlatformWidget());
- Widget* child = CreateChildPlatformWidget(parent->GetNativeView());
-
- parent->SetBounds(gfx::Rect(160, 100, 320, 200));
- child->SetBounds(gfx::Rect(50, 50, 30, 20));
-
- // Child shown first. Initially not visible, but on top of parent when shown.
- // Use ShowInactive whenever showing the child, otherwise the usual activation
- // logic will just put it on top anyway. Here, we want to ensure it is on top
- // of its parent regardless.
- child->ShowInactive();
- EXPECT_FALSE(child->IsVisible());
-
- parent->Show();
- EXPECT_TRUE(child->IsVisible());
- EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
- EXPECT_FALSE(IsWindowStackedAbove(parent.get(), child)); // Sanity check.
-
- WidgetAutoclosePtr popover(CreateTopLevelPlatformWidget());
- popover->SetBounds(gfx::Rect(150, 90, 340, 240));
- popover->Show();
-
- // NOTE: for aura-mus-client stacking of top-levels is not maintained in the
- // client, so z-order of top-levels can't be determined.
- const bool check_toplevel_z_order = !IsMus();
- if (check_toplevel_z_order)
- EXPECT_TRUE(IsWindowStackedAbove(popover.get(), child));
- EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
-
- // Showing the parent again should raise it and its child above the popover.
- parent->Show();
- EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
- if (check_toplevel_z_order)
- EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
-
- // Test grandchildren.
- Widget* grandchild = CreateChildPlatformWidget(child->GetNativeView());
- grandchild->SetBounds(gfx::Rect(5, 5, 15, 10));
- grandchild->ShowInactive();
- EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
- EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
- if (check_toplevel_z_order)
- EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
-
- popover->Show();
- if (check_toplevel_z_order)
- EXPECT_TRUE(IsWindowStackedAbove(popover.get(), grandchild));
- EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
-
- parent->Show();
- EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
- if (check_toplevel_z_order)
- EXPECT_TRUE(IsWindowStackedAbove(child, popover.get()));
-
- // Test hiding and reshowing.
- parent->Hide();
- EXPECT_FALSE(grandchild->IsVisible());
- parent->Show();
-
- EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
- EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
- if (check_toplevel_z_order)
- EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
-
- grandchild->Hide();
- EXPECT_FALSE(grandchild->IsVisible());
- grandchild->ShowInactive();
-
- EXPECT_TRUE(IsWindowStackedAbove(grandchild, child));
- EXPECT_TRUE(IsWindowStackedAbove(child, parent.get()));
- if (check_toplevel_z_order)
- EXPECT_TRUE(IsWindowStackedAbove(parent.get(), popover.get()));
-}
-
////////////////////////////////////////////////////////////////////////////////
// Widget ownership tests.
//
@@ -2116,7 +2038,7 @@ bool RunGetNativeThemeFromDestructor(const Widget::InitParams& in_params,
bool is_first_run) {
bool needs_second_run = false;
// Destroyed by CloseNow() below.
- WidgetAutoclosePtr widget(new Widget);
+ WidgetTest::WidgetAutoclosePtr widget(new Widget);
Widget::InitParams params(in_params);
// Deletes itself when the Widget is destroyed.
params.delegate = new GetNativeThemeFromDestructorView;
@@ -3815,6 +3737,142 @@ TEST_F(WidgetTest, MouseWheelEvent) {
EXPECT_EQ(1, event_count_view->GetEventCount(ui::ET_MOUSEWHEEL));
}
+class WidgetShadowTest : public WidgetTest {
+ public:
+ WidgetShadowTest() { InitControllers(); }
+
+ // WidgetTest:
+ Widget::InitParams CreateParams(Widget::InitParams::Type type) override {
+ Widget::InitParams params =
+ WidgetTest::CreateParams(override_type_.value_or(type));
+ params.shadow_type = Widget::InitParams::SHADOW_TYPE_DROP;
+ params.shadow_elevation = 10;
+ params.name = name_;
+ params.child = force_child_;
+ return params;
+ }
+
+ protected:
+ base::Optional<Widget::InitParams::Type> override_type_;
+ std::string name_;
+ bool force_child_ = false;
+
+ private:
+#if !defined(OS_CHROMEOS)
+ void InitControllers() {}
+#else
+ class TestFocusRules : public wm::BaseFocusRules {
+ public:
+ TestFocusRules() = default;
+
+ bool SupportsChildActivation(aura::Window* window) const override {
+ return true;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestFocusRules);
+ };
+
+ void InitControllers() {
+ // Add bits usually managed by the ash::Shell. Under Mus,
+ // DesktopNativeWidgetAura provides these in-process instead.
+ if (IsMus())
+ return;
+
+ focus_controller_ =
+ std::make_unique<wm::FocusController>(new TestFocusRules);
+ shadow_controller_ =
+ std::make_unique<wm::ShadowController>(focus_controller_.get());
+ }
+
+ std::unique_ptr<wm::FocusController> focus_controller_;
+ std::unique_ptr<wm::ShadowController> shadow_controller_;
+#endif // OS_CHROMEOS
+
+ DISALLOW_COPY_AND_ASSIGN(WidgetShadowTest);
+};
+
+// Disabled on Mac: All drop shadows are managed out of process for now.
+#if defined(OS_MACOSX) && !defined(USE_AURA)
+#define MAYBE_ShadowsInRootWindow DISABLED_ShadowsInRootWindow
+#else
+#define MAYBE_ShadowsInRootWindow ShadowsInRootWindow
+#endif
+
+// Test that shadows are not added to root windows when created or upon
+// activation. Test that shadows are added to non-root windows even if not
+// activated.
+TEST_F(WidgetShadowTest, MAYBE_ShadowsInRootWindow) {
+ // A desktop window clips to its bounds, so it shouldn't have a shadow.
+ bool top_level_window_should_have_shadow = false;
+
+#if defined(OS_CHROMEOS)
+ // In Mus, the shadow should be in the WindowServer process only. In non-mus
+ // CreateNativeDesktopWidget() creates a non-root window, so it should have
+ // a shadow.
+ top_level_window_should_have_shadow = !IsMus();
+#endif
+
+ // To start, just create a Widget. This constructs the first ShadowController
+ // which will start observing the environment for additional aura::Window
+ // initialization. The very first ShadowController in DesktopNativeWidgetAura
+ // is created after the call to aura::Window::Init(), so the ShadowController
+ // Impl class won't ever see this first Window being initialized.
+ name_ = "other_top_level";
+ Widget* other_top_level = CreateNativeDesktopWidget();
+
+ name_ = "top_level";
+ Widget* top_level = CreateNativeDesktopWidget();
+ top_level->SetBounds(gfx::Rect(100, 100, 320, 200));
+
+ EXPECT_FALSE(WidgetHasInProcessShadow(top_level));
+ EXPECT_FALSE(top_level->IsVisible());
+ top_level->ShowInactive();
+ EXPECT_EQ(top_level_window_should_have_shadow,
+ WidgetHasInProcessShadow(top_level));
+ top_level->Show();
+ EXPECT_EQ(top_level_window_should_have_shadow,
+ WidgetHasInProcessShadow(top_level));
+
+ name_ = "control";
+ Widget* control = CreateChildNativeWidgetWithParent(top_level);
+ control->SetBounds(gfx::Rect(20, 20, 160, 100));
+
+ // Widgets of TYPE_CONTROL become visible during Init, so start with a shadow.
+ EXPECT_TRUE(WidgetHasInProcessShadow(control));
+ control->ShowInactive();
+ EXPECT_TRUE(WidgetHasInProcessShadow(control));
+ control->Show();
+ EXPECT_TRUE(WidgetHasInProcessShadow(control));
+
+ name_ = "child";
+ override_type_ = Widget::InitParams::TYPE_POPUP;
+ force_child_ = true;
+ Widget* child = CreateChildNativeWidgetWithParent(top_level);
+ child->SetBounds(gfx::Rect(20, 20, 160, 100));
+
+ // Now false: the Widget hasn't been shown yet.
+ EXPECT_FALSE(WidgetHasInProcessShadow(child));
+ child->ShowInactive();
+ EXPECT_TRUE(WidgetHasInProcessShadow(child));
+ child->Show();
+ EXPECT_TRUE(WidgetHasInProcessShadow(child));
+
+ other_top_level->Show();
+
+ // Re-activate the top level window. This handles a hypothetical case where
+ // a shadow is added via the ActivationChangeObserver rather than by the
+ // aura::WindowObserver. Activation changes only modify an existing shadow
+ // (if there is one), but should never install a Shadow, even if the Window
+ // properties otherwise say it should have one.
+ top_level->Show();
+ EXPECT_EQ(top_level_window_should_have_shadow,
+ WidgetHasInProcessShadow(top_level));
+
+ top_level->Close();
+ other_top_level->Close();
+}
+
#if defined(OS_WIN)
namespace {
diff --git a/chromium/ui/views/win/hwnd_message_handler.cc b/chromium/ui/views/win/hwnd_message_handler.cc
index 5906900d721..c8fb7eecb9c 100644
--- a/chromium/ui/views/win/hwnd_message_handler.cc
+++ b/chromium/ui/views/win/hwnd_message_handler.cc
@@ -31,6 +31,7 @@
#include "ui/base/ime/text_input_type.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/view_prop.h"
+#include "ui/base/win/direct_manipulation.h"
#include "ui/base/win/internal_constants.h"
#include "ui/base/win/lock_state.h"
#include "ui/base/win/mouse_wheel_util.h"
@@ -48,7 +49,6 @@
#include "ui/gfx/icon_util.h"
#include "ui/gfx/path.h"
#include "ui/gfx/path_win.h"
-#include "ui/gfx/win/direct_manipulation.h"
#include "ui/gfx/win/hwnd_util.h"
#include "ui/gfx/win/rendering_window_manager.h"
#include "ui/native_theme/native_theme_win.h"
@@ -249,9 +249,6 @@ const int kTouchDownContextResetTimeout = 500;
// same location as the cursor.
const int kSynthesizedMouseMessagesTimeDifference = 500;
-// Currently this flag is always false - see http://crbug.com/763223
-const bool kUsePointerEventsForTouch = false;
-
} // namespace
// A scoping class that prevents a window from being able to redraw in response
@@ -371,6 +368,7 @@ HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate)
sent_window_size_changing_(false),
left_button_down_on_caption_(false),
background_fullscreen_hack_(false),
+ pointer_events_for_touch_(features::IsUsingWMPointerForTouch()),
autohide_factory_(this),
weak_factory_(this) {}
@@ -416,7 +414,7 @@ void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) {
// Direct Manipulation is enabled on Windows 10+. The CreateInstance function
// returns NULL if Direct Manipulation is not available.
direct_manipulation_helper_ =
- gfx::win::DirectManipulationHelper::CreateInstance();
+ ui::win::DirectManipulationHelper::CreateInstance();
if (direct_manipulation_helper_)
direct_manipulation_helper_->Initialize(hwnd());
@@ -1429,7 +1427,8 @@ LRESULT HWNDMessageHandler::OnCreate(CREATESTRUCT* create_struct) {
// Get access to a modifiable copy of the system menu.
GetSystemMenu(hwnd(), false);
- RegisterTouchWindow(hwnd(), TWF_WANTPALM);
+ if (!pointer_events_for_touch_)
+ RegisterTouchWindow(hwnd(), TWF_WANTPALM);
// We need to allow the delegate to size its contents since the window may not
// receive a size notification when its initial bounds are specified at window
@@ -1748,9 +1747,9 @@ LRESULT HWNDMessageHandler::OnPointerEvent(UINT message,
case PT_PEN:
return HandlePointerEventTypePen(message, w_param, l_param);
case PT_TOUCH:
- if (kUsePointerEventsForTouch)
+ if (pointer_events_for_touch_)
return HandlePointerEventTypeTouch(message, w_param, l_param);
- // FALLTHROUGH_INTENDED
+ FALLTHROUGH;
default:
SetMsgHandled(FALSE);
return -1;
@@ -2223,9 +2222,6 @@ void HWNDMessageHandler::OnSize(UINT param, const gfx::Size& size) {
void HWNDMessageHandler::OnSysCommand(UINT notification_code,
const gfx::Point& point) {
- if (!delegate_->ShouldHandleSystemCommands())
- return;
-
// Windows uses the 4 lower order bits of |notification_code| for type-
// specific information so we must exclude this when comparing.
static const int sc_mask = 0xFFF0;
@@ -2299,6 +2295,16 @@ void HWNDMessageHandler::OnTimeChange() {
LRESULT HWNDMessageHandler::OnTouchEvent(UINT message,
WPARAM w_param,
LPARAM l_param) {
+ if (pointer_events_for_touch_) {
+ // Release any associated memory with this event.
+ CloseTouchInputHandle(reinterpret_cast<HTOUCHINPUT>(l_param));
+
+ // Claim the event is handled. This shouldn't ever happen
+ // because we don't register touch windows when we are using
+ // pointer events.
+ return 0;
+ }
+
// Handle touch events only on Aura for now.
int num_points = LOWORD(w_param);
std::unique_ptr<TOUCHINPUT[]> input(new TOUCHINPUT[num_points]);
@@ -2309,7 +2315,10 @@ LRESULT HWNDMessageHandler::OnTouchEvent(UINT message,
// so use base::TimeTicks::Now().
const base::TimeTicks event_time = base::TimeTicks::Now();
TouchEvents touch_events;
+ TouchIDs stale_touches(touch_ids_);
+
for (int i = 0; i < num_points; ++i) {
+ stale_touches.erase(input[i].dwID);
POINT point;
point.x = TOUCH_COORD_TO_PIXEL(input[i].x);
point.y = TOUCH_COORD_TO_PIXEL(input[i].y);
@@ -2330,7 +2339,7 @@ LRESULT HWNDMessageHandler::OnTouchEvent(UINT message,
last_touch_or_pen_message_time_ = ::GetMessageTime();
gfx::Point touch_point(point.x, point.y);
- unsigned int touch_id = id_generator_.GetGeneratedID(input[i].dwID);
+ size_t touch_id = id_generator_.GetGeneratedID(input[i].dwID);
if (input[i].dwFlags & TOUCHEVENTF_DOWN) {
touch_ids_.insert(input[i].dwID);
@@ -2355,6 +2364,19 @@ LRESULT HWNDMessageHandler::OnTouchEvent(UINT message,
}
}
}
+ // If a touch has been dropped from the list (without a TOUCH_EVENTF_UP)
+ // we generate a simulated TOUCHEVENTF_UP event.
+ for (auto touch_number : stale_touches) {
+ // Log that we've hit this code. When usage drops off, we can remove
+ // this "workaround". See https://crbug.com/811273
+ UMA_HISTOGRAM_BOOLEAN("TouchScreen.MissedTOUCHEVENTF_UP", true);
+ size_t touch_id = id_generator_.GetGeneratedID(touch_number);
+ touch_ids_.erase(touch_number);
+ GenerateTouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(0, 0), touch_id,
+ event_time, &touch_events);
+ id_generator_.ReleaseNumber(touch_number);
+ }
+
// Handle the touch events asynchronously. We need this because touch
// events on windows don't fire if we enter a modal loop in the context of
// a touch event.
@@ -2720,6 +2742,7 @@ LRESULT HWNDMessageHandler::HandlePointerEventTypeTouch(UINT message,
return -1;
}
+ last_touch_or_pen_message_time_ = ::GetMessageTime();
// Ignore enter/leave events, otherwise they will be converted in
// |GetTouchEventType| to ET_TOUCH_PRESSED/ET_TOUCH_RELEASED events, which
// is not correct.
@@ -2728,7 +2751,18 @@ LRESULT HWNDMessageHandler::HandlePointerEventTypeTouch(UINT message,
return 0;
}
- unsigned int mapped_pointer_id = id_generator_.GetGeneratedID(pointer_id);
+ // Increment |touch_down_contexts_| on a pointer down. This variable
+ // is used to debounce the WM_MOUSEACTIVATE events.
+ if (message == WM_POINTERDOWN) {
+ touch_down_contexts_++;
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE,
+ base::BindOnce(&HWNDMessageHandler::ResetTouchDownContext,
+ weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kTouchDownContextResetTimeout));
+ }
+
+ size_t mapped_pointer_id = id_generator_.GetGeneratedID(pointer_id);
POINTER_INFO pointer_info = pointer_touch_info.pointerInfo;
POINT client_point = pointer_info.ptPixelLocationRaw;
ScreenToClient(hwnd(), &client_point);
@@ -2763,14 +2797,14 @@ LRESULT HWNDMessageHandler::HandlePointerEventTypeTouch(UINT message,
ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0, event_time, 1);
// There are cases where the code handling the message destroys the
- // window, so use the weak ptr to check if destruction occured or not.
+ // window, so use the weak ptr to check if destruction occurred or not.
base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr());
delegate_->HandleTouchEvent(event);
if (event_type == ui::ET_TOUCH_RELEASED)
id_generator_.ReleaseNumber(pointer_id);
if (ref)
- SetMsgHandled(TRUE);
+ SetMsgHandled(event.handled());
return 0;
}
@@ -2869,7 +2903,7 @@ void HWNDMessageHandler::PerformDwmTransition() {
void HWNDMessageHandler::GenerateTouchEvent(ui::EventType event_type,
const gfx::Point& point,
- unsigned int id,
+ size_t id,
base::TimeTicks time_stamp,
TouchEvents* touch_events) {
ui::TouchEvent event(
diff --git a/chromium/ui/views/win/hwnd_message_handler.h b/chromium/ui/views/win/hwnd_message_handler.h
index ad432b4d9ac..5d5765c1928 100644
--- a/chromium/ui/views/win/hwnd_message_handler.h
+++ b/chromium/ui/views/win/hwnd_message_handler.h
@@ -20,7 +20,7 @@
#include "base/strings/string16.h"
#include "base/win/scoped_gdi_object.h"
#include "base/win/win_util.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/base/ime/input_method_observer.h"
#include "ui/base/ui_base_types.h"
#include "ui/base/win/window_event_target.h"
@@ -34,9 +34,6 @@
namespace gfx {
class ImageSkia;
class Insets;
-namespace win {
-class DirectManipulationHelper;
-} // namespace win
} // namespace gfx
namespace ui {
@@ -44,7 +41,10 @@ class AXSystemCaretWin;
class InputMethod;
class TextInputClient;
class ViewProp;
-}
+namespace win {
+class DirectManipulationHelper;
+} // namespace win
+} // namespace ui
namespace views {
@@ -550,12 +550,6 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
const POINTER_INFO& pointer_info,
const gfx::Point& point,
const ui::PointerDetails& pointer_details);
- LRESULT GenerateTouchEventFromPointerEvent(
- UINT message,
- UINT32 pointer_id,
- const POINTER_INFO& pointer_info,
- const gfx::Point& point,
- const ui::PointerDetails& pointer_details);
// Returns true if the mouse message passed in is an OS synthesized mouse
// message.
@@ -575,7 +569,7 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
// |time_stamp| is the time stamp associated with the message.
void GenerateTouchEvent(ui::EventType event_type,
const gfx::Point& point,
- unsigned int id,
+ size_t id,
base::TimeTicks time_stamp,
TouchEvents* touch_events);
@@ -737,7 +731,7 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
// This class provides functionality to register the legacy window as a
// Direct Manipulation consumer. This allows us to support smooth scroll
// in Chrome on Windows 10.
- std::unique_ptr<gfx::win::DirectManipulationHelper>
+ std::unique_ptr<ui::win::DirectManipulationHelper>
direct_manipulation_helper_;
// The location where the user clicked on the caption. We cache this when we
@@ -759,6 +753,10 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
// partially or fully transparent.
bool is_translucent_ = false;
+ // True if the window should process WM_POINTER for touch events and
+ // not WM_TOUCH events.
+ bool pointer_events_for_touch_;
+
// This is a map of the HMONITOR to full screeen window instance. It is safe
// to keep a raw pointer to the HWNDMessageHandler instance as we track the
// window destruction and ensure that the map is cleaned up.
diff --git a/chromium/ui/views/win/hwnd_message_handler_delegate.h b/chromium/ui/views/win/hwnd_message_handler_delegate.h
index 2168aedea4b..d13f807e4a7 100644
--- a/chromium/ui/views/win/hwnd_message_handler_delegate.h
+++ b/chromium/ui/views/win/hwnd_message_handler_delegate.h
@@ -5,12 +5,16 @@
#ifndef UI_VIEWS_WIN_HWND_MESSAGE_HANDLER_DELEGATE_H_
#define UI_VIEWS_WIN_HWND_MESSAGE_HANDLER_DELEGATE_H_
+#include "base/win/windows_types.h"
+#include "ui/base/ui_base_types.h"
+#include "ui/gfx/native_widget_types.h"
#include "ui/views/views_export.h"
namespace gfx {
class Insets;
class Path;
class Point;
+class Rect;
class Size;
}
@@ -19,6 +23,8 @@ class Accelerator;
class InputMethod;
class KeyEvent;
class MouseEvent;
+class PointerEvent;
+class ScrollEvent;
class TouchEvent;
}
@@ -98,12 +104,6 @@ class VIEWS_EXPORT HWNDMessageHandlerDelegate {
virtual gfx::NativeViewAccessible GetNativeViewAccessible() = 0;
- // Returns true if the window should handle standard system commands, such as
- // close, minimize, maximize.
- // TODO(benwells): Remove this once bubbles don't have two widgets
- // implementing them on non-aura windows. http://crbug.com/189112.
- virtual bool ShouldHandleSystemCommands() const = 0;
-
// TODO(beng): Investigate migrating these methods to On* prefixes once
// HWNDMessageHandler is the WindowImpl.
diff --git a/chromium/ui/views/win/pen_event_processor.cc b/chromium/ui/views/win/pen_event_processor.cc
index dd15a85140f..17f51705029 100644
--- a/chromium/ui/views/win/pen_event_processor.cc
+++ b/chromium/ui/views/win/pen_event_processor.cc
@@ -187,9 +187,10 @@ std::unique_ptr<ui::Event> PenEventProcessor::GenerateTouchEvent(
int rotation_angle = static_cast<int>(pointer_details.twist) % 180;
if (rotation_angle < 0)
rotation_angle += 180;
- std::unique_ptr<ui::Event> event = std::make_unique<ui::TouchEvent>(
+ std::unique_ptr<ui::TouchEvent> event = std::make_unique<ui::TouchEvent>(
event_type, point, event_time, pointer_details,
flags | ui::GetModifiersFromKeyState(), rotation_angle);
+ event->set_hovering(event_type == ui::ET_TOUCH_RELEASED);
event->latency()->AddLatencyNumberWithTimestamp(
ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, 0, event_time, 1);
return event;
diff --git a/chromium/ui/views/window/client_view.cc b/chromium/ui/views/window/client_view.cc
index 2f080badef5..2b6a99a020c 100644
--- a/chromium/ui/views/window/client_view.cc
+++ b/chromium/ui/views/window/client_view.cc
@@ -75,7 +75,7 @@ const char* ClientView::GetClassName() const {
}
void ClientView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_CLIENT;
+ node_data->role = ax::mojom::Role::kClient;
}
void ClientView::OnBoundsChanged(const gfx::Rect& previous_bounds) {
diff --git a/chromium/ui/views/window/dialog_client_view.cc b/chromium/ui/views/window/dialog_client_view.cc
index 6b673090242..40cc9f35cfa 100644
--- a/chromium/ui/views/window/dialog_client_view.cc
+++ b/chromium/ui/views/window/dialog_client_view.cc
@@ -33,12 +33,6 @@ namespace {
// conflict with other groups that could be in the dialog content.
const int kButtonGroup = 6666;
-#if defined(OS_WIN) || defined(OS_CHROMEOS)
-const bool kIsOkButtonOnLeftSide = true;
-#else
-const bool kIsOkButtonOnLeftSide = false;
-#endif
-
// Returns true if the given view should be shown (i.e. exists and is
// visible).
bool ShouldShow(View* view) {
@@ -330,7 +324,7 @@ DialogClientView::GetButtonRowViews() {
View* first = ShouldShow(extra_view_) ? extra_view_ : nullptr;
View* second = cancel_button_;
View* third = ok_button_;
- if (kIsOkButtonOnLeftSide)
+ if (PlatformStyle::kIsOkButtonLeading)
std::swap(second, third);
return {{first, second, third}};
}
diff --git a/chromium/ui/views/window/dialog_delegate.cc b/chromium/ui/views/window/dialog_delegate.cc
index a741a22ad42..3e88b8db4c8 100644
--- a/chromium/ui/views/window/dialog_delegate.cc
+++ b/chromium/ui/views/window/dialog_delegate.cc
@@ -249,8 +249,8 @@ void DialogDelegate::DialogModelChanged() {
observer.OnDialogModelChanged();
}
-ui::AXRole DialogDelegate::GetAccessibleWindowRole() const {
- return ui::AX_ROLE_DIALOG;
+ax::mojom::Role DialogDelegate::GetAccessibleWindowRole() const {
+ return ax::mojom::Role::kDialog;
}
////////////////////////////////////////////////////////////////////////////////
@@ -283,7 +283,7 @@ View* DialogDelegateView::GetContentsView() {
void DialogDelegateView::ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) {
if (details.is_add && details.child == this && GetWidget())
- NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
+ NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
}
} // namespace views
diff --git a/chromium/ui/views/window/dialog_delegate.h b/chromium/ui/views/window/dialog_delegate.h
index 8061f680220..69add25e1a0 100644
--- a/chromium/ui/views/window/dialog_delegate.h
+++ b/chromium/ui/views/window/dialog_delegate.h
@@ -9,7 +9,7 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
-#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/base/models/dialog_model.h"
#include "ui/base/ui_base_types.h"
#include "ui/views/widget/widget.h"
@@ -130,7 +130,7 @@ class VIEWS_EXPORT DialogDelegate : public ui::DialogModel,
protected:
// Overridden from WidgetDelegate:
- ui::AXRole GetAccessibleWindowRole() const override;
+ ax::mojom::Role GetAccessibleWindowRole() const override;
private:
// A flag indicating whether this dialog is able to use the custom frame
diff --git a/chromium/ui/views/window/non_client_view.cc b/chromium/ui/views/window/non_client_view.cc
index 2d20a34cae2..1dbbeb4f839 100644
--- a/chromium/ui/views/window/non_client_view.cc
+++ b/chromium/ui/views/window/non_client_view.cc
@@ -201,7 +201,7 @@ void NonClientView::ViewHierarchyChanged(
}
void NonClientView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_CLIENT;
+ node_data->role = ax::mojom::Role::kClient;
node_data->SetName(accessible_name_);
}
@@ -319,7 +319,7 @@ void NonClientFrameView::ActivationChanged(bool active) {
}
void NonClientFrameView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
- node_data->role = ui::AX_ROLE_CLIENT;
+ node_data->role = ax::mojom::Role::kClient;
}
const char* NonClientFrameView::GetClassName() const {
diff --git a/chromium/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.html b/chromium/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.html
index 691625fb095..423a18a8e50 100644
--- a/chromium/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.html
+++ b/chromium/ui/webui/resources/cr_components/certificate_manager/certificate_subentry.html
@@ -36,21 +36,21 @@
title="[[i18n('moreActions')]]" on-tap="onDotsTap_"></button>
<template is="cr-lazy-render" id="menu">
<dialog is="cr-action-menu">
- <button class="dropdown-item" id="view"
+ <button slot="item" class="dropdown-item" id="view"
on-tap="onViewTap_">
[[i18n('certificateManagerView')]]
</button>
- <button class="dropdown-item" id="edit"
+ <button slot="item" class="dropdown-item" id="edit"
hidden$="[[!canEdit_(certificateType, model)]]"
on-tap="onEditTap_">
[[i18n('edit')]]
</button>
- <button class="dropdown-item" id="export"
+ <button slot="item" class="dropdown-item" id="export"
hidden$="[[!canExport_(certificateType, model)]]"
on-tap="onExportTap_">
[[i18n('certificateManagerExport')]]
</button>
- <button class="dropdown-item" id="delete"
+ <button slot="item" class="dropdown-item" id="delete"
hidden$="[[!canDelete_(model)]]"
on-tap="onDeleteTap_">
[[i18n('certificateManagerDelete')]]
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html b/chromium/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html
index dc8592fc98c..a71d029f68a 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/bluetooth_dialog.html
@@ -13,7 +13,7 @@
<template>
<style include="cr-hidden-style iron-flex">
dialog {
- @apply(--bluetooth-dialog-style);
+ @apply --bluetooth-dialog-style;
}
#pairing {
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/compiled_resources2.gyp b/chromium/ui/webui/resources/cr_components/chromeos/compiled_resources2.gyp
index 1e6afe0491a..02bc35a7bbe 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/compiled_resources2.gyp
+++ b/chromium/ui/webui/resources/cr_components/chromeos/compiled_resources2.gyp
@@ -11,6 +11,13 @@
],
},
{
+ 'target_name': 'quick_unlock_resources',
+ 'type': 'none',
+ 'dependencies': [
+ 'quick_unlock/compiled_resources2.gyp:*',
+ ],
+ },
+ {
'target_name': 'bluetooth_dialog',
'dependencies': [
'<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog',
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.html
index a2ba57be7c2..32c5b74d9e7 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.html
@@ -15,14 +15,14 @@
</style>
<!-- SSID (WiFi) -->
- <template is="dom-if" if="[[isType_(NetworkType_.WI_FI, type)]]">
+ <template is="dom-if" if="[[isType_(NetworkType_.WI_FI, type)]]" restamp>
<network-config-input id="ssid" label="[[i18n('OncWiFi-SSID')]]"
value="{{configProperties_.WiFi.SSID}}" disabled="[[hasGuid_(guid)]]">
</network-config-input>
</template>
<!-- Security (WiFi and Ethernet) -->
- <template is="dom-if" if="[[securityIsVisible_(type)]]">
+ <template is="dom-if" if="[[securityIsVisible_(type)]]" restamp>
<network-config-select id="security" label="[[i18n('OncWiFi-Security')]]"
value="{{security_}}"
disabled="[[!securityIsEnabled_(guid, type)]]"
@@ -32,7 +32,8 @@
</template>
<!-- Passphrase (WiFi) -->
- <template is="dom-if" if="[[configRequiresPassphrase_(type, security_)]]">
+ <template is="dom-if" if="[[configRequiresPassphrase_(type, security_)]]"
+ restamp>
<network-config-input label="[[i18n('OncWiFi-Passphrase')]]"
value="{{configProperties_.WiFi.Passphrase}}" password>
<iron-a11y-keys keys="enter" on-keys-pressed="connectIfConfigured_">
@@ -41,7 +42,7 @@
</template>
<!-- VPN -->
- <template is="dom-if" if="[[showVpn_]]">
+ <template is="dom-if" if="[[showVpn_]]" restamp>
<network-config-input label="[[i18n('OncVPN-Host')]]"
value="{{configProperties_.VPN.Host}}">
</network-config-input>
@@ -102,7 +103,7 @@
</template>
<!-- EAP (WiFi, WiMAX, Ethernet) -->
- <template is="dom-if" if="[[showEap_]]">
+ <template is="dom-if" if="[[showEap_]]" restamp>
<network-config-select id="outer" label="[[i18n('OncEAP-Outer')]]"
value="{{eapProperties_.Outer}}" items="[[eapOuterItems_]]"
onc-prefix="EAP.Outer" hidden="[[!showEap_.Outer]]">
@@ -147,7 +148,7 @@
<!-- Share (WiFi and WiMAX) -->
<template is="dom-if"
- if="[[shareIsVisible_(guid, type, networkProperties)]]">
+ if="[[shareIsVisible_(guid, type, networkProperties)]]" restamp>
<div class="property-box">
<div id="shareLabel" class="start">[[i18n('networkConfigShare')]]</div>
<paper-toggle-button id="share" checked="{{shareNetwork_}}"
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.js b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.js
index 74cdc9b049f..0b6ada22d5a 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.js
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config.js
@@ -9,7 +9,7 @@
*/
/**
- * Combinaiton of CrOnc.VPNType + AuthenticationType for IPsec.
+ * Combination of CrOnc.VPNType + AuthenticationType for IPsec.
* Note: closure does not always recognize this if inside function() {}.
* @enum {string}
*/
@@ -24,6 +24,7 @@ var VPNConfigType = {
/** @const */ var DEFAULT_HASH = 'default';
/** @const */ var DO_NOT_CHECK_HASH = 'do-not-check';
+/** @const */ var NO_CERTS_HASH = 'no-certs';
Polymer({
is: 'network-config',
@@ -53,9 +54,6 @@ Polymer({
*/
type: String,
- /** Set by embedder if saveOrConnect should always connect. */
- connectOnSave: Boolean,
-
/** True if the user configuring the network can toggle the shared state. */
shareAllowEnable: Boolean,
@@ -129,7 +127,7 @@ Polymer({
},
},
- /** @private */
+ /** @private {string|undefined} */
selectedServerCaHash_: String,
/**
@@ -143,7 +141,7 @@ Polymer({
},
},
- /** @private */
+ /** @private {string|undefined} */
selectedUserCertHash_: String,
/**
@@ -280,7 +278,7 @@ Polymer({
/**
* Array of values for the VPN Type dropdown. For L2TP-IPSec, the
- * IPsec AuthenticationType ('PSK' or 'Cert') is incuded in the type.
+ * IPsec AuthenticationType ('PSK' or 'Cert') is included in the type.
* Note: closure does not recognize Array<VPNConfigType> here.
* @private {!Array<string>}
* @const
@@ -313,6 +311,7 @@ Polymer({
'updateIsConfigured_(configProperties_, eapProperties_.*)',
'updateIsConfigured_(configProperties_.WiFi.*)',
'updateIsConfigured_(configProperties_.VPN.*, vpnType_)',
+ 'updateIsConfigured_(selectedUserCertHash_)',
],
/** @const */
@@ -343,6 +342,8 @@ Polymer({
init: function() {
this.propertiesSent_ = false;
+ this.selectedServerCaHash_ = undefined;
+ this.selectedUserCertHash_ = undefined;
this.guid = this.networkProperties.GUID;
this.type = this.networkProperties.Type;
if (this.guid) {
@@ -360,7 +361,19 @@ Polymer({
this.setShareNetwork_();
},
- saveOrConnect: function() {
+ save: function() {
+ this.saveAndConnect_(false /* connect */);
+ },
+
+ connect: function() {
+ this.saveAndConnect_(true /* connect */);
+ },
+
+ /**
+ * @param {boolean} connect If true, connect after save.
+ * @private
+ */
+ saveAndConnect_: function(connect) {
if (this.propertiesSent_)
return;
this.propertiesSent_ = true;
@@ -376,14 +389,14 @@ Polymer({
this.globalPolicy.AllowOnlyPolicyNetworksToConnect)) {
CrOnc.setTypeProperty(propertiesToSet, 'AutoConnect', false);
}
- // Create the configuration, then connect to it in the callback.
this.networkingPrivate.createNetwork(
- this.shareNetwork_, propertiesToSet,
- this.createNetworkCallback_.bind(this));
+ this.shareNetwork_, propertiesToSet, (guid) => {
+ this.createNetworkCallback_(connect, guid);
+ });
} else {
- propertiesToSet.GUID = this.guid;
- this.networkingPrivate.setProperties(
- this.guid, propertiesToSet, this.setPropertiesCallback_.bind(this));
+ this.networkingPrivate.setProperties(this.guid, propertiesToSet, () => {
+ this.setPropertiesCallback_(connect);
+ });
}
},
@@ -401,7 +414,7 @@ Polymer({
connectIfConfigured_: function() {
if (!this.isConfigured_)
return;
- this.saveOrConnect();
+ this.connect();
},
/** @private */
@@ -438,13 +451,30 @@ Polymer({
caCerts.push(this.getDefaultCert_(
this.i18n('networkCADoNotCheck'), DO_NOT_CHECK_HASH));
this.set('serverCaCerts_', caCerts);
+ if (this.selectedServerCaHash_ && !caCerts.find((cert) => {
+ return cert.hash == this.selectedServerCaHash_;
+ })) {
+ this.selectedServerCaHash_ = undefined;
+ }
var userCerts = certificateLists.userCertificates.slice();
if (!userCerts.length) {
userCerts = [this.getDefaultCert_(
- this.i18n('networkCertificateNoneInstalled'), '')];
+ this.i18n('networkCertificateNoneInstalled'), NO_CERTS_HASH)];
+ } else {
+ // Only hardware backed user certs are supported.
+ userCerts.forEach(function(cert) {
+ if (!cert.hardwareBacked)
+ cert.hash = ''; // Clear the hash to invalidate the certificate.
+ });
}
this.set('userCerts_', userCerts);
+ if (this.selectedUserCertHash_ && !userCerts.find((cert) => {
+ return cert.hash == this.selectedUserCertHash_;
+ })) {
+ this.selectedUserCertHash_ = undefined;
+ }
+
this.updateCertError_();
}.bind(this));
},
@@ -501,8 +531,9 @@ Polymer({
this.propertiesReceived_ = true;
this.networkProperties = properties;
this.setError_(properties.ErrorState);
+ this.updateCertError_();
- // Set the current shareNetwork_ value when porperties are received.
+ // Set the current shareNetwork_ value when properties are received.
this.setShareNetwork_();
},
@@ -727,7 +758,7 @@ Polymer({
} else {
this.set('eapProperties_.Inner', undefined);
}
- // Set the share vaule to its default when the EAP.Outer value changes.
+ // Set the share value to its default when the EAP.Outer value changes.
this.setShareNetwork_();
},
@@ -904,16 +935,39 @@ Polymer({
/** @private */
updateCertError_: function() {
- /** @const */ var certError = 'networkErrorNoUserCertificate';
- if (this.error && this.error != certError)
+ // If |this.error| was set to something other than a cert error, do not
+ // change it.
+ /** @const */ var noCertsError = 'networkErrorNoUserCertificate';
+ /** @const */ var noValidCertsError = 'networkErrorNotHardwareBacked';
+ if (this.error && this.error != noCertsError &&
+ this.error != noValidCertsError) {
return;
+ }
var requireCerts = (this.showEap_ && this.showEap_.UserCert) ||
(this.showVpn_ && this.showVpn_.UserCert);
- this.setError_(requireCerts && !this.userCerts_.length ? certError : '');
+ if (!requireCerts) {
+ this.setError_('');
+ return;
+ }
+ if (!this.userCerts_.length || this.userCerts_[0].hash == NO_CERTS_HASH) {
+ this.setError_(noCertsError);
+ return;
+ }
+ var validUserCert = this.userCerts_.find(function(cert) {
+ return !!cert.hash;
+ });
+ if (!validUserCert) {
+ this.setError_(noValidCertsError);
+ return;
+ }
+ this.setError_('');
+ return;
},
/**
+ * Sets the selected cert if |pem| (serverCa) or |certId| (user) is specified.
+ * Otherwise sets a default value if no certificate is selected.
* @param {string|undefined} pem
* @param {string|undefined} certId
* @private
@@ -936,8 +990,15 @@ Polymer({
if (userCert)
this.selectedUserCertHash_ = userCert.hash;
}
- if (!this.selectedUserCertHash_ && this.userCerts_[0])
- this.selectedUserCertHash_ = this.userCerts_[0].hash;
+ if (!this.selectedUserCertHash_) {
+ // Find either the first valid entry or the 'no-certs' entry.
+ var selectUserCert = this.userCerts_.find(function(cert) {
+ return !!cert.hash;
+ });
+ if (selectUserCert)
+ this.selectedUserCertHash_ = selectUserCert.hash;
+ }
+ this.updateIsConfigured_();
},
/**
@@ -945,6 +1006,9 @@ Polymer({
* @private
*/
getIsConfigured_: function() {
+ if (!this.configProperties_)
+ return false;
+
if (this.configProperties_.Type == CrOnc.Type.VPN)
return this.vpnIsConfigured_();
@@ -1063,13 +1127,22 @@ Polymer({
* @return {boolean}
* @private
*/
+ selectedUserCertHashIsValid_: function() {
+ return !!this.selectedUserCertHash_ &&
+ this.selectedUserCertHash_ != NO_CERTS_HASH;
+ },
+
+ /**
+ * @return {boolean}
+ * @private
+ */
eapIsConfigured_: function() {
var eap = this.getEap_(this.configProperties_);
if (!eap)
return false;
if (eap.Outer != CrOnc.EAPType.EAP_TLS)
return true;
- return !!this.selectedUserCertHash_;
+ return this.selectedUserCertHashIsValid_();
},
/**
@@ -1085,10 +1158,11 @@ Polymer({
case VPNConfigType.L2TP_IPSEC_PSK:
return !!this.get('L2TP.Username', vpn) && !!this.get('IPsec.PSK', vpn);
case VPNConfigType.L2TP_IPSEC_CERT:
- return !!this.get('L2TP.Username', vpn) && !!this.selectedUserCertHash_;
+ return !!this.get('L2TP.Username', vpn) &&
+ this.selectedUserCertHashIsValid_();
case VPNConfigType.OPEN_VPN:
return !!this.get('OpenVPN.Username', vpn) &&
- !!this.selectedUserCertHash_;
+ this.selectedUserCertHashIsValid_();
}
return false;
},
@@ -1096,6 +1170,11 @@ Polymer({
/** @private */
getPropertiesToSet_: function() {
var propertiesToSet = Object.assign({}, this.configProperties_);
+ // Do not set AutoConnect by default, the connection manager will set
+ // it to true on a successful connection.
+ CrOnc.setTypeProperty(propertiesToSet, 'AutoConnect', undefined);
+ if (this.guid)
+ propertiesToSet.GUID = this.guid;
var eap = this.getEap_(propertiesToSet);
if (eap)
this.setEapProperties_(eap);
@@ -1127,11 +1206,10 @@ Polymer({
* @private
*/
getUserCertPkcs11Id_: function() {
- var userHash = this.selectedUserCertHash_;
- if (!userHash)
+ if (!this.selectedUserCertHashIsValid_())
return '';
- var userCert = this.userCerts_.find(function(cert) {
- return cert.hash == userHash;
+ var userCert = this.userCerts_.find((cert) => {
+ return cert.hash == this.selectedUserCertHash_;
});
return (userCert && userCert.PKCS11Id) || '';
},
@@ -1203,8 +1281,11 @@ Polymer({
return (chrome.runtime.lastError && chrome.runtime.lastError.message) || '';
},
- /** @private */
- setPropertiesCallback_: function() {
+ /**
+ * @param {boolean} connect If true, connect after save.
+ * @private
+ */
+ setPropertiesCallback_: function(connect) {
this.setError_(this.getRuntimeError_());
if (this.error) {
console.error('setProperties error: ' + this.guid + ': ' + this.error);
@@ -1212,7 +1293,7 @@ Polymer({
return;
}
var connectState = this.networkProperties.ConnectionState;
- if (this.connectOnSave &&
+ if (connect &&
(!connectState ||
connectState == CrOnc.ConnectionState.NOT_CONNECTED)) {
this.startConnect_(this.guid);
@@ -1222,10 +1303,11 @@ Polymer({
},
/**
+ * @param {boolean} connect If true, connect after save.
* @param {string} guid
* @private
*/
- createNetworkCallback_: function(guid) {
+ createNetworkCallback_: function(connect, guid) {
this.setError_(this.getRuntimeError_());
if (this.error) {
console.error(
@@ -1234,7 +1316,8 @@ Polymer({
this.propertiesSent_ = false;
return;
}
- this.startConnect_(guid);
+ if (connect)
+ this.startConnect_(guid);
},
/**
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config_input.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config_input.html
index 12784fd7a51..d23f9ec5c4b 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_config_input.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_config_input.html
@@ -29,8 +29,8 @@
<div class="control-box">
<paper-input-container always-float-label>
- <label id="label">[[label]]</label>
- <input is="iron-input" value="{{value::input}}"
+ <label id="label" slot="label">[[label]]</label>
+ <input is="iron-input" value="{{value::input}}" slot="input"
tabindex="1" disabled="[[disabled]]" aria-label$="[[label]]"
type="[[getInputType_(password, showPassword)]]">
</paper-input-container>
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html
index 31ccb502f47..66dcf2537e8 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.html
@@ -14,6 +14,7 @@
[[i18n('networkIPConfigAuto')]]
</div>
<paper-toggle-button checked="{{automatic_}}" disabled="[[!editable]]"
+ on-change="onAutomaticChange_"
aria-labelledby="autoIPConfigLabel">
</paper-toggle-button>
</div>
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js b/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js
index de442adbaf3..4260815ca7f 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_ip_config.js
@@ -38,7 +38,6 @@ Polymer({
automatic_: {
type: Boolean,
value: true,
- observer: 'automaticChanged_',
},
/**
@@ -113,7 +112,7 @@ Polymer({
},
/** @private */
- automaticChanged_: function() {
+ onAutomaticChange_: function() {
if (!this.automatic_) {
var defaultIpv4 = {
Gateway: '192.168.1.1',
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html
index 0f8bc18aa14..4caf352d6bc 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_nameservers.html
@@ -90,7 +90,7 @@
<paper-input-container no-label-float>
<input id="nameserver[[index]]" is="iron-input" value="[[item]]"
disabled="[[!canEdit_(editable, nameserversType_)]]"
- on-change="onValueChange_">
+ on-change="onValueChange_" slot="input">
</paper-input-container>
</template>
</div>
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_property_list.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_property_list.html
index 3ea4c64f27e..534ce962de2 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_property_list.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_property_list.html
@@ -44,7 +44,7 @@
<template is="dom-if" if="[[isEditable_(
item, 'String', propertyDict, editFieldTypes)]]">
<paper-input-container no-label-float>
- <input id="[[item]]" is="iron-input"
+ <input id="[[item]]" is="iron-input" slot="input"
value="[[getPropertyValue_(item, prefix, propertyDict)]]"
on-change="onValueChange_">
</paper-input-container>
@@ -53,7 +53,7 @@
<template is="dom-if" if="[[isEditable_(
item, 'Password', propertyDict, editFieldTypes)]]">
<paper-input-container no-label-float>
- <input id="[[item]]" is="iron-input" type="password"
+ <input id="[[item]]" is="iron-input" type="password" slot="input"
value="[[getPropertyValue_(item, prefix, propertyDict)]]"
on-change="onValueChange_">
</paper-input-container>
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.html
index 4b328f9145b..1834e1db0f0 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.html
@@ -53,10 +53,10 @@
<div class="property-box indented"
hidden$="[[!matches_(proxy_.Type, ProxySettingsType_.PAC)]]">
<div>[[i18n('networkProxyAutoConfig')]]</div>
- <paper-input no-label-float class="middle" value="{{proxy_.PAC}}"
+ <paper-input id="pacInput" no-label-float class="middle"
+ value="{{proxy_.PAC}}" on-change="onPACChange_"
disabled="[[!isEditable_('PAC', networkProperties, editable,
- useSharedProxies)]]"
- on-change="onPACChange_">
+ useSharedProxies)]]">
</paper-input>
</div>
@@ -130,8 +130,8 @@
</network-proxy-exclusions>
<div class="layout horizontal">
<paper-input-container no-label-float class="flex">
- <input id="proxyExclusion" is="iron-input">
- <iron-a11y-keys keys="enter"
+ <input id="proxyExclusion" is="iron-input" slot="input">
+ <iron-a11y-keys keys="enter" slot="add-on"
on-keys-pressed="onAddProxyExclusionTap_">
</iron-a11y-keys>
</paper-input-container>
@@ -144,7 +144,7 @@
<paper-button id="saveManualProxy"
on-tap="onSaveProxyTap_" class="action-button"
disabled="[[!isSaveManualProxyEnabled_(networkProperties,
- proxyModified_, proxy_.*)]]">
+ proxyIsUserModified_, proxy_.*)]]">
[[i18n('save')]]
</paper-button>
</div>
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.js b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.js
index a1f2056eba8..7dd7aeb8fe8 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.js
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy.js
@@ -120,7 +120,7 @@ Polymer({
* override the edited values.
* @private {boolean}
*/
- proxyModified_: false,
+ proxyIsUserModified_: false,
/** @override */
attached: function() {
@@ -132,14 +132,14 @@ Polymer({
* is updated correctly.
*/
reset: function() {
- this.proxyModified_ = false;
+ this.proxyIsUserModified_ = false;
this.proxy_ = this.createDefaultProxySettings_();
this.updateProxy_();
},
/** @private */
networkPropertiesChanged_: function() {
- if (this.proxyModified_)
+ if (this.proxyIsUserModified_)
return; // Ignore update.
this.updateProxy_();
},
@@ -221,13 +221,13 @@ Polymer({
// Set this.proxy_ after dom-repeat has been stamped.
this.async(() => {
this.proxy_ = proxy;
- this.proxyModified_ = false;
+ this.proxyIsUserModified_ = false;
});
},
/** @private */
useSameProxyChanged_: function() {
- this.proxyModified_ = true;
+ this.proxyIsUserModified_ = true;
},
/**
@@ -283,7 +283,7 @@ Polymer({
return;
}
this.fire('proxy-change', {field: 'ProxySettings', value: proxy});
- this.proxyModified_ = false;
+ this.proxyIsUserModified_ = false;
},
/**
@@ -296,10 +296,41 @@ Polymer({
var type = /** @type {chrome.networkingPrivate.ProxySettingsType} */ (
target.value);
this.set('proxy_.Type', type);
- if (type == CrOnc.ProxySettingsType.MANUAL)
- this.proxyModified_ = true;
- else
+ var proxyTypeChangeIsReady;
+ var elementToFocus;
+ switch (type) {
+ case CrOnc.ProxySettingsType.DIRECT:
+ case CrOnc.ProxySettingsType.WPAD:
+ // No addtional values are required, send the type change.
+ proxyTypeChangeIsReady = true;
+ break;
+ case CrOnc.ProxySettingsType.PAC:
+ elementToFocus = this.$$('#pacInput');
+ // If a PAC is already defined, send the type change now, otherwise wait
+ // until the user provides a PAC value.
+ proxyTypeChangeIsReady = !!this.proxy_.PAC;
+ break;
+ case CrOnc.ProxySettingsType.MANUAL:
+ // Manual proxy configuration includes multiple input fields, so wait
+ // until the 'send' button is clicked.
+ proxyTypeChangeIsReady = false;
+ elementToFocus = this.$$('#manualProxy network-proxy-input');
+ break;
+ }
+
+ // If the new proxy type is fully configured, send it, otherwise set
+ // |proxyIsUserModified_| to true so that property updates do not
+ // overwrite user changes.
+ if (proxyTypeChangeIsReady)
this.sendProxyChange_();
+ else
+ this.proxyIsUserModified_ = true;
+
+ if (elementToFocus) {
+ this.async(() => {
+ elementToFocus.focus();
+ });
+ }
},
/** @private */
@@ -309,7 +340,7 @@ Polymer({
/** @private */
onProxyInputChange_: function() {
- this.proxyModified_ = true;
+ this.proxyIsUserModified_ = true;
},
/**
@@ -324,7 +355,7 @@ Polymer({
this.push('proxy_.ExcludeDomains', value);
// Clear input.
this.$.proxyExclusion.value = '';
- this.proxyModified_ = true;
+ this.proxyIsUserModified_ = true;
},
/**
@@ -333,7 +364,7 @@ Polymer({
* @private
*/
onProxyExclusionsChange_: function(event) {
- this.proxyModified_ = true;
+ this.proxyIsUserModified_ = true;
},
/** @private */
@@ -406,7 +437,7 @@ Polymer({
* @private
*/
isSaveManualProxyEnabled_: function() {
- if (!this.proxyModified_)
+ if (!this.proxyIsUserModified_)
return false;
var manual = this.proxy_.Manual;
var httpHost = this.get('HTTPProxy.Host', manual);
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html
index f574252c285..4438899755c 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_exclusions.html
@@ -9,7 +9,7 @@
<template>
<style include="network-shared cr-hidden-style iron-flex">
iron-icon {
- @apply(--cr-actionable);
+ @apply --cr-actionable;
margin: 5px;
}
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.html
index a1104bde59f..940a9433450 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.html
@@ -36,12 +36,12 @@
<div id="container">
<div id="label">[[label]]</div>
<paper-input-container id="host" no-label-float>
- <input is="iron-input" bind-value="{{value.Host}}"
+ <input is="iron-input" bind-value="{{value.Host}}" slot="input"
disabled="[[!editable]]" on-change="onValueChange_">
</paper-input-container>
<div>[[i18n('networkProxyPort')]]</div>
<paper-input-container id="port" no-label-float>
- <input is="iron-input" bind-value="{{value.Port}}"
+ <input is="iron-input" bind-value="{{value.Port}}" slot="input"
disabled="[[!editable]]" on-change="onValueChange_">
</paper-input-container>
</div>
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.js b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.js
index 63609b074ce..cb22d24ed38 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.js
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_proxy_input.js
@@ -43,6 +43,10 @@ Polymer({
},
},
+ focus: function() {
+ this.$$('input').focus();
+ },
+
/**
* Event triggered when an input value changes.
* @private
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html b/chromium/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html
index 3d6b9eee8d8..7c2deb92100 100644
--- a/chromium/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html
+++ b/chromium/ui/webui/resources/cr_components/chromeos/network/network_shared_css.html
@@ -19,7 +19,7 @@
}
.property-box {
- @apply(--cr-section);
+ @apply --cr-section;
border-top: none;
min-height: var(--cr-section-min-height);
padding: 0;
@@ -59,7 +59,7 @@
}
.secondary {
- @apply(--cr-secondary-text);
+ @apply --cr-secondary-text;
}
paper-input-container {
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/compiled_resources2.gyp b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/compiled_resources2.gyp
new file mode 100644
index 00000000000..eff59d15d7c
--- /dev/null
+++ b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/compiled_resources2.gyp
@@ -0,0 +1,16 @@
+# Copyright 2018 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+{
+ 'targets': [
+ {
+ 'target_name': 'pin_keyboard',
+ 'dependencies': [
+ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
+ '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-button/compiled_resources2.gyp:paper-button-extracted',
+ '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-input/compiled_resources2.gyp:paper-input-extracted',
+ ],
+ 'includes': ['../../../../../../third_party/closure_compiler/compile_js2.gypi'],
+ },
+ ],
+}
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.html b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.html
new file mode 100644
index 00000000000..ad554340880
--- /dev/null
+++ b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.html
@@ -0,0 +1,266 @@
+<!-- TODO(crbug.com/603217): Use i18n instead of string literals. Figure out
+ what i18n to use for keypad, ie, does 1 ABC make
+ sense in every scenario? -->
+
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="chrome://resources/cr_elements/icons.html">
+<link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html">
+
+<iron-iconset-svg name="pin-keyboard" size="24">
+ <svg>
+ <defs>
+ <!--
+ Inlined from Polymer's iron-icons to avoid importing everything.
+ See http://goo.gl/Y1OdAq for instructions on adding additional icons.
+ -->
+ <g id="arrow-forward">
+ <path d="M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z">
+ </path>
+ </g>
+ <g id="backspace">
+ <path d="M22 3H7c-.69 0-1.23.35-1.59.88L0 12l5.41 8.11c.36.53.9.89 1.59.89h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-3 12.59L17.59 17 14 13.41 10.41 17 9 15.59 12.59 12 9 8.41 10.41 7 14 10.59 17.59 7 19 8.41 15.41 12 19 15.59z">
+ </g>
+ </defs>
+ </svg>
+</iron-iconset-svg>
+
+<dom-module id="pin-keyboard">
+ <template>
+ <style include="cr-shared-style">
+ :host {
+ outline: none;
+ }
+
+ #root {
+ direction: ltr;
+ display: block;
+ }
+
+ .row {
+ display: flex;
+ }
+
+ :host([enable-password]) #pinInputDiv {
+ display: none;
+ }
+
+ .bottom-row {
+ margin-bottom: 6px;
+ }
+
+ .backspace-button-container {
+ position: relative;
+ }
+
+ .backspace-button-container paper-ripple {
+ left: var(--pin-keyboard-backspace-paper-ripple-offset, 0);
+ top: var(--pin-keyboard-backspace-paper-ripple-offset, 0);
+ }
+
+ .digit-button {
+ align-items: center;
+ background: none;
+ border-radius: 0;
+ box-sizing: border-box;
+ color: #000;
+ display: flex;
+ flex-direction: column;
+ height: 48px;
+ justify-content: center;
+ margin: 0;
+ min-height: 48px;
+ min-width: 48px;
+ opacity: 0.87px;
+ width: 60px;
+
+ @apply --pin-keyboard-digit-button;
+ }
+
+ .digit-button.backspace-button {
+ color: var(--pin-keyboard-backspace-color, #000);
+ left: 0;
+ opacity: var(--pin-keyboard-backspace-opacity, --dark-primary-opacity);
+ padding: 14px;
+ position: absolute;
+ top: 0;
+ }
+
+ .digit-button.backspace-button:not([has-content]) {
+ opacity: 0.34;
+ }
+
+ .digit-button inner-text {
+ display: flex;
+ flex-direction: column;
+ font-family: 'Roboto';
+ }
+
+ .letter {
+ color: var(--pin-keyboard-letter-color, --paper-blue-grey-700);
+ font-size: 9px;
+ margin-top: 4px;
+ }
+
+ .number {
+ color: var(--pin-keyboard-number-color, --paper-blue-grey-700);
+ font-size: 20px;
+ height: 52px;
+ }
+
+ paper-ripple {
+ border-radius: 100px;
+ color: #000;
+ height: 48px;
+ left: 6px;
+ width: 48px;
+
+ @apply --pin-keyboard-paper-ripple;
+ }
+
+ #pinInput {
+ background-color: white;
+ border: 0;
+ box-sizing: border-box;
+ font-face: Roboto-Regular;
+ font-size: 13px;
+ height: 43px;
+ left: 0;
+ opacity: var(--dark-secondary-opacity);
+ outline: 0;
+ position: relative;
+ text-align: center;
+ width: 180px;
+
+ --paper-input-container-input: {
+ caret-color: var(--paper-input-container-focus-color);
+ }
+ }
+
+ #pinInput[has-content] {
+ opacity: var(--dark-primary-opacity);
+ }
+
+ #pinInput[is-input-rtl] {
+ direction: rtl;
+ }
+
+ #pinInput[type=number]::-webkit-inner-spin-button,
+ #pinInput[type=number]::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+ }
+
+ :host([has-error]) #pinInput {
+ --paper-input-container-focus-color: var(--paper-red-500);
+ }
+
+ /* Ensure that all children of paper-button do not consume events. This
+ * simplifies the event handler code. */
+ paper-button * {
+ pointer-events: none;
+ }
+ </style>
+
+ <div id="root" on-contextmenu="onContextMenu_">
+ <div id="pinInputDiv" class="row">
+ <paper-input id="pinInput" type="password" no-label-float
+ value="[[value]]"
+ is-input-rtl$="[[isInputRtl_(value)]]"
+ has-content$="[[hasInput_(value)]]"
+ label="[[getInputPlaceholder_(enablePassword)]]"
+ on-keydown="onInputKeyDown_">
+ </paper-input>
+ </div>
+ <slot select="[problem]"></slot>
+ <div class="row">
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="1"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard1')]]</inner-text>
+ <paper-ripple>
+ </paper-button>
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="2"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard2')]]</inner-text>
+ <inner-text class="letter">ABC</inner-text>
+ <paper-ripple>
+ </paper-button>
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="3"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard3')]]</inner-text>
+ <inner-text class="letter">DEF</inner-text>
+ <paper-ripple>
+ </paper-button>
+ </div>
+ <div class="row">
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="4"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard4')]]</inner-text>
+ <inner-text class="letter">GHI</inner-text>
+ <paper-ripple>
+ </paper-button>
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="5"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard5')]]</inner-text>
+ <inner-text class="letter">JKL</inner-text>
+ <paper-ripple>
+ </paper-button>
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="6"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard6')]]</inner-text>
+ <inner-text class="letter">MNO</inner-text>
+ <paper-ripple>
+ </paper-button>
+ </div>
+ <div class="row">
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="7"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard7')]]</inner-text>
+ <inner-text class="letter">PQRS</inner-text>
+ <paper-ripple>
+ </paper-button>
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="8"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard8')]]</inner-text>
+ <inner-text class="letter">TUV</inner-text>
+ <paper-ripple>
+ </paper-button>
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="9"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard9')]]</inner-text>
+ <inner-text class="letter">WXYZ</inner-text>
+ <paper-ripple>
+ </paper-button>
+ </div>
+ <div class="row bottom-row">
+ <div class="digit-button"></div>
+ <paper-button class="digit-button" on-tap="onNumberTap_" value="0"
+ noink>
+ <inner-text class="number">[[i18n('pinKeyboard0')]]</inner-text>
+ <inner-text class="letter">+</inner-text>
+ <paper-ripple>
+ </paper-button>
+ <div class="backspace-button-container">
+ <paper-icon-button class="digit-button backspace-button"
+ has-content$="[[hasInput_(value)]]"
+ icon="pin-keyboard:backspace"
+ on-pointerdown="onBackspacePointerDown_"
+ on-pointerout="clearAndReset_"
+ on-pointerup="onBackspacePointerUp_"
+ aria-label="[[i18n('pinKeyboardDeleteAccessibleName')]]"
+ noink>
+ </paper-icon-button>
+ <paper-ripple>
+ </div>
+ </div>
+ </div>
+ </template>
+ <script src="pin_keyboard.js"></script>
+</dom-module>
diff --git a/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js
new file mode 100644
index 00000000000..2ebcaaf4724
--- /dev/null
+++ b/chromium/ui/webui/resources/cr_components/chromeos/quick_unlock/pin_keyboard.js
@@ -0,0 +1,416 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * 'pin-keyboard' is a keyboard that can be used to enter PINs or more generally
+ * numeric values.
+ *
+ * Properties:
+ * value: The value of the PIN keyboard. Writing to this property will adjust
+ * the PIN keyboard's value.
+ *
+ * Events:
+ * pin-change: Fired when the PIN value has changed. The PIN is available at
+ * event.detail.pin.
+ * submit: Fired when the PIN is submitted. The PIN is available at
+ * event.detail.pin.
+ *
+ * Example:
+ * <pin-keyboard on-pin-change="onPinChange" on-submit="onPinSubmit">
+ * </pin-keyboard>
+ */
+
+(function() {
+
+/**
+ * Once auto backspace starts, the time between individual backspaces.
+ * @type {number}
+ * @const
+ */
+var REPEAT_BACKSPACE_DELAY_MS = 150;
+
+/**
+ * How long the backspace button must be held down before auto backspace
+ * starts.
+ * @type {number}
+ * @const
+ */
+var INITIAL_BACKSPACE_DELAY_MS = 500;
+
+/**
+ * The key codes of the keys allowed to be used on the pin input, in addition to
+ * number keys. Currently we allow backspace(8), tab(9), left(37) and right(39).
+ * @type {Array<number>}
+ * @const
+ */
+var PIN_INPUT_ALLOWED_NON_NUMBER_KEY_CODES = [8, 9, 37, 39];
+
+Polymer({
+ is: 'pin-keyboard',
+
+ behaviors: [
+ I18nBehavior,
+ ],
+
+ properties: {
+ /**
+ * Whether or not the keyboard's input element should be numerical
+ * or password.
+ * @private
+ */
+ enablePassword: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * The password element the pin keyboard is associated with. If this is not
+ * set, then a default input element is shown and used.
+ * @type {?Element}
+ * @private
+ */
+ passwordElement: {
+ type: Object,
+ value: function() {
+ return this.$.pinInput.inputElement;
+ },
+ observer: 'onPasswordElementAttached_',
+ },
+
+ /**
+ * The intervalID used for the backspace button set/clear interval.
+ * @private
+ */
+ repeatBackspaceIntervalId_: {
+ type: Number,
+ value: 0,
+ },
+
+ /**
+ * The timeoutID used for the auto backspace.
+ * @private
+ */
+ startAutoBackspaceId_: {
+ type: Number,
+ value: 0,
+ },
+
+ /**
+ * Whether or not to show the default pin input.
+ * @private
+ */
+ showPinInput_: {
+ type: Boolean,
+ value: false,
+ },
+
+ /**
+ * The value stored in the keyboard's input element.
+ * @private
+ */
+ value: {
+ type: String,
+ notify: true,
+ value: '',
+ observer: 'onPinValueChange_',
+ },
+ },
+
+ /**
+ * Called when a password element is attached to the pin keyboard.
+ * @param {HTMLInputElement} inputElement The PIN keyboard's input element.
+ * @private
+ */
+ onPasswordElementAttached_: function(inputElement) {
+ this.showPinInput_ = inputElement == this.$.pinInput.inputElement;
+ inputElement.addEventListener('input', this.handleInputChanged_.bind(this));
+ },
+
+ /**
+ * Called when the user uses the keyboard to enter a value into the input
+ * element.
+ * @param {Event} event The event object.
+ * @private
+ */
+ handleInputChanged_: function(event) {
+ this.value = event.target.value;
+ },
+
+ /**
+ * Gets the selection start of the input field.
+ * @type {number}
+ * @private
+ */
+ get selectionStart_() {
+ return this.passwordElement.selectionStart;
+ },
+
+ /**
+ * Gets the selection end of the input field.
+ * @type {number}
+ * @private
+ */
+ get selectionEnd_() {
+ return this.passwordElement.selectionEnd;
+ },
+
+ /**
+ * Sets the selection start of the input field.
+ * @param {number} start The new selection start of the input element.
+ * @private
+ */
+ set selectionStart_(start) {
+ this.passwordElement.selectionStart = start;
+ },
+
+ /**
+ * Sets the selection end of the input field.
+ * @param {number} end The new selection end of the input element.
+ * @private
+ */
+ set selectionEnd_(end) {
+ this.passwordElement.selectionEnd = end;
+ },
+
+ /**
+ * Transfers blur to the input element.
+ */
+ blur: function() {
+ this.passwordElement.blur();
+ },
+
+ /**
+ * Transfers focus to the input element. This should not bring up the virtual
+ * keyboard, if it is enabled. After focus, moves the caret to the correct
+ * location if specified.
+ * @param {number=} opt_selectionStart
+ * @param {number=} opt_selectionEnd
+ */
+ focus: function(opt_selectionStart, opt_selectionEnd) {
+ setTimeout(function() {
+ this.passwordElement.focus();
+ this.selectionStart_ = opt_selectionStart || 0;
+ this.selectionEnd_ = opt_selectionEnd || 0;
+ }.bind(this), 0);
+ },
+
+ /**
+ * Called when a keypad number has been tapped.
+ * @param {Event} event The event object.
+ * @private
+ */
+ onNumberTap_: function(event) {
+ var numberValue = event.target.getAttribute('value');
+
+ // Add the number where the caret is, then update the selection range of the
+ // input element.
+ var selectionStart = this.selectionStart_;
+ this.value = this.value.substring(0, this.selectionStart_) + numberValue +
+ this.value.substring(this.selectionEnd_);
+
+ // If a number button is clicked, we do not want to switch focus to the
+ // button, therefore we transfer focus back to the input, but if a number
+ // button is tabbed into, it should keep focus, so users can use tab and
+ // spacebar/return to enter their PIN.
+ if (!event.target.receivedFocusFromKeyboard)
+ this.focus(selectionStart + 1, selectionStart + 1);
+ event.stopImmediatePropagation();
+ },
+
+ /** Fires a submit event with the current PIN value. */
+ firePinSubmitEvent_: function() {
+ this.fire('submit', {pin: this.value});
+ },
+
+ /**
+ * Fires an update event with the current PIN value. The event will only be
+ * fired if the PIN value has actually changed.
+ * @param {string} value
+ * @param {string} previous
+ */
+ onPinValueChange_: function(value, previous) {
+ if (value != previous) {
+ this.passwordElement.value = this.value;
+ this.fire('pin-change', {pin: value});
+ }
+ },
+
+ /**
+ * Called when the user wants to erase the last character of the entered
+ * PIN value.
+ * @private
+ */
+ onPinClear_: function() {
+ // If the input is shown, clear the text based on the caret location or
+ // selected region of the input element. If it is just a caret, remove the
+ // character in front of the caret.
+ var selectionStart = this.selectionStart_;
+ var selectionEnd = this.selectionEnd_;
+ if (selectionStart == selectionEnd && selectionStart)
+ selectionStart--;
+
+ this.value = this.value.substring(0, selectionStart) +
+ this.value.substring(selectionEnd);
+
+ // Move the caret or selected region to the correct new place.
+ this.selectionStart_ = selectionStart;
+ this.selectionEnd_ = selectionStart;
+ },
+
+ /**
+ * Called when the user presses or touches the backspace button. Starts a
+ * timer which starts an interval to repeatedly backspace the pin value until
+ * the interval is cleared.
+ * @param {Event} event The event object.
+ * @private
+ */
+ onBackspacePointerDown_: function(event) {
+ this.startAutoBackspaceId_ = setTimeout(function() {
+ this.repeatBackspaceIntervalId_ =
+ setInterval(this.onPinClear_.bind(this), REPEAT_BACKSPACE_DELAY_MS);
+ }.bind(this), INITIAL_BACKSPACE_DELAY_MS);
+
+ if (!event.target.receivedFocusFromKeyboard)
+ this.focus(this.selectionStart_, this.selectionEnd_);
+ event.stopImmediatePropagation();
+ },
+
+ /**
+ * Helper function which clears the timer / interval ids and resets them.
+ * @private
+ */
+ clearAndReset_: function() {
+ clearInterval(this.repeatBackspaceIntervalId_);
+ this.repeatBackspaceIntervalId_ = 0;
+ clearTimeout(this.startAutoBackspaceId_);
+ this.startAutoBackspaceId_ = 0;
+ },
+
+ /**
+ * Called when the user unpresses or untouches the backspace button. Stops the
+ * interval callback and fires a backspace event if there is no interval
+ * running.
+ * @param {Event} event The event object.
+ * @private
+ */
+ onBackspacePointerUp_: function(event) {
+ // If an interval has started, do not fire event on pointer up.
+ if (!this.repeatBackspaceIntervalId_)
+ this.onPinClear_();
+ this.clearAndReset_();
+
+ // Since on-down gives the input element focus, the input element will
+ // already have focus when on-up is called. This will actually bring up the
+ // virtual keyboard, even if focus() is wrapped in a setTimeout. Blur the
+ // input element first to workaround this.
+ this.blur();
+ if (!event.target.receivedFocusFromKeyboard)
+ this.focus(this.selectionStart_, this.selectionEnd_);
+ event.stopImmediatePropagation();
+ },
+
+ /**
+ * Helper function to check whether a given |event| should be processed by
+ * the numeric only input.
+ * @param {Event} event The event object.
+ * @private
+ */
+ isValidEventForInput_: function(event) {
+ // Valid if the key is a number, and shift is not pressed.
+ if ((event.keyCode >= 48 && event.keyCode <= 57) && !event.shiftKey)
+ return true;
+
+ // Valid if the key is one of the selected special keys defined in
+ // |PIN_INPUT_ALLOWED_NON_NUMBER_KEY_CODES|.
+ if (PIN_INPUT_ALLOWED_NON_NUMBER_KEY_CODES.indexOf(event.keyCode) > -1)
+ return true;
+
+ // Valid if the key is CTRL+A to allow users to quickly select the entire
+ // PIN.
+ if (event.keyCode == 65 && event.ctrlKey)
+ return true;
+
+ // The rest of the keys are invalid.
+ return false;
+ },
+
+ /**
+ * Called when a key event is pressed while the input element has focus.
+ * @param {Event} event The event object.
+ * @private
+ */
+ onInputKeyDown_: function(event) {
+ // Up/down pressed, swallow the event to prevent the input value from
+ // being incremented or decremented.
+ if (event.keyCode == 38 || event.keyCode == 40) {
+ event.preventDefault();
+ return;
+ }
+
+ // Enter pressed.
+ if (event.keyCode == 13) {
+ this.firePinSubmitEvent_();
+ event.preventDefault();
+ return;
+ }
+
+ // Do not pass events that are not numbers or special keys we care about. We
+ // use this instead of input type number because there are several issues
+ // with input type number, such as no selectionStart/selectionEnd and
+ // entered non numbers causes the caret to jump to the left.
+ if (!this.isValidEventForInput_(event)) {
+ event.preventDefault();
+ return;
+ }
+ },
+
+ /**
+ * Disables the backspace button if nothing is entered.
+ * @param {string} value
+ * @private
+ */
+ hasInput_: function(value) {
+ return value.length > 0;
+ },
+
+ /**
+ * Computes the value of the pin input placeholder.
+ * @param {boolean} enablePassword
+ * @private
+ */
+ getInputPlaceholder_: function(enablePassword) {
+ return enablePassword ? this.i18n('pinKeyboardPlaceholderPinPassword') :
+ this.i18n('pinKeyboardPlaceholderPin');
+ },
+
+ /**
+ * Computes the direction of the pin input.
+ * @param {string} password
+ * @private
+ */
+ isInputRtl_: function(password) {
+ // +password will convert a string to a number or to NaN if that's not
+ // possible. Number.isInteger will verify the value is not a NaN and that it
+ // does not contain decimals.
+ // This heuristic will fail for inputs like '1.0'.
+ //
+ // Since we still support users entering their passwords through the PIN
+ // keyboard, we swap the input box to rtl when we think it is a password
+ // (just numbers), if the document direction is rtl.
+ return (document.dir == 'rtl') && !Number.isInteger(+password);
+ },
+
+ /**
+ * Catch and stop propagation of context menu events since we the backspace
+ * button can be held down on touch.
+ * @param {!Event} e
+ * @private
+ */
+ onContextMenu_: function(e) {
+ e.preventDefault();
+ e.stopPropagation();
+ },
+});
+})();
diff --git a/chromium/ui/webui/resources/cr_components/cr_components_resources.grdp b/chromium/ui/webui/resources/cr_components/cr_components_resources.grdp
index 1e198676684..46a47e79eac 100644
--- a/chromium/ui/webui/resources/cr_components/cr_components_resources.grdp
+++ b/chromium/ui/webui/resources/cr_components/cr_components_resources.grdp
@@ -208,4 +208,15 @@
type="chrome_html"
compress="gzip" />
</if>
+ <if expr="chromeos">
+ <!-- Shared between settings and OOBE, which is not vulcanized. -->
+ <structure name="IDR_WEBUI_CHROMEOS_QUICK_UNLOCK_PIN_KEYBOARD_HTML"
+ file="cr_components/chromeos/quick_unlock/pin_keyboard.html"
+ type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_WEBUI_CHROMEOS_QUICK_UNLOCK_PIN_KEYBOARD_JS"
+ file="cr_components/chromeos/quick_unlock/pin_keyboard.js"
+ type="chrome_html"
+ compress="gzip" />
+ </if>
</grit-part>
diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js b/chromium/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js
index 67e7b727be0..3e6255cccb1 100644
--- a/chromium/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js
+++ b/chromium/ui/webui/resources/cr_elements/chromeos/cr_picture/cr_camera.js
@@ -77,6 +77,7 @@ Polymer({
this.$.cameraVideo.addEventListener('canplay', function() {
this.$.userImageStreamCrop.classList.add('preview');
this.cameraOnline_ = true;
+ this.focusTakePhotoButton();
}.bind(this));
this.startCamera();
},
diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js
index e604c76d55e..2b878fd620d 100644
--- a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js
+++ b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_list_item.js
@@ -78,8 +78,7 @@ Polymer({
if (connectionState == this.connectionState_)
return;
this.connectionState_ = connectionState;
- if (connectionState == CrOnc.ConnectionState.CONNECTED)
- this.fire('network-connected', this.networkState);
+ this.fire('network-connect-changed', this.networkState);
},
/**
@@ -104,9 +103,7 @@ Polymer({
* @private
*/
isStateTextVisible_: function() {
- return !!this.networkState &&
- (this.networkState.ConnectionState !=
- CrOnc.ConnectionState.NOT_CONNECTED);
+ return !!this.networkState && !!this.getNetworkStateText_();
},
/**
@@ -115,16 +112,20 @@ Polymer({
* @private
*/
getNetworkStateText_: function() {
- if (!this.isStateTextVisible_())
+ if (!this.networkState)
return '';
- var state = this.networkState.ConnectionState;
- // For Cellular, an empty ConnectionState indicates that the device is
- // still initializing.
- if (!state && this.networkState.Type == CrOnc.Type.CELLULAR)
- return CrOncStrings.networkListItemInitializing;
- if (state == CrOnc.ConnectionState.CONNECTED)
+ var connectionState = this.networkState.ConnectionState;
+ if (this.networkState.Type == CrOnc.Type.CELLULAR) {
+ // For Cellular, an empty ConnectionState indicates that the device is
+ // still initializing.
+ if (!connectionState)
+ return CrOncStrings.networkListItemInitializing;
+ if (this.networkState.Cellular && this.networkState.Cellular.Scanning)
+ return CrOncStrings.networkListItemScanning;
+ }
+ if (connectionState == CrOnc.ConnectionState.CONNECTED)
return CrOncStrings.networkListItemConnected;
- if (state == CrOnc.ConnectionState.CONNECTING)
+ if (connectionState == CrOnc.ConnectionState.CONNECTING)
return CrOncStrings.networkListItemConnecting;
return '';
},
diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html
index 8fea14ce971..def03d72acb 100644
--- a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html
+++ b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.html
@@ -15,7 +15,6 @@
</style>
<cr-network-list id="networkList"
on-selected="onNetworkListItemSelected_"
- on-network-connected="onNetworkConnected_"
networks="[[networkStateList_]]" custom-items="[[customItems]]"
show-buttons="[[showButtons]]"
no-bottom-scroll-border="[[noBottomScrollBorder]]">
diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js
index 2a3afa75347..26a37dc478f 100644
--- a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js
+++ b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_network_select.js
@@ -54,10 +54,16 @@ Polymer({
return [];
},
},
+
+ /**
+ * Cached Cellular Device state or undefined if there is no Cellular device.
+ * @private {!CrOnc.DeviceStateProperties|undefined} deviceState
+ */
+ cellularDeviceState_: Object,
},
- /** @type {string} */
- defaultStateGuid_: '',
+ /** @type {!CrOnc.NetworkStateProperties|undefined} */
+ defaultNetworkState_: undefined,
focus: function() {
this.$.networkList.focus();
@@ -124,60 +130,76 @@ Polymer({
* @private
*/
getDeviceStatesCallback_: function(deviceStates) {
- var uninitializedCellular = deviceStates.find(function(device) {
- return device.Type == CrOnc.Type.CELLULAR &&
- device.State == CrOnc.DeviceState.UNINITIALIZED;
- });
- this.getNetworkStates_(uninitializedCellular);
- },
-
- /**
- * @param {!CrOnc.DeviceStateProperties|undefined} uninitializedCellular
- * A cellular device state to pass to |getNetworksCallback_| or undefined.
- */
- getNetworkStates_: function(uninitializedCellular) {
var filter = {
networkType: chrome.networkingPrivate.NetworkType.ALL,
visible: true,
configured: false
};
- chrome.networkingPrivate.getNetworks(filter, function(states) {
- this.getNetworksCallback_(uninitializedCellular, states);
+ chrome.networkingPrivate.getNetworks(filter, function(networkStates) {
+ this.getNetworksCallback_(deviceStates, networkStates);
}.bind(this));
},
/**
- * @param {!CrOnc.DeviceStateProperties|undefined} uninitializedCellular
- * If defined, prepends a Cellular state with no ConnectionState to
- * represent an uninitialized Cellular device.
- * @param {!Array<!CrOnc.NetworkStateProperties>} states
+ * @param {!Array<!CrOnc.DeviceStateProperties>} deviceStates
+ * @param {!Array<!CrOnc.NetworkStateProperties>} networkStates
* @private
*/
- getNetworksCallback_: function(uninitializedCellular, states) {
- if (uninitializedCellular) {
- states.unshift({
- GUID: '',
- Type: uninitializedCellular.Type,
- });
+ getNetworksCallback_: function(deviceStates, networkStates) {
+ this.cellularDeviceState_ = deviceStates.find(function(device) {
+ return device.Type == CrOnc.Type.CELLULAR;
+ });
+ if (this.cellularDeviceState_)
+ this.ensureCellularNetwork_(networkStates);
+ this.networkStateList_ = networkStates;
+ var defaultNetwork;
+ if (networkStates.length > 0) {
+ // Handle an edge case where Ethernet is connecting.
+ if (networkStates.length > 1 &&
+ networkStates[0].ConnectionState ==
+ CrOnc.ConnectionState.CONNECTING &&
+ networkStates[1].ConnectionState == CrOnc.ConnectionState.CONNECTED) {
+ defaultNetwork = networkStates[1];
+ } else {
+ defaultNetwork = networkStates[0];
+ }
+ } else if (!this.defaultNetworkState_) {
+ return; // No change
}
- this.networkStateList_ = states;
- var defaultState = (this.networkStateList_.length > 0 &&
- this.networkStateList_[0].ConnectionState ==
- CrOnc.ConnectionState.CONNECTED) ?
- this.networkStateList_[0] :
- null;
-
- if (!defaultState && !this.defaultStateGuid_)
- return;
-
- // defaultState.GUID must never be empty.
- assert(!defaultState || defaultState.GUID);
+ if (defaultNetwork && this.defaultNetworkState_ &&
+ defaultNetwork.GUID == this.defaultNetworkState_.GUID &&
+ defaultNetwork.ConnectionState ==
+ this.defaultNetworkState_.ConnectionState) {
+ return; // No change to network or ConnectionState
+ }
+ this.defaultNetworkState_ =
+ /** @type {!CrOnc.NetworkStateProperties|undefined} */ (
+ Object.assign({}, defaultNetwork));
+ this.fire('default-network-changed', defaultNetwork);
+ },
- if (defaultState && defaultState.GUID == this.defaultStateGuid_)
+ /**
+ * Modifies |networkStates| to include a cellular network if none exists.
+ * @param {!Array<!CrOnc.NetworkStateProperties>} networkStates
+ * @private
+ */
+ ensureCellularNetwork_: function(networkStates) {
+ if (networkStates.find(function(network) {
+ return network.Type == CrOnc.Type.CELLULAR;
+ })) {
return;
-
- this.defaultStateGuid_ = defaultState ? defaultState.GUID : '';
- this.fire('default-network-changed', defaultState);
+ }
+ // Add a Cellular network after the Ethernet network if it exists.
+ var idx = networkStates.length > 0 &&
+ networkStates[0].Type == CrOnc.Type.ETHERNET ?
+ 1 :
+ 0;
+ var cellular = {
+ GUID: '',
+ Type: CrOnc.Type.CELLULAR,
+ Cellular: {Scanning: this.cellularDeviceState_.Scanning}
+ };
+ networkStates.splice(idx, 0, cellular);
},
/**
@@ -194,6 +216,18 @@ Polymer({
return;
}
+ // NOTE: This isn't used by OOBE (no handle-network-item-selected).
+ // TODO(stevenjb): Remove custom OOBE handling.
+ if (state.Type == CrOnc.Type.CELLULAR && this.cellularDeviceState_) {
+ var cellularDevice = this.cellularDeviceState_;
+ // If Cellular is not enabled and not SIM locked, enable Cellular.
+ if (cellularDevice.State != CrOnc.DeviceState.ENABLED &&
+ (!cellularDevice.SIMLockStatus ||
+ !cellularDevice.SIMLockStatus.LockType)) {
+ chrome.networkingPrivate.enableNetworkType(CrOnc.Type.CELLULAR);
+ }
+ }
+
if (state.ConnectionState != CrOnc.ConnectionState.NOT_CONNECTED)
return;
@@ -203,14 +237,4 @@ Polymer({
console.error('networkingPrivate.startConnect error: ' + lastError);
});
},
-
- /**
- * Event triggered when a cr-network-list-item becomes connected.
- * @param {!{target: HTMLElement, detail: !CrOnc.NetworkStateProperties}} e
- * @private
- */
- onNetworkConnected_: function(e) {
- if (e.detail && e.detail.GUID != this.defaultStateGuid_)
- this.refreshNetworks();
- },
});
diff --git a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js
index 5a7ed921c7b..b6671b12291 100644
--- a/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js
+++ b/chromium/ui/webui/resources/cr_elements/chromeos/network/cr_onc_types.js
@@ -30,6 +30,7 @@
* networkListItemConnecting: string,
* networkListItemConnectingTo: string,
* networkListItemInitializing: string,
+ * networkListItemScanning: string,
* networkListItemNotConnected: string,
* networkListItemNoNetwork: string,
* vpnNameTemplate: string,
@@ -498,7 +499,8 @@ CrOnc.setValidStaticIPConfig = function(config, properties) {
* @param {!chrome.networkingPrivate.NetworkConfigProperties} properties
* The ONC property dictionary to modify.
* @param {string} key The property key which may be nested, e.g. 'Foo.Bar'.
- * @param {!CrOnc.NetworkPropertyType} value The property value to set.
+ * @param {!CrOnc.NetworkPropertyType|undefined} value The property value to
+ * set. If undefined the property will be removed.
*/
CrOnc.setProperty = function(properties, key, value) {
while (true) {
@@ -511,7 +513,10 @@ CrOnc.setProperty = function(properties, key, value) {
properties = properties[keyComponent];
key = key.substr(index + 1);
}
- properties[key] = value;
+ if (value === undefined)
+ delete properties[key];
+ else
+ properties[key] = value;
};
/**
@@ -519,7 +524,8 @@ CrOnc.setProperty = function(properties, key, value) {
* @param {!chrome.networkingPrivate.NetworkConfigProperties} properties The
* ONC properties to set. properties.Type must be set already.
* @param {string} key The type property key, e.g. 'AutoConnect'.
- * @param {!CrOnc.NetworkPropertyType} value The property value to set.
+ * @param {!CrOnc.NetworkPropertyType|undefined} value The property value to
+ * set. If undefined the property will be removed.
*/
CrOnc.setTypeProperty = function(properties, key, value) {
if (properties.Type == undefined) {
diff --git a/chromium/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp b/chromium/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp
index c3698cf0147..5b542f023a5 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp
+++ b/chromium/ui/webui/resources/cr_elements/cr_action_menu/compiled_resources2.gyp
@@ -9,6 +9,7 @@
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util',
'<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_without_ink',
+ '<(EXTERNS_GYP):pending',
],
'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
},
diff --git a/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html b/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html
index 05ca3cc16ce..70acc097ff2 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html
+++ b/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.html
@@ -21,7 +21,7 @@
background-color: transparent;
}
- :host ::content .dropdown-item {
+ :host ::slotted(.dropdown-item) {
background: none;
border: none;
border-radius: 0;
@@ -35,20 +35,20 @@
width: 100%;
}
- :host ::content .dropdown-item:not([hidden]) {
+ :host ::slotted(.dropdown-item:not([hidden])) {
align-items: center;
display: flex;
}
- :host ::content .dropdown-item[disabled] {
+ :host ::slotted(.dropdown-item[disabled]) {
opacity: 0.65;
}
- :host ::content .dropdown-item:not([disabled]) {
- @apply(--cr-actionable);
+ :host ::slotted(.dropdown-item:not([disabled])) {
+ @apply --cr-actionable;
}
- :host ::content .dropdown-item:focus {
+ :host ::slotted(.dropdown-item:focus) {
background-color: var(--paper-grey-300);
outline: none;
}
@@ -58,7 +58,7 @@
}
</style>
<div class="item-wrapper" tabindex="-1" role="menu">
- <content select=".dropdown-item,hr" id="contentNode"></content>
+ <slot name="item" id="contentNode"></slot>
</div>
</template>
<script src="cr_action_menu.js"></script>
diff --git a/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js b/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js
index d524c5433cf..31613726bcc 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js
+++ b/chromium/ui/webui/resources/cr_elements/cr_action_menu/cr_action_menu.js
@@ -4,6 +4,22 @@
/**
* @typedef {{
+ * top: (number|undefined),
+ * left: (number|undefined),
+ * width: (number|undefined),
+ * height: (number|undefined),
+ * anchorAlignmentX: (number|undefined),
+ * anchorAlignmentY: (number|undefined),
+ * minX: (number|undefined),
+ * minY: (number|undefined),
+ * maxX: (number|undefined),
+ * maxY: (number|undefined),
+ * }}
+ */
+var ShowAtConfig;
+
+/**
+ * @typedef {{
* top: number,
* left: number,
* width: (number|undefined),
@@ -16,7 +32,7 @@
* maxY: (number|undefined),
* }}
*/
-var ShowConfig;
+var ShowAtPositionConfig;
/**
* @enum {number}
@@ -81,7 +97,7 @@ function getStartPointWithAnchor(
/**
* @private
- * @return {!ShowConfig}
+ * @return {!ShowAtPositionConfig}
*/
function getDefaultShowConfig() {
var doc = document.scrollingElement;
@@ -124,10 +140,25 @@ Polymer({
/** @private {?PolymerDomApi.ObserveHandle} */
contentObserver_: null,
+ /** @private {?ResizeObserver} */
+ resizeObserver_: null,
+
+ /** @private {?ShowAtPositionConfig} */
+ lastConfig_: null,
+
hostAttributes: {
tabindex: 0,
},
+ properties: {
+ // Setting this flag will make the menu listen for content size changes and
+ // reposition to its anchor accordingly.
+ autoReposition: {
+ type: Boolean,
+ value: false,
+ },
+ },
+
listeners: {
'keydown': 'onKeyDown_',
'mouseover': 'onMouseover_',
@@ -147,6 +178,11 @@ Polymer({
Polymer.dom(this.$.contentNode).unobserveNodes(this.contentObserver_);
this.contentObserver_ = null;
}
+
+ if (this.resizeObserver_) {
+ this.resizeObserver_.disconnect();
+ this.resizeObserver_ = null;
+ }
},
/**
@@ -251,12 +287,15 @@ Polymer({
cr.ui.focusWithoutInk(assert(this.anchorElement_));
this.anchorElement_ = null;
}
+ if (this.lastConfig_) {
+ this.lastConfig_ = null;
+ }
},
/**
* Shows the menu anchored to the given element.
* @param {!Element} anchorElement
- * @param {ShowConfig=} opt_config
+ * @param {ShowAtConfig=} opt_config
*/
showAt: function(anchorElement, opt_config) {
this.anchorElement_ = anchorElement;
@@ -265,7 +304,7 @@ Polymer({
this.anchorElement_.scrollIntoViewIfNeeded();
var rect = this.anchorElement_.getBoundingClientRect();
- this.showAtPosition(/** @type {ShowConfig} */ (Object.assign(
+ this.showAtPosition(/** @type {ShowAtPositionConfig} */ (Object.assign(
{
top: rect.top,
left: rect.left,
@@ -302,7 +341,7 @@ Polymer({
* (BEFORE_END, AFTER_START), whereas centering the menu below the bottom
* edge of the anchor would use (CENTER, AFTER_END).
*
- * @param {!ShowConfig} config
+ * @param {!ShowAtPositionConfig} config
*/
showAtPosition: function(config) {
// Save the scroll position of the viewport.
@@ -319,7 +358,7 @@ Polymer({
config.top += scrollTop;
config.left += scrollLeft;
- this.positionDialog_(/** @type {ShowConfig} */ (Object.assign(
+ this.positionDialog_(/** @type {ShowAtPositionConfig} */ (Object.assign(
{
minX: scrollLeft,
minY: scrollTop,
@@ -344,10 +383,11 @@ Polymer({
/**
* Position the dialog using the coordinates in config. Coordinates are
* relative to the top-left of the viewport when scrolled to (0, 0).
- * @param {!ShowConfig} config
+ * @param {!ShowAtPositionConfig} config
* @private
*/
positionDialog_: function(config) {
+ this.lastConfig_ = config;
var c = Object.assign(getDefaultShowConfig(), config);
var top = c.top;
@@ -397,6 +437,17 @@ Polymer({
}
});
});
+
+ if (this.autoReposition) {
+ this.resizeObserver_ = new ResizeObserver(() => {
+ if (this.lastConfig_) {
+ this.positionDialog_(this.lastConfig_);
+ this.fire('cr-action-menu-repositioned'); // For easier testing.
+ }
+ });
+
+ this.resizeObserver_.observe(this);
+ }
},
});
})();
diff --git a/chromium/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html b/chromium/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
index 759fcf8b6de..68cb78ff83f 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
+++ b/chromium/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
@@ -29,6 +29,7 @@
flex-direction: column;
max-height: 100vh;
overflow: auto;
+ @apply --cr-dialog-wrapper;
}
/* When needing to flex, force .body-container alone to shrink. */
@@ -49,7 +50,7 @@
:host ::slotted([slot=body]) {
padding: 12px 16px;
- @apply(--cr-dialog-body);
+ @apply --cr-dialog-body;
}
:host ::slotted([slot=title]) {
@@ -57,7 +58,7 @@
font-size: calc(15 / 13 * 100%);
line-height: 1;
padding: 16px 16px;
- @apply(--cr-dialog-title);
+ @apply --cr-dialog-title;
}
:host ::slotted([slot=button-container]) {
@@ -84,7 +85,7 @@
min-height: 60px; /* Minimum reasonably usable height. */
overflow: auto;
- @apply(--cr-dialog-body-container);
+ @apply --cr-dialog-body-container;
}
.body-container.bottom-scrollable {
@@ -116,6 +117,16 @@
align-self: flex-start;
margin-top: 4px;
padding: 10px; /* Makes the actual icon 16x16. */
+
+ @apply --cr-dialog-close-image;
+ }
+
+ #close:hover {
+ @apply --cr-dialog-close-image-hover;
+ }
+
+ #close:active {
+ @apply --cr-dialog-close-image-active;
}
</style>
<!-- This wrapper is necessary, such that the "pulse" animation is not
diff --git a/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html b/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html
index 2753d98bb65..e31345821ed 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html
+++ b/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.html
@@ -11,7 +11,7 @@
}
button[is=paper-icon-button-light] {
- @apply(--cr-paper-icon-button-margin);
+ @apply --cr-paper-icon-button-margin;
}
#outer {
@@ -26,8 +26,8 @@
<div id="outer" on-tap="toggleExpand_">
<div id="label" on-tap="toggleExpand_"><slot></slot></div>
<button is="paper-icon-button-light" class$="[[iconName_(expanded)]]"
- toggles active="{{expanded}}" disabled="[[disabled]]" alt="[[alt]]"
- aria-active-attribute="aria-expanded"
+ toggles active="{{expanded}}" disabled="[[disabled]]"
+ aria-label$="[[alt]]" aria-pressed$="[[getAriaPressed_(expanded)]]"
tabindex$="[[tabIndex]]">
</button>
</div>
diff --git a/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js b/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js
index 6cc2d178740..65a019c9e11 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js
+++ b/chromium/ui/webui/resources/cr_elements/cr_expand_button/cr_expand_button.js
@@ -44,4 +44,9 @@ Polymer({
this.expanded = !this.expanded;
event.stopPropagation();
},
+
+ /** @private */
+ getAriaPressed_: function(expanded) {
+ return expanded ? 'true' : 'false';
+ },
});
diff --git a/chromium/ui/webui/resources/cr_elements/cr_icons_css.html b/chromium/ui/webui/resources/cr_elements/cr_icons_css.html
index f207914c7da..f8dc56c8a7f 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_icons_css.html
+++ b/chromium/ui/webui/resources/cr_elements/cr_icons_css.html
@@ -11,7 +11,7 @@
button[is='paper-icon-button-light'],
.cr-icon {
- @apply(--cr-paper-icon-button-margin);
+ @apply --cr-paper-icon-button-margin;
background-position: center;
background-repeat: no-repeat;
background-size: var(--cr-icon-size);
diff --git a/chromium/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html b/chromium/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html
index 4f6115b4b82..97bb3cc66a7 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html
+++ b/chromium/ui/webui/resources/cr_elements/cr_link_row/cr_link_row.html
@@ -65,7 +65,7 @@
}
#subLabel {
- /* TODO(dschuyler): replace with: @apply(--cr-secondary-text); */
+ /* TODO(dschuyler): replace with: @apply --cr-secondary-text; */
color: var(--paper-grey-600);
font-weight: 400;
}
diff --git a/chromium/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html b/chromium/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html
index 29b9923b515..bc13ad1d5d6 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html
+++ b/chromium/ui/webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html
@@ -12,7 +12,7 @@
--avatar-spacing: 24px;
display: inline-flex;
- @apply(--avatar-selector);
+ @apply --avatar-selector;
}
#avatar-grid .avatar {
@@ -33,7 +33,7 @@
padding: 0;
width: var(--avatar-size);
- @apply(--avatar-selector-avatar);
+ @apply --avatar-selector-avatar;
}
#avatar-grid .avatar.iron-selected {
diff --git a/chromium/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html b/chromium/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
index 24ca91153a1..063e1fd2902 100644
--- a/chromium/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
+++ b/chromium/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
@@ -40,7 +40,7 @@
}
paper-spinner-lite {
- @apply(--cr-icon-height-width);
+ @apply --cr-icon-height-width;
--paper-spinner-color: white;
margin: 0 6px;
opacity: 0;
diff --git a/chromium/ui/webui/resources/cr_elements/paper_toggle_style_css.html b/chromium/ui/webui/resources/cr_elements/paper_toggle_style_css.html
index 95581fd1707..44260f5541d 100644
--- a/chromium/ui/webui/resources/cr_elements/paper_toggle_style_css.html
+++ b/chromium/ui/webui/resources/cr_elements/paper_toggle_style_css.html
@@ -28,7 +28,7 @@
--paper-toggle-button-checked-bar: var(--cr-toggle-bar-size);
--paper-toggle-button-checked-bar-color: var(--cr-toggle-color);
--paper-toggle-button-checked-button: {
- @apply(--cr-toggle-button-size);
+ @apply --cr-toggle-button-size;
transform: translate(18px, 0);
};
--paper-toggle-button-checked-button-color: var(--cr-toggle-color);
diff --git a/chromium/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js b/chromium/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
index 2ad60591ab2..e8b2bba0d98 100644
--- a/chromium/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
+++ b/chromium/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
@@ -120,7 +120,7 @@ var CrPolicyIndicatorBehavior = {
return ''; // Tooltips may not be defined, e.g. in OOBE.
switch (type) {
case CrPolicyIndicatorType.EXTENSION:
- return CrPolicyStrings.controlledSettingExtension;
+ return CrPolicyStrings.controlledSettingExtension.replace('$1', name);
case CrPolicyIndicatorType.PRIMARY_USER:
return CrPolicyStrings.controlledSettingShared.replace('$1', name);
case CrPolicyIndicatorType.OWNER:
diff --git a/chromium/ui/webui/resources/cr_elements/search_highlight_style_css.html b/chromium/ui/webui/resources/cr_elements/search_highlight_style_css.html
new file mode 100644
index 00000000000..451f86dd950
--- /dev/null
+++ b/chromium/ui/webui/resources/cr_elements/search_highlight_style_css.html
@@ -0,0 +1,48 @@
+<link rel="import" href="chrome://resources/html/polymer.html">
+
+<link rel="import" href="shared_vars_css.html">
+
+<dom-module id="search-highlight-style">
+ <template>
+ <style>
+ .search-bubble {
+ /* RGB value matches var(--paper-yellow-500). */
+ --search-bubble-color: rgba(255, 235, 59, 0.9);
+ position: absolute;
+ z-index: 1;
+ }
+
+ .search-bubble-innards {
+ align-items: center;
+ background-color: var(--search-bubble-color);
+ border-radius: 2px;
+ max-width: 100px;
+ min-width: 64px;
+ padding: 4px 10px;
+ text-align: center;
+ @apply --cr-text-elide;
+ }
+
+ /* Provides the arrow which points at the anchor element. */
+ .search-bubble-innards::after {
+ background-color: var(--search-bubble-color);
+ content: '';
+ height: 10px;
+ left: calc(50% - 5px);
+ position: absolute;
+ top: -5px;
+ transform: rotate(-45deg);
+ width: 10px;
+ z-index: -1;
+ }
+
+ /* Turns the arrow direction downwards, when the bubble is placed above
+ * the anchor element */
+ .search-bubble-innards.above::after {
+ bottom: -5px;
+ top: auto;
+ transform: rotate(-135deg);
+ }
+ </style>
+ </template>
+</dom-module>
diff --git a/chromium/ui/webui/resources/cr_elements/shared_style_css.html b/chromium/ui/webui/resources/cr_elements/shared_style_css.html
index f3bcb9eb1ff..090a611be97 100644
--- a/chromium/ui/webui/resources/cr_elements/shared_style_css.html
+++ b/chromium/ui/webui/resources/cr_elements/shared_style_css.html
@@ -36,7 +36,7 @@
}
[actionable] {
- @apply(--cr-actionable);
+ @apply --cr-actionable;
}
.subpage-arrow,
@@ -71,8 +71,8 @@
border-bottom-color: var(--google-grey-300);
}
[scrollable] iron-list > :not(.no-outline):focus {
- @apply(--cr-list-item-focus);
- @apply(--cr-selectable-focus);
+ @apply --cr-list-item-focus;
+ @apply --cr-selectable-focus;
}
.scroll-container {
@@ -83,15 +83,15 @@
[selectable]:focus,
[selectable] > :focus {
- @apply(--cr-selectable-focus);
+ @apply --cr-selectable-focus;
}
[selectable] > * {
- @apply(--cr-actionable);
+ @apply --cr-actionable;
}
/** Styles for elements that implement the CrContainerShadowBehavior */
#cr-container-shadow {
- @apply(--cr-container-shadow);
+ @apply --cr-container-shadow;
}
#cr-container-shadow.has-shadow {
diff --git a/chromium/ui/webui/resources/cr_elements/shared_vars_css.html b/chromium/ui/webui/resources/cr_elements/shared_vars_css.html
index 83d28f66dfd..f7eeb885181 100644
--- a/chromium/ui/webui/resources/cr_elements/shared_vars_css.html
+++ b/chromium/ui/webui/resources/cr_elements/shared_vars_css.html
@@ -67,6 +67,12 @@
padding: 0 var(--cr-section-padding);
};
+ --cr-text-elide: {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ };
+
--cr-title-text: {
color: rgb(90, 90, 90);
font-size: 107.6923%; /* Go to 14px from 13px. */
diff --git a/chromium/ui/webui/resources/cr_elements_resources.grdp b/chromium/ui/webui/resources/cr_elements_resources.grdp
index c5c61226a49..c348d34f2f6 100644
--- a/chromium/ui/webui/resources/cr_elements_resources.grdp
+++ b/chromium/ui/webui/resources/cr_elements_resources.grdp
@@ -284,6 +284,10 @@
file="../../webui/resources/cr_elements/paper_toggle_style_css.html"
type="chrome_html"
compress="gzip" />
+ <structure name="IDR_CR_ELEMENTS_SEARCH_HIGHLIGHT_STYLE_CSS_HTML"
+ file="../../webui/resources/cr_elements/search_highlight_style_css.html"
+ type="chrome_html"
+ compress="gzip" />
<structure name="IDR_CR_ELEMENTS_CR_SHARED_VARS_CSS_HTML"
file="../../webui/resources/cr_elements/shared_vars_css.html"
type="chrome_html"
diff --git a/chromium/ui/webui/resources/cr_polymer_resources.grdp b/chromium/ui/webui/resources/cr_polymer_resources.grdp
new file mode 100644
index 00000000000..96e7fecc19f
--- /dev/null
+++ b/chromium/ui/webui/resources/cr_polymer_resources.grdp
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Holds various resources under ui/webui/resources/{js,html}, that depend on
+ Polymer or are Polymer related. -->
+<grit-part>
+ <!-- HTML resources -->
+ <structure name="IDR_WEBUI_HTML_ACTION_LINK_CSS"
+ file="html/action_link_css.html" type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_WEBUI_HTML_CR_UI_FOCUS_WITHOUT_INK"
+ file="html/cr/ui/focus_without_ink.html" type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_WEBUI_HTML_I18N_BEHAVIOR"
+ file="html/i18n_behavior.html" type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_WEBUI_HTML_MD_SELECT_CSS_HTML"
+ file="html/md_select_css.html" type="chrome_html"
+ compress="gzip" flattenhtml="true" />
+ <structure name="IDR_WEBUI_HTML_POLYMER"
+ file="html/polymer.html" type="chrome_html" compress="gzip" />
+ <structure name="IDR_WEBUI_HTML_WEBUI_LISTENER_BEHAVIOR"
+ file="html/web_ui_listener_behavior.html" type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_WEBUI_HTML_SEARCH_HIGHLIGHT_UTILS"
+ file="html/search_highlight_utils.html" type="chrome_html"
+ compress="gzip" />
+
+ <!-- CSS resources -->
+ <structure name="IDR_WEBUI_CSS_MD_COLORS"
+ file="css/md_colors.css" type="chrome_html" compress="gzip" />
+
+ <!-- JS resources -->
+ <structure name="IDR_WEBUI_JS_I18N_BEHAVIOR"
+ file="js/i18n_behavior.js" type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_WEBUI_JS_CR_UI_FOCUS_WITHOUT_INK"
+ file="js/cr/ui/focus_without_ink.js" type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_WEBUI_JS_POLYMER_CONFIG"
+ file="js/polymer_config.js" type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_WEBUI_JS_WEBUI_LISTENER_BEHAVIOR"
+ file="js/web_ui_listener_behavior.js" type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_WEBUI_JS_SEARCH_HIGHLIGHT_UTILS"
+ file="js/search_highlight_utils.js" type="chrome_html"
+ compress="gzip" />
+</grit-part>
diff --git a/chromium/ui/webui/resources/html/action_link_css.html b/chromium/ui/webui/resources/html/action_link_css.html
index 9ece1d5701f..904395b8046 100644
--- a/chromium/ui/webui/resources/html/action_link_css.html
+++ b/chromium/ui/webui/resources/html/action_link_css.html
@@ -6,7 +6,7 @@
<template>
<style>
[is='action-link'] {
- @apply(--cr-actionable);
+ @apply --cr-actionable;
display: inline-block;
text-decoration: none;
}
diff --git a/chromium/ui/webui/resources/html/search_highlight_utils.html b/chromium/ui/webui/resources/html/search_highlight_utils.html
new file mode 100644
index 00000000000..5f7a8836bcc
--- /dev/null
+++ b/chromium/ui/webui/resources/html/search_highlight_utils.html
@@ -0,0 +1 @@
+<script src="chrome://resources/js/search_highlight_utils.js"></script>
diff --git a/chromium/ui/webui/resources/images/200-logo_chrome.png b/chromium/ui/webui/resources/images/200-logo_chrome.png
index c283720758c..44f808efaf6 100644
--- a/chromium/ui/webui/resources/images/200-logo_chrome.png
+++ b/chromium/ui/webui/resources/images/200-logo_chrome.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/200-logo_googleg.png b/chromium/ui/webui/resources/images/200-logo_googleg.png
index 85f92c09ca9..9ace71c2a9c 100644
--- a/chromium/ui/webui/resources/images/200-logo_googleg.png
+++ b/chromium/ui/webui/resources/images/200-logo_googleg.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/2x/apps/topbar_button_maximize.png b/chromium/ui/webui/resources/images/2x/apps/topbar_button_maximize.png
index 59377a4dc41..96cecc99da1 100644
--- a/chromium/ui/webui/resources/images/2x/apps/topbar_button_maximize.png
+++ b/chromium/ui/webui/resources/images/2x/apps/topbar_button_maximize.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/2x/apps/topbar_button_minimize.png b/chromium/ui/webui/resources/images/2x/apps/topbar_button_minimize.png
index 2c0afdb3eba..437c6f700dd 100644
--- a/chromium/ui/webui/resources/images/2x/apps/topbar_button_minimize.png
+++ b/chromium/ui/webui/resources/images/2x/apps/topbar_button_minimize.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/apps/button_butter_bar_close.png b/chromium/ui/webui/resources/images/apps/button_butter_bar_close.png
index 75edfba33bd..001f22742c3 100644
--- a/chromium/ui/webui/resources/images/apps/button_butter_bar_close.png
+++ b/chromium/ui/webui/resources/images/apps/button_butter_bar_close.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/apps/topbar_button_maximize.png b/chromium/ui/webui/resources/images/apps/topbar_button_maximize.png
index 3bd557fa5a4..7d452702c13 100644
--- a/chromium/ui/webui/resources/images/apps/topbar_button_maximize.png
+++ b/chromium/ui/webui/resources/images/apps/topbar_button_maximize.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/apps/topbar_button_minimize.png b/chromium/ui/webui/resources/images/apps/topbar_button_minimize.png
index 484079d5bdb..33b892dfe3d 100644
--- a/chromium/ui/webui/resources/images/apps/topbar_button_minimize.png
+++ b/chromium/ui/webui/resources/images/apps/topbar_button_minimize.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/check.png b/chromium/ui/webui/resources/images/check.png
index 94c58b78c43..0321d1b45d9 100644
--- a/chromium/ui/webui/resources/images/check.png
+++ b/chromium/ui/webui/resources/images/check.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/checkbox_black.png b/chromium/ui/webui/resources/images/checkbox_black.png
index 3609119e41a..16e82cb2a63 100644
--- a/chromium/ui/webui/resources/images/checkbox_black.png
+++ b/chromium/ui/webui/resources/images/checkbox_black.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/disabled_select.png b/chromium/ui/webui/resources/images/disabled_select.png
index 0aa20000d74..9bce7a30523 100644
--- a/chromium/ui/webui/resources/images/disabled_select.png
+++ b/chromium/ui/webui/resources/images/disabled_select.png
Binary files differ
diff --git a/chromium/ui/webui/resources/images/select.png b/chromium/ui/webui/resources/images/select.png
index 2af6f675864..3cb71fb514c 100644
--- a/chromium/ui/webui/resources/images/select.png
+++ b/chromium/ui/webui/resources/images/select.png
Binary files differ
diff --git a/chromium/ui/webui/resources/js/compiled_resources2.gyp b/chromium/ui/webui/resources/js/compiled_resources2.gyp
index 25f388bebeb..3b759c04f4b 100644
--- a/chromium/ui/webui/resources/js/compiled_resources2.gyp
+++ b/chromium/ui/webui/resources/js/compiled_resources2.gyp
@@ -32,6 +32,13 @@
'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{
+ 'target_name': 'search_highlight_utils',
+ 'dependencies': [
+ 'cr',
+ ],
+ 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
+ },
+ {
'target_name': 'icon',
'dependencies': [
'cr',
diff --git a/chromium/ui/webui/resources/js/cr/ui/tree.js b/chromium/ui/webui/resources/js/cr/ui/tree.js
index 89940b6b66a..87ffb019a71 100644
--- a/chromium/ui/webui/resources/js/cr/ui/tree.js
+++ b/chromium/ui/webui/resources/js/cr/ui/tree.js
@@ -465,7 +465,7 @@ cr.define('cr.ui', function() {
return getComputedStyle(this.labelElement).backgroundImage.slice(4, -1);
},
set icon(icon) {
- return this.labelElement.style.backgroundImage = url(icon);
+ return this.labelElement.style.backgroundImage = getUrlForCss(icon);
},
/**
diff --git a/chromium/ui/webui/resources/js/icon.js b/chromium/ui/webui/resources/js/icon.js
index ee8c445f11c..ef025e7133d 100644
--- a/chromium/ui/webui/resources/js/icon.js
+++ b/chromium/ui/webui/resources/js/icon.js
@@ -45,7 +45,7 @@ cr.define('cr.icon', function() {
var replaceStartIndex = path.indexOf('scalefactor');
if (replaceStartIndex < 0)
- return url(path);
+ return getUrlForCss(path);
var s = '';
for (var i = 0; i < supportedScaleFactors.length; ++i) {
@@ -53,7 +53,7 @@ cr.define('cr.icon', function() {
var pathWithScaleFactor = path.substr(0, replaceStartIndex) +
scaleFactor + path.substr(replaceStartIndex + 'scalefactor'.length);
- s += url(pathWithScaleFactor) + ' ' + scaleFactor + 'x';
+ s += getUrlForCss(pathWithScaleFactor) + ' ' + scaleFactor + 'x';
if (i != supportedScaleFactors.length - 1)
s += ', ';
@@ -72,7 +72,8 @@ cr.define('cr.icon', function() {
var chromeThemePath = 'chrome://theme';
var isChromeThemeUrl =
(path.slice(0, chromeThemePath.length) == chromeThemePath);
- return isChromeThemeUrl ? getImageSet(path + '@scalefactorx') : url(path);
+ return isChromeThemeUrl ? getImageSet(path + '@scalefactorx') :
+ getUrlForCss(path);
}
/**
diff --git a/chromium/ui/webui/resources/js/search_highlight_utils.js b/chromium/ui/webui/resources/js/search_highlight_utils.js
new file mode 100644
index 00000000000..d7bf3c8acb0
--- /dev/null
+++ b/chromium/ui/webui/resources/js/search_highlight_utils.js
@@ -0,0 +1,130 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('cr.search_highlight_utils', function() {
+ /** @type {string} */
+ const WRAPPER_CSS_CLASS = 'search-highlight-wrapper';
+
+ /** @type {string} */
+ const ORIGINAL_CONTENT_CSS_CLASS = 'search-highlight-original-content';
+
+ /** @type {string} */
+ const HIT_CSS_CLASS = 'search-highlight-hit';
+
+ /** @type {string} */
+ const SEARCH_BUBBLE_CSS_CLASS = 'search-bubble';
+
+ /**
+ * Applies the highlight UI (yellow rectangle) around all matches in |node|.
+ * @param {!Node} node The text node to be highlighted. |node| ends up
+ * being hidden.
+ * @param {!Array<string>} tokens The string tokens after splitting on the
+ * relevant regExp. Even indices hold text that doesn't need highlighting,
+ * odd indices hold the text to be highlighted. For example:
+ * const r = new RegExp('(foo)', 'i');
+ * 'barfoobar foo bar'.split(r) => ['bar', 'foo', 'bar ', 'foo', ' bar']
+ */
+ function highlight(node, tokens) {
+ const wrapper = document.createElement('span');
+ wrapper.classList.add(WRAPPER_CSS_CLASS);
+ // Use existing node as placeholder to determine where to insert the
+ // replacement content.
+ node.parentNode.replaceChild(wrapper, node);
+
+ // Keep the existing node around for when the highlights are removed. The
+ // existing text node might be involved in data-binding and therefore should
+ // not be discarded.
+ const span = document.createElement('span');
+ span.classList.add(ORIGINAL_CONTENT_CSS_CLASS);
+ span.style.display = 'none';
+ span.appendChild(node);
+ wrapper.appendChild(span);
+
+ for (let i = 0; i < tokens.length; ++i) {
+ if (i % 2 == 0) {
+ wrapper.appendChild(document.createTextNode(tokens[i]));
+ } else {
+ const hitSpan = document.createElement('span');
+ hitSpan.classList.add(HIT_CSS_CLASS);
+ hitSpan.style.backgroundColor = '#ffeb3b'; // --var(--paper-yellow-500)
+ hitSpan.textContent = tokens[i];
+ wrapper.appendChild(hitSpan);
+ }
+ }
+ }
+
+ /**
+ * Finds all previous highlighted nodes under |node| (both within self and
+ * children's Shadow DOM) and replaces the highlights (yellow rectangles)
+ * with the original search node.
+ * @param {!Node} node
+ * @private
+ */
+ function findAndRemoveHighlights(node) {
+ const wrappers = node.querySelectorAll(`* /deep/ .${WRAPPER_CSS_CLASS}`);
+
+ for (let i = 0; i < wrappers.length; i++) {
+ const wrapper = wrappers[i];
+ const originalNode =
+ wrapper.querySelector(`.${ORIGINAL_CONTENT_CSS_CLASS}`);
+ wrapper.parentElement.replaceChild(originalNode.firstChild, wrapper);
+ }
+ }
+
+ /**
+ * Finds and removes all previously created yellow search bubbles under
+ * |node| (both within self and children's Shadow DOM).
+ * @param {!Node} node
+ * @private
+ */
+ function findAndRemoveBubbles(node) {
+ const searchBubbles =
+ node.querySelectorAll(`* /deep/ .${SEARCH_BUBBLE_CSS_CLASS}`);
+ for (let bubble of searchBubbles)
+ bubble.remove();
+ }
+
+ /**
+ * Highlights an HTML element by displaying a search bubble. The element
+ * should already be visible or the bubble will render incorrectly.
+ * @param {!HTMLElement} element The element to be highlighted.
+ * @param {string} rawQuery The search query.
+ * @private
+ */
+ function highlightControlWithBubble(element, rawQuery) {
+ let searchBubble = element.querySelector(`.${SEARCH_BUBBLE_CSS_CLASS}`);
+ // If the element has already been highlighted, there is no need to do
+ // anything.
+ if (searchBubble)
+ return;
+
+ searchBubble = document.createElement('div');
+ searchBubble.classList.add(SEARCH_BUBBLE_CSS_CLASS);
+ const innards = document.createElement('div');
+ innards.classList.add('search-bubble-innards');
+ innards.textContent = rawQuery;
+ searchBubble.appendChild(innards);
+ element.appendChild(searchBubble);
+
+ const updatePosition = function() {
+ searchBubble.style.top = element.offsetTop +
+ (innards.classList.contains('above') ? -searchBubble.offsetHeight :
+ element.offsetHeight) +
+ 'px';
+ };
+ updatePosition();
+
+ searchBubble.addEventListener('mouseover', function() {
+ innards.classList.toggle('above');
+ updatePosition();
+ });
+ }
+
+ return {
+ highlight: highlight,
+ highlightControlWithBubble: highlightControlWithBubble,
+ findAndRemoveBubbles: findAndRemoveBubbles,
+ findAndRemoveHighlights: findAndRemoveHighlights,
+ };
+});
diff --git a/chromium/ui/webui/resources/js/util.js b/chromium/ui/webui/resources/js/util.js
index 27faa1b60bf..a5099bf9b56 100644
--- a/chromium/ui/webui/resources/js/util.js
+++ b/chromium/ui/webui/resources/js/util.js
@@ -56,7 +56,7 @@ function announceAccessibleMessage(msg) {
* @param {string} s The URL to generate the CSS url for.
* @return {string} The CSS url string.
*/
-function url(s) {
+function getUrlForCss(s) {
// http://www.w3.org/TR/css3-values/#uris
// Parentheses, commas, whitespace characters, single quotes (') and double
// quotes (") appearing in a URI must be escaped with a backslash
diff --git a/chromium/ui/webui/resources/polymer_resources.grdp b/chromium/ui/webui/resources/polymer_resources.grdp
index 6e5f88e36b1..6f4a7f9d3f0 100644
--- a/chromium/ui/webui/resources/polymer_resources.grdp
+++ b/chromium/ui/webui/resources/polymer_resources.grdp
@@ -276,6 +276,14 @@
file="../../../third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-overlay-manager.html"
type="chrome_html"
compress="gzip" />
+ <structure name="IDR_POLYMER_1_0_IRON_OVERLAY_BEHAVIOR_IRON_SCROLL_MANAGER_EXTRACTED_JS"
+ file="../../../third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-scroll-manager-extracted.js"
+ type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_POLYMER_1_0_IRON_OVERLAY_BEHAVIOR_IRON_SCROLL_MANAGER_HTML"
+ file="../../../third_party/polymer/v1_0/components-chromium/iron-overlay-behavior/iron-scroll-manager.html"
+ type="chrome_html"
+ compress="gzip" />
<structure name="IDR_POLYMER_1_0_IRON_PAGES_IRON_PAGES_EXTRACTED_JS"
file="../../../third_party/polymer/v1_0/components-chromium/iron-pages/iron-pages-extracted.js"
type="chrome_html"
@@ -700,30 +708,6 @@
file="../../../third_party/polymer/v1_0/components-chromium/paper-listbox/paper-listbox.html"
type="chrome_html"
compress="gzip" />
- <structure name="IDR_POLYMER_1_0_PAPER_MATERIAL_PAPER_MATERIAL_SHARED_STYLES_HTML"
- file="../../../third_party/polymer/v1_0/components-chromium/paper-material/paper-material-shared-styles.html"
- type="chrome_html"
- compress="gzip" />
- <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_MENU_EXTRACTED_JS"
- file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-menu-extracted.js"
- type="chrome_html"
- compress="gzip" />
- <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_MENU_SHARED_STYLES_HTML"
- file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-menu-shared-styles.html"
- type="chrome_html"
- compress="gzip" />
- <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_MENU_HTML"
- file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-menu.html"
- type="chrome_html"
- compress="gzip" />
- <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_SUBMENU_EXTRACTED_JS"
- file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-submenu-extracted.js"
- type="chrome_html"
- compress="gzip" />
- <structure name="IDR_POLYMER_1_0_PAPER_MENU_PAPER_SUBMENU_HTML"
- file="../../../third_party/polymer/v1_0/components-chromium/paper-menu/paper-submenu.html"
- type="chrome_html"
- compress="gzip" />
<structure name="IDR_POLYMER_1_0_PAPER_PROGRESS_PAPER_PROGRESS_EXTRACTED_JS"
file="../../../third_party/polymer/v1_0/components-chromium/paper-progress/paper-progress-extracted.js"
type="chrome_html"
@@ -784,10 +768,6 @@
file="../../../third_party/polymer/v1_0/components-chromium/paper-spinner/paper-spinner-styles.html"
type="chrome_html"
compress="gzip" />
- <structure name="IDR_POLYMER_1_0_PAPER_STYLES_CLASSES_SHADOW_LAYOUT_HTML"
- file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/classes/shadow-layout.html"
- type="chrome_html"
- compress="gzip" />
<structure name="IDR_POLYMER_1_0_PAPER_STYLES_CLASSES_SHADOW_HTML"
file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/classes/shadow.html"
type="chrome_html"
@@ -804,6 +784,14 @@
file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/default-theme.html"
type="chrome_html"
compress="gzip" />
+ <structure name="IDR_POLYMER_1_0_PAPER_STYLES_ELEMENT_STYLES_PAPER_ITEM_STYLES_HTML"
+ file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/element-styles/paper-item-styles.html"
+ type="chrome_html"
+ compress="gzip" />
+ <structure name="IDR_POLYMER_1_0_PAPER_STYLES_ELEMENT_STYLES_PAPER_MATERIAL_STYLES_HTML"
+ file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/element-styles/paper-material-styles.html"
+ type="chrome_html"
+ compress="gzip" />
<structure name="IDR_POLYMER_1_0_PAPER_STYLES_PAPER_STYLES_CLASSES_HTML"
file="../../../third_party/polymer/v1_0/components-chromium/paper-styles/paper-styles-classes.html"
type="chrome_html"
diff --git a/chromium/ui/webui/resources/webui_resources.grd b/chromium/ui/webui/resources/webui_resources.grd
index 980b689ac1e..a704601c238 100644
--- a/chromium/ui/webui/resources/webui_resources.grd
+++ b/chromium/ui/webui/resources/webui_resources.grd
@@ -236,8 +236,6 @@ without changes to the corresponding grd file. -->
compress="gzip" />
<structure name="IDR_WEBUI_CSS_LIST"
file="css/list.css" type="chrome_html" compress="gzip" />
- <structure name="IDR_WEBUI_CSS_MD_COLORS"
- file="css/md_colors.css" type="chrome_html" compress="gzip" />
<structure name="IDR_WEBUI_CSS_MENU"
file="css/menu.css" type="chrome_html" compress="gzip"
flattenhtml="true" />
@@ -274,9 +272,6 @@ without changes to the corresponding grd file. -->
<structure name="IDR_WEBUI_HTML_ACTION_LINK"
file="html/action_link.html" type="chrome_html"
compress="gzip" />
- <structure name="IDR_WEBUI_HTML_ACTION_LINK_CSS"
- file="html/action_link_css.html" type="chrome_html"
- compress="gzip" />
<structure name="IDR_WEBUI_HTML_ASSERT"
file="html/assert.html" type="chrome_html" compress="gzip" />
<structure name="IDR_WEBUI_HTML_PROMISE_RESOLVER"
@@ -319,9 +314,6 @@ without changes to the corresponding grd file. -->
<structure name="IDR_WEBUI_HTML_CR_UI_FOCUS_ROW"
file="html/cr/ui/focus_row.html" type="chrome_html"
compress="gzip" />
- <structure name="IDR_WEBUI_HTML_CR_UI_FOCUS_WITHOUT_INK"
- file="html/cr/ui/focus_without_ink.html" type="chrome_html"
- compress="gzip" />
<structure name="IDR_WEBUI_HTML_CR_UI_LIST"
file="html/cr/ui/list.html"
type="chrome_html" compress="gzip" />
@@ -366,25 +358,14 @@ without changes to the corresponding grd file. -->
<structure name="IDR_WEBUI_HTML_I18N_TEMPLATE"
file="html/i18n_template.html" type="chrome_html"
compress="gzip" />
- <structure name="IDR_WEBUI_HTML_MD_SELECT_CSS_HTML"
- file="html/md_select_css.html" type="chrome_html"
- compress="gzip" flattenhtml="true" />
<structure name="IDR_WEBUI_HTML_LOAD_TIME_DATA"
file="html/load_time_data.html" type="chrome_html"
compress="gzip" />
<structure name="IDR_WEBUI_HTML_PARSE_HTML_SUBSET"
file="html/parse_html_subset.html" type="chrome_html"
compress="gzip" />
- <structure name="IDR_WEBUI_HTML_POLYMER"
- file="html/polymer.html" type="chrome_html" compress="gzip" />
- <structure name="IDR_WEBUI_HTML_I18N_BEHAVIOR"
- file="html/i18n_behavior.html" type="chrome_html"
- compress="gzip" />
<structure name="IDR_WEBUI_HTML_UTIL"
file="html/util.html" type="chrome_html" compress="gzip" />
- <structure name="IDR_WEBUI_HTML_WEBUI_LISTENER_BEHAVIOR"
- file="html/web_ui_listener_behavior.html" type="chrome_html"
- compress="gzip" />
<structure name="IDR_WEBUI_HTML_WEBUI_LISTENER_TRACKER"
file="html/webui_listener_tracker.html" type="chrome_html"
compress="gzip" />
@@ -454,9 +435,6 @@ without changes to the corresponding grd file. -->
<structure name="IDR_WEBUI_JS_CR_UI_FOCUS_ROW"
file="js/cr/ui/focus_row.js" type="chrome_html"
compress="gzip" />
- <structure name="IDR_WEBUI_JS_CR_UI_FOCUS_WITHOUT_INK"
- file="js/cr/ui/focus_without_ink.js" type="chrome_html"
- compress="gzip" />
<structure name="IDR_WEBUI_JS_CR_UI_LIST"
file="js/cr/ui/list.js" type="chrome_html" compress="gzip" />
<structure name="IDR_WEBUI_JS_CR_UI_LIST_ITEM"
@@ -546,24 +524,17 @@ without changes to the corresponding grd file. -->
<structure name="IDR_WEBUI_JS_PARSE_HTML_SUBSET"
file="js/parse_html_subset.js" type="chrome_html"
compress="gzip" />
- <structure name="IDR_WEBUI_JS_POLYMER_CONFIG"
- file="js/polymer_config.js" type="chrome_html"
- compress="gzip" />
- <structure name="IDR_WEBUI_JS_I18N_BEHAVIOR"
- file="js/i18n_behavior.js" type="chrome_html"
- compress="gzip" />
<structure name="IDR_WEBUI_JS_UTIL"
file="js/util.js" type="chrome_html" compress="gzip"
flattenhtml="true" />
- <structure name="IDR_WEBUI_JS_WEBUI_LISTENER_BEHAVIOR"
- file="js/web_ui_listener_behavior.js" type="chrome_html"
- compress="gzip" />
<structure name="IDR_WEBUI_JS_WEBUI_RESOURCE_TEST"
file="js/webui_resource_test.js" type="chrome_html"
compress="gzip" />
- <if expr="not is_android">
+
+ <if expr="not is_android and not is_ios">
<part file="cr_components/cr_components_resources.grdp" />
<part file="cr_elements_resources.grdp" />
+ <part file="cr_polymer_resources.grdp" />
<part file="polymer_resources.grdp" />
</if>
</structures>
diff --git a/chromium/ui/wm/core/shadow.cc b/chromium/ui/wm/core/shadow.cc
index 0fb91267c3a..20def6b8976 100644
--- a/chromium/ui/wm/core/shadow.cc
+++ b/chromium/ui/wm/core/shadow.cc
@@ -9,30 +9,22 @@
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/shadow_util.h"
-#include "ui/wm/core/shadow_types.h"
namespace wm {
namespace {
// Duration for opacity animation in milliseconds.
-const int kShadowAnimationDurationMs = 100;
-
-// Default rounded corner radius. Shadow::SetRoundedCornerRadius can
-// be used to override this for elements with a different rounded
-// corner radius.
-const int kDefaultRoundedCornerRadius = 2;
+constexpr int kShadowAnimationDurationMs = 100;
} // namespace
-Shadow::Shadow()
- : desired_elevation_(ShadowElevation::NONE),
- rounded_corner_radius_(kDefaultRoundedCornerRadius) {}
+Shadow::Shadow() {}
Shadow::~Shadow() {}
-void Shadow::Init(ShadowElevation elevation) {
- DCHECK_NE(ShadowElevation::DEFAULT, elevation);
+void Shadow::Init(int elevation) {
+ DCHECK_GE(elevation, 0);
desired_elevation_ = elevation;
layer_.reset(new ui::Layer(ui::LAYER_NOT_DRAWN));
RecreateShadowLayer();
@@ -48,8 +40,8 @@ void Shadow::SetContentBounds(const gfx::Rect& content_bounds) {
UpdateLayerBounds();
}
-void Shadow::SetElevation(ShadowElevation elevation) {
- DCHECK_NE(ShadowElevation::DEFAULT, elevation);
+void Shadow::SetElevation(int elevation) {
+ DCHECK_GE(elevation, 0);
if (desired_elevation_ == elevation)
return;
diff --git a/chromium/ui/wm/core/shadow.h b/chromium/ui/wm/core/shadow.h
index 03c65e7db0f..4c224a20b45 100644
--- a/chromium/ui/wm/core/shadow.h
+++ b/chromium/ui/wm/core/shadow.h
@@ -21,7 +21,6 @@ class Layer;
} // namespace ui
namespace wm {
-enum class ShadowElevation;
// Simple class that draws a drop shadow around content at given bounds.
class WM_CORE_EXPORT Shadow : public ui::ImplicitAnimationObserver {
@@ -29,7 +28,10 @@ class WM_CORE_EXPORT Shadow : public ui::ImplicitAnimationObserver {
Shadow();
~Shadow() override;
- void Init(ShadowElevation elevation);
+ // Initialize for the the given shadow |elevation|. This is passed to
+ // gfx::ShadowValue::MakeMdShadowValues() and controls the y-offset and blur
+ // for the shadow style.
+ void Init(int elevation);
// Returns |layer_.get()|. This is exposed so it can be added to the same
// layer as the content and stacked below it. SetContentBounds() should be
@@ -42,13 +44,13 @@ class WM_CORE_EXPORT Shadow : public ui::ImplicitAnimationObserver {
ui::Layer* shadow_layer() const { return shadow_layer_.get(); }
const gfx::Rect& content_bounds() const { return content_bounds_; }
- ShadowElevation desired_elevation() const { return desired_elevation_; }
+ int desired_elevation() const { return desired_elevation_; }
// Moves and resizes the shadow layer to frame |content_bounds|.
void SetContentBounds(const gfx::Rect& content_bounds);
// Sets the shadow's appearance, animating opacity as necessary.
- void SetElevation(ShadowElevation elevation);
+ void SetElevation(int elevation);
// Sets the radius for the rounded corners to take into account when
// adjusting the shadow layer to frame |content_bounds|. 0 or greater.
@@ -71,11 +73,11 @@ class WM_CORE_EXPORT Shadow : public ui::ImplicitAnimationObserver {
// dictates the shadow's display characteristics and is proportional to the
// size of the blur and its offset. This may not match reality if the window
// isn't big enough to support it.
- ShadowElevation desired_elevation_;
+ int desired_elevation_ = 0;
// Rounded corners are drawn on top of the window's content layer,
// we need to exclude them from the occlusion area.
- int rounded_corner_radius_;
+ int rounded_corner_radius_ = 2;
// The details of the shadow image that's currently set on |shadow_layer_|.
// This will be null until a positive elevation has been set. Once set, it
diff --git a/chromium/ui/wm/core/shadow_controller.cc b/chromium/ui/wm/core/shadow_controller.cc
index 93552daa5c1..875ed5e9b14 100644
--- a/chromium/ui/wm/core/shadow_controller.cc
+++ b/chromium/ui/wm/core/shadow_controller.cc
@@ -20,6 +20,7 @@
#include "ui/base/ui_base_types.h"
#include "ui/compositor/layer.h"
#include "ui/wm/core/shadow.h"
+#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_client.h"
@@ -32,41 +33,38 @@ namespace wm {
namespace {
-constexpr ShadowElevation kInactiveNormalShadowElevation =
- ShadowElevation::MEDIUM;
-
-ShadowElevation GetDefaultShadowElevationForWindow(aura::Window* window) {
+int GetDefaultShadowElevationForWindow(aura::Window* window) {
switch (window->type()) {
case aura::client::WINDOW_TYPE_NORMAL:
case aura::client::WINDOW_TYPE_PANEL:
- return kInactiveNormalShadowElevation;
+ return kShadowElevationInactiveWindow;
case aura::client::WINDOW_TYPE_MENU:
case aura::client::WINDOW_TYPE_TOOLTIP:
- return ShadowElevation::SMALL;
+ return kShadowElevationMenuOrTooltip;
default:
break;
}
- return ShadowElevation::NONE;
+ return kShadowElevationNone;
}
-// Returns the ShadowElevation for |window|, converting |DEFAULT| to the
-// appropriate ShadowElevation.
-ShadowElevation GetShadowElevationConvertDefault(aura::Window* window) {
- ShadowElevation elevation = window->GetProperty(kShadowElevationKey);
- return elevation == ShadowElevation::DEFAULT
+// Returns the shadow elevation for |window|, converting
+// |kShadowElevationDefault| to the appropriate value.
+int GetShadowElevationConvertDefault(aura::Window* window) {
+ int elevation = window->GetProperty(kShadowElevationKey);
+ return elevation == kShadowElevationDefault
? GetDefaultShadowElevationForWindow(window)
: elevation;
}
-ShadowElevation GetShadowElevationForActiveState(aura::Window* window) {
- ShadowElevation elevation = window->GetProperty(kShadowElevationKey);
- if (elevation != ShadowElevation::DEFAULT)
+int GetShadowElevationForActiveState(aura::Window* window) {
+ int elevation = window->GetProperty(kShadowElevationKey);
+ if (elevation != kShadowElevationDefault)
return elevation;
if (IsActiveWindow(window))
- return ShadowController::kActiveNormalShadowElevation;
+ return kShadowElevationActiveWindow;
return GetDefaultShadowElevationForWindow(window);
}
@@ -74,15 +72,14 @@ ShadowElevation GetShadowElevationForActiveState(aura::Window* window) {
// Returns the shadow style to be applied to |losing_active| when it is losing
// active to |gaining_active|. |gaining_active| may be of a type that hides when
// inactive, and as such we do not want to render |losing_active| as inactive.
-ShadowElevation GetShadowElevationForWindowLosingActive(
- aura::Window* losing_active,
- aura::Window* gaining_active) {
+int GetShadowElevationForWindowLosingActive(aura::Window* losing_active,
+ aura::Window* gaining_active) {
if (gaining_active && GetHideOnDeactivate(gaining_active)) {
if (base::ContainsValue(GetTransientChildren(losing_active),
gaining_active))
- return ShadowController::kActiveNormalShadowElevation;
+ return kShadowElevationActiveWindow;
}
- return kInactiveNormalShadowElevation;
+ return kShadowElevationInactiveWindow;
}
} // namespace
@@ -108,6 +105,7 @@ class ShadowController::Impl :
void OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) override;
+ void OnWindowVisibilityChanging(aura::Window* window, bool visible) override;
void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds,
@@ -160,25 +158,45 @@ ShadowController::Impl* ShadowController::Impl::GetInstance() {
}
void ShadowController::Impl::OnWindowInitialized(aura::Window* window) {
+ // During initialization, the window can't reliably tell whether it will be a
+ // root window. That must be checked in the first visibility change
+ DCHECK(!window->parent());
+ DCHECK(!window->TargetVisibility());
observer_manager_.Add(window);
- HandlePossibleShadowVisibilityChange(window);
}
void ShadowController::Impl::OnWindowPropertyChanged(aura::Window* window,
const void* key,
intptr_t old) {
- if (key == kShadowElevationKey) {
- if (window->GetProperty(kShadowElevationKey) ==
- static_cast<ShadowElevation>(old))
- return;
- } else if (key == aura::client::kShowStateKey) {
- if (window->GetProperty(aura::client::kShowStateKey) ==
- static_cast<ui::WindowShowState>(old)) {
- return;
- }
- } else {
+ bool shadow_will_change = false;
+ if (key == kShadowElevationKey)
+ shadow_will_change = window->GetProperty(kShadowElevationKey) != old;
+
+ if (key == aura::client::kShowStateKey) {
+ shadow_will_change = window->GetProperty(aura::client::kShowStateKey) !=
+ static_cast<ui::WindowShowState>(old);
+ }
+
+ // Check the target visibility. IsVisible() may return false if a parent layer
+ // is hidden, but |this| only observes calls to Show()/Hide() on |window|.
+ if (shadow_will_change && window->TargetVisibility())
+ HandlePossibleShadowVisibilityChange(window);
+}
+
+void ShadowController::Impl::OnWindowVisibilityChanging(aura::Window* window,
+ bool visible) {
+ // At the time of the first visibility change, |window| will give a correct
+ // answer for whether or not it is a root window. If it is, don't bother
+ // observing: a shadow should never be added. Root windows can only have
+ // shadows in the WindowServer (where a corresponding aura::Window may no
+ // longer be a root window). Without this check, a second shadow is added,
+ // which clips to the root window bounds; filling any rounded corners the
+ // window may have.
+ if (window->IsRootWindow()) {
+ observer_manager_.Remove(window);
return;
}
+
HandlePossibleShadowVisibilityChange(window);
}
@@ -207,9 +225,8 @@ void ShadowController::Impl::OnWindowActivated(ActivationReason reason,
}
if (lost_active) {
Shadow* shadow = GetShadowForWindow(lost_active);
- if (shadow &&
- GetShadowElevationConvertDefault(lost_active) ==
- kInactiveNormalShadowElevation) {
+ if (shadow && GetShadowElevationConvertDefault(lost_active) ==
+ kShadowElevationInactiveWindow) {
shadow->SetElevation(
GetShadowElevationForWindowLosingActive(lost_active, gained_active));
}
@@ -225,7 +242,7 @@ bool ShadowController::Impl::ShouldShowShadowForWindow(
return false;
}
- return static_cast<int>(GetShadowElevationConvertDefault(window)) > 0;
+ return GetShadowElevationConvertDefault(window) > 0;
}
void ShadowController::Impl::HandlePossibleShadowVisibilityChange(
@@ -241,12 +258,19 @@ void ShadowController::Impl::HandlePossibleShadowVisibilityChange(
}
void ShadowController::Impl::CreateShadowForWindow(aura::Window* window) {
+ DCHECK(!window->IsRootWindow());
Shadow* shadow = new Shadow();
window->SetProperty(kShadowLayerKey, shadow);
+
+ int corner_radius = window->GetProperty(aura::client::kWindowCornerRadiusKey);
+ if (corner_radius >= 0)
+ shadow->SetRoundedCornerRadius(corner_radius);
+
shadow->Init(GetShadowElevationForActiveState(window));
shadow->SetContentBounds(gfx::Rect(window->bounds().size()));
shadow->layer()->SetVisible(ShouldShowShadowForWindow(window));
window->layer()->Add(shadow->layer());
+ window->layer()->StackAtBottom(shadow->layer());
}
ShadowController::Impl::Impl()
diff --git a/chromium/ui/wm/core/shadow_controller.h b/chromium/ui/wm/core/shadow_controller.h
index 34ac15a3fea..f9c3bee5336 100644
--- a/chromium/ui/wm/core/shadow_controller.h
+++ b/chromium/ui/wm/core/shadow_controller.h
@@ -10,7 +10,6 @@
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/wm_core_export.h"
#include "ui/wm/public/activation_change_observer.h"
@@ -29,9 +28,6 @@ class Shadow;
// which observes all window creation.
class WM_CORE_EXPORT ShadowController : public ActivationChangeObserver {
public:
- static constexpr ShadowElevation kActiveNormalShadowElevation =
- ShadowElevation::LARGE;
-
// Returns the shadow for the |window|, or NULL if no shadow exists.
static Shadow* GetShadowForWindow(aura::Window* window);
diff --git a/chromium/ui/wm/core/shadow_controller_unittest.cc b/chromium/ui/wm/core/shadow_controller_unittest.cc
index b4a6269c4bc..c3af5692265 100644
--- a/chromium/ui/wm/core/shadow_controller_unittest.cc
+++ b/chromium/ui/wm/core/shadow_controller_unittest.cc
@@ -61,23 +61,24 @@ TEST_F(ShadowControllerTest, Shadow) {
window->Init(ui::LAYER_TEXTURED);
ParentWindow(window.get());
- // We should create the shadow before the window is visible (the shadow's
- // layer won't get drawn yet since it's a child of the window's layer).
+ // The shadow is not created until the Window is shown (some Windows should
+ // never get shadows, which is checked when the window first becomes visible).
+ EXPECT_FALSE(ShadowController::GetShadowForWindow(window.get()));
+ window->Show();
+
const Shadow* shadow = ShadowController::GetShadowForWindow(window.get());
ASSERT_TRUE(shadow != NULL);
EXPECT_TRUE(shadow->layer()->visible());
// The shadow should remain visible after window visibility changes.
- window->Show();
- EXPECT_TRUE(shadow->layer()->visible());
window->Hide();
EXPECT_TRUE(shadow->layer()->visible());
// If the shadow is disabled, it should be hidden.
- SetShadowElevation(window.get(), ShadowElevation::NONE);
+ SetShadowElevation(window.get(), kShadowElevationNone);
window->Show();
EXPECT_FALSE(shadow->layer()->visible());
- SetShadowElevation(window.get(), ShadowElevation::MEDIUM);
+ SetShadowElevation(window.get(), kShadowElevationInactiveWindow);
EXPECT_TRUE(shadow->layer()->visible());
// The shadow's layer should be a child of the window's layer.
@@ -97,7 +98,7 @@ TEST_F(ShadowControllerTest, ShadowBounds) {
// When the shadow is first created, it should use the window's size (but
// remain at the origin, since it's a child of the window's layer).
- SetShadowElevation(window.get(), ShadowElevation::MEDIUM);
+ SetShadowElevation(window.get(), kShadowElevationInactiveWindow);
const Shadow* shadow = ShadowController::GetShadowForWindow(window.get());
ASSERT_TRUE(shadow != NULL);
EXPECT_EQ(gfx::Rect(kOldBounds.size()).ToString(),
@@ -123,7 +124,7 @@ TEST_F(ShadowControllerTest, ShadowStyle) {
// window1 is active, so style should have active appearance.
Shadow* shadow1 = ShadowController::GetShadowForWindow(window1.get());
ASSERT_TRUE(shadow1 != NULL);
- EXPECT_EQ(ShadowElevation::LARGE, shadow1->desired_elevation());
+ EXPECT_EQ(kShadowElevationActiveWindow, shadow1->desired_elevation());
// Create another window and activate it.
std::unique_ptr<aura::Window> window2(new aura::Window(NULL));
@@ -137,8 +138,8 @@ TEST_F(ShadowControllerTest, ShadowStyle) {
// window1 is now inactive, so shadow should go inactive.
Shadow* shadow2 = ShadowController::GetShadowForWindow(window2.get());
ASSERT_TRUE(shadow2 != NULL);
- EXPECT_EQ(ShadowElevation::MEDIUM, shadow1->desired_elevation());
- EXPECT_EQ(ShadowElevation::LARGE, shadow2->desired_elevation());
+ EXPECT_EQ(kShadowElevationInactiveWindow, shadow1->desired_elevation());
+ EXPECT_EQ(kShadowElevationActiveWindow, shadow2->desired_elevation());
}
// Tests that shadow gets updated when the window show state changes.
@@ -151,7 +152,7 @@ TEST_F(ShadowControllerTest, ShowState) {
Shadow* shadow = ShadowController::GetShadowForWindow(window.get());
ASSERT_TRUE(shadow != NULL);
- EXPECT_EQ(ShadowElevation::MEDIUM, shadow->desired_elevation());
+ EXPECT_EQ(kShadowElevationInactiveWindow, shadow->desired_elevation());
window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
EXPECT_FALSE(shadow->layer()->visible());
@@ -175,7 +176,7 @@ TEST_F(ShadowControllerTest, SmallShadowsForTooltipsAndMenus) {
Shadow* tooltip_shadow =
ShadowController::GetShadowForWindow(tooltip_window.get());
ASSERT_TRUE(tooltip_shadow != NULL);
- EXPECT_EQ(ShadowElevation::SMALL, tooltip_shadow->desired_elevation());
+ EXPECT_EQ(kShadowElevationMenuOrTooltip, tooltip_shadow->desired_elevation());
std::unique_ptr<aura::Window> menu_window(new aura::Window(NULL));
menu_window->SetType(aura::client::WINDOW_TYPE_MENU);
@@ -187,7 +188,7 @@ TEST_F(ShadowControllerTest, SmallShadowsForTooltipsAndMenus) {
Shadow* menu_shadow =
ShadowController::GetShadowForWindow(tooltip_window.get());
ASSERT_TRUE(menu_shadow != NULL);
- EXPECT_EQ(ShadowElevation::SMALL, menu_shadow->desired_elevation());
+ EXPECT_EQ(kShadowElevationMenuOrTooltip, menu_shadow->desired_elevation());
}
// http://crbug.com/120210 - transient parents of certain types of transients
@@ -204,7 +205,7 @@ TEST_F(ShadowControllerTest, TransientParentKeepsActiveShadow) {
// window1 is active, so style should have active appearance.
Shadow* shadow1 = ShadowController::GetShadowForWindow(window1.get());
ASSERT_TRUE(shadow1 != NULL);
- EXPECT_EQ(ShadowElevation::LARGE, shadow1->desired_elevation());
+ EXPECT_EQ(kShadowElevationActiveWindow, shadow1->desired_elevation());
// Create a window that is transient to window1, and that has the 'hide on
// deactivate' property set. Upon activation, window1 should still have an
@@ -220,7 +221,7 @@ TEST_F(ShadowControllerTest, TransientParentKeepsActiveShadow) {
ActivateWindow(window2.get());
// window1 is now inactive, but its shadow should still appear active.
- EXPECT_EQ(ShadowElevation::LARGE, shadow1->desired_elevation());
+ EXPECT_EQ(kShadowElevationActiveWindow, shadow1->desired_elevation());
}
} // namespace wm
diff --git a/chromium/ui/wm/core/shadow_types.cc b/chromium/ui/wm/core/shadow_types.cc
index 431ab2e41cf..bc8679fc1a2 100644
--- a/chromium/ui/wm/core/shadow_types.cc
+++ b/chromium/ui/wm/core/shadow_types.cc
@@ -6,29 +6,12 @@
#include "ui/base/class_property.h"
-DEFINE_EXPORTED_UI_CLASS_PROPERTY_TYPE(WM_CORE_EXPORT, ::wm::ShadowElevation);
-
namespace wm {
-DEFINE_UI_CLASS_PROPERTY_KEY(ShadowElevation,
- kShadowElevationKey,
- ShadowElevation::DEFAULT);
+DEFINE_UI_CLASS_PROPERTY_KEY(int, kShadowElevationKey, kShadowElevationDefault);
-void SetShadowElevation(aura::Window* window, ShadowElevation elevation) {
+void SetShadowElevation(aura::Window* window, int elevation) {
window->SetProperty(kShadowElevationKey, elevation);
}
-bool IsValidShadowElevation(int64_t value) {
- switch (static_cast<ShadowElevation>(value)) {
- case ShadowElevation::DEFAULT:
- case ShadowElevation::NONE:
- case ShadowElevation::TINY:
- case ShadowElevation::SMALL:
- case ShadowElevation::MEDIUM:
- case ShadowElevation::LARGE:
- return true;
- }
- return false;
-}
-
} // namespace wm
diff --git a/chromium/ui/wm/core/shadow_types.h b/chromium/ui/wm/core/shadow_types.h
index b61a325ac04..5cc02c20baf 100644
--- a/chromium/ui/wm/core/shadow_types.h
+++ b/chromium/ui/wm/core/shadow_types.h
@@ -10,39 +10,28 @@
namespace wm {
+// Indicates an elevation should be chosen based on the window. This is used
+// by wm::ShadowController, but is not a valid elevation to pass to wm::Shadow.
+constexpr int kShadowElevationDefault = -1;
+
// Different types of drop shadows that can be drawn under a window by the
-// shell. Used as a value for the kShadowTypeKey property. The integer value of
-// each entry is directly used for determining the size of the shadow.
-enum class ShadowElevation {
- // Indicates an elevation should be chosen based on the window. This is the
- // default.
- DEFAULT = -1,
- NONE = 0,
- TINY = 2,
- SMALL = 6,
- MEDIUM = 8,
- LARGE = 24,
-};
-
-WM_CORE_EXPORT void SetShadowElevation(aura::Window* window,
- ShadowElevation elevation);
-
-// Returns true if |value| is a valid element of ShadowElevation elements.
-WM_CORE_EXPORT bool IsValidShadowElevation(int64_t value);
+// shell. Used as a value for the kShadowElevationKey property.
+constexpr int kShadowElevationNone = 0;
+
+// Standard shadow elevations used by the the aura window manager. The value is
+// used to initialize an instance of wm::Shadow and controls the offset and blur
+// of the shadow style created by gfx::ShadowValue::MakeMdShadowValues().
+constexpr int kShadowElevationMenuOrTooltip = 6;
+constexpr int kShadowElevationInactiveWindow = 8;
+constexpr int kShadowElevationActiveWindow = 24;
+
+WM_CORE_EXPORT void SetShadowElevation(aura::Window* window, int elevation);
// A property key describing the drop shadow that should be displayed under the
// window. A null value is interpreted as using the default.
-WM_CORE_EXPORT extern const aura::WindowProperty<ShadowElevation>* const
+WM_CORE_EXPORT extern const aura::WindowProperty<int>* const
kShadowElevationKey;
} // namespace wm
-// Declaring the template specialization here to make sure that the
-// compiler in all builds, including jumbo builds, always knows about
-// the specialization before the first template instance use (for
-// instance in shadw_controller.cc). Using a template instance before
-// its specialization is declared in a translation unit is a C++
-// error.
-DECLARE_EXPORTED_UI_CLASS_PROPERTY_TYPE(WM_CORE_EXPORT, ::wm::ShadowElevation);
-
#endif // UI_WM_CORE_SHADOW_TYPES_H_
diff --git a/chromium/ui/wm/core/shadow_unittest.cc b/chromium/ui/wm/core/shadow_unittest.cc
index 3e720a404f0..28cef9b62ac 100644
--- a/chromium/ui/wm/core/shadow_unittest.cc
+++ b/chromium/ui/wm/core/shadow_unittest.cc
@@ -8,11 +8,13 @@
#include "ui/aura/test/aura_test_base.h"
#include "ui/gfx/shadow_util.h"
#include "ui/gfx/shadow_value.h"
-#include "ui/wm/core/shadow_types.h"
namespace wm {
namespace {
+constexpr int kElevationLarge = 24;
+constexpr int kElevationSmall = 6;
+
gfx::Insets InsetsForElevation(int elevation) {
return -gfx::Insets(2 * elevation) + gfx::Insets(elevation, 0, -elevation, 0);
}
@@ -33,22 +35,22 @@ TEST_F(ShadowTest, SetContentBounds) {
// Verify that layer bounds are outset from content bounds.
Shadow shadow;
{
- shadow.Init(ShadowElevation::LARGE);
+ shadow.Init(kElevationLarge);
gfx::Rect content_bounds(100, 100, 300, 300);
shadow.SetContentBounds(content_bounds);
EXPECT_EQ(content_bounds, shadow.content_bounds());
gfx::Rect shadow_bounds(content_bounds);
- shadow_bounds.Inset(InsetsForElevation(24));
+ shadow_bounds.Inset(InsetsForElevation(kElevationLarge));
EXPECT_EQ(shadow_bounds, shadow.layer()->bounds());
}
{
- shadow.SetElevation(ShadowElevation::SMALL);
+ shadow.SetElevation(kElevationSmall);
gfx::Rect content_bounds(100, 100, 300, 300);
shadow.SetContentBounds(content_bounds);
EXPECT_EQ(content_bounds, shadow.content_bounds());
gfx::Rect shadow_bounds(content_bounds);
- shadow_bounds.Inset(InsetsForElevation(6));
+ shadow_bounds.Inset(InsetsForElevation(kElevationSmall));
EXPECT_EQ(shadow_bounds, shadow.layer()->bounds());
}
}
@@ -57,12 +59,12 @@ TEST_F(ShadowTest, SetContentBounds) {
// the full elevation.
TEST_F(ShadowTest, AdjustElevationForSmallContents) {
Shadow shadow;
- shadow.Init(ShadowElevation::LARGE);
+ shadow.Init(kElevationLarge);
{
gfx::Rect content_bounds(100, 100, 300, 300);
shadow.SetContentBounds(content_bounds);
gfx::Rect shadow_bounds(content_bounds);
- shadow_bounds.Inset(InsetsForElevation(24));
+ shadow_bounds.Inset(InsetsForElevation(kElevationLarge));
EXPECT_EQ(shadow_bounds, shadow.layer()->bounds());
}
@@ -88,13 +90,13 @@ TEST_F(ShadowTest, AdjustElevationForSmallContents) {
// Test that rounded corner radius is handled correctly.
TEST_F(ShadowTest, AdjustRoundedCornerRadius) {
Shadow shadow;
- shadow.Init(ShadowElevation::SMALL);
+ shadow.Init(kElevationSmall);
gfx::Rect content_bounds(100, 100, 300, 300);
shadow.SetContentBounds(content_bounds);
EXPECT_EQ(content_bounds, shadow.content_bounds());
shadow.SetRoundedCornerRadius(0);
gfx::Rect shadow_bounds(content_bounds);
- shadow_bounds.Inset(InsetsForElevation(6));
+ shadow_bounds.Inset(InsetsForElevation(kElevationSmall));
EXPECT_EQ(shadow_bounds, shadow.layer()->bounds());
EXPECT_EQ(NineboxImageSizeForElevationAndCornerRadius(6, 0),
shadow.details_for_testing()->ninebox_image.size());
diff --git a/chromium/ui/wm/core/window_util.cc b/chromium/ui/wm/core/window_util.cc
index 264ea83ec1a..d8cbfdc9e6a 100644
--- a/chromium/ui/wm/core/window_util.cc
+++ b/chromium/ui/wm/core/window_util.cc
@@ -131,11 +131,6 @@ void Unminimize(aura::Window* window) {
window->SetProperty(
aura::client::kShowStateKey,
window->GetProperty(aura::client::kPreMinimizedShowStateKey));
- // Clear the property only when the window is actually unminimized.
- if (window->GetProperty(aura::client::kShowStateKey) !=
- ui::SHOW_STATE_MINIMIZED) {
- window->ClearProperty(aura::client::kPreMinimizedShowStateKey);
- }
}
aura::Window* GetActivatableWindow(aura::Window* window) {